Is it secure to use window.location.href directly without validation
Is it secure to use window.location.href without any validation?
<script> var value = window.location.href; alert(value); </script>
From the above example, is it vulnerable to Cross-site scripting (XSS) attack?
If it is, then how? How the attacker can modify the value of window.location.href to the malicious content?
Edit (Second Situation)
This is the url : www.example.com?url=www.attack.com
Just assume taht I have a getQueryString() function that will return value without validation.
<script> var value = getQueryString('url'); window.location.href = value; </script>
Same question, is it vulnerable to Cross-site scripting (XSS) attack?
If it is, then how? How can an attacker just make use of “window.location.href = value” to perform XSS?
location.href can be understood to include two things:
- Using the value of
location.hrefby passing it around in your code, manipulating it and using it to guide the logic in your code.
- Assigning someting to
location.href, causing the browser to navigate to different URLs.
The first one, using the value, can be considered safe. The value of
location.href is nothing more than a string. Of course it’s part of user input, so you don’t want to pass it to an
eval statement, but that’s true for all other forms of user input as well. In fact, the value of
location.href is always a valid URL, so certain assumptions can be made of its content. In that sense you could argue it’s more safe than most forms of user input. As long as you don’t make any wrong assumptions.
The second one is something you should be careful with. Assigning unvalidated values to it can lead to open redirects that can be used for phishing and what’s more, XSS issues arising from the use of
Edit: As requested, here’s a more in-depth explanation of the problems with assiging to
Say you have an attacker controlled variable
foo. The source of it can be anything really, but a query string parameter is a good example. When you assign the value of
location.href, what happens? Well, the browser does its best to interpret the value as a URI and then redirects the user to the resulting address. In most cases, this will trigger a page load; e.g. if
"https://www.google.com/", Google’s front page will be loaded. Allowing that to happen without user interaction is known as an open redirect and is considered a security vulnerability!
There are, however, types of URIs that won’t trigger a page load. A common example of such a URI would be one that contains nothing but a fragment identifier, e.g.
#quux. Assigning that to
location.href would cause the page to scroll to the element with the ID “quux” and do nothing else. Fragment URIs are safe as long as you don’t do anything stupid with the values of the fragments themselves.
Then to the interesting part:
foo: all an attacker has to do to launch an attack against your users is inject a script URI into the variable. When you assign it to
location.href, it’s basically the same as calling
eval on the script.
Finally, there’s one more interesting URI scheme to consider: the data URI. Data URIs are file literals: entire files encoded as URIs. They can be used to encode any files, including HTML documents. And those documents, like any others, can contain scripts.
Most browsers treat each data URI as its own unique origin. That means the scripts in an HTML document wrapped in a data URI can not access any data on other pages. Except in Firefox.
Firefox treats data URIs a bit differently from all other browsers. In it, data URIs inherit the origin of whatever document is opening it. That means any scripts can access the data contained in the referring document. And that’s XSS for you.
A XSS is not possible under #1
The worst case I can think of is someone using that for Social Engineering (lets say your domain is really popular like Ebay or Amazon), what an attacker could do is craft a message saying something like “Amazon/Ebay free stuff for you, just go to http://haxor.site” using the URL and sending it to someone.
But still I don’t find it dangerous, because of the URL encoding the message would look pretty messy.
This only answer #1, since when I answered this question there wasn’t a “#2”
var value = getQueryString('url'); window.location.href = encodeURI(value);
I think this is the easiest way