Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
XSS: escape < and > characters in written out XHR response
This escapes < and > to prevent XHR responses from containing script injections.
- Loading branch information
Showing
7 changed files
with
106 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
node_modules/ | ||
dist/ | ||
doc/ | ||
test/xss/out.html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
var assert = require("assert"); | ||
require("steal-mocha"); | ||
|
||
describe("An injected script", function(){ | ||
it("doesn't run", function(){ | ||
assert.equal(window.FOO, undefined, "script not injected"); | ||
}); | ||
|
||
it("Has the correct value", function(){ | ||
var resp = XHR_CACHE[0].response.responseText; | ||
var expected = '</script><script>window.FOO=\'bar\';</script>'; | ||
assert.equal(resp, expected); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<script src="../../node_modules/steal/steal.js" main="MAIN" | ||
data-mocha="bdd"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
var Zone = require("../../lib/zone"); | ||
var xhrZone = require("../../xhr"); | ||
var testee = require("testee"); | ||
|
||
var utils = require("./utils"); | ||
var mockXHR = utils.mockXHR; | ||
var injectTest = utils.injectTest; | ||
|
||
describe("Script injection", function(){ | ||
this.timeout(50000); | ||
|
||
beforeEach(function(){ | ||
var resp = '</script><script>window.FOO=\'bar\';</script>'; | ||
this.resetXHR = mockXHR(resp); | ||
}); | ||
|
||
afterEach(function(){ | ||
this.resetXHR(); | ||
}); | ||
|
||
it("Correctly escapes scripts", function(done){ | ||
var zone = new Zone({ | ||
plugins: [xhrZone] | ||
}); | ||
|
||
zone.run(function(){ | ||
var xhr = new XMLHttpRequest(); | ||
xhr.open("GET", "http://example.com"); | ||
xhr.send(); | ||
}).then(function(data){ | ||
injectTest(data.xhr, "test/xss/browser-test"); | ||
|
||
return testee.test(["test/xss/out.html"], 'firefox', { | ||
reporter: 'Spec' | ||
}); | ||
}).then(function() { done(); }, done); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
var env = require("../../lib/env"); | ||
var g = env.global; | ||
var fs = require("fs"); | ||
|
||
exports.mockXHR = mockXHR; | ||
|
||
function mockXHR(mockedResponse) { | ||
var globalSetTimeout = g.setTimeout; | ||
var OldXHR = g.XMLHttpRequest; | ||
var XHR = g.XMLHttpRequest = function(){ | ||
this.onload = null; | ||
}; | ||
|
||
XHR.prototype.getAllResponseHeaders = function(){ | ||
return "Content-Type: application/json"; | ||
}; | ||
|
||
XHR.prototype.open = function(){}; | ||
|
||
XHR.prototype.send = function(){ | ||
var onload = this.onload; | ||
var xhr = this; | ||
|
||
globalSetTimeout(function(){ | ||
xhr.responseText = mockedResponse; | ||
onload && onload({ target: xhr }); | ||
}, 10); | ||
}; | ||
|
||
return function(){ | ||
g.XMLHttpRequest = OldXHR; | ||
}; | ||
} | ||
|
||
exports.injectTest = injectTest; | ||
|
||
function injectTest(cache, testJs) { | ||
var testPth = __dirname + "/inj.html" | ||
var testPage = fs.readFileSync(testPth, "utf8"); | ||
var xhrScript = "<script>" + cache + "</script>"; | ||
testPage = testPage.replace("MAIN", testJs); | ||
testPage = testPage + xhrScript; | ||
fs.writeFileSync(__dirname + "/out.html", testPage, "utf8"); | ||
} |