You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
JS DOM-safe rendering: stop string-concat HTML into the toolbar iframe
The toolbar iframe is loaded same-origin with the host app, so any HTML
injection inside it is effectively XSS against the app being developed.
Several panels were composing HTML by string concatenation from data that
crosses the toolbar's trust boundary (cross-origin response headers,
attacker-influenced URLs, raw composer error bodies). Replace each sink
with DOM construction via `document.createElement` / jQuery `.text()` /
`.append()`.
* HistoryPanel: build each row by parsing the template once, substituting
only the (sanitized) UUID `{id}` into the href/data-request attributes,
and populating method/status/type/url/time via `.text()`. Replaces the
prior pattern that interpolated all six placeholders raw into HTML and
parsed the result with `.after(string)`. Also rewrites the
`[data-request=...]` selector as a `.filter()` predicate so a runtime
request id can't slip into selector syntax.
* CachePanel / RequestPanel `addMessage`: switch
`$(`<p>${text}</p>`)` to `$('<p>').text(text)`.
* PackagesPanel: assemble the success / error output as jQuery-built
elements with `.text()`, and `showMessage()` clears the terminal with
`.empty().append(...)` rather than `.html(string)`. Fixes a pre-existing
bug along the way: the error callback was passing the jQuery `textStatus`
argument to `buildErrorMessage` (which expected an XHR object), so every
non-2xx response was previously a silent JSON.parse throw. The error
builder now takes the jqXHR object directly and falls back to
`responseText` / `statusText` / a literal "Request failed".
* postMessage handlers in `inject-iframe.js` and `Toolbar.onMessage` now
reject any message whose origin is not same-origin and whose source is
not the expected counterpart window (the iframe contentWindow on the
parent side, `window.parent` on the iframe side). Today only resize and
XHR-counter messages flow, so the practical impact of the missing check
is low, but the one-line hardening keeps the protocol safe as it grows.
ESLint output for the touched files is clean; the remaining lint
warnings/errors (Turbo undefined, unnamed function expressions in Toolbar
and inject-iframe, Keyboard.js return) are pre-existing on 5.x.
0 commit comments