XHR2 withCredentials - which cookies are sent? - javascript

Hopefully this is simple to answer.
With a credentialed request in XHR2, which cookies are sent?
I've been following the MDN article on credentialed requests, and it shows that the cookie pageAccess=2 is sent with the request. However it doesn't explain where that cookie comes from, and why that cookie specifically is being sent. Is it simply that all cookies set by the page are sent in any credentialed request?

From the HTML5 Rocks page on CORS:
The .withCredentials property will include any cookies from the remote domain in the request, and it will also set any cookies from the remote domain.
I assume "any cookies" means "all cookies" (probably subject to a HTTPS-only flag on the cookie), since there is no mechanism to specify cookies with XHR2.
The cookies that get sent are the cookies that were set by the remote domain: if foo.com sends a request a credentialed request to bar.com, any cookies set by bar.com are sent. To put this in practical terms, suppose facebook.com has a CORS-aware API that requires you to be logged in to use. I've logged in to Facebook earlier in my browser session, but now I'm browsing foo.com, which is going to use Facebook's API on my behalf. foo.com asks th ebrowser to send a cross-domain request to facebook.com along with all my facebook.com cookies so Facebook knows who I am and that I've already authenticated to Facebook.

Related

How does httpOnly prevent from malicious package to steal the content in it?

If for example, an installed third party package issues an HTTP request to their servers, and by default, any HTTP request leaves with the cookies content in the request headers, doesn't it make the content to be exposed to the server who receives the request? I don't get how httpOnly prevents from the access token to be revealed...
HTTP requests carry with it only cookies that are applicable to the domain being requested, not all of the browser's cookies. If you have a browser with cookies for bank.com, shop.com, and evil-site.com, a request to evil-site.com would only send evil-site.com cookies with the request. Not so useful.
Now say a malicious script has infected bank.com and has placed itself on a page in that domain. Now that script is running in the context of bank.com and the currently viewing user. It can now read bank.com's non-HttpOnly cookies using document.cookie and send them to evil-site.com with a simple script. This means that if you logged in to bank.com and viewed that infected page, your login cookies can now be stolen.
Marking a cookie as HttpOnly tells the browser not to expose the cookie to JavaScript, i.e. any script, legit or not, cannot read the cookie's value from document.cookie. So if bank.com made their login cookie HttpOnly, this cookie would not be readable by any script on the page. However, the cookie is still passed back and forth between browser and bank.com in requests and responses while the cookies are present and valid.
HttpOnly is just one of the many measures to prevent cookie theft and should be complemented by other security features. Secure makes sure the cookie is only ever sent through HTTPS connections. SameSite defines when the cookie is allowed to cross sites. HTTPS connections prevent reading the request over the network.
The httpOnly attribute purpose is to hide the cookie from the JavaScript context.
To observe it, you can type document.cookie in the console of any web page, and you'll notice that the result contains all of the cookies that are not httpOnly and from the current domain. You can verify it with the Application tab of the DevTools.
That means if an attacker somehow manages to execute malicious code on a user's web page (e.g. by exploiting a script injection vulnerability), he may be able to send requests on behalf of that user but he should not be able to retrieve the cookie's value.

Can same orgin policy prevent attack if jwt is stolen?

I read this blog What Happens If Your JWT Is Stolen?
The blog says that if one gets the JWT he/she can send requests to the server on behalf of the user.
My question is:- if JWT is stolen and my website don't allow request from unknown domain (due to same origin policy), will I be safe? Is there a way to override same origin policy by the hacker.
I know with XSS attack hacker can send the request from my domain. But here, just assume the hacker only has the JWT and there is no XSS attack.
These policies are a set of rules for browsers. Every HTTP client like curl or Postman can "override" these policies and send custom requests. With Postman you can configure the request as you want.
Same origin policies don't protect your server from attackers. They protect users of your web application from involuntary executing malicious code.
If attackers get a valid token they can send valid requests.
"Can same orgin policy prevent attack if jwt is stolen?" No, they can't.
Your website is a server that answers HTTP(S) requests. An HTTP request is just a bunch of text in a few IP packets. Anybody connected to the Internet can send any text they want to your server. The only information in there which is reliable is the origin and target IP adress of the server and the client connecting (as otherwise the packets won't arrive). Now to ensure that a certain request comes from a certain user, you share a secret with the user, which gets send with the request. When a request arrives, this secret is the only way to authenticate the user. If someone is able to steal or guess that secret, there is no way for the server to distinguish between the user and the attacker.
my website don't allow request from unknown domain
Not quite, the browser which the user uses to store the secret the server gave to the user, ensures that the secret gets only shared with your server. If you disable cross origin sharing, code of other websites the user visits with their webbrowser is unable to perform requests to your server in the background. Thus it prevents that other code uses the secret to perform an action on your server.
In conclusion CORS policies only help to keep secrets secret, if the secret is not secret anymore they won't help.

Set Cross-Origin Cookies Using POST Method

I wish to set cross-origin cookies in server side using POST method.
Cors settings are set up in server side to allow the cross-domain requests and credentials.
After sending a POST from a cross-domain JS application, the cookie is not shown in the browser although the response has set-cookies headers.
However, using GET method to set the cross-domain Cookie from the server works fine and it is saved in the browser.
I failed to find some documentation about this, much appreciated if anyone could explain why the cookies can’t be set using POST?
The cookie set by other server will only be visible in the origin site.
For example, you have site.com and ads.com. Site.com wants to use some resources from ads.com.
Step 1: site.com sends a GET/POST request to ads.com.
Step 2: ads.com sends a response with cookie(ad_id=blala) attached. This cookie originates from ads.com and will only be visible at ads.com.
Step 3: site.com sends other requests with the cookie(ad_id=blala) to ads.com.
If you check cookies in site.com, you cannot find the ad_id cookie because this cookie is only visible in ads.com.
In this case, to view the cookie, go to ads.com rather than your site.

How to bypass CORS in ajax call in your localhost when working with Fetch API? [duplicate]

I am trying to understand why CORS is working in way that it works.
As I learned from this post, when page from www.a.com makes AJAX request to www.b.com, then it's the www.b.com that decides if request should be allowed or not.
But what is exactly secured on client in such model?
For example, if a hacker succeeds to make an XSS script injection to my page, then it makes an AJAX request to his domain to store user data. So a hacker's domain will allow such a request for sure.
I thought that www.a.com should decide to which domains to allow the request to. So in theory within a header Access-Control-Allow-Origin I would like to put the whole list of the domains that are allowed for AJAX CORS requests.
Can someone explain what security problems the current CORS implementation handles?
As I learned from this post, when page from www.a.com makes AJAX request to www.b.com, then it's the www.b.com that decides if request should be allowed or not.
Not quite. The request isn't blocked (at least, if it is simple).
By default the JavaScript running on www.a.com is forbidden access to the response from www.b.com.
CORS provides a means by which www.b.com can give permission to the JavaScript on www.a.com to access the response.
But what is exactly secured on client in such model?
It stops the author of www.a.com from reading data from www.b.com using the browser of a User who has visited both sites and has been authenticated on www.b.com (and thus has access to data that isn't public).
For example, Alice is logged into Google. Alice visits malicious.example which uses XMLHttpRequest to access data from gmail.com. Alice has a GMail account so the response has a list of the most recent email in her inbox. The same origin policy prevents malicious.example from reading it.
For example, hacker success to make XSS script injection to my page, then it makes AJAX request to his domain to store user data. So hackers domain will allow such request for sure.
Correct. XSS is a different security problem that needs to be addressed at source (i.e. at www.a.com and not in the browser).
In addition to #Quentin's excellent answer, there is another technology known as Content Security Policy which describes what you are after.
I thought that www.a.com should decide to which domains to allow the request to. So in theory within a header Access-Control-Allow-Origin I would like to put the whole list of the domains that are allowed for AJAX CORS requests.
With CSP, you could set a header from your domain (www.a.com in your example) to restrict AJAX requests:
connect-src limits the origins to which you can connect (via XHR, WebSockets, and EventSource).
So to use this you can add this Content-Security-Policy HTTP header to your HTML response:
Content-Security-Policy: connect-src 'self'
This will restrict AJAX requests to www.a.com if that header is in the response from www.a.com:
'self' matches the current origin, but not its subdomains
See here for supported browsers.

Cookies not sent on OPTIONS requests

For an Angular 1 app I am working on, cookie authentication is used. The problem is: when making OPTIONS calls, cookies are not sent and the server tries to redirect user to login again. Just wondering, whose "fault" is it? Server (Azure API Apps) or frontend? If frontend, how do I send cookies on OPTIONS call? I am using augular-resource and have configured it as below:
$httpProvider.defaults.withCredentials = true
The specification says:
Otherwise, make a preflight request. Fetch the request URL from origin source origin using referrer source as override referrer source with the manual redirect flag and the block cookies flag set, using the method OPTIONS, and with the following additional constraints … Exclude user credentials.
and also
The term user credentials for the purposes of this specification means cookies, HTTP authentication, and client-side SSL certificates that would be sent based on the user agent's previous interactions with the origin. Specifically it does not refer to proxy authentication or the Origin header.
So the client should not send cookies, and the server should be able to respond to the preflight request without requiring authentication to take place first.

Categories