I have an embed script that simply does this:
document.write(unescape('%3Cscript src="' + mp_protocol + 'blah.cloudapp.net/js?location="' + window.location +' type="text/javascript"%3E%3C/script%3E'));
As you can see right now the URL of the webpage that is embedding the code is passed in using window.location. But this can easily be edited by the client.
I wanted to know if I can get the referrer instead of passing the url. I wasn't sure if referring info would be passed since this script is embedded?
(yes, you can also fake referrers... but that is a bit more effort than I think most people will want).
The browser will usually send a "Referer" (sic) header for script requests which contain the URL of the page that contains the script link, regardless of how that script element was created.
This is accessible by checking the "Referer" HTTP variable (note unusual spelling).
The idea is that you can check this variable and see if it refers to part of your site.
Note that this variable is not always accurate; a user may elect to protect their privacy by not sending a referer header (using some sort of dinky privacy tool) and they may even modify their browser to send whatever they want in this field. So it shouldn't be relied upon for authentication, unless you also take into account that even a legitimate user may have left it blank or put an arbitrary string in it.
Related
I have a slightly strange question and I'm not sure if this could be achieved at all but anyway I'm curious to try.
I have 2 sites that are independent, lets say www.site1.com and www.site2.com.
site2 will be placed in a href in site1. The question is - is it possible site2 to be accessible only after the user is redirected to it from site1 and if the user tries to open site2 directly or thru an a href from another site different then site1 to not be able to access it?
Check for:
window.document.referrer
// Empty if User is directly loading page.
The value is an empty string if the user navigated to the page directly (not through a link, but, for example, by using a bookmark). Because this property returns only a string, it doesn't give you document object model (DOM) access to the referring page.
MDN Documentation: https://developer.mozilla.org/en-US/docs/Web/API/Document/referrer
Browser Support:
You can check for a post parameter that you set from the website 1 redirection (either through a form or plain javascript). And then set a local storage variable to check for when loading site 2.
Local storage doc
JavaScript post request like a form submit
But keep in mind this can be easily bypassed with enough html/js knowledge.
To ensure that only your website can make post parameter, you could maybe (not sure about me there): generate code (used as post parameter) on the go from webserver 1 and send them to webserver 2 at the same time (or a little before) to ensure the code received by the server 2 is really generated at server 1
Depending on the backend server you are using, you can use something called REFERRER details that will be there in the http header of the request ( for your www.site2.com page for example). This REFERRER will have the information on who referred the user to this site. You can add a condition something like if REFERRER is www.site1.com then render the page .
Here is a link to start with
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer
I want to make it so that for example if I'm on myownwebsite.com when it loads I want the URL to change but not visit the link just have it say the URL I want in there for example mysecondwebsite.com is this possible?
Your particular example isn't possible with JavaScript only. The history API does publish a method called pushState(), which allows you to change the URL displayed in the address bar, but -- like so many other JavaScript features -- it is bound by the same-origin policy. In this case, you cannot change the address to a URL that has a different origin (i.e. hostname + port number) than the currently loaded page. Otherwise, it would be way too easy for malicious websites to pose as Google, Facebook, etc.
This doesn't exactly answer your question as it is not javascript, but would a DNS CNAME record work in your case?
quote: "A Canonical Name record (abbreviated as CNAME record) is a type of resource record in the Domain Name System (DNS) used to specify that a domain name is an alias for another domain (the 'canonical' domain)."
from: https://en.wikipedia.org/wiki/CNAME_record
No, it is impossible.
The browser won't authorize you to "cheat" on users.
If the URL is the second website's URL, it should show the second website's content.
What if you make the second website show the first website's content while you receive a certain query parameter?
Is it secure to use window.location.href without any validation?
For example:
<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?
Using location.href can be understood to include two things:
Using the value of location.href by 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 javascript: and vbscript: URIs.
Edit: As requested, here's a more in-depth explanation of the problems with assiging to location.href:
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 foo to 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 value is "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: javascript: and vbscript: URIs. These are the ones that will bite you. The JavaScript and VBScript URI schemes are non-standard URI schemes that can be used to execute code in the context of the currently open web page. Sounds bad, doesn't it? Well, it should. Consider our attacker-controlled variable 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.
JavaScript URIs work in all modern browsers, while VBScript is IE-only, and requires the page to be rendered in quirks mode.
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.
EDIT:
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
I would like to create some javascript that will only run on a given domain. We want to give each of our subscribers a bit of javascript that they can only run on their domain. The javascript will create an iFrame and bring in a page, etc.
If the javascript is placed on a different domain, an error is thrown and the script stops and the iFrame page will not load. Before you say this is not possible, it is done by Google Maps.
So, in short, we would like to mimic what Google Maps is doing. You register a domain with Google, they give you code that has a key and if you place this code on any other domain, it will not work. How do they do it?
The hostname property of window.location contains a hostname. It can be faked, so you could try checking the Referer header when serving your script, too – but absolutely do not rely on that.
You could also do a bit of a validity check by making a request to a nonexistent page on that domain – it’ll be blocked by cross-origin policies if the developer is cheating.
Another possible solution is to use the IP address, since the code is placed on a server.
I've made an license script with this method, and so far only 2 mad customers, but that was because they moved their website to another server without me telling it.
I think its good to have a client check, but that can be by-passed, if someone figures out how the script works. So, always do a server-side check.
Here is some code I use for the license check, its server based.
Also, I removed some functions that are specific to my website.
I can't figure out how to post code so I put it on pastebin.
http://pastebin.com/ftEDXhTP
When you give the user their snippet of code, on the server-side, store a specific domain name with an identifier you give to the user. You will likely generate this code automatically, like StackOverflow did with your question. They called it 19850979, so let's use that as the identifier you give to your user for example. When the user puts the snippet in place, when they use the iframe for example, the URL referenced in the iframe must contain the identifier.
Not sure what your server-side technologies are, but generally this concept works across the board:
For example... your server saves this information in its database:
user-example-domain.com,19850979
Your user's iframe ( which you generate and give them ) references:
your-serving-domain.com/iframeloader/19850979
Now, in the code that handles /iframeloader/ and receives 19850979 as the identifier, compare the hostname of the referrer. This is the Referer header, which is an HTTP header field:
http://en.wikipedia.org/wiki/List_of_HTTP_header_fields
If the hostname of the referrer is value, continue loading the iframe. If not, abort and show some kind of informative error message.
So I have two documents dA and dB hosted on two different servers sA and sB respectively.
Document dA has some JS which opens up an iframe src'ing document dB, with a form on it. when the form in document dB is submitted to a form-handler on server sB, I want the iframe on page dA to close.
I hope that was clear enough. Is there a way to do this?
Thanks!
-Mala
UPDATE: I have no control over dA or sA except via inserted javascript
This isn't supposed to be possible due to browser/JavaScript security sandbox policy. That being said, it is possible to step outside of those limitations with a bit of hackery. There are a variety of methods, some involving Flash.
I would recommend against doing this if possible, but if you must, I'd recommend the DNS approach referred to here:
http://www.alexpooley.com/2007/08/07/how-to-cross-domain-javascript/
Key Excerpt:
Say domain D wants to
connect to domain E. In a nutshell,
the trick is to use DNS to point a
sub-domain of D, D_s, to E’s server.
In doing so, D_s takes on the
characteristics of E, while also being
accessible to D.
Assume that I create page A, that lies withing a frame that covers the entire page.
Let A link to yourbank.com, and you click on that link. Now if I could use javascript that modifies the content of the frame (banking site), I would be able to quite easily read the password you are using and store it in a cookie, send it to my server, etc.
That is the reason you cannot modify the content in another frame, whose content is NOT from the same domain. However, if they ARE from the same domain, you should be able to modify it as you see fit (both pages must be on your server).
You should be able to access the iframe with this code:
window["iframe_name"].document.body
If you just want the top-level to close, you can just call something like this:
window.top.location = "http://www.example.com/dC.html";
This will close out dA and sent the user to dC.html instead. dC.html can have the JS you want to run (for example, to close the window) in the onload handler.
Other people explained security implications. But the question is legitimate, there are use cases for that, and it is possible in some scenarios to do what you want.
W3C defines a property on document called domain, which is used to check security permissions. This property can be manipulated cooperatively by both documents, so they can access each other in some cases.
The governing document is DOM Level 1 Spec. Look at the description of document. As you can see this property is defined there and … it is read-only. In reality all browsers allow to modify it:
Mozilla's document.domain description.
Microsoft's domain property description.
Modifications cannot be arbitrary. Usually only super-domains are allowed. It means that you can make two documents served by different server to access each other, as long as they have a common super-domain.
So if you want two pages to communicate, you need to add a small one-liner, which should be run on page load. Something like that should do the trick:
document.domain = "yourdomain.com";
Now you can serve them from different subdomains without losing their accessibility.
Obviously you should watch for timing issues. They can be avoided if you establish a notification protocol of some sort. For example, one page (the master) sets its domain, and loads another page (the server). When the server is operational, it changes its domain and accesses the master triggering some function.
A mechanism to do so would be capable of a cross-site scripting attack (since you could do more than just remove a benign bit of page content).
A safe approach would limit to just the iframe document emptying/hiding itself, but if the iframe containing it is fixed size, you will just end up with a blank spot on the page.
If you don't have control over dA or Sa this isn't possible because of browser security restrictions. Even the Flash methods require access to both servers.
This is a bit convoluted but may be more legitimate than a straight XSS solution:
You have no control over server A other than writing javascript to document A. But you are opening an iframe within document A, which suggests that you only have write-access to document A. This a bit confusing. Are you writing the js to document A or injecting it somehow?
Either way, here is what I dreamed up. It won't work if you have no access to the server which hosts the page which has the iframe.
The user hits submit on the form within the iframe. The form, once completed, most likely changes something on the server hosting that form. So you have an AJAX function on Document A which asks a server-side script to check if the form has been submitted yet. If it has, the script returns a "submitted" value to the AJAX function, which triggers another js function to close the iframe.
The above requires a few things:
The iframe needs to be on a page hosted on a server where you can write an additional server-side script (this avoids the cross-domain issue, since the AJAX is pointing to the same directory, in theory).
The server within the iframe must have some url that can be requested which will return some kind of confirmation that the form has been submitted.
The "check-for-submitted" script needs to know both the above-mentioned URL and what to look for upon loading said URL.
If you have all of the above, the ajax function calls the server-script, the server-script uses cURL to go the URL that reflects if the form is done, the server-script looks for the "form has been submitted" indicators, and, depending on what it finds, returns an answer of "not submitted" or "submitted" to the ajax function.
For example, maybe the form is for user registration. If your outer document knows what username will be entered into the form, the server-side script can go to http://example.org/username and if it comes up with "user not found" you know the form has yet to be submitted.
Anything that goes beyond what is possible in the above example is probably outside of what is safe and secure anyway. While it would be very convenient to have the iframe close automatically when the user has submitted it, consider the possibility that I have sent you an email saying your bank account needs looking at. The email has a link to a page I have made which has an iframe of your bank's site set to fill the entire viewable part of my page. You log in as normal, because you are very trusting. If I had access to the fact that you hit submit on the page, that would imply I also had access to what you submitted or at the very least the URL that the iframe redirected to (which could have a session ID in or all sorts of other data the bank shouldn't include in a URL).
I don't mean to sound preachy at all. You should just consider that in order to know about one event, you often are given access to other data that you ought not have.
I think a slightly less elegant solution to your problem would be to have a link above the iframe that says "Finished" or "Close" that kills the iframe when the user is done with the form. This would not only close the iframe when the user has submitted the form, but also give them a chance to to say "oops! I don't want to fill out this form anyway. Nevermind!" Right now with your desired automatic solution, there is no way to get rid of the iframe unless the user hits submit.
Thank you everybody for your answers. I found a solution that works:
On my server, I tell the form to redirect to the url that created the iframe.
On the site containing the iframe, I add a setInterval function to poll for the current location of the iframe.
Due to JS sandboxing, this poll does not work while the url is foreign (i.e. before my form is submitted). However, once the url is local (i.e. identical to that of the calling page), the url is readable, and the function closes the iframe. This works as soon as the iframe is redirected, I don't even need to wait for the additional pageload.
Thank you very much Greg for helping me :)