How to restrict access to a resource based on domain - javascript

I've got a theoretical problem I'd like to solve. Imagine I want to reference an external resource from within an HTML document. However, I want the behaviour when following the link to vary depending on the domain of the referring page (the page with the link).
e.g.
A page hosted at http://somedummydomain.com/mypage.html contains a link to a resource http://someotherdummydomain.com/mydoc.pdf?key=123456789.
When a user clicks on the link to mydoc.pdf, I would only like mydoc.pdf to be returned (200 OK) if the referrer is somedummydomain.com - if it's any other domain then return 401 NOT AUTHORIZED. The significance of the key in the query params is that the application serving mydoc.pdf will, internally, have associated that key with the somedummydomain.com domain, thus stipulating that the resource can only be accessed via that domain.
Obviously I could check the referrer, but it's trivial to spoof the referrer in the HTTP headers so, were I genuinely trying to lock something down, the referrer header is not going to be satisfactory.
I'm kind of assuming that JavaScript would have to come into play in some way? I'm judging that based on things like the Google Analytics JS code that will only accept events occurring on a page hosted at a pre-registered domain.
Does anyone know how this type of behaviour could be achieved?

Related

Python : Setting cookie into another website

I am implementing one advertising system in which when one user puts down script code into their website A. what I want to do at that time is set up a cookie into website A while it display response or resource of website B(Advertising System), so in present day when user comes again , I can log it's entry. I have read down this question and came to know that it is possible to set cookie into other website A when that website A is display content from another website B
In script I am executing one rest API and returning one response like below..
source_image = "http://example.com/media/format.png"
response = Response({'success':source_image})
response.set_cookie( 'cookie_name', 'cookie_value' )
return response
Now I am able to see cookie set in browser of the response of this url. But when I reload it ,cookie does not get display. Also why it is not getting display in the cookies section of the site in which I have put down script code.
Am I doing right thing to set up a cookie? And I have tried to set cookie's expiry date for 1 day. But still it is getting destroyed..Please help..
There are a few important things to know about cookies and browsers and how they interact across domains.
Websites can set cookies for their own website
Websites cannot set cookies for a different website
Cookies can be set on the response or using things such as JavaScript
The first two may seem confusing, especially when some sources say they are possible. It's important to note that they only affect cases where the response is directly setting the cookie using the Set-Cookie header, which allows a website to directly set a cookie. There are some special cases for things like subdomains, but in general you should not expect browsers to respect cookies set on other domains that you don't control.
If you were allowed to arbitrarily set cookies on other websites, this would open the door for websites to arbitrarily set and unset cookies you are using, even if they are unrelated. This would include the ability to log someone out across domains in just the response alone, which isn't possible.
The third point is important for cases like advertising, as cookies can be set using the Set-Cookie header (or response.set_cookie in Django) or using JavaScript through the document.cookie property. As JavaScript can included from any domain using the src property on <script> tags, any domain can manage cookies on another domain if it is included through JavaScript. This is important to how many analytics services, such as Google Analytics, work becuase it allows them to store unqiue cookies on each website for each user that is being monitored, even though they do not have full control over the response. They also typically use tracking beacons in the form of images to send data back to the external domain and associate it with the stored cookie.
The answer you linked to talks about this with images, but explains that it does not actually set the cookie on another domain. The cookie which is being set using the image or frame is stored only on the external domain, and cannot be accessed from the domain including the remote image.
Make sure that the HTTP header of "Set-Cookie" is being passed to the client in the HTTP response.
Try adding in the "domain" attribute for the cookie so the browser knows where to send the cookie.

Browser XSS: am I missing something?

