How can I send cookies from a bookmarklet XMLHttpRequest which belong to the site being accessed? - security

I'm trying to create a bookmarklet which needs to hit a server (using a POST) to obtain some data. Accessing that data requires that I am logged in, which is kept track of by using cookies. The problem is, my bookmarklet is running in the context of some random web site, and so it can't access the cookies belonging to the site I am trying to hit and in fact it doesn't even send the cookies that belong to that web site.
I have seen some hints that suggest that what I am trying to do is possible, but which are a bit unclear on exactly how this could be accomplished. For instance, in this question, the accepted answer includes this tidbit: "Very often these types of bookmarklets open a small popup for the user which contains a page from the app" but I do not understand how this would accomplish what I am trying to do. I assume it has something to do with the fact that the page itself is in the proper domain and thus can send the required cookies, but I'm not sure how to get data into the page to tell it what I want (I suppose I could do something where I encoded the request in the URL parameters, but then this would show up in the http logs which is not desirable), but more importantly I am not sure how I would get the data back from the window - whenever I try I get an exception "Permission denied to access property 'document'" (or whatever I try to access). I also get the same problem if I use an IFRAME and try to access the parent from the child (or the other way around).

You have asked several quetions.
1.) How can I send cookies from a bookmarklet XMLHttpRequest which belong to the site being accessed?
XMLHttpRequest will send cookies belonging to the domain you are calling. If you want to cross domains you have to enable CORS: http://enable-cors.org/
2.) "Very often these types of bookmarklets open a small popup for the user which contains a page from the app"
This is not about making an XMLHttpRequest. The data goes into the popup via GET. You can even do this via POST but it is slightly more complex. Just search "post to popup" or "post to iframe".
3.) I am not sure how I would get the data back from the window
If the other window/iframe is holding a page from a different domain, use postMessage: https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage - this can actually go in both directions and can actually be used to enable complex cross domain communication without CORS.

Related

How do I protect sensitive information from cross site access?

