fix(contacts): sanitize company website href to block stored XSS #136

Merged
David merged 2 commits from fix/mapps-149-sanitize-website-href into main 2026-06-14 15:57:08 +02:00
Owner

The company detail page rendered the user-supplied website value straight into an anchor href, so a value like javascript:alert(1) executed attacker-controlled script in the authenticated origin when clicked (stored XSS, token theft via sessionStorage). React-style text escaping does not cover URL values placed in href.

Add safe_href to utils::url: it allowlists URL schemes (http, https, mailto) and rejects javascript:, data:, vbscript: and any other explicit scheme, ignoring case and embedded whitespace/control bytes that browsers strip before resolving the scheme. The company website now renders a live link only when the value passes safe_href, falling back to plain text otherwise, and the target="_blank" anchor gains rel="noopener noreferrer" to close the reverse-tabnabbing gap.

Unit tests cover the dangerous schemes, case/whitespace evasion, safe schemes, blank input, and scheme-less relative references.

#MAPPS-149

The company detail page rendered the user-supplied `website` value straight into an anchor `href`, so a value like `javascript:alert(1)` executed attacker-controlled script in the authenticated origin when clicked (stored XSS, token theft via sessionStorage). React-style text escaping does not cover URL values placed in `href`. Add `safe_href` to `utils::url`: it allowlists URL schemes (`http`, `https`, `mailto`) and rejects `javascript:`, `data:`, `vbscript:` and any other explicit scheme, ignoring case and embedded whitespace/control bytes that browsers strip before resolving the scheme. The company website now renders a live link only when the value passes `safe_href`, falling back to plain text otherwise, and the `target="_blank"` anchor gains `rel="noopener noreferrer"` to close the reverse-tabnabbing gap. Unit tests cover the dangerous schemes, case/whitespace evasion, safe schemes, blank input, and scheme-less relative references. #MAPPS-149
fix(contacts): sanitize company website href to block stored XSS
All checks were successful
Check / clippy + fmt + tests (pull_request) Successful in 2m47s
51a813c94d
The company detail page rendered the user-supplied `website` value straight into an anchor `href`, so a value like `javascript:alert(1)` executed attacker-controlled script in the authenticated origin when clicked (stored XSS, token theft via sessionStorage). React-style text escaping does not cover URL values placed in `href`.

Add `safe_href` to `utils::url`: it allowlists URL schemes (`http`, `https`, `mailto`) and rejects `javascript:`, `data:`, `vbscript:` and any other explicit scheme, ignoring case and embedded whitespace/control bytes that browsers strip before resolving the scheme. The company website now renders a live link only when the value passes `safe_href`, falling back to plain text otherwise, and the `target="_blank"` anchor gains `rel="noopener noreferrer"` to close the reverse-tabnabbing gap.

Unit tests cover the dangerous schemes, case/whitespace evasion, safe schemes, blank input, and scheme-less relative references.

#MAPPS-149
Merge branch 'main' into fix/mapps-149-sanitize-website-href
All checks were successful
Create release / Create release from merged PR (pull_request) Has been skipped
Check / clippy + fmt + tests (pull_request) Successful in 1m16s
40dd637a91
David merged commit 3e17ce740b into main 2026-06-14 15:57:08 +02:00
David deleted branch fix/mapps-149-sanitize-website-href 2026-06-14 15:57:09 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/mokosh-apps!136
No description provided.