Skip to content

fix: keep a document's frames, scripts and styles from reaching MemoryStick's own page - #7

Merged
MotherSphere merged 2 commits into
mainfrom
fix/gfm-tagfilter
Oct 9, 2026
Merged

MotherSphere merged 2 commits into
mainfrom
fix/gfm-tagfilter

Conversation

@MotherSphere

@MotherSphere MotherSphere commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

What changed

render() in dist/app.js parses a document in an inert <template> before showing it. It used to drop only <meta> and <link> elements. It now also drops iframe, frame, frameset, object, embed, script, base and style:

  • An <iframe srcdoc> shares the page's origin, and the CSP frame-src 'none' does not govern about:srcdoc frames, so <iframe srcdoc="<script src='app.js'></script>"> could load MemoryStick's own scripts in a frame. It is now removed before the page sees it.
  • A document's <style> (including one inside inline SVG) applied to the whole window, not only to the document. It is now left out, as on GitHub.
  • object, embed and base were already blocked by the CSP (object-src 'none', base-uri 'none'); they are removed as well, so the DOM pass does not depend on the CSP.

Other raw HTML (kbd, details, sub, inline SVG...) is kept. Mermaid's own SVG styles are added after this pass and are unaffected.

A document stays in its own area

A document's inline styles are kept (as style attributes), and the CSP allows them, so <div style="position:fixed;inset:0;z-index:9999"> could cover the toolbar. #content now has contain: paint: a fixed element is placed and clipped within the document's box, and the toolbar, contents panel and toasts stay on top.

Regression check

The selector is now the DROPPED_ELEMENTS constant in dist/app.js. A new CI job, Document filter, runs .github/scripts/check-document-filter.py, which fails if one of the ten elements goes missing from it, if it starts dropping ordinary HTML such as kbd or details, or if render() stops applying it.

Why not comrak's tagfilter

The plan was to also turn on GFM tagfilter in markdown.rs. comrak 0.56.0 (the version in Cargo.lock) removed that extension after deprecating it in 0.55.0, and going back to 0.54 would drop the 0.55/0.56 DoS fixes. tagfilter was also a narrower string filter than the DOM pass (it does not cover object, embed, base, meta or link). So the template pass in render() is the single place these elements are removed, and a comment in markdown.rs next to r#unsafe now states that contract.

The README's privacy paragraph now says that scripts, frames, embedded objects and style sheets are left out of a displayed document.

Verification

  • cargo fmt --check and cargo test --locked in src-tauri: 8 passed.
  • node --check dist/app.js.
  • The new selector was run through jsdom against meta refresh, base, link prefetch, iframe srcdoc, frameset/frame, object, embed, script src=app.js, style and SVG style: all removed, while kbd, details and inline svg content stay. The same check on main's selector leaks base, iframe, object, embed, script and style.
  • docs/sample.md uses none of the removed elements, so it renders the same.
  • python3 .github/scripts/check-document-filter.py passes, and fails when iframe is swapped for kbd in the constant.

…yStick's own page

render() parses a document in an inert template and dropped only meta and link elements. It now also drops iframe, frame, frameset, object, embed, script, base and style, so an <iframe srcdoc> cannot load the app's own scripts in a same-origin frame and a document's style sheet cannot restyle the interface. comrak 0.56 removed its tagfilter extension, so the DOM pass in app.js is where these elements are removed; markdown.rs documents that contract.
… in CI

#content gets contain: paint, so an element with an inline position: fixed
is placed and clipped within the document and cannot cover the toolbar.
The dropped-element selector moves to DROPPED_ELEMENTS, and a new CI job
fails if it loses one of the elements or stops being applied.
@MotherSphere
MotherSphere merged commit 30b485e into main Oct 9, 2026
9 checks passed
@MotherSphere
MotherSphere deleted the fix/gfm-tagfilter branch October 9, 2026 12:39
@github-actions github-actions Bot mentioned this pull request Oct 9, 2026
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