Skip to content

fix(legal): Prevent stored XSS via javascript: URLs in policy revision flow#114283

Merged
swartzrock merged 4 commits into
masterfrom
swartzrock/policies-xss-fix
May 4, 2026
Merged

fix(legal): Prevent stored XSS via javascript: URLs in policy revision flow#114283
swartzrock merged 4 commits into
masterfrom
swartzrock/policies-xss-fix

Conversation

@swartzrock
Copy link
Copy Markdown
Contributor

@swartzrock swartzrock commented Apr 29, 2026

The legal/compliance policy row rendered policy URLs in two unsafe ways: the "Review" LinkButton used the raw policy.url string directly as an href, and the showPolicy popup handler also passed the raw URL to window.open. Because new URL('javascript:...') parses successfully, safeURL returned a truthy URL object for javascript: scheme values, allowing the outer policy.url && policyUrl guard to pass. Any billing user who clicked "Review" on an affected policy would execute arbitrary JavaScript in the current page's context.

Fixes: - Add an explicit http/https protocol allowlist check after safeURL so that javascript:, data:, and other dangerous schemes are treated as invalid and produce a null policyUrl. - Replace policy.url with policyUrl.toString() in the "Review" LinkButton and showPolicy so all three rendering paths (iframe src, window.open, and anchor href) go through the validated reference. - Add a validate function to PolicyRevisionSchema's url field in the admin form so non-http(s) URLs are rejected at submission time, preventing malicious values from being stored in the first place.

Fixes https://linear.app/getsentry/issue/REVENG-38

…n flow

The legal/compliance policy row rendered policy URLs in two unsafe ways: the "Review" LinkButton used the raw `policy.url` string directly as an href, and the `showPolicy` popup handler also passed the raw URL to `window.open`. Because `new URL('javascript:...')` parses successfully, `safeURL` returned a truthy URL object for javascript: scheme values, allowing the outer `policy.url && policyUrl` guard to pass. Any billing user who clicked "Review" on an affected policy would execute arbitrary JavaScript in the current page's context.

Fixes: - Add an explicit http/https protocol allowlist check after `safeURL` so   that javascript:, data:, and other dangerous schemes are treated as   invalid and produce a null `policyUrl`. - Replace `policy.url` with `policyUrl.toString()` in the "Review"   LinkButton and `showPolicy` so all three rendering paths (iframe src,   window.open, and anchor href) go through the validated reference. - Add a `validate` function to `PolicyRevisionSchema`'s url field in the   admin form so non-http(s) URLs are rejected at submission time,   preventing malicious values from being stored in the first place.
@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Apr 29, 2026
@swartzrock swartzrock changed the title fix(legal): Prevent stored XSS via javascript: URLs in policy revisio… fix(legal): Prevent stored XSS via javascript: URLs in policy revision flow Apr 29, 2026
@linear-code
Copy link
Copy Markdown

linear-code Bot commented Apr 30, 2026

@swartzrock swartzrock marked this pull request as ready for review April 30, 2026 01:14
@swartzrock swartzrock requested a review from a team as a code owner April 30, 2026 01:14
@swartzrock swartzrock merged commit 9644ccb into master May 4, 2026
67 checks passed
@swartzrock swartzrock deleted the swartzrock/policies-xss-fix branch May 4, 2026 19:12
cleptric pushed a commit that referenced this pull request May 5, 2026
…n flow (#114283)

The legal/compliance policy row rendered policy URLs in two unsafe ways:
the "Review" LinkButton used the raw `policy.url` string directly as an
href, and the `showPolicy` popup handler also passed the raw URL to
`window.open`. Because `new URL('javascript:...')` parses successfully,
`safeURL` returned a truthy URL object for javascript: scheme values,
allowing the outer `policy.url && policyUrl` guard to pass. Any billing
user who clicked "Review" on an affected policy would execute arbitrary
JavaScript in the current page's context.

Fixes: - Add an explicit http/https protocol allowlist check after
`safeURL` so that javascript:, data:, and other dangerous schemes are
treated as invalid and produce a null `policyUrl`. - Replace
`policy.url` with `policyUrl.toString()` in the "Review" LinkButton and
`showPolicy` so all three rendering paths (iframe src, window.open, and
anchor href) go through the validated reference. - Add a `validate`
function to `PolicyRevisionSchema`'s url field in the admin form so
non-http(s) URLs are rejected at submission time, preventing malicious
values from being stored in the first place.

Fixes https://linear.app/getsentry/issue/REVENG-38
@github-actions github-actions Bot locked and limited conversation to collaborators May 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants