Breaking Out of Restricted Mode: XSS to RCE in Visual Studio Code

Author: Devesh Logendran (STAR Labs SG)
Published: May 14, 2025
Source: https://starlabs.sg/blog/2025/05-breaking-out-of-restricted-mode-xss-to-rce-in-visual-studio-code/

Summary

STAR Labs detailed a cross-site scripting flaw in Visual Studio Code’s Jupyter notebook error rendering that can be chained into full remote code execution. A crafted .ipynb file triggers unsanitized HTML in the “minimal error” renderer, executing JavaScript inside a VS Code WebView. From there the researcher pivoted through the vscode-file origin and abused two IPC file handlers to write to a Node module and gain code execution as the VS Code user. Notably, the initial XSS fires even in Restricted Mode, the default for untrusted workspaces. Microsoft assessed the report as low severity and declined immediate servicing, and the research was publicly disclosed on May 14, 2025. The article cites VS Code ≤ 1.89.1 as affected.

Technical Details

The entry point is the minimal error renderer introduced for notebook support in VS Code 1.89. When VS Code displays an error stack trace, formatStackTrace() (in stackTraceHelper.ts) and the related linkifyStack() logic use a regular expression to turn cell references such as “Cell In [1], line 6” into HTML anchor tags. The regex captures the expected prefix but allows arbitrary attacker-controlled content to precede the “Cell In” marker, so a stack trace like <a><img src onerror=...>Cell In [1], line 6 produces malformed HTML. createMinimalError() then assigns this string directly to headerSection.innerHTML when it begins with <a, so the injected <img onerror> handler runs JavaScript within the vscode-app-origin WebView. Because this path is the minimal error rendering, it bypasses the workspace trust checks and executes even with Restricted Mode enabled.

Escalation to RCE. From the WebView iframe, the exploit loads a malicious SVG — a valid extension under the vscode-file protocol — so the code runs in the vscode-file origin, which exposes top.vscode.ipcRenderer. Two IPC handlers, "vscode:readNlsFile" and "vscode:writeNlsFile", are vulnerable to directory traversal. The researcher used the write handler to plant executable code into graceful-fs.js (a Node module loaded by VS Code) and then triggered a window reload, causing the planted code to execute. The root cause is unsanitized HTML reaching innerHTML in a trusted WebView, compounded by IPC file handlers that fail to constrain path traversal.

Impact

The chain yields full remote code execution as the VS Code process user: arbitrary command execution and arbitrary filesystem read/write, up to system-level compromise of the developer’s machine. Delivery is via a malicious notebook file, and the critical property is that the triggering XSS works even against untrusted workspaces opened in Restricted Mode, weakening a protection users specifically rely on for untrusted code. The article rates the issue High severity and lists Visual Studio Code ≤ 1.89.1 as affected (discovered April 2024).

Mitigation

Per the disclosure timeline, Microsoft (2024-08-02) assessed the report as low severity and declined immediate servicing, citing the extensive user interaction required, and the researcher published the details on 2025-05-14. The writeup recommends strictly validating the errorLocation/stack-trace format before any innerHTML assignment, and implementing a Content Security Policy in the notebook renderer WebViews for Restricted Mode. As defensive guidance, users should be cautious opening untrusted notebook files, keep VS Code updated, and not rely on Restricted Mode alone as a boundary for hostile content. Note: the article does not assign a CVE for this issue.

References

Leave a Comment