mirror of
https://github.com/github/codeql.git
synced 2026-04-27 09:45:15 +02:00
JS: Port PrototypePollutingMergeCall
This commit is contained in:
@@ -14,7 +14,10 @@ import semmle.javascript.dependencies.SemVer
|
||||
import PrototypePollutionCustomizations::PrototypePollution
|
||||
|
||||
// Materialize flow labels
|
||||
private class ConcreteTaintedObjectWrapper extends TaintedObjectWrapper {
|
||||
/**
|
||||
* We no longer use this flow label, since it does not work in a world where flow states inherit taint steps.
|
||||
*/
|
||||
deprecated private class ConcreteTaintedObjectWrapper extends TaintedObjectWrapper {
|
||||
ConcreteTaintedObjectWrapper() { this = this }
|
||||
}
|
||||
|
||||
@@ -22,7 +25,45 @@ private class ConcreteTaintedObjectWrapper extends TaintedObjectWrapper {
|
||||
* A taint tracking configuration for user-controlled objects flowing into deep `extend` calls,
|
||||
* leading to prototype pollution.
|
||||
*/
|
||||
class Configuration extends TaintTracking::Configuration {
|
||||
module PrototypePollutionConfig implements DataFlow::StateConfigSig {
|
||||
class FlowState = DataFlow::FlowLabel;
|
||||
|
||||
predicate isSource(DataFlow::Node node, DataFlow::FlowLabel label) {
|
||||
node.(Source).getAFlowLabel() = label
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node node, DataFlow::FlowLabel label) {
|
||||
node.(Sink).getAFlowLabel() = label
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(
|
||||
DataFlow::Node src, DataFlow::FlowLabel inlbl, DataFlow::Node dst, DataFlow::FlowLabel outlbl
|
||||
) {
|
||||
TaintedObject::step(src, dst, inlbl, outlbl)
|
||||
}
|
||||
|
||||
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet contents) {
|
||||
// For recursive merge sinks, the deeply tainted object only needs to be reachable from the input, the input itself
|
||||
// does not need to be deeply tainted.
|
||||
isSink(node, TaintedObject::label()) and
|
||||
contents = DataFlow::ContentSet::anyProperty()
|
||||
}
|
||||
|
||||
predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel label) {
|
||||
node = TaintedObject::SanitizerGuard::getABarrierNode(label)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Taint tracking for user-controlled objects flowing into deep `extend` calls,
|
||||
* leading to prototype pollution.
|
||||
*/
|
||||
module PrototypePollutionFlow = TaintTracking::GlobalWithState<PrototypePollutionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `PrototypePollutionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "PrototypePollution" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node, DataFlow::FlowLabel label) {
|
||||
|
||||
@@ -19,13 +19,11 @@
|
||||
|
||||
import javascript
|
||||
import semmle.javascript.security.dataflow.PrototypePollutionQuery
|
||||
import DataFlow::PathGraph
|
||||
import DataFlow::DeduplicatePathGraph<PrototypePollutionFlow::PathNode, PrototypePollutionFlow::PathGraph>
|
||||
|
||||
from
|
||||
Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, string moduleName,
|
||||
Locatable dependencyLoc
|
||||
from PathNode source, PathNode sink, string moduleName, Locatable dependencyLoc
|
||||
where
|
||||
cfg.hasFlowPath(source, sink) and
|
||||
PrototypePollutionFlow::flowPath(source.getAnOriginalPathNode(), sink.getAnOriginalPathNode()) and
|
||||
sink.getNode().(Sink).dependencyInfo(moduleName, dependencyLoc)
|
||||
select sink.getNode(), source, sink,
|
||||
"Prototype pollution caused by merging a $@ using a vulnerable version of $@.", source,
|
||||
|
||||
@@ -1,77 +1,62 @@
|
||||
nodes
|
||||
| angularmerge.js:1:30:1:34 | event |
|
||||
| angularmerge.js:1:30:1:34 | event |
|
||||
| angularmerge.js:2:21:2:42 | JSON.pa ... t.data) |
|
||||
| angularmerge.js:2:21:2:42 | JSON.pa ... t.data) |
|
||||
| angularmerge.js:2:32:2:36 | event |
|
||||
| angularmerge.js:2:32:2:41 | event.data |
|
||||
| src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo |
|
||||
| src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo |
|
||||
| src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo |
|
||||
| src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } |
|
||||
| src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } |
|
||||
| src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value |
|
||||
| src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value |
|
||||
| src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value |
|
||||
| src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value |
|
||||
| src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } |
|
||||
| src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } |
|
||||
| src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing |
|
||||
| webix/webix.html:3:34:3:38 | event |
|
||||
| webix/webix.html:3:34:3:38 | event |
|
||||
| webix/webix.html:4:26:4:47 | JSON.pa ... t.data) |
|
||||
| webix/webix.html:4:26:4:47 | JSON.pa ... t.data) |
|
||||
| webix/webix.html:4:37:4:41 | event |
|
||||
| webix/webix.html:4:37:4:46 | event.data |
|
||||
| webix/webix.html:5:24:5:45 | JSON.pa ... t.data) |
|
||||
| webix/webix.html:5:24:5:45 | JSON.pa ... t.data) |
|
||||
| webix/webix.html:5:35:5:39 | event |
|
||||
| webix/webix.html:5:35:5:44 | event.data |
|
||||
| webix/webix.js:3:30:3:34 | event |
|
||||
| webix/webix.js:3:30:3:34 | event |
|
||||
| webix/webix.js:4:22:4:43 | JSON.pa ... t.data) |
|
||||
| webix/webix.js:4:22:4:43 | JSON.pa ... t.data) |
|
||||
| webix/webix.js:4:33:4:37 | event |
|
||||
| webix/webix.js:4:33:4:42 | event.data |
|
||||
| webix/webix.js:5:20:5:41 | JSON.pa ... t.data) |
|
||||
| webix/webix.js:5:20:5:41 | JSON.pa ... t.data) |
|
||||
| webix/webix.js:5:31:5:35 | event |
|
||||
| webix/webix.js:5:31:5:40 | event.data |
|
||||
| angularmerge.js:1:30:1:34 | event | semmle.label | event |
|
||||
| angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | semmle.label | JSON.pa ... t.data) |
|
||||
| angularmerge.js:2:32:2:36 | event | semmle.label | event |
|
||||
| angularmerge.js:2:32:2:41 | event.data | semmle.label | event.data |
|
||||
| src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | semmle.label | req.query.foo |
|
||||
| src-vulnerable-lodash/tst.js:10:17:12:5 | [post update] {\\n ... K\\n } [value] | semmle.label | [post update] {\\n ... K\\n } [value] |
|
||||
| src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } | semmle.label | {\\n ... K\\n } |
|
||||
| src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } [value] | semmle.label | {\\n ... K\\n } [value] |
|
||||
| src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | semmle.label | req.query.value |
|
||||
| src-vulnerable-lodash/tst.js:14:9:16:5 | opts [thing] | semmle.label | opts [thing] |
|
||||
| src-vulnerable-lodash/tst.js:14:16:16:5 | {\\n ... e\\n } [thing] | semmle.label | {\\n ... e\\n } [thing] |
|
||||
| src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value | semmle.label | req.query.value |
|
||||
| src-vulnerable-lodash/tst.js:17:17:19:5 | [post update] {\\n ... K\\n } [value] | semmle.label | [post update] {\\n ... K\\n } [value] |
|
||||
| src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | semmle.label | {\\n ... K\\n } |
|
||||
| src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } [value] | semmle.label | {\\n ... K\\n } [value] |
|
||||
| src-vulnerable-lodash/tst.js:18:16:18:19 | opts [thing] | semmle.label | opts [thing] |
|
||||
| src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | semmle.label | opts.thing |
|
||||
| webix/webix.html:3:34:3:38 | event | semmle.label | event |
|
||||
| webix/webix.html:4:26:4:47 | JSON.pa ... t.data) | semmle.label | JSON.pa ... t.data) |
|
||||
| webix/webix.html:4:37:4:41 | event | semmle.label | event |
|
||||
| webix/webix.html:4:37:4:46 | event.data | semmle.label | event.data |
|
||||
| webix/webix.html:5:24:5:45 | JSON.pa ... t.data) | semmle.label | JSON.pa ... t.data) |
|
||||
| webix/webix.html:5:35:5:39 | event | semmle.label | event |
|
||||
| webix/webix.html:5:35:5:44 | event.data | semmle.label | event.data |
|
||||
| webix/webix.js:3:30:3:34 | event | semmle.label | event |
|
||||
| webix/webix.js:4:22:4:43 | JSON.pa ... t.data) | semmle.label | JSON.pa ... t.data) |
|
||||
| webix/webix.js:4:33:4:37 | event | semmle.label | event |
|
||||
| webix/webix.js:4:33:4:42 | event.data | semmle.label | event.data |
|
||||
| webix/webix.js:5:20:5:41 | JSON.pa ... t.data) | semmle.label | JSON.pa ... t.data) |
|
||||
| webix/webix.js:5:31:5:35 | event | semmle.label | event |
|
||||
| webix/webix.js:5:31:5:40 | event.data | semmle.label | event.data |
|
||||
edges
|
||||
| angularmerge.js:1:30:1:34 | event | angularmerge.js:2:32:2:36 | event |
|
||||
| angularmerge.js:1:30:1:34 | event | angularmerge.js:2:32:2:36 | event |
|
||||
| angularmerge.js:2:32:2:36 | event | angularmerge.js:2:32:2:41 | event.data |
|
||||
| angularmerge.js:2:32:2:41 | event.data | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) |
|
||||
| angularmerge.js:2:32:2:41 | event.data | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) |
|
||||
| src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo |
|
||||
| src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } |
|
||||
| src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } |
|
||||
| src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } |
|
||||
| src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } |
|
||||
| src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing |
|
||||
| src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing |
|
||||
| src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } |
|
||||
| src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } |
|
||||
| src-vulnerable-lodash/tst.js:10:17:12:5 | [post update] {\\n ... K\\n } [value] | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } [value] |
|
||||
| src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } [value] | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } |
|
||||
| src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | src-vulnerable-lodash/tst.js:10:17:12:5 | [post update] {\\n ... K\\n } [value] |
|
||||
| src-vulnerable-lodash/tst.js:14:9:16:5 | opts [thing] | src-vulnerable-lodash/tst.js:18:16:18:19 | opts [thing] |
|
||||
| src-vulnerable-lodash/tst.js:14:16:16:5 | {\\n ... e\\n } [thing] | src-vulnerable-lodash/tst.js:14:9:16:5 | opts [thing] |
|
||||
| src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value | src-vulnerable-lodash/tst.js:14:16:16:5 | {\\n ... e\\n } [thing] |
|
||||
| src-vulnerable-lodash/tst.js:17:17:19:5 | [post update] {\\n ... K\\n } [value] | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } [value] |
|
||||
| src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } [value] | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } |
|
||||
| src-vulnerable-lodash/tst.js:18:16:18:19 | opts [thing] | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing |
|
||||
| src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | src-vulnerable-lodash/tst.js:17:17:19:5 | [post update] {\\n ... K\\n } [value] |
|
||||
| webix/webix.html:3:34:3:38 | event | webix/webix.html:4:37:4:41 | event |
|
||||
| webix/webix.html:3:34:3:38 | event | webix/webix.html:4:37:4:41 | event |
|
||||
| webix/webix.html:3:34:3:38 | event | webix/webix.html:5:35:5:39 | event |
|
||||
| webix/webix.html:3:34:3:38 | event | webix/webix.html:5:35:5:39 | event |
|
||||
| webix/webix.html:4:37:4:41 | event | webix/webix.html:4:37:4:46 | event.data |
|
||||
| webix/webix.html:4:37:4:46 | event.data | webix/webix.html:4:26:4:47 | JSON.pa ... t.data) |
|
||||
| webix/webix.html:4:37:4:46 | event.data | webix/webix.html:4:26:4:47 | JSON.pa ... t.data) |
|
||||
| webix/webix.html:5:35:5:39 | event | webix/webix.html:5:35:5:44 | event.data |
|
||||
| webix/webix.html:5:35:5:44 | event.data | webix/webix.html:5:24:5:45 | JSON.pa ... t.data) |
|
||||
| webix/webix.html:5:35:5:44 | event.data | webix/webix.html:5:24:5:45 | JSON.pa ... t.data) |
|
||||
| webix/webix.js:3:30:3:34 | event | webix/webix.js:4:33:4:37 | event |
|
||||
| webix/webix.js:3:30:3:34 | event | webix/webix.js:4:33:4:37 | event |
|
||||
| webix/webix.js:3:30:3:34 | event | webix/webix.js:5:31:5:35 | event |
|
||||
| webix/webix.js:3:30:3:34 | event | webix/webix.js:5:31:5:35 | event |
|
||||
| webix/webix.js:4:33:4:37 | event | webix/webix.js:4:33:4:42 | event.data |
|
||||
| webix/webix.js:4:33:4:42 | event.data | webix/webix.js:4:22:4:43 | JSON.pa ... t.data) |
|
||||
| webix/webix.js:4:33:4:42 | event.data | webix/webix.js:4:22:4:43 | JSON.pa ... t.data) |
|
||||
| webix/webix.js:5:31:5:35 | event | webix/webix.js:5:31:5:40 | event.data |
|
||||
| webix/webix.js:5:31:5:40 | event.data | webix/webix.js:5:20:5:41 | JSON.pa ... t.data) |
|
||||
| webix/webix.js:5:31:5:40 | event.data | webix/webix.js:5:20:5:41 | JSON.pa ... t.data) |
|
||||
subpaths
|
||||
#select
|
||||
| angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | angularmerge.js:1:30:1:34 | event | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | angularmerge.js:1:30:1:34 | event | user-controlled value | angularmerge.js:2:3:2:43 | angular ... .data)) | angular |
|
||||
| src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | user-controlled value | src-vulnerable-lodash/package.json:3:19:3:26 | "4.17.4" | lodash |
|
||||
|
||||
Reference in New Issue
Block a user