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:
- The app stores
window.location.href
intoreturnUrl
item in session storage - It sets
window.location.href
to an external login page - When the user enter their credentials, the external login page redirects to
logged-in.html
page of my app. logged-in.html
contains the above code, settingwindow.location.href
to the value stored inreturnUrl
item of session storage.
Why is this vulnerable?. How can I mitigate it?
EDIT: I din't execute Fortify, an external company did it, and reported the following:
CWE-80. Input Validation and Representation: Cross-Site Scripting: DOM
CodePudding user response:
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;
}