JS: Add ajv error as source of ExceptionXss

This commit is contained in:
Asger Feldthaus
2021-02-26 08:35:38 +00:00
parent 24199a5499
commit 7afa755597
7 changed files with 117 additions and 7 deletions

View File

@@ -5,8 +5,8 @@
<overview>
<p>
Directly writing exceptions to a webpage without sanitization allows for a cross-site scripting
vulnerability if the value of the exception can be influenced by a user.
Directly writing error messages to a webpage without sanitization allows for a cross-site scripting
vulnerability if parts of the error message can be influenced by a user.
</p>
</overview>
@@ -27,6 +27,19 @@ leaving the website vulnerable to cross-site scripting.
<sample src="examples/ExceptionXss.js" />
</example>
<example>
<p>
This second example shows an input being validated using the JSON schema validator <code>ajv</code>,
and in case of an error, the error message is sent directly back in the response.
</p>
<sample src="examples/ExceptionXssAjv.js" />
<p>
This is unsafe, because the error message can contain parts of the input.
For example, the input <code>{'&lt;img src=x onerror=alert(1)&gt;': 'foo'}</code> will generate the error
<code>data/&lt;img src=x onerror=alert(1)&gt; should be number</code>, causing reflected XSS.
</p>
</example>
<references>
<li>
OWASP:

View File

@@ -15,8 +15,18 @@ import javascript
import semmle.javascript.security.dataflow.ExceptionXss::ExceptionXss
import DataFlow::PathGraph
/**
* Gets a description of the source.
*/
string getSourceDescription(DataFlow::Node source) {
result = source.(ErrorSource).getDescription()
or
not source instanceof ErrorSource and
result = "Exception text"
}
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink.getNode(), source, sink,
"$@ is reinterpreted as HTML without escaping meta-characters.", source.getNode(),
"Exception text"
getSourceDescription(source.getNode())

View File

@@ -0,0 +1,13 @@
import express from 'express';
import Ajv from 'ajv';
let app = express();
let ajv = new Ajv();
ajv.addSchema({type: 'object', additionalProperties: {type: 'number'}}, 'pollData');
app.post('/polldata', (req, res) => {
if (!ajv.validate('pollData', req.body)) {
res.send(ajv.errorsText());
}
});