Skip to content

v0.1.48

Latest

Choose a tag to compare

@github-actions github-actions released this 01 Oct 08:55

release: aurora 0.1.48

Refuse a slot in a script's URL, and name the file input that cannot take a value

A third audit, all four findings confirmed.

<script src> was guarded like any other URL: javascript:, vbscript: and data: were neutralised and everything else went through. But every URL in that position is code with the page's authority — https:// on another origin runs, and so does a blob: the page minted from someone's upload; Chromium ran one from the markup the server used to emit. No check on the value can tell the script the author meant from one the value picked, so a slot there is now refused on every path: src in HTML, href and xlink:href on an SVG script, and the .src property. A script chosen at runtime is a decision for code that creates the element itself. A non-empty .value on an threw the DOM's own InvalidStateError on the client render and on hydration, which named neither the binding nor the fix. aurora now throws E_AURORA_FILE_INPUT_VALUE first, pointing at "" to clear the field. The server's attribute is left alone: the browser ignores it, and the scanner does not read the value of type. HttpClient.extend() copied every default but the XSRF settings, so a derived client fell back to the default cookie and header names and stopped sending the CSRF header an app had configured. They are inherited now, and overridable like the rest. And liveClient's doc still required a reactive slot to be the only content of its element. SSR has wrapped every text slot in markers since, so `Count: ${count}!` hydrates and patches; the rule is gone and a test shows it. ### Close the scripts foreign content left open, and guard what loads code Two more audits, every execution finding confirmed in Chromium before it was fixed. The proofs live in tests/browser/execution-contexts.test.ts: each case renders the markup the old code emitted into a same-origin srcdoc iframe and watches a probe get set, then shows the new code refuse. createContextualFragment was the first attempt and it lied — it never runs an SVG script, so it made a live hole look closed. <script> is a script. The previous round suspended the raw-text rules under because the tokenizer does not switch state there, which is true of the tokenizer and irrelevant to the result: an SVG script element still runs its text content. The same holds for <style>. Both are now tracked as code inside foreign content and a slot in them is refused. MathML gets its remaining integration points (mi, mo, mn, ms, mtext), and foreign content now ends where the parser ends it — a ,

, and the rest of the breakout list, and the

and
end tags, pop back to HTML, so

<script> is an HTML script again, not SVG text. <script/> is not self-closing. In HTML a trailing slash is ignored on everything but a void element, so <script/>${v} put the value in a live script while the scanner believed the tag closed. The slash is honoured only in foreign content and on and themselves, and a space between the slash and the > cancels it —