Security hardening: escape generated HTML (XSS), validate manifest path, pin/lock deps - #11
Open
jmitchellol wants to merge 1 commit into
Open
Security hardening: escape generated HTML (XSS), validate manifest path, pin/lock deps#11jmitchellol wants to merge 1 commit into
jmitchellol wants to merge 1 commit into
Conversation
…n risk - SKILL.md: require HTML-escaping of all interpolated content and add a restrictive Content-Security-Policy to the generated guide and dashboard. Analyzed source (or an imported manifest) can contain markup, and the artifacts are auto-opened in a browser, so unescaped content was an XSS vector. - server.py: validate that the --manifest path resolves to a .json file as defense in depth for the atomic manifest write (Snyk CWE-23). - mcp: stop git-ignoring uv.lock and add an upper bound to the mcp dependency so installs are reproducible and auditable. Co-authored-by: Cursor <cursoragent@cursor.com>
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
Hardens the skill's generated artifacts and the MCP server against issues found in a security review.
1. Prevent XSS in generated HTML (highest impact)
SKILL.mdtells the agent to embed real source snippets — and, in the dashboard, manifestname/descriptionfields and imported manifests — into self-contained HTML that Phase 6 auto-opens in the browser. Nothing required escaping that content, so a source file (or imported manifest) containing markup like</pre><script>...</script>or<img src=x onerror=...>would execute as JavaScript when the guide/dashboard opens. This matters precisely because the skill is pointed at unfamiliar/inherited code.& < > " '; neverinnerHTMLwith untrusted strings; prefertextContent).Content-Security-Policymeta tag in every generated file — compatible with the inline-script design and blocks network exfiltration as defense in depth.2. Validate the
--manifestpath (mcp/server.py)The
--manifestargument flowed unsanitized into the atomic write insave_manifest(Snyk CWE-23, Low). It is trusted operator config, but as defense in depthconfigure_manifestnow requires it to resolve to a.jsonfile.3. Reproducible dependencies (
mcp/)uv.lockwas git-ignored andmcpwas pinned open-ended (>=1.2.0), so installs weren't reproducible and there was no lockfile to audit. Stops ignoringuv.lockand adds an upper bound (mcp>=1.2.0,<2). Runuv lockand commit the result to finish this.Test plan
python3 -m py_compile mcp/server.pycoverage_summary/find_by_filework on the example manifest; a non-.json--manifestpath is rejectedmcp/test_server.pypasses (4/4). pytest isn't installable in this environment, so the exact test functions were run via a stdlib driver supplying thetmp_pathfixture; all use.jsonmanifest paths, so the new validation doesn't affect them.<script>/<img>execution, no network callback), while an unescaped control does fire — confirming escaping is the effective defense. The CSP meta tag is present in every generated artifact as defense in depth.Found via a security audit (Snyk SAST + package health + manual review).
Made with Cursor