I am trying to make an API call to a service (on a different domain) and in its response headers, there are some Set-Cookie headers.
And in the response, I have an URL that I need to hit again along with these cookies. But the browser does not seem to respect these cookies and they do not get sent.
Now what I tried to do was, after making the XmlHTTPRequest, I used document.cookie to set the cookies (cookies were also available as part of the API response) along with the domain. And even then the subsequent request (normal http) would not use these cookies.
Now, if I try to visit the page of the actual service, they set cookies in my browser under their domain and now my requests start working properly!
What else I did? I got the cookies and URL from the API response and used cURL to make the request. Voila it worked!
How do I acheive the same with JavaScript. Is it because you cant set cookies for a different domain or something?
Related
I've developed a plugin for a web site, for the sake of this post let's call it www.somesite.com
The plugin has authorization page on my website, let's call it www.mysite.com, which returns cookie upon authorization, which I obviously want to use in subsequent requests to www.mysite.com.
The plugin uses dynamic rules to change Access-Control-Allow-Origin on request to www.somesite.com to "*", so cross-origin requests can be sent from the page to www.mysite.com. However cookies of www.mysite.com are not passed automatically with the request when I send requests from plugin's injected code using XMLHttpRequest. As I understand this is intended browser behavior to prevent "stealing" cookies via cross origin requests, and cookies are only passed if the request is originated from the browser itself.
Question is, is there a way around this? Obviously I'm not trying to steal your cookies :) I just need the cookies of www.mysite.com to be sent automatically in XHR requests I send from the webpage on www.somesite.com domain.
I've seen a similar question, but it required to modify response headers of the origin site, which I obviously have no access to, so in my case that solution won't work. I have access to backend of www.mysite.com, front end of www.mysite.com, frontend of www.somesite.com (via script injection via plugin) and NO ACCESS to backend of www.somesite.com.
Thanks!
used framework: nuxt.js + spring boot(api)
Invoke once api to generate random values and set httpOnly cookie(e.g. key=csrfToken) when the page is first accessed.
The api response is also stored in vuex.
(the response also has token body. with Set-Cookie header.)
When request using axios, If there is the "csrfToken" cookie, add custom header(e.g. key=CSRF_TOKEN_HEADER) to the request.
In the server, if csrfToken cookies are delivered, look up the custom header values to compare them to see if they are the same.
I know that $store is not secure in itself. However, I think CSRF is defensible because $store is not accessible from outside sites.
Please let me know if there is anything wrong with me.
When request using axios, If there is the "csrfToken" cookie, add custom header(e.g. key=CSRF_TOKEN_HEADER) to the request.
Since the cookie is httpOnly, you wouldn't be able to tell if there was or not.
A CSRF attack works by tricking the user into making a request that they didn't intend to make.
The traditional way to do this is to have a form on an attacking website which has the action sent to the website being attacked. When that form is submitted, the request comes from the user's browser and has all the user's cookies for the target website included.
The defence against this is to require that the request includes information that the attacking site cannot know. The CSRF token.
Since the attacking site can't read that token from the user's cookies or the site's session store (depending on where it was stored) or from anywhere else, they can't include it in the form data.
But you aren't using a regular form submission. You are using JavaScript to make the request.
This comes with a built-in defence: The Same Origin Policy and Preflight Requests.
All you need do is force the request to be preflighted (e.g. by setting the Content-Type request header to application/json and including a JSON payload in the body).
This will force a request from the attacking site to make a preflight request. Your server won't have the attacker whitelisted. The browser will therefore never make the attacking request.
If the attacker tries to make a non-preflighted request, it won't have the JSON payload, so your server can reject it as malformed.
So I followed the steps outlined on the AWS blog here. (Note: I also used this method without the domain parameter same result)
Here is the issue: I see the cookie like so on my chrome browser Developer Tools> Network
So gateway is sending the settings back and it is being understood by the browser but when I look at the actually cookie storage I don't see the cookie. Just other ad cookies.
Here is the Set-Cookie Header that I am sending.
Any Ideas why the cookie, is not actually being set, and is not persistent?
I'd recommend abandoning usage of Set-Cookie header in your asynchronous requests because of inconsistent browser cross domain policies. Instead you can set the Cookie in client-side Javascript after receiving the response as a temporary measure.
You can consider migrating the logic to send the data in the request body as a JSON payload.
Is there a programmatic way in javascript to ignore cookies sent from the server (without changing browser settings).
We use certain plugins on our web server that will randomly update our security cookie. However this causes issues for some of our URLs and we want to ignore those cookies for some cases.
Our security architect recommended we look into this possibility.
example:
1). create ajax request with URL: www.site.com/abc/comtd
2). ignore any cookies that come back in the response
The only way I can think of is to send the AJAX request from a completely different domain. Because the AJAX would be a Cross-Origin Resource Sharing (CORS) request, any response headers would be denied unless the server sends the access-control-allow-origin header. If the AJAX request is not a CORS request, the browser has to respect all Set-cookie headers it receives per the standard.
its not an option in our case to change domains. We need to pass cookies to the server or the requests will not get through security. If we change domains our security cookies would not get passed. What we want is to pass the cookies but ignore any set-cookie response headers for certain URLs.
I think this is not possible on the browser so I am investigating some Apache server plugins like mod_headers. Maybe we can do it on the server itself. Im closing this question and will open another one related to mod_headers.
Just a thought - if you send the request from a WebWorker - I think that is isolated from the main browser context ?
I have a working CORS set up in my app.
On the server side REST service I added setting of cookies in the ajax responses.This works great ,the next Ajax requests to the CORS service are sent with cookies.
Now I want on the client side to get/set the values these set cookies from javascript.
document.cookies returns an empty string even though they are sent from the browser with each request to the rest service(this means they are stored somewhere).
I am running both the service and the client from localhost, and in chrome developer tools in the resources tab under the cookies section these sent cookies are not present.
Where are these cookies stored and how can I access them ?
The only interface JavaScript (on a webpage) has for reading cookies is document.cookie which contains the cookies for the current HTML document.
Cookies set via a cross-domain Ajax request are not for the current HTML document, so are not available through that interface.
XMLHttpRequest does have a getAllResponseHeaders() method, but Set-Cookie headers are suppressed by browsers so you can't access them as they are being set either.