I feel like I am missing something fundamental about XSS prevention (either in general or about the browsers' current implementation of it).
I have a site at domain A, that uses jQuery. Under certain conditions I want it to periodically retrieve and format some data which is hosted at domain B.
In the source for domain A's page, it appears that I can quite happily put in a <script src="http://B/something.js"></script> and it will load and execute the script in the context of the current page (in particular allowing it to read and update the DOM). I can also do the same thing using jQuery.getScript (which internally fetches and executes the script via AJAX).
However regardless of whether I put it into the domain A page or into the JS on domain B, if I try to use jQuery.ajax to load http://B/data.json it generates a CORS violation error:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
(Note that while testing this, domain A is a local file://, which is probably why it's showing a null origin there. It will be a "real" site in practice.)
I am having a hard time understanding this behaviour. I fail to see how loading JSON data is in any way less safe than loading arbitrary script -- in fact the opposite seems more likely.
Mostly I'm asking this question to try to understand how this can possibly make sense, but as a side question I'm interested to know the "right" way to perform this sort of thing (have a script on domain B be able to load data from its own domain, despite being run from domain A). It is possible for me to add the Allow-Origin header to domain B if absolutely required, but I would prefer not to do so. (It's not possible to do this on domain A.)

Request permission for cross-domain request dynamically

Is it possible to make a cross-domain request from a Chrome extension without statically listing the domain in manifest.json (presumably by dynamically prompting the visitor for permission)?
For a use case, suppose I wanted to let visitors supply an RSS feed address, which I'd then query as part of my application's dashboard screen. I cannot list that domain in manifest.json since I clearly can't know the domain until the visitor enters it at runtime.
I'm hoping there's some mechanism for dynamically requesting access to a domain ("This extension wants to browse your data on www.example.com; do you want to allow this?")
Any ideas?
I think you'd need to specify a match pattern of: http://*/*

AJAX between a static webpage and google app-engine server sharing same TLD

I have the main website hosted by a reliable static web hosting service. Which only allow me to host static files like html, css, js etc. Now I have few requirements which would need user Login and data storage. I think I can handle this using App Engine Python.
My app is similar to a Voting module, So i will explain it using its example.
My plan is to configure things something like this:
main website: www.example.com
appengine: gae.example.com
On the main website an anonymous user visits: http://www.example.com/vote.html, he should see current voting status (which has been retrieved from app engine). and a login button (from twitter/facebook). when he logins, he should be able to cast his vote and the vote be saved back to the appengine server.
I can handle most of the things but two. (taking same origin policy into account.)
How do I maintain authentication between two domain names. i.e. www.example.com and gae.example.com.
How do I make HTTP POST request to the gae.example.com from www.example.com and use the returned json data.
Note: I want to avoid iframes as much as possible.
You need to use JSONP.
Subdomains actually violate the same origin policy. This is because some hosted solutions provide subdomains for different users. This would allow users to attack each other's sites.
See: Same Origin Policy - AJAX & using Public APIs
You can maintain login between the two sub-domains by making sure that the login cookie is set on the root domain with subdomain access allowed. The sub-domains will be able to access the cookies of the root domain. See https://serverfault.com/questions/153409/can-subdomain-example-com-set-a-cookie-that-can-be-read-by-example-com for some examples.
I don't believe you can make ajax calls directly to another sub-domain. If the target sub-domain is cooperating and supports JSONP, you can do it that way (you end up inserting a script tag with a call to a script and that script calls you back with the data). Because the loading of scripts isn't subject to the same origin policy, you can work around it, but the target sub-domain has to be configured to allow and support JSONP.

Can one use Ajax on Google App Engine as a logged in user over https from a non-appspot.com domain?

Suppose:
You have a website http://www.example.com that redirects to a project on Google App Engine (i.e. example.appspot.com);
you want communications to pass between the user over SSL (i.e. https://example.appspot.com); and
You want the domain to be shown to the user to be *://www.example.com (i.e. not https://example.appspot.com).
Given that Google's Appspot HTTPS support only works for https://example.appspot.com (i.e. you cannot set up https://www.example.com with GAE), I'd like to have an Ajax solution, namely:
http://www.example.com serves HTML and Javascript over http
Ajax requests go over SSL to https://example.appspot.com
My question/concern is: How does one ensure that the users logged into http://www.example.com (by way of Google's users API) pass their authentication credentials over Ajax to https://example.appspot.com?
This seems to be a violation of the same origin policy (which may or may not be a concern for the Google Users API), so how would one know what user is logged in to example.com for the Ajax requests to example.appspot.com?
Thoughts, comments and input is quite appreciated.
Thank you.
Brian
There are ways to work around same-origin when both sites cooperate, e.g. see this post, but only trial-and-error will reveal which techniques do work for your specific requirements (it may depend on how strictly the user has set security safeguards in their browser, as well as on server-side implementations).
You can try using JSONP to get around the around that. However JSONP doesnt have very good error recovery like JSON does when doing XHR calls.
Wouldn't it be far simpler to use frames? Serve up a single full-size frameset from yourdomain.com containing content from https://yourapp.appspot.com/.
Note, though, that either solution has the problem that users see an unsecured site, not a secured one.
example.appspot.com does not share any cookies with example.com - it will be impossible for you to identify the user without making them sign-in on example.appspot.com as well.
you could, of course, completely ditch Google Authentication on example.appspot.com and implement your own scheme; you could append a signature and the username to the AJAX requests you create and verify that signature on your app-engine app. if the signature is valid, just accept the user that was passed in as the authenticated user and pretend he logged in.

Categories

Resources