Skip to content

[UI] Escape event history values before rendering them as HTML - #5533

Open
r0g18 wants to merge 1 commit into
google:masterfrom
r0g18:fix/event-history-escape
Open

r0g18 wants to merge 1 commit into
google:masterfrom
r0g18:fix/event-history-escape

Conversation

@r0g18

@r0g18 r0g18 commented Oct 7, 2026

Copy link
Copy Markdown

testcase-event-history renders _formatEvent() through inner-h-t-m-l, and _formatEvent builds that string with JSON.stringify, which escapes for JavaScript and not for HTML: it leaves < and > untouched. Event fields include task_comments, which carries text produced during task execution, so markup that ends up in an event becomes live DOM on the testcase detail page. The default CSP allows script-src 'unsafe-inline', so an injected inline event handler runs in the authenticated origin.

Fixes #5532.

This escapes every dynamic key and value before interpolating them; the <b> wrappers stay markup, so the rendering is unchanged for ordinary values.

Verified by running the repository's real _formatEvent in headless Chrome under the production CSP, with task_comments set to <img src=x onerror=...>:

before after
sink content {"task_comments": "<img src="x" onerror="...">"} {"task_comments": "&lt;img src=x onerror=...&gt;"}
inline handler ran yes no

On tests: the only JavaScript test file under src/clusterfuzz/_internal/tests/appengine/javascripts/ is fake_test.js, and I could not find a runner wiring these Polymer components into CI, so I did not add a test that would not run. If you point me at the harness you want this covered by, I will add one.

@r0g18
r0g18 requested a review from a team as a code owner October 7, 2026 08:50
@google-cla

google-cla Bot commented Oct 7, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

testcase-event-history renders _formatEvent() through inner-h-t-m-l, and
_formatEvent builds that string with JSON.stringify, which does not HTML-encode.
Event fields include task_comments, which carries text produced during task
execution, so markup in that text becomes live DOM on the testcase detail page.
The default CSP allows script-src 'unsafe-inline', so an injected inline event
handler runs in the authenticated origin.

Escape every dynamic key and value before interpolating them; only the <b>
wrappers remain markup.
@r0g18
r0g18 force-pushed the fix/event-history-escape branch from cb0532d to 7e11dfc Compare October 7, 2026 08:55

This branch has not been deployed

No deployments
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.

Stored XSS: testcase event history renders event fields through inner-h-t-m-l without escaping

1 participant