How to Achieve RCE on Windows 11 via Discord Activity Iframe: Exploiting Discord 1.0.9245

This article explains how the Discord Activity stock-client RCE PoC exploits the V8 JavaScript engine and Electron IPC bridge to achieve native code execution on Windows 11 through a sandboxed iframe.

The discord-activity-stock-client-rce-poc in the bikini/exploitarium repository demonstrates a sophisticated proof-of-concept that chains multiple vulnerabilities to escape the Activity iframe sandbox and execute arbitrary Windows commands. This exploit specifically targets Discord version 1.0.9245 by manipulating the Electron renderer process and native function resolution.

Understanding the Discord Activity Sandbox Architecture

Discord Activities load third-party web applications inside a sandboxed renderer environment served through <APP_ID>.discordsays.com. The platform implements Content Security Policy (CSP) nonces that propagate to every inline script, creating a restricted execution context that this exploit circumvents through memory corruption techniques.

The Iframe CSP and Proxy Mechanism

When a user launches an Activity, Discord proxies the request through https://<APP_ID>.discordsays.com and injects a CSP nonce into the page header. According to the source analysis, this nonce is propagated to every inline script during initial render. The sandboxed iframe runs inside a V8 renderer process that normally prevents access to native system APIs.

The Multi-Stage Exploit Chain

The RCE achieves code execution through four distinct stages, progressing from JavaScript memory corruption to native process creation.

Stage 1: Memory Primitive Acquisition

The exploit begins by abusing a V8 JIT-spray or out-of-bounds write primitive to corrupt memory within the renderer process. Specifically, the attacker rewrites the auxiliary-window policy in the stock Discord binary located in the main process memory. This modification allows the creation of auxiliary renderer windows without requiring explicit user permission, bypassing Discord's window management security controls.

Stage 2: Auxiliary Renderer Creation

With the policy bypass in place, the exploit opens a second renderer window through the compromised auxiliary window API. This secondary renderer operates with different privilege boundaries than the original Activity iframe, providing access to internal Electron APIs that are normally inaccessible from sandboxed content.

Stage 3: Electron IPC Bridge Resolution

The second-stage script resolves critical Electron IPC bridge functions including DiscordNative.app.relaunch and DiscordNative.processUtils.getLastCrash. These native bindings, implemented in server.js, expose the underlying Node.js process to the renderer context. The exploit uses this bridge to invoke native functions inside the main Discord process, breaking the isolation between the web content and the host operating system.

Stage 4: Native Payload Execution

The final stage constructs position-independent shellcode that resolves three critical Windows API functions from the loaded Discord executable: CreateProcessW, Sleep, and ExitProcess. The payload specifically calls CreateProcessW("C:\\Windows\\System32\\calc.exe") to demonstrate code execution, then exits with the sentinel value 0x51a71338. The run.ps1 helper script monitors for this exit code to confirm successful exploitation before triggering a Discord relaunch to restore original user settings.

Preparing the Environment and Validation

Before executing the exploit, the environment must meet strict prerequisites to ensure reliable operation.

Discord Build Verification

The PoC validates the exact Discord build hash to ensure memory offsets and binary structures match the expected layout. The run.ps1 script checks for hash C14A6B393AAD5EFAF7E9CCB2BADDBE6943D00B2073D777A6786FDD5AC405722E before proceeding. Additionally, the system must have exactly one running stock Discord process with no other Discord instances active, as verified by the PowerShell helper at lines 45-48.

Environment Prerequisites

The attack requires:

  • Windows 11 target system with Discord 1.0.9245 installed
  • Node.js runtime for the PoC server
  • Network tunnel (such as cloudflared) to expose the local server via HTTPS
  • Valid Discord application with Activities enabled in the Developer Portal

Running the Proof-of-Concept

Execute the exploit chain using the provided automation scripts and manual configuration steps.

Automated Setup with PowerShell

Validate the target binary and launch the coordination server:


# Navigate to the PoC directory and execute the helper

.\run.ps1

This script performs hash validation, backs up the user's Discord settings to prevent data loss, ensures single-process operation, and starts the Node.js server. It also handles post-exploitation cleanup and Discord restoration.

Starting the PoC Server

Install dependencies and launch the HTTP server that serves the malicious Activity page:

cd discord-activity-stock-client-rce-poc
npm install
node server.js

The server.js file implements the HTTP server, handles CSP nonce propagation, serves the multi-stage exploit JavaScript, and coordinates the auxiliary window creation flow described in the technical analysis.

Configuring the Discord Activity

Complete the setup through the Discord Developer Portal:

  1. Create a new application or select an existing one.
  2. Navigate to Activities and enable the feature.
  3. Set the Launch URL to your HTTPS tunnel endpoint pointing to the PoC server.
  4. Share the Activity invite link in a channel and click Launch.

Discord loads the Activity through https://<APP_ID>.discordsays.com, triggering the exploit chain that ultimately executes calc.exe on the target Windows 11 system.

Summary

  • The exploit targets Discord 1.0.9245 on Windows 11 through a malicious Activity iframe.
  • Memory corruption bypasses the auxiliary-window policy to create unauthorized renderer windows.
  • The Electron IPC bridge (DiscordNative.app.relaunch) exposes native process capabilities to JavaScript.
  • Native API functions (CreateProcessW, Sleep, ExitProcess) are resolved dynamically from the Discord binary.
  • The run.ps1 helper validates build hash C14A6B393AAD5EFAF7E9CCB2BADDBE6943D00B2073D777A6786FDD5AC405722E and manages the exploitation lifecycle.
  • Successful execution is confirmed via exit code 0x51a71338 before automatic restoration of user settings.

Frequently Asked Questions

What specific Discord version is vulnerable to this Activity iframe RCE?

The proof-of-concept specifically targets Discord version 1.0.9245 with the exact binary hash C14A6B393AAD5EFAF7E9CCB2BADDBE6943D00B2073D777A6786FDD5AC405722E. The run.ps1 validation script ensures these specific conditions are met before execution, as memory offsets and auxiliary window policies vary between builds.

How does the exploit bypass Discord's sandbox protections?

The attack chains a V8 memory corruption primitive to rewrite the auxiliary-window policy in the Discord binary, allowing creation of a second renderer without user consent. This secondary renderer accesses the internal Electron IPC bridge (DiscordNative namespace) that exposes native Node.js APIs, effectively breaking the sandbox isolation between web content and the host process.

What files are required to execute this Windows 11 RCE proof-of-concept?

The exploit requires server.js to serve the Activity page and coordinate stages, run.ps1 to validate the environment and manage execution, and the evidence/verified-stock-run.json file which contains the execution evidence template. The Node.js server handles CSP nonce propagation and auxiliary window coordination while the PowerShell script manages binary validation and cleanup.

Why does the PoC use calc.exe as the payload?

The proof-of-concept uses CreateProcessW("C:\\Windows\\System32\\calc.exe") as a benign demonstration of arbitrary code execution capability. This approach provides visual confirmation of successful RCE without causing system damage. The payload exits with sentinel value 0x51a71338, which the verification page polls to confirm successful exploitation before triggering the final Discord relaunch via DiscordNative.app.relaunch to restore original settings.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →