Sending POST, GET and COOKIE data with AJAX request - javascript

The POST and GET data are done very easily with ajax. I can't find a way to 'include' a cookie. How can I include a 'cookie'?

There is no way to explicitly add a cookie to an XMLHttpRequest request (or for any of the other techniques used for Ajax). The setRequestHeader method explicitly forbids setting cookies.
You need to add a cookie through the normal methods (i.e. via the HTTP Set-Cookie response header and the JS document.cookie API) and then make the request.
You'll also need to set xml.withCredentials = true; for a cross-origin request (and the cookie will need to belong to the host you are making the request to, not the document hosting the JS making the request).

Related

Setting and getting a cookie back from a javascript tag request

I have the following situation:
Javascript tag with src=domain1.com in another_domain.com page
Javascript tag returns a cookie header and script content from domain1.com server
Script content collects data and send it via request to domain1.com
I want to be able to set a cookie in the point 2 and recover it in the point 3. I've been able to set the cookie by returning a Set-Cookie header like this:
set-cookie: cookieName="cookieValue";Version=1;Domain=domain1.com;Path=/;SameSite=None;Max-Age=600;Secure
But I am not able to recover it in the request in the point 3, as the cookie is not sent with the request.
So, two questions at this point:
Do I need to manually send the cookie in the second request? When tested doing redirects, the cookie header is "autoattached" to the second request and I'm able to recover it, but this is not happening with the requests from the javascript tag.
I am only able to set a cookie in https (Secure cookie) and with SameSite=None from the script? When tried without Secure and SameSite=None or in an http environment, the cookie was not set and a cross-site error was thrown by the developer console.
Thanks for reading.
There are several things to consider here. First of all we have to note that we are facing a case of cross domain communications.
If you need to send in the step 3 the Cookie set by the server in the step 2, you have to explicitly configure it when making the request. In case you are using XMLHTTPRequest you have to set up withCredentials to true, here is the docs.
If you are using fetch take a look at Request credentials.
As it's a cross domain communication, make sure your CORS headers are properly configured. When the request credentials mode is "include" you will need to set the Access-Control-Allow-Origin header to something valid and not a wildcard "*". You will also need Access-Control-Allow-Credentials to true, check it here.
With this configuration, the cookie will be "autoattached" (as per your words) in the third step. You can't set a cookie via JS on a cross-domain setting for security reasons, see this response.

How to make the Browser include the cookies of the domain of the host origin when making a cross-origin HTTP request

I made a cross-origin HTTP request from the website 'demo.home.com' to 'demo.company.com' using the Fetch api with the credentials set to 'include'. There are two cookies. One is 'cookie_home=123; Domain=demo.home.com', the other is 'cookie_company=456; Domain=demo.company.com'. As a result, the cookie 'cookie_company' was included by the request. Is there any way to let the cookie 'cookie_home' be included by the request?
// the request is made in the website 'http://demo.home.com'
// the cookies are:
// 'cookie_home=123; Domain=demo.home.com'
// 'cookie_company=456; Domain=demo.company.com'
fetch('http://demo.company.com/api/test', {
method: 'GET',
credentials: 'include'
});
You can't. fetch (and XMLHttpRequest) provide no mechanism to manually set cookies in a request.
They'll only send cookies in the browser's cookie jar for the target URL. This applies the normal rules for which domain a cookie belongs to.
You need to use some other mechanism to send the data you would store in the cookies.

Make an HTTP Request from a browser, without sending any cookies in the request headers

Is it possible to make a request from a browser, preferably using the built-in XMLHttpRequest API, "WITHOUT" sending any cookies in the request headers?
As far as I understand setting the "allowCredentials" property to false will only disable cookies for CORS requests, where I want to make a request to the same server while not sending a "Cookie" header.
I know this sounds a bit strange, but because of current project constrains I do not have the ability to alter the Server to change the "path" in the "Set-Cookie" response header.
I'm not sure if there is a way to exclude cookies for a single request.
If you know the names of the cookies and they will not be needed by other requests later, you can delete their values like this:
document.cookie="COOKIENAME=";
The cookie names will still be there though.
If you need the values later, you can save the cookies to a variable:
var cookie = document.cookie;
// Delete the cookie values like above.
// Make a request without cookie values.
document.cookie=cookie;
But if you need to make requests with and without cookie values at the same time, this will obviously not work. And if the cookies have the HTTPOnly attribute, you will not be able to read them or change their values.

