Fortify SCA reports that the following code is DOM XSS vulnerable:
const returnUrl = sessionStorage.getItem('returnUrl') || '/';
window.location.href = returnUrl;
When a user enters my application by clicking a link for example, and the user is not logged in:
window.location.href
into returnUrl
item in session storagewindow.location.href
to an external login pagelogged-in.html
page of my app.logged-in.html
contains the above code, setting window.location.href
to the value stored in returnUrl
item of session storage.Why is this vulnerable?. How can I mitigate it?
I didn't execute Fortify, an external company did it, and reported the following:
CWE-80.
Input Validation and
Representation:
Cross-Site Scripting:
DOM
How can I mitigate it?
Don't store a full URL, just store the necessary information (such as a page name, or even an enum-like value that identifies the page to go to). Then, when going back to the page, validate the data from session storage before building a URL from only known values and validated values:
const returnInfo = JSON.parse(sessionStorage.getItem("returnUrl"));
if (returnInfo && validatePageName(returnInfo.pageName) && /*...*/) {
window.location.href = "/" + returnInfo.pageName; // Or similar
}
...where validatePageName
ensures that the string passed to it is just the name of a page in your app, and not (for instance) a full URL.
Or if that's too much of a change, at least validate the URL before using it:
const returnUrl = new URL(
sessionStorage.getItem("returnUrl") || "/"),
location
);
if (
returnUrl.protocol === location.protocol &&
returnUrl.port === location.port &&
returnUrl.hostname === location.hostname &&
/*...other checks as necessary ...*/
) {
window.location.href = returnUrl;
}