HERMES-GIELIE/static
Nathan Esquenazi b563484a56 fix(smd): strip javascript:/data:/vbscript: URLs — smd does not sanitize schemes
streaming-markdown@0.2.15 preserves arbitrary URL schemes in href/src.
Verified with a Node + jsdom harness:

  IN : [click](javascript:alert(1))
  OUT: <p><a href="javascript:alert(1">click</a>)</p>        ← XSS vector

Confirmed unsafe for: javascript:, vbscript:, data:text/html, file://.
The library uses only safe DOM primitives (createElement/appendChild/
createTextNode — no innerHTML/eval), so <script> tags are escaped as
text, but URL-scheme filtering is absent. The existing renderMd() path
implicitly filtered to http(s) via its regex, so this is a regression
the moment streaming markdown is enabled.

Attack path: agent echoes prompt-injection content containing a
markdown link with javascript: href → smd renders it live → user clicks
during the streaming window → JS executes in webui origin → session
cookie, API calls, etc.

Fix: walk the live DOM after each parser_write (and again after
parser_end) and remove href/src attributes whose scheme isn't on the
safe allowlist (http, https, mailto, tel, and relative/anchor paths).
Blocked anchors keep their text content but lose href; blocked images
lose src and get data-blocked-scheme="1" for debugging.

Harness confirms all 10 tested cases behave correctly — javascript:,
vbscript:, data:text/html, file:// all stripped; https://, /path,
#anchor, mailto:, tel: all preserved.

Added 5 regression tests in TestSmdUrlSchemeSanitization that lock:
  - the sanitize helper exists
  - the allowlist regex permits https? and forbids javascript/vbscript/data:
  - _smdWrite invokes sanitize after parser_write
  - _smdEndParser invokes sanitize after parser_end
  - the sanitizer covers both <a href> and <img src>

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 16:28:40 -07:00
..
boot.js release: v0.50.151 — credential_pool provider detection + Ollama Cloud support (PR #820 by @starship-s) 2026-04-22 20:18:02 +00:00
commands.js fix(ui): slash command input now echoed as user message in chat (closes #840) 2026-04-21 23:08:24 -07:00
favicon-32.png fix: add favicon (SVG + PNG + ICO), fix static MIME types (#613) 2026-04-16 20:11:02 -07:00
favicon.ico fix: add favicon (SVG + PNG + ICO), fix static MIME types (#613) 2026-04-16 20:11:02 -07:00
favicon.svg fix: add favicon (SVG + PNG + ICO), fix static MIME types (#613) 2026-04-16 20:11:02 -07:00
i18n.js fix(ci): add missing provider i18n keys to non-English locales — v0.50.160 2026-04-23 01:24:11 +00:00
icons.js feat: composer-centric UI refresh + Hermes Control Center (v0.50.0, closes #242) 2026-04-12 11:55:40 -07:00
index.html feat: incremental streaming markdown via streaming-markdown (v0.50.180, #917) 2026-04-23 23:09:08 +00:00
login.js feat: support subpath mount via reverse proxy — v0.50.67 (PR #588 by @vcavichini) 2026-04-16 11:20:08 -07:00
manifest.json feat: add PWA support (manifest, service worker, install prompt) (#920) 2026-04-23 15:14:21 -07:00
messages.js fix(smd): strip javascript:/data:/vbscript: URLs — smd does not sanitize schemes 2026-04-23 16:28:40 -07:00
onboarding.js fix(config): use Hermes config.yaml as single source of default model (#773) 2026-04-20 22:12:01 +00:00
panels.js fix(mobile): adapt settings dialog and message controls for mobile screens (#919) 2026-04-23 15:12:07 -07:00
sessions.js fix(settings): show live models in default model picker and apply to new chats (#872) (#900) 2026-04-23 09:58:15 -07:00
style.css fix(mobile): adapt settings dialog and message controls for mobile screens (#919) 2026-04-23 15:12:07 -07:00
sw.js feat: add PWA support (manifest, service worker, install prompt) (#920) 2026-04-23 15:14:21 -07:00
ui.js fix(models): duplicate dropdown entries, stale default model, lowercase injected label (#907 #908 #909) (#918) 2026-04-23 14:41:06 -07:00
workspace.js feat: support subpath mount via reverse proxy — v0.50.67 (PR #588 by @vcavichini) 2026-04-16 11:20:08 -07:00