Skip to content

fix(renderer): vendor marked/dompurify to close third-party CDN RCE vector#51

Merged
djleamen merged 2 commits into
mainfrom
claude/intelligent-maxwell-gqrtrz
Jul 6, 2026
Merged

fix(renderer): vendor marked/dompurify to close third-party CDN RCE vector#51
djleamen merged 2 commits into
mainfrom
claude/intelligent-maxwell-gqrtrz

Conversation

@djleamen

@djleamen djleamen commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Summary

src/renderer/index.html loaded marked@12.0.2 and dompurify@3.1.5 from cdn.jsdelivr.net with no Subresource Integrity and no Content-Security-Policy. Those scripts execute inside a pywebview window whose window.pywebview.api bridge reaches execute_command (subprocess.run(..., shell=True)) and read_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.sanitize fallback in renderer.js (raw HTML is rendered if DOMPurify fails to load from the CDN).

Changes

  • Vendor the exact pinned versions locallymarked 12.0.2 and DOMPurify 3.1.5, extracted from the official npm tarballs, added under src/renderer/vendor/ and loaded by relative path. No library code is fetched over the network at launch anymore.
  • Add a script-src 'self' CSP to the window (object-src 'none'; base-uri 'none'), mirroring the policy terminal.html already ships under pywebview, so only same-origin scripts can ever execute in this bridge-privileged window. default-src is intentionally left unset so fonts, styles, images, and the pywebview bridge are unaffected.

Verification

  • Confirmed the vendored files are byte-identical to the published npm packages and match the previously-referenced CDN versions.
  • Loaded both under Node: marked.parse renders markdown correctly and DOMPurify exports its browser factory.
  • The renderer performs all IO through the pywebview bridge (no fetch/XHR/WebSocket), so restricting script-src does 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

…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
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@github-advanced-security github-advanced-security AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
@sonarqubecloud

sonarqubecloud Bot commented Jul 6, 2026

Copy link
Copy Markdown

@djleamen
djleamen merged commit 12d3a74 into main Jul 6, 2026
11 checks passed
@djleamen
djleamen deleted the claude/intelligent-maxwell-gqrtrz branch July 6, 2026 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants