Why cookies and set-cookie headers can't be set while making xmlhttprequest using setRequestHeader?

I am sure you would have gone through the working draft and found

The above headers are controlled by the user agent to let it control those aspects of transport.

Firstly we need to understand, These are standards working as guidelines for interoperability of functions between different browsers. It's not mandated for the browser and hence browsers do have different level of adherence to this standard for different reasons.

Secondly, Technically speaking you can emulate a user agent , treat your program as the browser and can very well set those values as per mentioned standards.

Finally, the intent of disallowing overwriting of Headers or setting up headers for certain fields like Content-Length , Cookie ethos the secure design approach. It is to discourage or at least try to discourage HTTP Request smuggling.


You can disable this behaviour:

var xhr = new XMLHttpRequest();
xhr.setDisableHeaderCheck(true);
xhr.open(...);
...

As is well known, for browsers, cookies (among other properties) need to be carefully managed to prevent third parties from stealing user sessions (or other data). This is an issue with browsers, and the uncontrolled nature of visiting a website that runs arbitrary Javascript.

Of course this risk of arbitrary code execution is either a low or non-risk for node.js, as you only run a script which you wrote which may run other code you planned for.

If you have a look at the source code for driverdan's XMLHttpRequest.js you will find:

 // These headers are not user setable.   
 // The following are allowed but banned in the spec:   
 // * user-agent   
 var forbiddenRequestHeaders = [
    "accept-charset",
    "accept-encoding",
    "access-control-request-headers",
    "access-control-request-method",
    "connection",
    "content-length",
    "content-transfer-encoding",
    "cookie",
    "cookie2",
    "date",
    "expect",
    "host",
    "keep-alive",
    "origin",
    "referer",
    "te",
    "trailer",
    "transfer-encoding",
    "upgrade",
    "via"   ];

This answer your specific question of why the restriction particularly applies to this script used for node.js - the coder was following the spec (as closely as possible), despite that feeling it probably wasn't a required security precaution in node.js. Nevertheless this default security level is readily modified.

As robertklep pointed out, you can disable this default precaution by using the setDisableHeaderCheck method. And yes this final point does answer or contribute significantly toward an answer for your question because in your question you stated:

I have found a patch and successfully able to send the cookie-header

We have now found you didn't need that patch.

Good Luck!


Yes, it is required for data-integrity and security. To understand this, you have to understand the role of cookies in HTTP request methods.

Cookies are important in identifying the user, browser, connection etc and are stored at web browser. JavaScript allows you to manipulate cookies, but not all cookies on the browser. See HTTP cookies, these are only set by browser, so that user can't misuse it (via JavaScript).

On a supported browser, an HttpOnly session cookie will be used only when transmitting HTTP (or HTTPS) requests, thus restricting access from other, non-HTTP APIs (such as JavaScript).

When you send xmlhttprequest it reads HttpOnly cookies and sends to server via Cookie header. Now if you do xhr.setRequestHeader('Cookie', "key=value"); , you are trying to tamper with the cookies sent to server. setRequestHeader will add extra key=value that may compromise the integrity of the cookies sent.

These are used by server to authenticate the user (session, email-account or any account). This essentially allows server to prevent misuse of cookies to get access into server.