# Guest Blog Post - Attacking the DevTools

Unvalidated remoteBase/devtools_page/channel-message inputs let a malicious Edge extension run code in DevTools, script privileged pages, read local files, and escape the sandbox.

- Payout: $36,000
- Severity: high
- Program: Microsoft
- Credited: David Erceg
- Disclosed: 2021-07-21
- Write-up quality: 9/10
- Original: https://microsoftedge.github.io/edgevr/posts/attacking-the-devtools/
- Library page: https://bugbountylibrary.com/r/blog%3Amicrosoftedge-github-io-edgevr-posts-attacking-the-devtools
- Tags: domain:browser impact:privesc impact:rce kind:bounty platform:blog sev:high tech:chromium technique:chained technique:source-review vuln:privilege-escalation vuln:rce vuln:sandbox-escape

**Target:** Chromium/Edge DevTools frontend (inspector.html, ExtensionServer, devtools_page, chrome.devtools messaging)
**Root cause:** DevTools trusted attacker-influenced inputs: remoteBase and devtools_page accepted javascript: URLs, and channel messages from extension DevTools pages could overwrite the stored extension origin used to build panel iframe URLs.
**Steps:**
1. Open DevTools while logging chrome.webRequest.onBeforeRequest; observe devtools:// loading https://devtools.azureedge.net/.../third_party/webhint/worker_frame.html
2. Undock DevTools, press Ctrl+Shift+I to debug it, trace minified JS constructing the frame URL from remoteBase
3. Load `devtools://devtools/bundled/inspector.html?remoteBase=javascript:console.log('x')//` to confirm unvalidated javascript: iframe src
4. Alternatively set devtools_page manifest entry to a javascript: URL so the iframe scripts the DevTools parent
5. Send crafted MessageChannel messages to overwrite the stored extension origin, then call chrome.devtools.panels.create so the panel iframe src becomes a javascript: URL
6. From DevTools context call `InspectorFrontendHost.setInjectedScriptForOrigin('https://en.wikipedia.org','console.log(location.href)//')` then load that site in an iframe to script it
7. Read local files via `DevToolsAPI.sendMessageToEmbedder('loadNetworkResource',['file:///c:/','',0],cb)` with streamWrite hooked
8. Sandbox escape: set localStorage.consolePins to code, open attached DevTools (F12 via Input.dispatchKeyEvent with debugger permission), navigate target to chrome://downloads, pin calls OpenFileRequiringGesture within 5s gesture window
**How found:** Logged webRequest traffic while opening DevTools to spot privileged pages loading frames; debugged the undocked DevTools to trace how remoteBase built the iframe URL; read ExtensionServer.ts/ExtensionAPI.ts to see channel-message handling and origin storage, hypothesizing origin overwrite could yield javascript: iframe src.
**Exploitation:** A malicious extension loads a DevTools URL or its devtools_page, achieves script execution in the DevTools context, then uses DevTools privileges: reads local files, injects scripts into any extension (e.g. Edge Feedback App saveBytesToFile writing an executable to the Startup folder), or uses console pins plus CDP to open a downloaded executable via chrome://downloads.
**Escalation:** Chained DevTools code execution to scripting builtin extensions with private APIs (arbitrary file write to startup folder) and to full Chrome DevTools Protocol access for sandbox escape.
**Insight:** Log chrome.webRequest.onBeforeRequest while loading privileged pages to catch privileged-to-unprivileged frame loads you can redirect; then debug the undocked DevTools and read ExtensionServer.ts to find attacker-controllable values (origins, base URLs) that get concatenated into iframe src.