How to make a cookieless ajax request?

Is it possible to explicitly make a cookieless request with javascript? I know you can't make a request "emulating" cookies (i.e. submitting data as a cookie value can't be done unless there is an actual cookie set with that value), but this seems to be more acceptable security-wise.
The choices I see are:
You can clear all the client-controlled cookies before making the ajax request (this won't clear server-side only cookies).
You can add an argument to your ajax requests that instructs the server to ignore any cookie values for that particular request.
You can set things up so that the ajax request goes to a server or path that doesn't have access to the cookies of interest so they won't be sent with that request.
If it is one specific cookie value and that value is client-controlled, then you could save that cookie value, clear it, send the ajax request, then restore the cookie value again. Actually, I guess you could do this with all cookie values, but it's simpler to do it with just a few.
As was mentioned in a comment to the question, this is not possible, you do not have any control over this aspect of the browser. The only way I can think to get this to work is to set the PATH of your cookies to a specific directory in your domain (e.g. host.domain.com/myApp), and then have your ajax request be to a directory that is not a child of the directory of the PATH you set for your cookies (e.g. host.domain.com/ajaxDirectory).
A common practice to reduce request size is to have resources on a different sub-domain. This way most cookies won't be sent, but obviously that isn't an option for AJAX (unless you're using JSONP).
this seems to be more acceptable security-wise
Just ignore the cookie that are unused in the server side, or first do a request to the logout service. Another alternative is to code your server so you can override the data in the cookie with, say form encoded data in post body or request header.

Can jQuery.getJSON put a domain's cookies in the header of the request it makes?

(Note: See also the related question Can browsers react to Set-Cookie specified in headers in an XSS jquery.getJSON() request?)
I can't seem to set a cookie (whose name is mwLastWriteTime) in the request header of a JSON operation. The request itself is a simple one from the Freebase MQL tutorials, and it is working fine otherwise:
// Invoke mqlread and call the function below when it is done.
// Adding callback=? to the URL makes jQuery do JSONP instead of XHR.
jQuery.getJSON("http://api.sandbox-freebase.com/api/service/mqlread?callback=?",
{query: JSON.stringify(envelope)}, // URL parameters
displayResults); // Callback function
I'd hoped that I could set this cookie with something along the lines of:
$.cookie('mwLastWriteTime', value, {domain: ".sandbox-freebase.com"});
Unfortunately, looking in FireBug at the outgoing request header I see only:
Host api.sandbox-freebase.com
User-Agent [...]
Accept */*
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive 115
Connection keep-alive
Referer [...]
But if I don't specify the domain (or if I explicitly specify the domain of the requesting site) I can get mwLastWriteTime to show up in the headers for local requests. Since the .sandbox-freebase.com domain owns these cookies, shouldn't they be traveling along with the GET? Or does one need a workaround of some sort?
My code is all JavaScript, and I would like to set this cookie and then call the getJSON immediately afterward.
You cannot set a cross-domain cookie, because that would open the browser (and therefore the user) to XSS attacks.
To quote from the QuirksMode.org article that I reference above:
Please note that the purpose of the
domain is to allow cookies to cross
sub-domains. My cookie will not be
read by search.quirksmode.org because
its domain is www.quirksmode.org .
When I set the domain to
quirksmode.org, the search sub-domain
may also read the cookie. I cannot set
the cookie domain to a domain I'm not
in, I cannot make the domain
www.microsoft.com . Only
quirksmode.org is allowed, in this
case.
If you want to make cross-site request with cookie values you will need to set up a special proxy on a server you control that will let you pass in values to be sent as cookie values (probably via POST parameters). You'll also want to make sure that you properly secure it, lest your proxy become the means by which someone else's private information is "liberated".
Are you running all of your tests through localhost? Are you using IE? If so it will be enforcing its own special brand of security requirements and likely dumping your cookies. Open fiddler and use http://ipv4.fiddler to bypass that.
If that type of trickery is not going on (as it appears you are using FireFox) , it may also be the case that you do need to explicitely set the cookie's domain to be the same as the domain of your JSON request. A browser won't send cookies set for domain A to a request to domain B. I am not 100% sure this is the case though.

Categories

Resources