Skip to content

fix(security): sanitize note HTML (XSS) and add a Host allowlist (#125)#141

Merged
CryptoJones merged 1 commit into
mainfrom
fix/125-web-xss-host-allowlist
Jul 1, 2026
Merged

fix(security): sanitize note HTML (XSS) and add a Host allowlist (#125)#141
CryptoJones merged 1 commit into
mainfrom
fix/125-web-xss-host-allowlist

Conversation

@CryptoJones

Copy link
Copy Markdown
Owner

Closes #125.

  • Stored XSS: note markdown is authored by agents and synced from mesh peers (untrusted), and was rendered through marked v15 straight into innerHTML — a prompt-injected note (<img src=x onerror=...>, a javascript: 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.
  • DNS rebinding: the API had no Host validation. Added TrustedHostMiddleware (localhost allowlist by default); omind serve adds an explicit bind host to the allowlist and disables the check only for a deliberate 0.0.0.0/:: bind, warning in both non-localhost cases.

Test plan

  • New tests: a foreign Host header gets 400, an explicitly-allowed host gets 200. node --check on app.js. Wheel build confirms purify.min.js is 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/

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>
@CryptoJones CryptoJones merged commit c262a38 into main Jul 1, 2026
14 checks passed
@CryptoJones CryptoJones deleted the fix/125-web-xss-host-allowlist branch July 1, 2026 23:40
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.

Web UI: sanitize rendered note HTML (stored XSS) and add localhost auth / Host allowlist

1 participant