Merge pull request #69 from superhumane/xss_fix
Escape strings in HTML output (XSS fix)
This commit is contained in:
commit
89b6183704
|
@ -19,7 +19,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"accepts": "^1.3.3",
|
"accepts": "^1.3.3",
|
||||||
"debug": "^2.2.0",
|
"debug": "^2.2.0",
|
||||||
"ejs": "^2.4.2",
|
"ejs": "^2.5.7",
|
||||||
"http-status": "^1.0.0",
|
"http-status": "^1.0.0",
|
||||||
"js2xmlparser": "^3.0.0",
|
"js2xmlparser": "^3.0.0",
|
||||||
"strong-globalize": "^3.1.0"
|
"strong-globalize": "^3.1.0"
|
||||||
|
|
|
@ -472,6 +472,47 @@ describe('strong-error-handler', function() {
|
||||||
done);
|
done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('HTML-escapes all 4xx response properties in production mode',
|
||||||
|
function(done) {
|
||||||
|
const error = new ErrorWithProps({
|
||||||
|
name: 'Error<img onerror=alert(1) src=a>',
|
||||||
|
message:
|
||||||
|
'No instance with id <img onerror=alert(1) src=a> found for Model',
|
||||||
|
statusCode: 404,
|
||||||
|
});
|
||||||
|
givenErrorHandlerForError(error, {debug: false});
|
||||||
|
requestHTML()
|
||||||
|
.end(function(err, res) {
|
||||||
|
expect(res.statusCode).to.eql(404);
|
||||||
|
const body = res.error.text;
|
||||||
|
expect(body).to.match(
|
||||||
|
/<title>Error<img onerror=alert\(1\) src=a><\/title>/
|
||||||
|
);
|
||||||
|
expect(body).to.match(
|
||||||
|
/with id <img onerror=alert\(1\) src=a> found for Model/
|
||||||
|
);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it('HTML-escapes all 5xx response properties in development mode',
|
||||||
|
function(done) {
|
||||||
|
const error = new ErrorWithProps({
|
||||||
|
message: 'a test error message<img onerror=alert(1) src=a>',
|
||||||
|
});
|
||||||
|
error.statusCode = 500;
|
||||||
|
givenErrorHandlerForError(error, {debug: true});
|
||||||
|
requestHTML()
|
||||||
|
.expect(500)
|
||||||
|
.expect(/<title>ErrorWithProps<\/title>/)
|
||||||
|
.expect(
|
||||||
|
/500(.*?)a test error message<img onerror=alert\(1\) src=a>/,
|
||||||
|
done
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
it('contains subset of properties when status=4xx', function(done) {
|
it('contains subset of properties when status=4xx', function(done) {
|
||||||
var error = new ErrorWithProps({
|
var error = new ErrorWithProps({
|
||||||
name: 'ValidationError',
|
name: 'ValidationError',
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset='utf-8'>
|
<meta charset='utf-8'>
|
||||||
<title><%- data.name || data.message %></title>
|
<title><%= data.name || data.message %></title>
|
||||||
<style><%- include style.css %></style>
|
<style><%- include style.css %></style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
<h1><%- data.name %></h1>
|
<h1><%= data.name %></h1>
|
||||||
<h2><em><%- data.statusCode %></em> <%- data.message %></h2>
|
<h2><em><%= data.statusCode %></em> <%= data.message %></h2>
|
||||||
<%
|
<%
|
||||||
// display all the non-standard properties
|
// display all the non-standard properties
|
||||||
var standardProps = ['name', 'statusCode', 'message', 'stack'];
|
var standardProps = ['name', 'statusCode', 'message', 'stack'];
|
||||||
for (var prop in data) {
|
for (var prop in data) {
|
||||||
if (standardProps.indexOf(prop) == -1 && data[prop]) { %>
|
if (standardProps.indexOf(prop) == -1 && data[prop]) { %>
|
||||||
<div><b><%- prop %></b>: <%- data[prop] %></div>
|
<div><b><%= prop %></b>: <%= data[prop] %></div>
|
||||||
<% }
|
<% }
|
||||||
}
|
}
|
||||||
if (data.stack) { %>
|
if (data.stack) { %>
|
||||||
|
|
Loading…
Reference in New Issue