fix(renderer): vendor marked/dompurify to close third-party CDN RCE vector#51
Merged
Conversation
…ector index.html loaded marked and dompurify from cdn.jsdelivr.net with no Subresource Integrity and no CSP. Those scripts run in a pywebview window whose window.pywebview.api bridge reaches execute_command (subprocess.run(shell=True)) and read_file/write_file, so a MITM or a jsdelivr compromise serving altered library code would gain arbitrary shell execution and file access on the user's machine. The same gap also silently defeated the DOMPurify.sanitize fallback in renderer.js when the CDN failed to load. Vendor the exact pinned versions (marked 12.0.2, DOMPurify 3.1.5, taken from the npm tarballs) under src/renderer/vendor and load them by relative path so no library code is fetched over the network at launch. Add a script-src 'self' Content-Security-Policy to the window (mirroring the policy terminal.html already ships) so only same-origin scripts can ever execute here. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JjqBRjjqNLJuUCMibLDKKP
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Contributor
There was a problem hiding this comment.
ESLint found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
npx eslint . linted the newly vendored marked.min.js / purify.min.js, producing ~1,500 style errors on third-party minified code. Exclude the vendor directory and any *.min.js from linting so ESLint only scans first-party source. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JjqBRjjqNLJuUCMibLDKKP
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
src/renderer/index.htmlloadedmarked@12.0.2anddompurify@3.1.5fromcdn.jsdelivr.netwith no Subresource Integrity and no Content-Security-Policy. Those scripts execute inside a pywebview window whosewindow.pywebview.apibridge reachesexecute_command(subprocess.run(..., shell=True)) andread_file/write_file(python/services/mcp_tools.py).That means a network MITM or a jsdelivr compromise serving altered library code would gain arbitrary shell execution and file read/write on the user's machine — every launch fetches these scripts over the network. The same gap also silently defeated the
DOMPurify.sanitizefallback inrenderer.js(raw HTML is rendered if DOMPurify fails to load from the CDN).Changes
marked 12.0.2andDOMPurify 3.1.5, extracted from the official npm tarballs, added undersrc/renderer/vendor/and loaded by relative path. No library code is fetched over the network at launch anymore.script-src 'self'CSP to the window (object-src 'none'; base-uri 'none'), mirroring the policyterminal.htmlalready ships under pywebview, so only same-origin scripts can ever execute in this bridge-privileged window.default-srcis intentionally left unset so fonts, styles, images, and the pywebview bridge are unaffected.Verification
marked.parserenders markdown correctly andDOMPurifyexports its browser factory.fetch/XHR/WebSocket), so restrictingscript-srcdoes not affect app functionality.Note: this is a code-only change to a desktop GUI app, so it could not be exercised end-to-end in the review environment; the swap is behavior-preserving (same library code, served locally).
Generated by Claude Code