Skip to content

Commit

Permalink
Merge pull request #1168 from fatso83/1063-rebased__fix-for-1061-unsa…
Browse files Browse the repository at this point in the history
…fe-headers

Fix #1061: add configurable unsafe header checks
  • Loading branch information
fatso83 authored Oct 20, 2016
2 parents f19ae7f + ea97add commit 4ff653d
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 14 deletions.
6 changes: 5 additions & 1 deletion lib/sinon/util/fake_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ var fakeServer = {
server.requestCount = 0;

this.xhr.onCreate = function (xhrObj) {
xhrObj.unsafeHeadersEnabled = function () {
return !(server.unsafeHeadersEnabled === false);
};
server.addRequest(xhrObj);
};

Expand All @@ -105,7 +108,8 @@ var fakeServer = {
"autoRespondAfter": true,
"respondImmediately": true,
"fakeHTTPMethods": true,
"logger": true
"logger": true,
"unsafeHeadersEnabled": true
};
var setting;

Expand Down
29 changes: 17 additions & 12 deletions lib/sinon/util/fake_xml_http_request.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,22 @@ sinonXhr.supportsCORS = isReactNative ||
var unsafeHeaders = {
"Accept-Charset": true,
"Accept-Encoding": true,
Connection: true,
"Connection": true,
"Content-Length": true,
Cookie: true,
Cookie2: true,
"Cookie": true,
"Cookie2": true,
"Content-Transfer-Encoding": true,
Date: true,
Expect: true,
Host: true,
"Date": true,
"Expect": true,
"Host": true,
"Keep-Alive": true,
Referer: true,
TE: true,
Trailer: true,
"Referer": true,
"TE": true,
"Trailer": true,
"Transfer-Encoding": true,
Upgrade: true,
"Upgrade": true,
"User-Agent": true,
Via: true
"Via": true
};

// An upload object is created for each
Expand Down Expand Up @@ -476,7 +476,12 @@ extend(FakeXMLHttpRequest.prototype, sinonEvent.EventTarget, {
setRequestHeader: function setRequestHeader(header, value) {
verifyState(this);

if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
var checkUnsafeHeaders = true;
if (typeof this.unsafeHeadersEnabled === "function") {
checkUnsafeHeaders = this.unsafeHeadersEnabled();
}

if (checkUnsafeHeaders && (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header))) {
throw new Error("Refused to set unsafe header \"" + header + "\"");
}

Expand Down
12 changes: 12 additions & 0 deletions test/util/fake-server-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ if (typeof window !== "undefined") {
"fakeServer.create should accept 'fakeHTTPMethods' setting"
);
});
it("allows the 'unsafeHeadersEnabled' setting", function () {
var server = sinon.fakeServer.create({
unsafeHeadersEnabled: false
});
assert.defined(
server.unsafeHeadersEnabled,
"'unsafeHeadersEnabled' expected to be defined at server level");
assert(
!server.unsafeHeadersEnabled,
"fakeServer.create should accept 'unsafeHeadersEnabled' setting"
);
});
it("does not assign a non-whitelisted setting", function () {
var server = sinonFakeServer.create({
foo: true
Expand Down
94 changes: 93 additions & 1 deletion test/util/fake-xml-http-request-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var sinonSpy = require("../../lib/sinon/spy");
var sinonExtend = require("../../lib/sinon/extend");
var sinonSandbox = require("../../lib/sinon/sandbox");
var sinonFakeXhr = require("../../lib/sinon/util/fake_xml_http_request");
var sinon = require("../../lib/sinon");

var TextDecoder = global.TextDecoder || require("text-encoding").TextDecoder;
var FakeXMLHttpRequest = sinonFakeXhr.FakeXMLHttpRequest;
Expand Down Expand Up @@ -282,7 +283,7 @@ if (typeof window !== "undefined") {
});
});

it("disallows unsafe headers", function () {
it("disallows unsafe headers by default", function () {
var xhr = this.xhr;

assert.exception(function () {
Expand Down Expand Up @@ -366,6 +367,97 @@ if (typeof window !== "undefined") {
});
});

it("allows unsafe headers when fake server unsafeHeadersEnabled option is turned off", function () {
var server = sinon.fakeServer.create({
unsafeHeadersEnabled: false
});

var xhr = new sinon.FakeXMLHttpRequest();
xhr.open("GET", "/");

refute.exception(function () {
xhr.setRequestHeader("Accept-Charset", "");
});

refute.exception(function () {
xhr.setRequestHeader("Accept-Encoding", "");
});

refute.exception(function () {
xhr.setRequestHeader("Connection", "");
});

refute.exception(function () {
xhr.setRequestHeader("Content-Length", "");
});

refute.exception(function () {
xhr.setRequestHeader("Cookie", "");
});

refute.exception(function () {
xhr.setRequestHeader("Cookie2", "");
});

refute.exception(function () {
xhr.setRequestHeader("Content-Transfer-Encoding", "");
});

refute.exception(function () {
xhr.setRequestHeader("Date", "");
});

refute.exception(function () {
xhr.setRequestHeader("Expect", "");
});

refute.exception(function () {
xhr.setRequestHeader("Host", "");
});

refute.exception(function () {
xhr.setRequestHeader("Keep-Alive", "");
});

refute.exception(function () {
xhr.setRequestHeader("Referer", "");
});

refute.exception(function () {
xhr.setRequestHeader("TE", "");
});

refute.exception(function () {
xhr.setRequestHeader("Trailer", "");
});

refute.exception(function () {
xhr.setRequestHeader("Transfer-Encoding", "");
});

refute.exception(function () {
xhr.setRequestHeader("Upgrade", "");
});

refute.exception(function () {
xhr.setRequestHeader("User-Agent", "");
});

refute.exception(function () {
xhr.setRequestHeader("Via", "");
});

refute.exception(function () {
xhr.setRequestHeader("Proxy-Oops", "");
});

refute.exception(function () {
xhr.setRequestHeader("Sec-Oops", "");
});

server.restore();
});

it("sets header and value", function () {
this.xhr.setRequestHeader("X-Fake", "Yeah!");

Expand Down

0 comments on commit 4ff653d

Please sign in to comment.