fix(security): sanitize note HTML (XSS) and add a Host allowlist (#125)#141
Merged
Conversation
Note markdown is authored by agents and synced from mesh peers — untrusted — and was rendered through marked into innerHTML with no sanitization, so a prompt-injected note (<img src=x onerror=...>, a javascript: link) could run JS with same-origin access to the destructive CRUD API the moment the note was opened. Run the rendered HTML through DOMPurify (vendored 3.4.8, sha256-verified against the official build; keeps the wikilink/tag <a>/<span>, strips scripts/handlers/dangerous URLs); fall back to escaping if it fails to load. The API also had no Host validation, so a malicious page could rebind its hostname to 127.0.0.1 and drive it (DNS rebinding). Add a TrustedHostMiddleware allowlist (localhost by default; the CLI adds an explicit bind host and disables the check for a deliberate 0.0.0.0 bind) and warn on a non-localhost bind. Closes #125. Co-Authored-By: Claude Fable 5 <noreply@anthropic.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.
Closes #125.
innerHTML— a prompt-injected note (<img src=x onerror=...>, ajavascript:link) could execute JS with same-origin access to the destructive CRUD API the moment the note was opened. The rendered HTML is now run through DOMPurify (vendored 3.4.8, sha256-verified against the official jsdelivr build; keeps the wikilink/tag<a>/<span>—class+data-*— and strips scripts/event-handlers/dangerous URLs). Falls back to escaping if the vendor script fails to load.TrustedHostMiddleware(localhost allowlist by default);omind serveadds an explicit bind host to the allowlist and disables the check only for a deliberate0.0.0.0/::bind, warning in both non-localhost cases.Test plan
Hostheader gets 400, an explicitly-allowed host gets 200.node --checkon app.js. Wheel build confirmspurify.min.jsis packaged. Full suite: 724 passed, 1 skipped. ruff + mypy clean.🤖 Generated with Claude Code
Proudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/