Merge pull request #6024 from erik-krogh/serialize-javascript

Approved by asgerf
This commit is contained in:
CodeQL CI
2021-06-07 06:08:05 -07:00
committed by GitHub
8 changed files with 61 additions and 1 deletions

View File

@@ -0,0 +1,4 @@
lgtm,codescanning
* The dataflow libraries now model dataflow in the [`serialize-javascript`](https://npmjs.com/package/serialize-javascript) library.
Affected packages are
[serialize-javascript](https://npmjs.com/package/serialize-javascript)

View File

@@ -29,7 +29,8 @@ private class PlainJsonParserCall extends JsonParserCall {
callee = DataFlow::moduleImport("parse-json") or
callee = DataFlow::moduleImport("json-parse-better-errors") or
callee = DataFlow::moduleImport("json-safe-parse") or
callee = AngularJS::angular().getAPropertyRead("fromJson")
callee = AngularJS::angular().getAPropertyRead("fromJson") or
callee = DataFlow::moduleImport("serialize-javascript")
)
}

View File

@@ -55,6 +55,17 @@ module Shared {
}
}
/**
* A call to `serialize-javascript`, which prevents XSS vulnerabilities unless
* the `unsafe` option is set.t
*/
class SerializeJavascriptSanitizer extends Sanitizer, DataFlow::CallNode {
SerializeJavascriptSanitizer() {
this = DataFlow::moduleImport("serialize-javascript").getACall() and
not this.getOptionArgument(1, "unsafe").mayHaveBooleanValue(true)
}
}
private import semmle.javascript.security.dataflow.IncompleteHtmlAttributeSanitizationCustomizations::IncompleteHtmlAttributeSanitization as IncompleteHTML
/**
@@ -359,6 +370,9 @@ module DomBasedXss {
private class UriEncodingSanitizer extends Sanitizer, Shared::UriEncodingSanitizer { }
private class SerializeJavascriptSanitizer extends Sanitizer, Shared::SerializeJavascriptSanitizer {
}
private class IsEscapedInSwitchSanitizer extends Sanitizer, Shared::IsEscapedInSwitchSanitizer { }
private class QuoteGuard extends SanitizerGuard, Shared::QuoteGuard { }
@@ -497,6 +511,9 @@ module ReflectedXss {
private class UriEncodingSanitizer extends Sanitizer, Shared::UriEncodingSanitizer { }
private class SerializeJavascriptSanitizer extends Sanitizer, Shared::SerializeJavascriptSanitizer {
}
private class IsEscapedInSwitchSanitizer extends Sanitizer, Shared::IsEscapedInSwitchSanitizer { }
private class QuoteGuard extends SanitizerGuard, Shared::QuoteGuard { }
@@ -534,6 +551,9 @@ module StoredXss {
private class UriEncodingSanitizer extends Sanitizer, Shared::UriEncodingSanitizer { }
private class SerializeJavascriptSanitizer extends Sanitizer, Shared::SerializeJavascriptSanitizer {
}
private class IsEscapedInSwitchSanitizer extends Sanitizer, Shared::IsEscapedInSwitchSanitizer { }
private class QuoteGuard extends SanitizerGuard, Shared::QuoteGuard { }

View File

@@ -166,6 +166,7 @@ typeInferenceMismatch
| tst.js:2:13:2:20 | source() | tst.js:45:10:45:24 | x.map(x2 => x2) |
| tst.js:2:13:2:20 | source() | tst.js:47:10:47:30 | Buffer. ... 'hex') |
| tst.js:2:13:2:20 | source() | tst.js:48:10:48:22 | new Buffer(x) |
| tst.js:2:13:2:20 | source() | tst.js:51:10:51:31 | seriali ... ript(x) |
| xml.js:5:18:5:25 | source() | xml.js:8:14:8:17 | text |
| xml.js:12:17:12:24 | source() | xml.js:13:14:13:19 | result |
| xml.js:23:18:23:25 | source() | xml.js:20:14:20:17 | attr |

View File

@@ -46,4 +46,7 @@ function test() {
sink(Buffer.from(x, 'hex')); // NOT OK
sink(new Buffer(x)); // NOT OK
const serializeJavaScript = require("serialize-javascript");
sink(serializeJavaScript(x)) // NOT OK
}

View File

@@ -182,6 +182,14 @@ nodes
| tst2.js:36:12:36:12 | p |
| tst2.js:37:12:37:18 | other.p |
| tst2.js:37:12:37:18 | other.p |
| tst2.js:43:7:43:24 | p |
| tst2.js:43:9:43:9 | p |
| tst2.js:43:9:43:9 | p |
| tst2.js:49:7:49:53 | unsafe |
| tst2.js:49:16:49:53 | seriali ... true}) |
| tst2.js:49:36:49:36 | p |
| tst2.js:51:12:51:17 | unsafe |
| tst2.js:51:12:51:17 | unsafe |
| tst3.js:5:7:5:24 | p |
| tst3.js:5:9:5:9 | p |
| tst3.js:5:9:5:9 | p |
@@ -338,6 +346,13 @@ edges
| tst2.js:30:9:30:9 | p | tst2.js:30:7:30:24 | p |
| tst2.js:33:11:33:11 | p | tst2.js:37:12:37:18 | other.p |
| tst2.js:33:11:33:11 | p | tst2.js:37:12:37:18 | other.p |
| tst2.js:43:7:43:24 | p | tst2.js:49:36:49:36 | p |
| tst2.js:43:9:43:9 | p | tst2.js:43:7:43:24 | p |
| tst2.js:43:9:43:9 | p | tst2.js:43:7:43:24 | p |
| tst2.js:49:7:49:53 | unsafe | tst2.js:51:12:51:17 | unsafe |
| tst2.js:49:7:49:53 | unsafe | tst2.js:51:12:51:17 | unsafe |
| tst2.js:49:16:49:53 | seriali ... true}) | tst2.js:49:7:49:53 | unsafe |
| tst2.js:49:36:49:36 | p | tst2.js:49:16:49:53 | seriali ... true}) |
| tst3.js:5:7:5:24 | p | tst3.js:6:12:6:12 | p |
| tst3.js:5:7:5:24 | p | tst3.js:6:12:6:12 | p |
| tst3.js:5:9:5:9 | p | tst3.js:5:7:5:24 | p |
@@ -385,4 +400,5 @@ edges
| tst2.js:21:14:21:14 | p | tst2.js:14:9:14:9 | p | tst2.js:21:14:21:14 | p | Cross-site scripting vulnerability due to $@. | tst2.js:14:9:14:9 | p | user-provided value |
| tst2.js:36:12:36:12 | p | tst2.js:30:9:30:9 | p | tst2.js:36:12:36:12 | p | Cross-site scripting vulnerability due to $@. | tst2.js:30:9:30:9 | p | user-provided value |
| tst2.js:37:12:37:18 | other.p | tst2.js:30:9:30:9 | p | tst2.js:37:12:37:18 | other.p | Cross-site scripting vulnerability due to $@. | tst2.js:30:9:30:9 | p | user-provided value |
| tst2.js:51:12:51:17 | unsafe | tst2.js:43:9:43:9 | p | tst2.js:51:12:51:17 | unsafe | Cross-site scripting vulnerability due to $@. | tst2.js:43:9:43:9 | p | user-provided value |
| tst3.js:6:12:6:12 | p | tst3.js:5:9:5:9 | p | tst3.js:6:12:6:12 | p | Cross-site scripting vulnerability due to $@. | tst3.js:5:9:5:9 | p | user-provided value |

View File

@@ -39,4 +39,5 @@
| tst2.js:21:14:21:14 | p | Cross-site scripting vulnerability due to $@. | tst2.js:14:9:14:9 | p | user-provided value |
| tst2.js:36:12:36:12 | p | Cross-site scripting vulnerability due to $@. | tst2.js:30:9:30:9 | p | user-provided value |
| tst2.js:37:12:37:18 | other.p | Cross-site scripting vulnerability due to $@. | tst2.js:30:9:30:9 | p | user-provided value |
| tst2.js:51:12:51:17 | unsafe | Cross-site scripting vulnerability due to $@. | tst2.js:43:9:43:9 | p | user-provided value |
| tst3.js:6:12:6:12 | p | Cross-site scripting vulnerability due to $@. | tst3.js:5:9:5:9 | p | user-provided value |

View File

@@ -35,4 +35,18 @@ app.get('/baz', function(req, res) {
res.send(p); // NOT OK
res.send(other.p); // NOT OK
});
const serializeJavaScript = require('serialize-javascript');
app.get('/baz', function(req, res) {
let { p } = req.params;
var serialized = serializeJavaScript(p);
res.send(serialized); // OK
var unsafe = serializeJavaScript(p, {unsafe: true});
res.send(unsafe); // NOT OK
});