This is the first time I`m toying with PhoneGap, so I actually never needed Cross Origin Resource Sharing (CORS) before.
It is by default blocked, and the options I found in the web are either hacks or insecure.
My question is: What is the best or proper way to accomplish server integration using PhoneGap?
Bear in mind:
I need session control serverside to keep the user logged in
The request is coming from a file in PhoneGap's webview so origin = null
I'm using PHP serverside and have full control over it
<access origin="*" /> is already added to config.xml (it enables me to reach out for the server, but doesn't guarantee it will respond to a cross-origin request)
A long search on the web lead me to:
Access-Control-Allow-Origin *
Access-Control-Allow-Credentials true
But I understood they're rather unsafe, specially combined.
I could save the user session ID locally, but that seems hacky and unsafe.
There's also JSONP to the rescue, but that also seems hacky, unsafe and won't persist my session ID.
I could use a proxy server, but that seems far from optimal and as I understand it'll be hard to prevent an attacker to not use this same proxy server to perform the same operations.
Hi you can disable security to browser and use it.
Please find the link for disabling security for chrome.
[Disable same origin policy in Chrome
I'm working on extensions for Firefox and Chrome. The data used by my extensions is mostly generated from ajax requests. The type of data being returned is private, so it needs to be secure. My server supports https and the ajax calls are being sent to an https domain. Information is being sent back and forth, and the extensions are working correctly.
My questions are:
Do the extensions actually make secure connections with the server, or is this considered the same as cross domain posting, sending a request from a http page to a https page?
Am I putting my users' information at more risk during the transfers than if the user were to access the information directly from an https web page in the browser?
Thanks in advance!
The browser absolutely makes a secure connection when you use HTTPS. Certainly, a browser would never downgrade the security of your connection without telling you: it will either complete the request as written or it throw some sort of error if it is not possible.
Extensions for both Chrome and Firefox are permitted to make cross-domain AJAX requests. In Chrome, you simply need to supply the protocol/name of the host as a permission in your manifest.json. In Firefox, I think you may need to use Components.classes to get a cross-domain requester, as described in the MDN page for Using XMLHttpRequest, but I'm not 100% sure about that. Just try doing a normal request and see if it succeeds; if not, use the Components.classes solution.
I'm trying to determine the most secure method for an ajax based login form to authenticate and set a client side cookie. I've seen things about XSS attacks such as this:
How do HttpOnly cookies work with AJAX requests?
and
http://www.codinghorror.com/blog/archives/001167.html
So, I guess my core questions are...
1) Is using pure ajax to set cookies secure, if so, what is the most secure method (httpOnly + SSL + encrypted values, etc.)?
2) Does a pure ajax method involve setting the cookie client side? Is this at all secure?
3) Is setting cookies this way reliable across all major browsers/OSs?
4) Would using a hidden IFrame be any more secure (calling a web page to set the cookies)?
5) If possible, does anybody have code for this (PHP is my backend)?
My goal is to set the cookies and have them available for the next call to the server without navigating away from the page.
I really want to nail down the consensus, most secure way to do this. Eventually, this code is planned to be made Open Source, so please no commercial code (or nothing that wouldn't stand up to public scrutiny)
Thanks,
-Todd
The cookie needs to be generated server-side because the session binds the client to the server, and therefore the token exchange must go from server to client at some stage. It would not really be useful to generate the cookie client-side, because the client is the untrusted remote machine.
It is possible to have the cookie set during an AJAX call. To the server (and the network) an AJAX call is simply an HTTP call, and any HTTP response by the server can set a cookie. So yes, it is possible to initiate a session in response to an AJAX call, and the cookie will be stored by the client as normal.
So, you can use AJAX to do the logging in process in the same was as you could have just relied on a POST from a form on the page. The server will see them the same way, and if the server sets a cookie the browser will store it.
Basically, client-side Javascript never needs to be able to know the value of the cookie (and it is better for security if it doesn't, which can be achieved using the "httponly" cookie extension honored by recent browsers). Note that further HTTP calls from the client to the server, whether they are normal page requests or they are AJAX requests, will include that cookie automatically, even if it's marked httponly and the browser honors that extension. Your script does not need to be 'aware' of the cookie.
You mentioned using HTTPS (HTTP over SSL) - that prevents others from being able to read information in transit or impersonate the server, so it's very handy for preventing plain text transmission of the password or other important information. It can also help guard against network based attacks, though it does not make you immune to everything that CSRF can throw you, and it does not at all protect you against the likes of session fixation or XSS. So I would avoid thinking of HTTPS as a fix-all if you use it: you still need to be vigilant about cross-site scripting and cross-site request forgery.
(see 1. I sort of combined them)
Given that the cookie is set by the server in its HTTP response headers, yes it is reliable. However, to make it cross-browser compatible you still need to ensure logging in is possible when AJAX is unavailable. This may require implementing an alternative that is seen only when there is no Javascript or if AJAX isn't available. (Note: now in 2014, you don't need to worry about browser support for AJAX anymore).
It would not change the security. There would be no need for it, except that I have seen hidden iframes used before to 'simulate' AJAX before - ie make asyncronous calls to the server. Basically, however you do it doesn't matter, it's the server setting the cookie, and the client will accept and return the cookie whether it does it by AJAX or not.
For the most part, whether you use AJAX or not does not affect the security all that much as all the real security happens on the server side, and to the server an AJAX call is just like a non-AJAX call: not to be trusted. Therefore you'll need to be aware of issues such as session fixation and login CSRF as well as issues affecting the session as a whole like CSRF and XSS just as much as you would if you were using no AJAX. The issues don't really change when using AJAX except, except, I guess, that you may make more mistakes with a technology if you're less familiar with it or it's more complicated.
Answer updated September 2014
I have done a bit of testing on this myself (During the server side processing of a DWR Framework Ajax request handler to be exact) and it seems you CAN successfully manipulate cookies, but this goes against much that I have read on Ajax best practices and how browsers interpret the response from an XmlHttpRequest. Note I have tested on:
IE 6 and 7
Firefox 2 and 3
Safari
and in all cases standard cookie operations on the HttpServletResponse object during Ajax request handling were correctly interpreted by the browser, but I would like to know if it best practice to push the cookie manipulation to the client side, or if this (much cleaner) server side cookie handling can be trusted.
I would welcome answers both specific to the DWR Framework and Ajax in general.
XMLHttpRequest always uses the Web Browser's connection framework. This is a requirement for AJAX programs to work correctly as the user would get logged out if the XHR object lacked access to the browser's cookie pool.
It's theoretically possible for a web browser to simply share session cookies without using the browser's connection framework, but this has never (to my knowledge) happened in practice. Even the Flash plugin uses the Web Browser's connections.
Thus the end result is that it IS safe to manipulate cookies via AJAX. Just keep in mind that the AJAX call might never happen. They are not guaranteed events, so don't count on them.
In the context of DWR it may not be "safe".
From reading the DWR site it says:
It is important that you treat the HTTP request and response as read-only. While HTTP headers might get through OK, there is a good chance that some browsers will ignore them.
I've taken this to mean that setting cookies or request attributes is a no-no.
Saying that, I have code which does set request attributes (code I wrote before I read that page) and it appears to work fine (apart from deleting cookies which I mentioned in my comment above).
Manipulating cookies on the client side is rather the opposite of "best practice". And it shouldn't be necessary, either. HttpOnly cookies weren't introduced for nothing.
JavaScript needs access to cookies if AJAX is used on a site with access restrictions based on cookies. Will HttpOnly cookies work on an AJAX site?
Edit: Microsoft created a way to prevent XSS attacks by disallowing JavaScript access to cookies if HttpOnly is specified. FireFox later adopted this. So my question is: If you are using AJAX on a site, like StackOverflow, are Http-Only cookies an option?
Edit 2: Question 2. If the purpose of HttpOnly is to prevent JavaScript access to cookies, and you can still retrieve the cookies via JavaScript through the XmlHttpRequest Object, what is the point of HttpOnly?
Edit 3: Here is a quote from Wikipedia:
When the browser receives such a cookie, it is supposed to use it as usual in the following HTTP exchanges, but not to make it visible to client-side scripts.[32] The HttpOnly flag is not part of any standard, and is not implemented in all browsers. Note that there is currently no prevention of reading or writing the session cookie via a XMLHTTPRequest. [33].
I understand that document.cookie is blocked when you use HttpOnly. But it seems that you can still read cookie values in the XMLHttpRequest object, allowing for XSS. How does HttpOnly make you any safer than? By making cookies essentially read only?
In your example, I cannot write to your document.cookie, but I can still steal your cookie and post it to my domain using the XMLHttpRequest object.
<script type="text/javascript">
var req = null;
try { req = new XMLHttpRequest(); } catch(e) {}
if (!req) try { req = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
if (!req) try { req = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
req.open('GET', 'http://stackoverflow.com/', false);
req.send(null);
alert(req.getAllResponseHeaders());
</script>
Edit 4: Sorry, I meant that you could send the XMLHttpRequest to the StackOverflow domain, and then save the result of getAllResponseHeaders() to a string, regex out the cookie, and then post that to an external domain. It appears that Wikipedia and ha.ckers concur with me on this one, but I would love be re-educated...
Final Edit: Ahh, apparently both sites are wrong, this is actually a bug in FireFox. IE6 & 7 are actually the only browsers that currently fully support HttpOnly.
To reiterate everything I've learned:
HttpOnly restricts all access to document.cookie in IE7 & and FireFox (not sure about other browsers)
HttpOnly removes cookie information from the response headers in XMLHttpObject.getAllResponseHeaders() in IE7.
XMLHttpObjects may only be submitted to the domain they originated from, so there is no cross-domain posting of the cookies.
edit: This information is likely no longer up to date.
Yes, HTTP-Only cookies would be fine for this functionality. They will still be provided with the XmlHttpRequest's request to the server.
In the case of Stack Overflow, the cookies are automatically provided as part of the XmlHttpRequest request. I don't know the implementation details of the Stack Overflow authentication provider, but that cookie data is probably automatically used to verify your identity at a lower level than the "vote" controller method.
More generally, cookies are not required for AJAX. XmlHttpRequest support (or even iframe remoting, on older browsers) is all that is technically required.
However, if you want to provide security for AJAX enabled functionality, then the same rules apply as with traditional sites. You need some method for identifying the user behind each request, and cookies are almost always the means to that end.
In your example, I cannot write to your document.cookie, but I can still steal your cookie and post it to my domain using the XMLHttpRequest object.
XmlHttpRequest won't make cross-domain requests (for exactly the sorts of reasons you're touching on).
You could normally inject script to send the cookie to your domain using iframe remoting or JSONP, but then HTTP-Only protects the cookie again since it's inaccessible.
Unless you had compromised StackOverflow.com on the server side, you wouldn't be able to steal my cookie.
Edit 2: Question 2. If the purpose of Http-Only is to prevent JavaScript access to cookies, and you can still retrieve the cookies via JavaScript through the XmlHttpRequest Object, what is the point of Http-Only?
Consider this scenario:
I find an avenue to inject JavaScript code into the page.
Jeff loads the page and my malicious JavaScript modifies his cookie to match mine.
Jeff submits a stellar answer to your question.
Because he submits it with my cookie data instead of his, the answer will become mine.
You vote up "my" stellar answer.
My real account gets the point.
With HTTP-Only cookies, the second step would be impossible, thereby defeating my XSS attempt.
Edit 4: Sorry, I meant that you could send the XMLHttpRequest to the StackOverflow domain, and then save the result of getAllResponseHeaders() to a string, regex out the cookie, and then post that to an external domain. It appears that Wikipedia and ha.ckers concur with me on this one, but I would love be re-educated...
That's correct. You can still session hijack that way. It does significantly thin the herd of people who can successfully execute even that XSS hack against you though.
However, if you go back to my example scenario, you can see where HTTP-Only does successfully cut off the XSS attacks which rely on modifying the client's cookies (not uncommon).
It boils down to the fact that a) no single improvement will solve all vulnerabilities and b) no system will ever be completely secure. HTTP-Only is a useful tool in shoring up against XSS.
Similarly, even though the cross domain restriction on XmlHttpRequest isn't 100% successful in preventing all XSS exploits, you'd still never dream of removing the restriction.
Yes, they are a viable option for an Ajax based site. Authentication cookies aren't for manipulation by scripts, but are simply included by the browser on all HTTP requests made to the server.
Scripts don't need to worry about what the session cookie says - as long as you are authenticated, then any requests to the server initiated by either a user or the script will include the appropriate cookies. The fact that the scripts cannot themselves know the content of the cookies doesn't matter.
For any cookies that are used for purposes other than authentication, these can be set without the HTTP only flag, if you want script to be able to modify or read these. You can pick and choose which cookies should be HTTP only, so for example anything non-sensitive like UI preferences (sort order, collapse left hand pane or not) can be shared in cookies with the scripts.
I really like the HTTP only cookies - it's one of those proprietary browser extensions that was a really neat idea.
Not necessarily, it depends what you want to do. Could you elaborate a bit? AJAX doesn't need access to cookies to work, it can make requests on its own to extract information, the page request that the AJAX call makes could access the cookie data & pass that back to the calling script without Javascript having to directly access the cookies
As clarification - from the server's perspective, the page that is requested by an AJAX request is essentially no different to a standard HTTP get request done by the user clicking on a link. All the normal request properties: user-agent, ip, session, cookies, etc. are passed to the server.
There's a bit more to this.
Ajax doesn't strictly require cookies, but they can be useful as other posters have mentioned. Marking a cookie HTTPOnly to hide it from scripts only partially works, because not all browsers support it, but also because there are common workarounds.
It's odd that the XMLHTTPresponse headers are giving the cookie, technically the server doesn't have to return the cookie with the response. Once it's set on the client, it stays set until it expires. Though there are schemes in which the cookie is changed with every request to prevent re-use. So you may be able to avoid that workaround by changing the server to not provide the cookie on the XMLHTTP responses.
In general though, I think HTTPOnly should be used with some caution. There are cross site scripting attacks where an attacker arranges for a user to submit an ajax-like request originating from another site, using simple post forms, without the use of XMLHTTP, and your browser's still-active cookie would authenticate the request.
If you want to be sure that an AJAX request is authenticated, the request itself AND the HTTP headers need to contain the cookie. Eg through the use of scripts or unique hidden inputs. HTTPOnly would hinder that.
Usually the interesting reason to want HTTPOnly is to prevent third-party content included on your webpage from stealing cookies. But there are many interesting reasons to be very cautious about including third-party content, and filter it aggressively.
Cookies are automatically handled by the browser when you make an AJAX call, so there's no need for your Javascript to mess around with cookies.
Therefore I am assuming JavaScript needs access to your cookies.
All HTTP requests from your browser transmit your cookie information for the site in question. JavaScript can both set and read cookies. Cookies are not by definition required for Ajax applications, but they are required for most web applications to maintain user state.
The formal answer to your question as phrased - "Does JavaScript need access to cookies if AJAX is used?" - is therefore "no". Think of enhanced search fields that use Ajax requests to provide auto-suggest options, for example. There is no need of cookie information in that case.
No, the page that the AJAX call requests has access to cookies too & that's what checks whether you're logged in.
You can do other authentication with the Javascript, but I wouldn't trust it, I always prefer putting any sort of authentication checking in the back-end.
Yes, cookies are very useful for Ajax.
Putting the authentication in the request URL is bad practice. There was a news item last week about getting the authentication tokens in the URL's from the google cache.
No, there is no way to prevent attacks. Older browsers still allow trivial access to cookies via javascript. You can bypass http only, etc. Whatever you come up with can be gotten around given enough effort. The trick is to make it too much effort to be worthwhile.
If you want to make your site more secure (there is no perfect security) you could use an authentication cookie that expires. Then, if the cookie is stolen, the attacker must use it before it expires. If they don't then you have a good indication there's suspicious activity on that account. The shorter the time window the better for security but the more load it puts on your server generating and maintaining keys.