Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access-Control-Expose-Headers does not work to allow JS client side to read cookies

I make AJAX calls to CORS server, I make many attempts to be able to read cookies returned on response using javascript client side, however, in vain .

1. First Attempt :

- Server Side (node.js powered by express) :

  response.header('Access-Control-Allow-Origin', '*');
  response.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept, Set-Cookie');
  response.header('Access-Control-Expose-Headers', "Set-Cookie");

 //------SET COOKIES
  response.cookie('SessionId', GeneratorId(64), {
            maxAge:3600000,
            httpOnly:flase // i disable httpOnly ==> does not work
          });

- client Side :

var xhttp=new XMLHttpRequest();
xhttp.open("POST", "http://localhost:9090/api/map", true);
xhttp,send(`{layer:1}`);

2. Second Attempt: (withCredentials)

-Server Side :

 //Append another response' header 
  response.header('Access-Control-Allow-Credentials','true'); 

-Client Side :

// Before xhttp.send , I add another instruction : 
 xhttp.withCredentials=true;

3. Third Attempt :

- Server Side :

//Avoid the wildcard on Access-Control-Allow-Origin =>Replace the first header by :
response.header('Access-Control-Allow-Origin', request.get('Origin'));

- Client Side :

 // Nothing is appended  

Conclusion :

With all those attempts , xhttp.getResponseHeader('Set-Cookie') still returns null even :

  • Set-Cookie is assigned to the response header : Access-Control-Expose-Headers .
  • I saw cookies on the browser console (Inspector) :

enter image description here

like image 311
Abdennour TOUMI Avatar asked Sep 15 '16 05:09

Abdennour TOUMI


People also ask

What does Access-Control expose headers do?

The Access-Control-Expose-Headers response header allows a server to indicate which response headers should be made available to scripts running in the browser, in response to a cross-origin request. Only the CORS-safelisted response headers are exposed by default.

How do I pass cookies in the header?

To send cookies to the server, you need to add the "Cookie: name=value" header to your request. To send multiple Cookies in one cookie header, you can separate them with semicolons. In this Send Cookies example, we are sending HTTP cookies to the ReqBin echo URL.

Which response header sends a cookie to the client?

The Set-Cookie HTTP response header is used to send a cookie from the server to the user agent, so that the user agent can send it back to the server later.


1 Answers

TL;DR: the Set-Cookie header is entirely off-limits: you can't access it, even when you include it in Access-Control-Expose-Headers. However, once it's set, and the cookie isn't marked httpOnly, you should be able to access it through document.cookie.

TMI follows:

As documented here,

A response will typically get its CORS-exposed header-name list set by parsing the Access-Control-Expose-Headers header. This list is used by a CORS filtered response to determine which headers to expose.

What a CORS filtered response is, is documented here:

A CORS filtered response is a filtered response whose type is "cors", header list excludes any headers in internal response's header list whose name is not a CORS-safelisted response-header name, given internal response's CORS-exposed header-name list, and trailer is empty.

And safelisted headers are subsequently documented here:

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

Any value in list that is not a forbidden response-header name.

Finally, the list of forbidden response-header names is listed here:

  • Set-Cookie
  • Set-Cookie2
like image 191
robertklep Avatar answered Sep 18 '22 13:09

robertklep