My web application displays some sensitive information to a logged in user. The user visits another site without explicitly logging out of my site first. How do I ensure that the other site can not access the sensitive information without accept from me or the user?
If for example my sensitive data is in JavaScript format, the other site can include it in a script tag and read the side effects. I could continue on building a blacklist, but I do not want to enumerate what is unsafe. I want to know what is safe, but I can not find any documentation of this.
UPDATE: In my example JavaScript from the victim site was executed on the attacker's site, not the other way around, which would have been Cross Site Scripting.
Another example is images, where any other site can read the width and height, but I don't think they can read the content, but they can display it.
A third example is that everything without an X-Frame-Options header can be loaded into an iframe, and from there it is possible to steal the data by tricking the user into doing drag-and-drop or copy-and-paste.
The key point of Cross Site Attack is to ensure that your input from user which is going to be displayed, is legal, not containing some scripts. You may stop it at the beginning.
If for example my sensitive data is in JavaScript format, the other site can include it in a script tag
Yep! So don't put it in JavaScript/JSONP format.
The usual fix for passing back JSON or JS code is to put something unexecutable at the front to cause a syntax error or a hang (for(;;); is popular). So including the resource as a <script> doesn't get the attacker anywhere. When you access it from your own site you can fetch it with an XMLHttpRequest and chop off the prefix before evaluating it.
(A workaround that doesn't work is checking window.location in the returned script: when you're being included in an attacker's page they have control of the JavaScript environment and could sabotage the built-in objects to do unexpected things.)
Since I did not get the answer I was looking for here, I asked in another forum an got the answer. It is here:
https://groups.google.com/forum/?fromgroups=#!topic/mozilla.dev.security/9U6HTOh-p4g
I also found this page which answers my question:
http://code.google.com/p/browsersec/wiki/Part2#Life_outside_same-origin_rules
First of all like superpdm states, design your app from the ground up to ensure that either the sensitive information is not stored on the client side in the first place or that it is unintelligible to a malicious users.
Additionally, for items of data you don't have much control over, you can take advantage of inbuilt HTTP controls like HttpOnly that tries to ensure that client-side scripts will not have access to cookies like your session token and so forth. Setting httpOnly on your cookies will go a long way to ensure malicious vbscripts, javascripts etc will not read or modify your client-side tokens.
I think some confusion is still in our web-security knowledge world. You are afraid of Cross Site Request Forgery, and yet describing and looking for solution to Cross Site Scripting.
Cross Site Scripting is a vulnerability that allows malicious person to inject some unwanted content into your site. It may be some text, but it also may be some JS code or VB or Java Applet (I mentioned applets because they can be used to circumvent protection provided by the httpOnly flag). And thus if your aware user clicks on the malicious link he may get his data stolen. It depends on amount of sensitive data presented to the user. Clicking on a link is not only attack vector for XSS attack, If you present to users unfiltered contents provided by other users, someone may also inject some evil code and do some damage. He does not need to steal someone's cookie to get what he wants. And it has notnig to do with visiting other site while still being logged to your app. I recommend:XSS
Cross Site Request Forgery is a vulnerability that allows someone to construct specially crafted form and present it to Logged in user, user after submitting this form may execute operation in your app that he didin't intended. Operation may be transfer, password change, or user add. And this is the threat you are worried about, if user holds session with your app and visits site with such form which gets auto-submited with JS such request gets authenticated, and operation executed. And httpOnly will not protect from it because attacker does not need to access sessionId stored in cookies. I recommend: CSRF

Admin access through a GET parameter

I'm working on a really simple web site. I usually do a full blown admin to edit the site, but this time I thought about editing in place (contenteditable="true").
To simplify login for the user, I'd like to just give him a password that he can type in the address bar to log him in, instead of the usual login form. So he would visit domain.com/page?p=the_password and then I would store his data in a session and give him a cookie with a session id (usual stuff) and redirect him to domain.com/page.
How safe / unsafe is this? I'm doing this in PHP, but I guess it applies to any server-side language.
Your login idea is unsafe: URLs for requests end up in web server logs and other places besides, so that means passwords will end up in web server logs.
Your "contentedittable" idea is probably unsafe, but in a more subtle way. It's also (again, probably) non-compliant with the HTTP specification.
GET requests should always be idempotent. This is because user agents (browsers, caches, etc...) are allowed to reissue the same GET request any number of times without user consent. One reason why a browser might do that is because the user pressed the back button and the previous page is no longer in the cache. If the request is not idempotent then issuing it a second time may have an unexpected and unwanted side effect.
It sounds like your "editing in place" feature might not always be idempotent. There are many kinds of simple edits which are in fact idempotent so I could be wrong, but as soon as you have for example the ability to add a new item to a list via this kind of interface it's not.
Non-idempotent requests should be issued through methods like PUT, POST, and DELETE.
To add to #Celada answer. The URL will be stored in the browser history or network caches/proxies, so the password can leak in this way. Also it would be trivial to login a random Internet user as someone else (Login Cross Site Request Forgery attack), by for example having a web site with an img element pointing to domain.com/page?p=the_password
You don't write about this, but once the user is logged in your scheme needs to protect against Cross Site Request Forgery (so a random page can not perform admin actions on behave of the logged-in user).

What can "Same Origin Policy" buy us?

Same Origin Policy(SOP) is often mentioned together with Cross Site Scripting(XSS). But it seems that in the world with SOP, XSS still happens from time to time.
So I am never clear about what exactly kind of attacks do Same Origin Policy prevent?
In other words, imagine a world without SOP, what other power a malicious attacker could gain compared to the real world with SOP?
I read on this website(http://security.stackexchange.com/questions/8264/why-is-the-same-origin-policy-so-important) that "Assume you are logged into Facebook and visit a malicious website in another browser tab. Without the same origin policy JavaScript on that website could do anything to your Facebook account that you are allowed to do.". This actually makes me even more confused because I have never heard of any mechanism for webpage in one tab manipulating other tabs even from the same domain.
It is also mentioned (more explicitly) here (http://javascript.info/tutorial/same-origin-security-policy) that SOP prevents script in one window to manipulate DOM elements in another window. But I really cannot relate the example to what is explained (what does window mean here? it seems that the example is talking about iframe).
To sum up, can anyone give some concrete examples of what can happen if there were no SOP?
Also, I am curious about how script in one window can manipulate DOM elements in another window assuming the two window are from the same domain. But this is not the main course of this question
Thank you!
I have never heard of any mechanism for webpage in one tab manipulating other tabs [...] it seems that the example is talking about iframe
iframe is the easiest but not the only way of getting cross-window scripting. Another way to do it would be for the attacker page to window.open a document from facebook.com into a new tab. Because open returns a handle to the tab's window object, it is possible for script in one tab to interact with content in another tab.
Without the SOP, that script could fill in and submit forms in that tab on your behalf.
XSS still happens from time to time. So I am never clear about what exactly kind of attacks do Same Origin Policy prevent?
Without SOP, every web page is vulnerable to XSS and no-one can ever be secure.
With SOP, web pages are secure against XSS unless their authors make a mistake. XSS still happens from time to time because site authors do, unfortunately, make mistakes.
One example: for malicious web page it would be possible to make some javascript ajax requests to other web page where the user is already logged in the user's context. This other page would assume that the request comes from authorized user.
For example malicius script could make some ajax calls to Facebook and post new status or to bank transaction service and make a transfer if only the user is logged in to Facebook or his bank. People usually open many pages in browser tabs at the same time, so it would be very probable that someone browsing the malicious web page is at the same time logged to some sensitive service that could be hacked that way.

How to restrict access to my webpage

I have a url to a search page (e.g. http://x.y.z/search?initialQuery=test). It isn't a webservice endpoint, its just a basic url (which goes through a Spring controller). There is no security around accessing page, you can enter the link in a browser and it will render results.
What I want is to find a way to prevent other sites from submitting requests to this url, unless they are specifically allowed.
I build a filter which would intercept all request to this page, and perform some validation. If validation failed then they would be redirected to another page.
The problem is what validation to perform... I tried using the referer field to see if the request was coming from an "allowed" site but I know the referer field isn't always populated and can easily be faked.
Is there a way to achieve this?
We also have IHS so if there is something that can be done in there either that would be great.
I'd suggest implementing some kind of system to allow users to log in if you really want to protect a page from being accessed.
You could try to detect the IP address of the incoming request, but I'd imaging that this can be spoofed quite easily.
Realistically, pages that are public are open to any kind of interrogation to the limits that you set. Perhaps limiting the data that the page returns is a more practical option?
This is the reason that website's like Facebook and Twitter implement oAuth to prevent resources from being accessed by unauthorised users.
How about you only run the result if the referring page has passed along a POST variable called "token" or something which has been set to a value that you give each app that's going to hit the search page. If you get a request for that page with a query string, but not POST value for "token", then you know its an unauthorized request and can handle it accordingly.
If you know the IPs of sites which can contact your service, you can put Apache as a proxy and use access control to permit/deny access to specific directories/urls.
I assume that you want to avoid having your site "scraped" by bots, but do want to allow humans to access your search page.
This is a fairly common requirement (google "anti scraping"). In ascending order of robustness (but descending order of user-friendliness):
block requests based on the HTTP headers (IP address, user agent, referrer).
implement some kind of CAPTCHA system
require users to log in before accessing the search URL
You may be able to buy some off-the-shelf wizardry that (claims to) do it all for you, but if your data is valuable enough, those who want it will hire mechanical turks to get it...
make a certification security.
u can make self signed certification using openssl or java keytool
and u will have to send a copy of certificate to ur client.
If this client will not have this certificate, It will not be able to call ur service.
And to make certificate enable in ur web container.I dont know bout other containers but
in Apache tomcat, u can do it in connector tag of ur server.xml

How to ensure http requests originate from a specific location?

HTTP Referer is the way I'm doing it at the moment. As everyone who's used this method knows it is not 100% accurate as the Referer header is optional and maybe fiddled with.
Looking at how-to-ensure-access-to-my-web-service-from-my-code-only I'm still unsure of how to go about this in a minimal way.
The situation:
Advertising on someone else's site. Using an iFrame so I can change content/function at will. I pay $x.xx for every time an action is completed. Therefore I need to ensure that the action is being completed from where I said it is allowed to be completed from.
What I'm trying to prevent:
some other webmaster coming along going - "hey that's a nice tool, let me put that on my site"
So as i said at the top, what i do atm is if the referer doesn't match I redirect to a page that has the same tool however whatever actions are preformed on that page they don't cost me any money.
While trying to prevent the above, allow the following:
I don't mind if the webmaster/site owner I'm paying cash to for "actions complete" puts the code on other sites - obviously this is a good thing. Lots more coverage, the site owner gets more cash & i get more actions completed, which generates me more cash.
Question
What can I get the other party to do so I know all the requests coming into my web page are from the other party I have an agreement with and not some random.
Thanks :)
info re app
other parties website has an iFrame. iFrame displays a html/js/php page of mine that sits on one of my domains. This page uses ajax requests to interact with the actual webservice that is a ruby/sinatra app. I have lots of different pages that fit into the look and feel of the other parties website.
So I'm thinking some sort of chatter between the other parties server and my server would be a good idea. Then the result of this chatter would be somehow present during the iFrame request.
However I'm not sure if the other party would be able to set a cookie for the domain being served in the iFrame - in fact I'm pretty sure it can't.
Now to get around that limitation I could have a script included as part of the iFrame on the page that could set a cookie.
Ok the above ideas summarised:
OtherParty server sends a request to my server gets a response.
renders the page with that response as a param to a <script src="...?param"></script>
my script sets a cookie
as script is before iFrame, script is loaded first
iFrame loads with page as a cookie has been set on that domain cookie set before is sent as well
bingo, request verified legit
Does this sound ok?
btw my tool that I want action completed on only works if JS is enabled so...
If you really want to secure who can load your iframe, then one way to do this is via 2-legged OAuth (i.e. have your trusted partner "sign" the iframe GET request). Then your server can grant access based on a cryptographically valid signature and a known signing party. You'll want to enforce relatively short valid lifetimes for the signed requests to prevent someone else from just copying them and embedding them in their own site.
This also gives you the advantage of just having to do an initial, offline key exchange without having your partner making extra server requests of you ahead of the iframe insertion.

Resources