JS: Port UnvalidatedDynamicMethodCall

This commit is contained in:
Asger F
2023-10-05 09:26:19 +02:00
parent ba9edb4e54
commit 83095535f9
4 changed files with 161 additions and 159 deletions

View File

@@ -54,6 +54,30 @@ module UnvalidatedDynamicMethodCall {
}
}
/**
* A barrier guard for unvalidated dynamic method calls.
*/
abstract class BarrierGuard extends DataFlow::Node {
/**
* Holds if this node acts as a barrier for data flow, blocking further flow from `e` if `this` evaluates to `outcome`.
*/
predicate blocksExpr(boolean outcome, Expr e) { none() }
/**
* Holds if this node acts as a barrier for `label`, blocking further flow from `e` if `this` evaluates to `outcome`.
*/
predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { none() }
}
/** A subclass of `BarrierGuard` that is used for backward compatibility with the old data flow library. */
abstract class BarrierGuardLegacy extends BarrierGuard, TaintTracking::SanitizerGuardNode {
override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) }
override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) {
this.blocksExpr(outcome, e, label)
}
}
/**
* A flow label describing values read from a user-controlled property that
* may not be functions.
@@ -109,13 +133,13 @@ module UnvalidatedDynamicMethodCall {
* A check of the form `typeof x === 'function'`, which sanitizes away the `MaybeNonFunction`
* taint kind.
*/
class FunctionCheck extends TaintTracking::LabeledSanitizerGuardNode, DataFlow::ValueNode {
class FunctionCheck extends BarrierGuardLegacy, DataFlow::ValueNode {
override EqualityTest astNode;
Expr operand;
FunctionCheck() { TaintTracking::isTypeofGuard(astNode, operand, "function") }
override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) {
override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) {
outcome = astNode.getPolarity() and
e = operand and
label instanceof MaybeNonFunction
@@ -123,12 +147,12 @@ module UnvalidatedDynamicMethodCall {
}
/** A guard that checks whether `x` is a number. */
class NumberGuard extends TaintTracking::SanitizerGuardNode instanceof DataFlow::CallNode {
class NumberGuard extends BarrierGuardLegacy instanceof DataFlow::CallNode {
Expr x;
boolean polarity;
NumberGuard() { TaintTracking::isNumberGuard(this, x, polarity) }
override predicate sanitizes(boolean outcome, Expr e) { e = x and outcome = polarity }
override predicate blocksExpr(boolean outcome, Expr e) { e = x and outcome = polarity }
}
}

View File

@@ -27,7 +27,72 @@ private class ConcreteMaybeFromProto extends MaybeFromProto {
/**
* A taint-tracking configuration for reasoning about unvalidated dynamic method calls.
*/
class Configuration extends TaintTracking::Configuration {
module UnvalidatedDynamicMethodCallConfig implements DataFlow::StateConfigSig {
class FlowState = DataFlow::FlowLabel;
predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
source.(Source).getFlowLabel() = label
}
predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
sink.(Sink).getFlowLabel() = label
}
predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel label) {
node.(Sanitizer).getFlowLabel() = label
or
TaintTracking::defaultSanitizer(node) and
label.isTaint()
or
node = DataFlow::MakeLabeledBarrierGuard<BarrierGuard>::getABarrierNode(label)
}
predicate isBarrier(DataFlow::Node node) {
node = DataFlow::MakeBarrierGuard<BarrierGuard>::getABarrierNode()
}
predicate isAdditionalFlowStep(
DataFlow::Node src, DataFlow::FlowLabel srclabel, DataFlow::Node dst,
DataFlow::FlowLabel dstlabel
) {
exists(DataFlow::PropRead read |
src = read.getPropertyNameExpr().flow() and
dst = read and
srclabel.isTaint() and
(
dstlabel instanceof MaybeNonFunction
or
// a property of `Object.create(null)` cannot come from a prototype
not PropertyInjection::isPrototypeLessObject(read.getBase().getALocalSource()) and
dstlabel instanceof MaybeFromProto
) and
// avoid overlapping results with unsafe dynamic method access query
not PropertyInjection::hasUnsafeMethods(read.getBase().getALocalSource())
)
or
exists(DataFlow::SourceNode base, DataFlow::CallNode get | get = base.getAMethodCall("get") |
src = get.getArgument(0) and
dst = get
) and
srclabel.isTaint() and
dstlabel instanceof MaybeNonFunction
or
srclabel.isTaint() and
TaintTracking::defaultTaintStep(src, dst) and
srclabel = dstlabel
}
}
/**
* Taint-tracking for reasoning about unvalidated dynamic method calls.
*/
module UnvalidatedDynamicMethodCallFlow =
DataFlow::GlobalWithState<UnvalidatedDynamicMethodCallConfig>;
/**
* DEPRECATED. Use the `UnvalidatedDynamicMethodCallFlow` module instead.
*/
deprecated class Configuration extends TaintTracking::Configuration {
Configuration() { this = "UnvalidatedDynamicMethodCall" }
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
@@ -53,26 +118,6 @@ class Configuration extends TaintTracking::Configuration {
DataFlow::Node src, DataFlow::Node dst, DataFlow::FlowLabel srclabel,
DataFlow::FlowLabel dstlabel
) {
exists(DataFlow::PropRead read |
src = read.getPropertyNameExpr().flow() and
dst = read and
srclabel.isTaint() and
(
dstlabel instanceof MaybeNonFunction
or
// a property of `Object.create(null)` cannot come from a prototype
not PropertyInjection::isPrototypeLessObject(read.getBase().getALocalSource()) and
dstlabel instanceof MaybeFromProto
) and
// avoid overlapping results with unsafe dynamic method access query
not PropertyInjection::hasUnsafeMethods(read.getBase().getALocalSource())
)
or
exists(DataFlow::SourceNode base, DataFlow::CallNode get | get = base.getAMethodCall("get") |
src = get.getArgument(0) and
dst = get
) and
srclabel.isTaint() and
dstlabel instanceof MaybeNonFunction
UnvalidatedDynamicMethodCallConfig::isAdditionalFlowStep(src, srclabel, dst, dstlabel)
}
}

View File

@@ -13,10 +13,12 @@
import javascript
import semmle.javascript.security.dataflow.UnvalidatedDynamicMethodCallQuery
import DataFlow::PathGraph
import DataFlow::DeduplicatePathGraph<UnvalidatedDynamicMethodCallFlow::PathNode, UnvalidatedDynamicMethodCallFlow::PathGraph>
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
from PathNode source, PathNode sink
where
UnvalidatedDynamicMethodCallFlow::flowPath(source.getAnOriginalPathNode(),
sink.getAnOriginalPathNode())
select sink.getNode(), source, sink,
"Invocation of method with $@ name may dispatch to unexpected target and cause an exception.",
source.getNode(), "user-controlled"

View File

@@ -1,131 +1,82 @@
nodes
| UnsafeDynamicMethodAccess.js:5:37:5:38 | ev |
| UnsafeDynamicMethodAccess.js:5:37:5:38 | ev |
| UnsafeDynamicMethodAccess.js:6:9:6:37 | message |
| UnsafeDynamicMethodAccess.js:6:19:6:37 | JSON.parse(ev.data) |
| UnsafeDynamicMethodAccess.js:6:30:6:31 | ev |
| UnsafeDynamicMethodAccess.js:6:30:6:36 | ev.data |
| UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] |
| UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] |
| UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] |
| UnsafeDynamicMethodAccess.js:15:9:15:15 | message |
| UnsafeDynamicMethodAccess.js:15:9:15:20 | message.name |
| UnvalidatedDynamicMethodCall2.js:13:9:13:47 | action |
| UnvalidatedDynamicMethodCall2.js:13:18:13:47 | actions ... action) |
| UnvalidatedDynamicMethodCall2.js:13:30:13:46 | req.params.action |
| UnvalidatedDynamicMethodCall2.js:13:30:13:46 | req.params.action |
| UnvalidatedDynamicMethodCall2.js:14:13:14:18 | action |
| UnvalidatedDynamicMethodCall2.js:14:13:14:18 | action |
| UnvalidatedDynamicMethodCall.js:14:7:14:41 | action |
| UnvalidatedDynamicMethodCall.js:14:7:14:41 | action |
| UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] |
| UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] |
| UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action |
| UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action |
| UnvalidatedDynamicMethodCall.js:15:11:15:16 | action |
| UnvalidatedDynamicMethodCall.js:15:11:15:16 | action |
| UnvalidatedDynamicMethodCall.js:15:11:15:16 | action |
| UnvalidatedDynamicMethodCallGood4.js:14:13:14:51 | action |
| UnvalidatedDynamicMethodCallGood4.js:14:22:14:51 | actions ... action) |
| UnvalidatedDynamicMethodCallGood4.js:14:34:14:50 | req.params.action |
| UnvalidatedDynamicMethodCallGood4.js:14:34:14:50 | req.params.action |
| UnvalidatedDynamicMethodCallGood4.js:15:17:15:22 | action |
| UnvalidatedDynamicMethodCallGood4.js:15:17:15:22 | action |
| tst.js:6:39:6:40 | ev |
| tst.js:6:39:6:40 | ev |
| tst.js:7:9:7:39 | name |
| tst.js:7:16:7:34 | JSON.parse(ev.data) |
| tst.js:7:16:7:39 | JSON.pa ... a).name |
| tst.js:7:27:7:28 | ev |
| tst.js:7:27:7:33 | ev.data |
| tst.js:9:5:9:16 | obj[ev.data] |
| tst.js:9:5:9:16 | obj[ev.data] |
| tst.js:9:5:9:16 | obj[ev.data] |
| tst.js:9:9:9:10 | ev |
| tst.js:9:9:9:15 | ev.data |
| tst.js:11:5:11:13 | obj[name] |
| tst.js:11:5:11:13 | obj[name] |
| tst.js:11:5:11:13 | obj[name] |
| tst.js:11:9:11:12 | name |
| tst.js:17:9:17:22 | fn |
| tst.js:17:9:17:22 | fn |
| tst.js:17:14:17:22 | obj[name] |
| tst.js:17:14:17:22 | obj[name] |
| tst.js:17:18:17:21 | name |
| tst.js:18:5:18:6 | fn |
| tst.js:18:5:18:6 | fn |
| tst.js:18:5:18:6 | fn |
| tst.js:20:7:20:8 | fn |
| tst.js:20:7:20:8 | fn |
| tst.js:21:7:21:15 | obj[name] |
| tst.js:21:7:21:15 | obj[name] |
| tst.js:21:7:21:15 | obj[name] |
| tst.js:21:11:21:14 | name |
| tst.js:22:11:22:12 | fn |
| tst.js:22:11:22:12 | fn |
| tst.js:26:7:26:15 | obj[name] |
| tst.js:26:7:26:15 | obj[name] |
| tst.js:26:7:26:15 | obj[name] |
| tst.js:26:11:26:14 | name |
| tst.js:28:7:28:15 | obj[name] |
| tst.js:28:7:28:15 | obj[name] |
| tst.js:28:11:28:14 | name |
| tst.js:34:9:34:24 | key |
| tst.js:34:15:34:24 | "$" + name |
| tst.js:34:21:34:24 | name |
| tst.js:35:5:35:12 | obj[key] |
| tst.js:35:5:35:12 | obj[key] |
| tst.js:35:5:35:12 | obj[key] |
| tst.js:35:9:35:11 | key |
| tst.js:37:7:37:14 | obj[key] |
| tst.js:37:7:37:14 | obj[key] |
| tst.js:37:11:37:13 | key |
| tst.js:47:39:47:40 | ev |
| tst.js:47:39:47:40 | ev |
| tst.js:48:9:48:39 | name |
| tst.js:48:16:48:34 | JSON.parse(ev.data) |
| tst.js:48:16:48:39 | JSON.pa ... a).name |
| tst.js:48:27:48:28 | ev |
| tst.js:48:27:48:33 | ev.data |
| tst.js:49:9:49:23 | fn |
| tst.js:49:14:49:23 | obj2[name] |
| tst.js:49:19:49:22 | name |
| tst.js:50:5:50:6 | fn |
| tst.js:50:5:50:6 | fn |
| UnsafeDynamicMethodAccess.js:5:37:5:38 | ev | semmle.label | ev |
| UnsafeDynamicMethodAccess.js:6:9:6:37 | message | semmle.label | message |
| UnsafeDynamicMethodAccess.js:6:19:6:37 | JSON.parse(ev.data) | semmle.label | JSON.parse(ev.data) |
| UnsafeDynamicMethodAccess.js:6:30:6:31 | ev | semmle.label | ev |
| UnsafeDynamicMethodAccess.js:6:30:6:36 | ev.data | semmle.label | ev.data |
| UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] | semmle.label | obj[message.name] |
| UnsafeDynamicMethodAccess.js:15:9:15:15 | message | semmle.label | message |
| UnsafeDynamicMethodAccess.js:15:9:15:20 | message.name | semmle.label | message.name |
| UnvalidatedDynamicMethodCall2.js:13:9:13:47 | action | semmle.label | action |
| UnvalidatedDynamicMethodCall2.js:13:18:13:47 | actions ... action) | semmle.label | actions ... action) |
| UnvalidatedDynamicMethodCall2.js:13:30:13:46 | req.params.action | semmle.label | req.params.action |
| UnvalidatedDynamicMethodCall2.js:14:13:14:18 | action | semmle.label | action |
| UnvalidatedDynamicMethodCall.js:14:7:14:41 | action | semmle.label | action |
| UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] | semmle.label | actions ... action] |
| UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action | semmle.label | req.params.action |
| UnvalidatedDynamicMethodCall.js:15:11:15:16 | action | semmle.label | action |
| UnvalidatedDynamicMethodCallGood4.js:14:13:14:51 | action | semmle.label | action |
| UnvalidatedDynamicMethodCallGood4.js:14:22:14:51 | actions ... action) | semmle.label | actions ... action) |
| UnvalidatedDynamicMethodCallGood4.js:14:34:14:50 | req.params.action | semmle.label | req.params.action |
| UnvalidatedDynamicMethodCallGood4.js:15:17:15:22 | action | semmle.label | action |
| tst.js:6:39:6:40 | ev | semmle.label | ev |
| tst.js:7:9:7:39 | name | semmle.label | name |
| tst.js:7:16:7:34 | JSON.parse(ev.data) | semmle.label | JSON.parse(ev.data) |
| tst.js:7:16:7:39 | JSON.pa ... a).name | semmle.label | JSON.pa ... a).name |
| tst.js:7:27:7:28 | ev | semmle.label | ev |
| tst.js:7:27:7:33 | ev.data | semmle.label | ev.data |
| tst.js:9:5:9:16 | obj[ev.data] | semmle.label | obj[ev.data] |
| tst.js:9:9:9:10 | ev | semmle.label | ev |
| tst.js:9:9:9:15 | ev.data | semmle.label | ev.data |
| tst.js:11:5:11:13 | obj[name] | semmle.label | obj[name] |
| tst.js:11:9:11:12 | name | semmle.label | name |
| tst.js:17:9:17:22 | fn | semmle.label | fn |
| tst.js:17:14:17:22 | obj[name] | semmle.label | obj[name] |
| tst.js:17:18:17:21 | name | semmle.label | name |
| tst.js:18:5:18:6 | fn | semmle.label | fn |
| tst.js:20:7:20:8 | fn | semmle.label | fn |
| tst.js:21:7:21:15 | obj[name] | semmle.label | obj[name] |
| tst.js:21:11:21:14 | name | semmle.label | name |
| tst.js:22:11:22:12 | fn | semmle.label | fn |
| tst.js:26:7:26:15 | obj[name] | semmle.label | obj[name] |
| tst.js:26:11:26:14 | name | semmle.label | name |
| tst.js:28:7:28:15 | obj[name] | semmle.label | obj[name] |
| tst.js:28:11:28:14 | name | semmle.label | name |
| tst.js:34:9:34:24 | key | semmle.label | key |
| tst.js:34:15:34:24 | "$" + name | semmle.label | "$" + name |
| tst.js:34:21:34:24 | name | semmle.label | name |
| tst.js:35:5:35:12 | obj[key] | semmle.label | obj[key] |
| tst.js:35:9:35:11 | key | semmle.label | key |
| tst.js:37:7:37:14 | obj[key] | semmle.label | obj[key] |
| tst.js:37:11:37:13 | key | semmle.label | key |
| tst.js:47:39:47:40 | ev | semmle.label | ev |
| tst.js:48:9:48:39 | name | semmle.label | name |
| tst.js:48:16:48:34 | JSON.parse(ev.data) | semmle.label | JSON.parse(ev.data) |
| tst.js:48:16:48:39 | JSON.pa ... a).name | semmle.label | JSON.pa ... a).name |
| tst.js:48:27:48:28 | ev | semmle.label | ev |
| tst.js:48:27:48:33 | ev.data | semmle.label | ev.data |
| tst.js:49:9:49:23 | fn | semmle.label | fn |
| tst.js:49:14:49:23 | obj2[name] | semmle.label | obj2[name] |
| tst.js:49:19:49:22 | name | semmle.label | name |
| tst.js:50:5:50:6 | fn | semmle.label | fn |
edges
| UnsafeDynamicMethodAccess.js:5:37:5:38 | ev | UnsafeDynamicMethodAccess.js:6:30:6:31 | ev |
| UnsafeDynamicMethodAccess.js:5:37:5:38 | ev | UnsafeDynamicMethodAccess.js:6:30:6:31 | ev |
| UnsafeDynamicMethodAccess.js:6:9:6:37 | message | UnsafeDynamicMethodAccess.js:15:9:15:15 | message |
| UnsafeDynamicMethodAccess.js:6:19:6:37 | JSON.parse(ev.data) | UnsafeDynamicMethodAccess.js:6:9:6:37 | message |
| UnsafeDynamicMethodAccess.js:6:30:6:31 | ev | UnsafeDynamicMethodAccess.js:6:30:6:36 | ev.data |
| UnsafeDynamicMethodAccess.js:6:30:6:36 | ev.data | UnsafeDynamicMethodAccess.js:6:19:6:37 | JSON.parse(ev.data) |
| UnsafeDynamicMethodAccess.js:15:9:15:15 | message | UnsafeDynamicMethodAccess.js:15:9:15:20 | message.name |
| UnsafeDynamicMethodAccess.js:15:9:15:20 | message.name | UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] |
| UnsafeDynamicMethodAccess.js:15:9:15:20 | message.name | UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] |
| UnsafeDynamicMethodAccess.js:15:9:15:20 | message.name | UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] |
| UnvalidatedDynamicMethodCall2.js:13:9:13:47 | action | UnvalidatedDynamicMethodCall2.js:14:13:14:18 | action |
| UnvalidatedDynamicMethodCall2.js:13:9:13:47 | action | UnvalidatedDynamicMethodCall2.js:14:13:14:18 | action |
| UnvalidatedDynamicMethodCall2.js:13:18:13:47 | actions ... action) | UnvalidatedDynamicMethodCall2.js:13:9:13:47 | action |
| UnvalidatedDynamicMethodCall2.js:13:30:13:46 | req.params.action | UnvalidatedDynamicMethodCall2.js:13:18:13:47 | actions ... action) |
| UnvalidatedDynamicMethodCall2.js:13:30:13:46 | req.params.action | UnvalidatedDynamicMethodCall2.js:13:18:13:47 | actions ... action) |
| UnvalidatedDynamicMethodCall.js:14:7:14:41 | action | UnvalidatedDynamicMethodCall.js:15:11:15:16 | action |
| UnvalidatedDynamicMethodCall.js:14:7:14:41 | action | UnvalidatedDynamicMethodCall.js:15:11:15:16 | action |
| UnvalidatedDynamicMethodCall.js:14:7:14:41 | action | UnvalidatedDynamicMethodCall.js:15:11:15:16 | action |
| UnvalidatedDynamicMethodCall.js:14:7:14:41 | action | UnvalidatedDynamicMethodCall.js:15:11:15:16 | action |
| UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] | UnvalidatedDynamicMethodCall.js:14:7:14:41 | action |
| UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] | UnvalidatedDynamicMethodCall.js:14:7:14:41 | action |
| UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action | UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] |
| UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action | UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] |
| UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action | UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] |
| UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action | UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] |
| UnvalidatedDynamicMethodCallGood4.js:14:13:14:51 | action | UnvalidatedDynamicMethodCallGood4.js:15:17:15:22 | action |
| UnvalidatedDynamicMethodCallGood4.js:14:13:14:51 | action | UnvalidatedDynamicMethodCallGood4.js:15:17:15:22 | action |
| UnvalidatedDynamicMethodCallGood4.js:14:22:14:51 | actions ... action) | UnvalidatedDynamicMethodCallGood4.js:14:13:14:51 | action |
| UnvalidatedDynamicMethodCallGood4.js:14:34:14:50 | req.params.action | UnvalidatedDynamicMethodCallGood4.js:14:22:14:51 | actions ... action) |
| UnvalidatedDynamicMethodCallGood4.js:14:34:14:50 | req.params.action | UnvalidatedDynamicMethodCallGood4.js:14:22:14:51 | actions ... action) |
| tst.js:6:39:6:40 | ev | tst.js:7:27:7:28 | ev |
| tst.js:6:39:6:40 | ev | tst.js:7:27:7:28 | ev |
| tst.js:6:39:6:40 | ev | tst.js:9:9:9:10 | ev |
| tst.js:6:39:6:40 | ev | tst.js:9:9:9:10 | ev |
| tst.js:7:9:7:39 | name | tst.js:11:9:11:12 | name |
| tst.js:7:9:7:39 | name | tst.js:17:18:17:21 | name |
@@ -139,41 +90,21 @@ edges
| tst.js:7:27:7:33 | ev.data | tst.js:7:16:7:34 | JSON.parse(ev.data) |
| tst.js:9:9:9:10 | ev | tst.js:9:9:9:15 | ev.data |
| tst.js:9:9:9:15 | ev.data | tst.js:9:5:9:16 | obj[ev.data] |
| tst.js:9:9:9:15 | ev.data | tst.js:9:5:9:16 | obj[ev.data] |
| tst.js:9:9:9:15 | ev.data | tst.js:9:5:9:16 | obj[ev.data] |
| tst.js:11:9:11:12 | name | tst.js:11:5:11:13 | obj[name] |
| tst.js:11:9:11:12 | name | tst.js:11:5:11:13 | obj[name] |
| tst.js:11:9:11:12 | name | tst.js:11:5:11:13 | obj[name] |
| tst.js:17:9:17:22 | fn | tst.js:18:5:18:6 | fn |
| tst.js:17:9:17:22 | fn | tst.js:18:5:18:6 | fn |
| tst.js:17:9:17:22 | fn | tst.js:18:5:18:6 | fn |
| tst.js:17:9:17:22 | fn | tst.js:18:5:18:6 | fn |
| tst.js:17:9:17:22 | fn | tst.js:20:7:20:8 | fn |
| tst.js:17:9:17:22 | fn | tst.js:20:7:20:8 | fn |
| tst.js:17:9:17:22 | fn | tst.js:22:11:22:12 | fn |
| tst.js:17:9:17:22 | fn | tst.js:22:11:22:12 | fn |
| tst.js:17:14:17:22 | obj[name] | tst.js:17:9:17:22 | fn |
| tst.js:17:14:17:22 | obj[name] | tst.js:17:9:17:22 | fn |
| tst.js:17:18:17:21 | name | tst.js:17:14:17:22 | obj[name] |
| tst.js:17:18:17:21 | name | tst.js:17:14:17:22 | obj[name] |
| tst.js:21:11:21:14 | name | tst.js:21:7:21:15 | obj[name] |
| tst.js:21:11:21:14 | name | tst.js:21:7:21:15 | obj[name] |
| tst.js:21:11:21:14 | name | tst.js:21:7:21:15 | obj[name] |
| tst.js:26:11:26:14 | name | tst.js:26:7:26:15 | obj[name] |
| tst.js:26:11:26:14 | name | tst.js:26:7:26:15 | obj[name] |
| tst.js:26:11:26:14 | name | tst.js:26:7:26:15 | obj[name] |
| tst.js:28:11:28:14 | name | tst.js:28:7:28:15 | obj[name] |
| tst.js:28:11:28:14 | name | tst.js:28:7:28:15 | obj[name] |
| tst.js:34:9:34:24 | key | tst.js:35:9:35:11 | key |
| tst.js:34:9:34:24 | key | tst.js:37:11:37:13 | key |
| tst.js:34:15:34:24 | "$" + name | tst.js:34:9:34:24 | key |
| tst.js:34:21:34:24 | name | tst.js:34:15:34:24 | "$" + name |
| tst.js:35:9:35:11 | key | tst.js:35:5:35:12 | obj[key] |
| tst.js:35:9:35:11 | key | tst.js:35:5:35:12 | obj[key] |
| tst.js:35:9:35:11 | key | tst.js:35:5:35:12 | obj[key] |
| tst.js:37:11:37:13 | key | tst.js:37:7:37:14 | obj[key] |
| tst.js:37:11:37:13 | key | tst.js:37:7:37:14 | obj[key] |
| tst.js:47:39:47:40 | ev | tst.js:48:27:48:28 | ev |
| tst.js:47:39:47:40 | ev | tst.js:48:27:48:28 | ev |
| tst.js:48:9:48:39 | name | tst.js:49:19:49:22 | name |
| tst.js:48:16:48:34 | JSON.parse(ev.data) | tst.js:48:16:48:39 | JSON.pa ... a).name |
@@ -181,9 +112,9 @@ edges
| tst.js:48:27:48:28 | ev | tst.js:48:27:48:33 | ev.data |
| tst.js:48:27:48:33 | ev.data | tst.js:48:16:48:34 | JSON.parse(ev.data) |
| tst.js:49:9:49:23 | fn | tst.js:50:5:50:6 | fn |
| tst.js:49:9:49:23 | fn | tst.js:50:5:50:6 | fn |
| tst.js:49:14:49:23 | obj2[name] | tst.js:49:9:49:23 | fn |
| tst.js:49:19:49:22 | name | tst.js:49:14:49:23 | obj2[name] |
subpaths
#select
| UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] | UnsafeDynamicMethodAccess.js:5:37:5:38 | ev | UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | UnsafeDynamicMethodAccess.js:5:37:5:38 | ev | user-controlled |
| UnvalidatedDynamicMethodCall2.js:14:13:14:18 | action | UnvalidatedDynamicMethodCall2.js:13:30:13:46 | req.params.action | UnvalidatedDynamicMethodCall2.js:14:13:14:18 | action | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | UnvalidatedDynamicMethodCall2.js:13:30:13:46 | req.params.action | user-controlled |