0 day streak
javascript / intermediate
Snippet

Preventing JavaScript Pseudo-Protocol XSS in Dynamic Link URLs

Passing untrusted user input directly into an anchor href can expose React apps to Cross-Site Scripting (XSS) via 'javascript:' pseudo-protocols. Parsing candidate links with the native URL API and validating allowed protocols ensures that malicious scripts cannot execute when links are clicked.

snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import React from 'react';
function isSafeUrl(rawUrl) {
try {
const parsed = new URL(rawUrl, window.location.origin);
return parsed.protocol === 'http:' || parsed.protocol === 'https:';
} catch {
return false;
}
}
export function SafeExternalLink({ href, children }) {
const safeHref = isSafeUrl(href) ? href : '#';
return (
<a
href={safeHref}
target="_blank"
rel="noopener noreferrer"
className={safeHref === '#' ? 'disabled-link' : ''}
>
{children}
</a>
);
}
react
Breakdown
1
const parsed = new URL(rawUrl, window.location.origin);
Parses and normalizes the input string against a base origin, throwing if the syntax is malformed.
2
return parsed.protocol === 'http:' || parsed.protocol === 'https:';
Enforces an explicit protocol allowlist to block dangerous schemes like 'javascript:' or 'data:'.
3
const safeHref = isSafeUrl(href) ? href : '#';
Substitutes an inert fallback URL if validation rejects the supplied link string.
4
rel="noopener noreferrer"
Prevents the target browsing context from accessing window.opener for tab-nabbing defense.