Repository navigation
fix: keep a document's frames, scripts and styles from reaching MemoryStick's own page - #7
Merged
Merged
Conversation
…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.
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.
What changed
render()indist/app.jsparses a document in an inert<template>before showing it. It used to drop only<meta>and<link>elements. It now also dropsiframe,frame,frameset,object,embed,script,baseandstyle:<iframe srcdoc>shares the page's origin, and the CSPframe-src 'none'does not governabout:srcdocframes, 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.<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,embedandbasewere 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
styleattributes), and the CSP allows them, so<div style="position:fixed;inset:0;z-index:9999">could cover the toolbar.#contentnow hascontain: 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_ELEMENTSconstant indist/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 askbdordetails, or ifrender()stops applying it.Why not comrak's tagfilter
The plan was to also turn on GFM
tagfilterinmarkdown.rs. comrak 0.56.0 (the version inCargo.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 coverobject,embed,base,metaorlink). So the template pass inrender()is the single place these elements are removed, and a comment inmarkdown.rsnext tor#unsafenow 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 --checkandcargo test --lockedinsrc-tauri: 8 passed.node --check dist/app.js.meta refresh,base,link prefetch,iframe srcdoc,frameset/frame,object,embed,script src=app.js,styleand SVGstyle: all removed, whilekbd,detailsand inlinesvgcontent stay. The same check onmain's selector leaksbase,iframe,object,embed,scriptandstyle.docs/sample.mduses none of the removed elements, so it renders the same.python3 .github/scripts/check-document-filter.pypasses, and fails wheniframeis swapped forkbdin the constant.