Skip to content

security: harden URL schemes in non-HTML renderers#255

Merged
dereuromark merged 1 commit into
masterfrom
security/importer-url-hardening
Jun 27, 2026
Merged

security: harden URL schemes in non-HTML renderers#255
dereuromark merged 1 commit into
masterfrom
security/importer-url-hardening

Conversation

@dereuromark

Copy link
Copy Markdown
Contributor

Follow-up to the always-on HTML hardening (#253). Closes the real carry-through behind the HtmlToDjot importer concern.

Problem

The HTML renderer blanks dangerous URL schemes, but the Markdown / plain-text / ANSI renderers emitted link destinations and image sources verbatim. A javascript: / vbscript: / data: / file: URL therefore carried straight into a Markdown or terminal export - markup that is rendered or clicked somewhere else (the same XSS path the importer worried about, just on the output side).

The importer itself is deliberately not a sanitizer (documented at HtmlToDjot line 27); its output is re-rendered through these renderers, which is the correct place to enforce the denylist. Doing it here covers every source - imported HTML, hand-written Djot, anything - not just the importer.

Change

  • Add Djot\Util\UrlSafety - the shared dangerous-scheme denylist (javascript, vbscript, data, file) plus hasDangerousScheme() / sanitize(). Scheme detection strips C0 controls + spaces, so java\tscript: cannot evade.
  • MarkdownRenderer / AnsiRenderer blank a dangerous link/image URL; PlainTextRenderer falls back to the link text. Safe and relative URLs are untouched.
  • Refactor HtmlRenderer to delegate its always-on baseline to UrlSafety (single source of truth; behavior unchanged).

Follow-up to the always-on HTML hardening: the Markdown, plain-text and ANSI
renderers emitted link destinations and image sources verbatim, so a dangerous
scheme (javascript:/vbscript:/data:/file:) carried straight into a Markdown or
terminal export - markup that gets rendered or clicked elsewhere.

- Add Djot\Util\UrlSafety with the shared scheme denylist + sanitize helpers.
- MarkdownRenderer / AnsiRenderer blank a dangerous link/image URL; PlainText
  falls back to the link text. Safe and relative URLs are untouched.
- Refactor HtmlRenderer to delegate its baseline to UrlSafety (single source).

This is the renderer-side fix for the carry-through; the HtmlToDjot importer is
deliberately not a sanitizer (its output is re-rendered through these now-hardened
renderers).
@codecov

codecov Bot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.35%. Comparing base (ff46886) to head (c740c15).

Additional details and impacted files
@@            Coverage Diff            @@
##             master     #255   +/-   ##
=========================================
  Coverage     92.35%   92.35%           
- Complexity     3628     3630    +2     
=========================================
  Files           108      109    +1     
  Lines         10250    10253    +3     
=========================================
+ Hits           9466     9469    +3     
  Misses          784      784           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@dereuromark dereuromark merged commit f584070 into master Jun 27, 2026
6 checks passed
@dereuromark dereuromark deleted the security/importer-url-hardening branch June 27, 2026 02:35
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.

1 participant