JS: Port PrototypePollutingAssignment

This commit is contained in:
Asger F
2023-10-04 21:36:31 +02:00
parent 81d2721248
commit f1f45927b1
6 changed files with 286 additions and 307 deletions

View File

@@ -38,6 +38,30 @@ module PrototypePollutingAssignment {
*/
abstract class Sanitizer extends DataFlow::Node { }
/**
* A barrier guard for prototype-polluting assignments.
*/
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 representing the `Object.prototype` value. */
abstract class ObjectPrototype extends DataFlow::FlowLabel {
ObjectPrototype() { this = "Object.prototype" }
@@ -46,7 +70,9 @@ module PrototypePollutingAssignment {
/** The base of an assignment or extend call, as a sink for `Object.prototype` references. */
private class DefaultSink extends Sink {
DefaultSink() {
this = any(DataFlow::PropWrite write).getBase()
// Avoid using PropWrite here as we only want assignments that can mutate a pre-existing object,
// so not object literals or array literals.
this = any(AssignExpr assign).getTarget().(PropAccess).getBase().flow()
or
this = any(ExtendCall c).getDestinationOperand()
or
@@ -67,7 +93,9 @@ module PrototypePollutingAssignment {
* A parameter of an exported function, seen as a source prototype-polluting assignment.
*/
class ExternalInputSource extends Source {
ExternalInputSource() { this = Exports::getALibraryInputParameter() }
ExternalInputSource() {
this = Exports::getALibraryInputParameter() and not this instanceof RemoteFlowSource
}
override string describe() { result = "library input" }
}

View File

@@ -19,16 +19,18 @@ private class ConcreteObjectPrototype extends ObjectPrototype {
}
/** A taint-tracking configuration for reasoning about prototype-polluting assignments. */
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "PrototypePollutingAssignment" }
module PrototypePollutingAssignmentConfig implements DataFlow::StateConfigSig {
class FlowState = DataFlow::FlowLabel;
override predicate isSource(DataFlow::Node node) { node instanceof Source }
predicate isSource(DataFlow::Node node, DataFlow::FlowLabel label) {
node instanceof Source and label.isTaint()
}
override predicate isSink(DataFlow::Node node, DataFlow::FlowLabel lbl) {
predicate isSink(DataFlow::Node node, DataFlow::FlowLabel lbl) {
node.(Sink).getAFlowLabel() = lbl
}
override predicate isSanitizer(DataFlow::Node node) {
predicate isBarrier(DataFlow::Node node) {
node instanceof Sanitizer
or
// Concatenating with a string will in practice prevent the string `__proto__` from arising.
@@ -53,17 +55,24 @@ class Configuration extends TaintTracking::Configuration {
not replace.getRawReplacement().getStringValue() = ""
)
)
or
node = DataFlow::MakeBarrierGuard<BarrierGuard>::getABarrierNode()
}
override predicate isSanitizerOut(DataFlow::Node node, DataFlow::FlowLabel lbl) {
predicate isBarrierOut(DataFlow::Node node, DataFlow::FlowLabel lbl) {
// Suppress the value-preserving step src -> dst in `extend(dst, src)`. This is modeled as a value-preserving
// step because it preserves all properties, but the destination is not actually Object.prototype.
node = any(ExtendCall call).getASourceOperand() and
lbl instanceof ObjectPrototype
}
override predicate isAdditionalFlowStep(
DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl
predicate isBarrierIn(DataFlow::Node node, DataFlow::FlowLabel lbl) {
// FIXME: This should only be an in-barrier for the corresponding flow state, but flow-state specific in-barriers are not supported right now.
isSource(node, lbl)
}
predicate isAdditionalFlowStep(
DataFlow::Node pred, DataFlow::FlowLabel inlbl, DataFlow::Node succ, DataFlow::FlowLabel outlbl
) {
// Step from x -> obj[x] while switching to the ObjectPrototype label
// (If `x` can have the value `__proto__` then the result can be Object.prototype)
@@ -91,7 +100,80 @@ class Configuration extends TaintTracking::Configuration {
outlbl instanceof ObjectPrototype
)
or
DataFlow::localFieldStep(pred, succ) and inlbl = outlbl
// TODO: local field step becomes a jump step, resulting in FPs (closure-lib)
// TODO: localFieldStep is too expensive with dataflow2
// DataFlow::localFieldStep(pred, succ)
none()
or
inlbl.isTaint() and
TaintTracking::defaultTaintStep(pred, succ) and
inlbl = outlbl
}
DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext }
predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel lbl) {
lbl.isTaint() and
TaintTracking::defaultSanitizer(node)
or
// Don't propagate into the receiver, as the method lookups will generally fail on Object.prototype.
node instanceof DataFlow::ThisNode and
lbl instanceof ObjectPrototype
or
node = DataFlow::MakeLabeledBarrierGuard<BarrierGuard>::getABarrierNode(lbl)
}
}
/** Taint-tracking for reasoning about prototype-polluting assignments. */
module PrototypePollutingAssignmentFlow =
DataFlow::GlobalWithState<PrototypePollutingAssignmentConfig>;
/**
* Holds if the given `source, sink` pair should not be reported, as we don't have enough
* confidence in the alert given that source is a library input.
*/
bindingset[source, sink]
predicate isIgnoredLibraryFlow(ExternalInputSource source, Sink sink) {
exists(source) and
// filter away paths that start with library inputs and end with a write to a fixed property.
exists(DataFlow::PropWrite write | sink = write.getBase() |
// fixed property name
exists(write.getPropertyName())
or
// non-string property name (likely number)
exists(Expr prop | prop = write.getPropertyNameExpr() |
not prop.analyze().getAType() = TTString()
)
)
}
/**
* DEPRECATED. Use the `PrototypePollutingAssignmentFlow` module instead.
*/
deprecated class Configuration extends TaintTracking::Configuration {
Configuration() { this = "PrototypePollutingAssignment" }
override predicate isSource(DataFlow::Node node) { node instanceof Source }
override predicate isSink(DataFlow::Node node, DataFlow::FlowLabel lbl) {
node.(Sink).getAFlowLabel() = lbl
}
override predicate isSanitizer(DataFlow::Node node) {
PrototypePollutingAssignmentConfig::isBarrier(node)
}
override predicate isSanitizerOut(DataFlow::Node node, DataFlow::FlowLabel lbl) {
// Suppress the value-preserving step src -> dst in `extend(dst, src)`. This is modeled as a value-preserving
// step because it preserves all properties, but the destination is not actually Object.prototype.
node = any(ExtendCall call).getASourceOperand() and
lbl instanceof ObjectPrototype
}
override predicate isAdditionalFlowStep(
DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl
) {
PrototypePollutingAssignmentConfig::isAdditionalFlowStep(pred, inlbl, succ, outlbl)
}
override predicate hasFlowPath(DataFlow::SourcePathNode source, DataFlow::SinkPathNode sink) {
@@ -174,9 +256,7 @@ private predicate isPropertyPresentOnObjectPrototype(string prop) {
}
/** A check of form `e.prop` where `prop` is not present on `Object.prototype`. */
private class PropertyPresenceCheck extends TaintTracking::LabeledSanitizerGuardNode,
DataFlow::ValueNode
{
private class PropertyPresenceCheck extends BarrierGuardLegacy, DataFlow::ValueNode {
override PropAccess astNode;
PropertyPresenceCheck() {
@@ -184,7 +264,7 @@ private class PropertyPresenceCheck extends TaintTracking::LabeledSanitizerGuard
not isPropertyPresentOnObjectPrototype(astNode.getPropertyName())
}
override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) {
override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) {
e = astNode.getBase() and
outcome = true and
label instanceof ObjectPrototype
@@ -192,14 +272,14 @@ private class PropertyPresenceCheck extends TaintTracking::LabeledSanitizerGuard
}
/** A check of form `"prop" in e` where `prop` is not present on `Object.prototype`. */
private class InExprCheck extends TaintTracking::LabeledSanitizerGuardNode, DataFlow::ValueNode {
private class InExprCheck extends BarrierGuardLegacy, DataFlow::ValueNode {
override InExpr astNode;
InExprCheck() {
not isPropertyPresentOnObjectPrototype(astNode.getLeftOperand().getStringValue())
}
override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) {
override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) {
e = astNode.getRightOperand() and
outcome = true and
label instanceof ObjectPrototype
@@ -207,10 +287,10 @@ private class InExprCheck extends TaintTracking::LabeledSanitizerGuardNode, Data
}
/** A check of form `e instanceof X`, which is always false for `Object.prototype`. */
private class InstanceofCheck extends TaintTracking::LabeledSanitizerGuardNode, DataFlow::ValueNode {
private class InstanceofCheck extends BarrierGuardLegacy, DataFlow::ValueNode {
override InstanceofExpr astNode;
override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) {
override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) {
e = astNode.getLeftOperand() and
outcome = true and
label instanceof ObjectPrototype
@@ -218,7 +298,7 @@ private class InstanceofCheck extends TaintTracking::LabeledSanitizerGuardNode,
}
/** A check of form `typeof e === "string"`. */
private class TypeofCheck extends TaintTracking::LabeledSanitizerGuardNode, DataFlow::ValueNode {
private class TypeofCheck extends BarrierGuardLegacy, DataFlow::ValueNode {
override EqualityTest astNode;
Expr operand;
boolean polarity;
@@ -231,7 +311,7 @@ private class TypeofCheck extends TaintTracking::LabeledSanitizerGuardNode, Data
)
}
override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) {
override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) {
polarity = outcome and
e = operand and
label instanceof ObjectPrototype
@@ -239,20 +319,20 @@ private class TypeofCheck extends TaintTracking::LabeledSanitizerGuardNode, Data
}
/** 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 }
}
/** A call to `Array.isArray`, which is false for `Object.prototype`. */
private class IsArrayCheck extends TaintTracking::LabeledSanitizerGuardNode, DataFlow::CallNode {
private class IsArrayCheck extends BarrierGuardLegacy, DataFlow::CallNode {
IsArrayCheck() { this = DataFlow::globalVarRef("Array").getAMemberCall("isArray") }
override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) {
override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) {
e = this.getArgument(0).asExpr() and
outcome = true and
label instanceof ObjectPrototype
@@ -262,12 +342,12 @@ private class IsArrayCheck extends TaintTracking::LabeledSanitizerGuardNode, Dat
/**
* Sanitizer guard of form `x !== "__proto__"`.
*/
private class EqualityCheck extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode {
private class EqualityCheck extends BarrierGuardLegacy, DataFlow::ValueNode {
override EqualityTest astNode;
EqualityCheck() { astNode.getAnOperand().getStringValue() = "__proto__" }
override predicate sanitizes(boolean outcome, Expr e) {
override predicate blocksExpr(boolean outcome, Expr e) {
e = astNode.getAnOperand() and
outcome = astNode.getPolarity().booleanNot()
}
@@ -276,10 +356,10 @@ private class EqualityCheck extends TaintTracking::SanitizerGuardNode, DataFlow:
/**
* Sanitizer guard of the form `x.includes("__proto__")`.
*/
private class IncludesCheck extends TaintTracking::LabeledSanitizerGuardNode, InclusionTest {
private class IncludesCheck extends BarrierGuardLegacy, InclusionTest {
IncludesCheck() { this.getContainedNode().mayHaveStringValue("__proto__") }
override predicate sanitizes(boolean outcome, Expr e) {
override predicate blocksExpr(boolean outcome, Expr e) {
e = this.getContainerNode().asExpr() and
outcome = this.getPolarity().booleanNot()
}
@@ -288,7 +368,7 @@ private class IncludesCheck extends TaintTracking::LabeledSanitizerGuardNode, In
/**
* A sanitizer guard that checks tests whether `x` is included in a list like `["__proto__"].includes(x)`.
*/
private class DenyListInclusionGuard extends TaintTracking::SanitizerGuardNode, InclusionTest {
private class DenyListInclusionGuard extends BarrierGuardLegacy, InclusionTest {
DenyListInclusionGuard() {
this.getContainerNode()
.getALocalSource()
@@ -297,7 +377,7 @@ private class DenyListInclusionGuard extends TaintTracking::SanitizerGuardNode,
.mayHaveStringValue("__proto__")
}
override predicate sanitizes(boolean outcome, Expr e) {
override predicate blocksExpr(boolean outcome, Expr e) {
e = this.getContainedNode().asExpr() and
outcome = super.getPolarity().booleanNot()
}

View File

@@ -19,10 +19,13 @@
import javascript
import semmle.javascript.security.dataflow.PrototypePollutingAssignmentQuery
import DataFlow::PathGraph
import PrototypePollutingAssignmentFlow::PathGraph
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
from
PrototypePollutingAssignmentFlow::PathNode source, PrototypePollutingAssignmentFlow::PathNode sink
where
PrototypePollutingAssignmentFlow::flowPath(source, sink) and
not isIgnoredLibraryFlow(source.getNode(), sink.getNode())
select sink, source, sink,
"This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@.",
source.getNode(), source.getNode().(Source).describe()

View File

@@ -0,0 +1 @@
| query-tests/Security/CWE-915/PrototypePollutingAssignment/lib.js:70 | expected an alert, but found none | NOT OK | Config |

View File

@@ -2,6 +2,15 @@ import javascript
import testUtilities.ConsistencyChecking
import semmle.javascript.security.dataflow.PrototypePollutingAssignmentQuery
class Config extends ConsistencyConfiguration, Configuration {
class Config extends ConsistencyConfiguration {
Config() { this = "Config" }
override File getAFile() { any() }
override DataFlow::Node getAnAlert() {
exists(DataFlow::Node source |
PrototypePollutingAssignmentFlow::flow(source, result) and
not isIgnoredLibraryFlow(source, result)
)
}
}

View File

@@ -1,371 +1,230 @@
nodes
| lib.js:1:38:1:40 | obj |
| lib.js:1:43:1:46 | path |
| lib.js:1:43:1:46 | path |
| lib.js:1:43:1:46 | path |
| lib.js:2:7:2:27 | currentPath |
| lib.js:2:7:2:27 | currentPath |
| lib.js:2:21:2:24 | path |
| lib.js:2:21:2:24 | path |
| lib.js:2:21:2:27 | path[0] |
| lib.js:2:21:2:27 | path[0] |
| lib.js:6:7:6:9 | obj |
| lib.js:6:7:6:9 | obj |
| lib.js:11:17:11:32 | obj[currentPath] |
| lib.js:11:17:11:32 | obj[currentPath] |
| lib.js:11:21:11:31 | currentPath |
| lib.js:11:21:11:31 | currentPath |
| lib.js:11:35:11:38 | path |
| lib.js:11:35:11:38 | path |
| lib.js:11:35:11:47 | path.slice(1) |
| lib.js:11:35:11:47 | path.slice(1) |
| lib.js:14:38:14:41 | path |
| lib.js:14:38:14:41 | path |
| lib.js:15:3:15:14 | obj[path[0]] |
| lib.js:15:3:15:14 | obj[path[0]] |
| lib.js:15:7:15:10 | path |
| lib.js:15:7:15:13 | path[0] |
| lib.js:20:7:20:25 | path |
| lib.js:20:14:20:22 | arguments |
| lib.js:20:14:20:22 | arguments |
| lib.js:20:14:20:25 | arguments[1] |
| lib.js:22:3:22:14 | obj[path[0]] |
| lib.js:22:3:22:14 | obj[path[0]] |
| lib.js:22:7:22:10 | path |
| lib.js:22:7:22:13 | path[0] |
| lib.js:25:44:25:47 | path |
| lib.js:25:44:25:47 | path |
| lib.js:26:10:26:21 | obj[path[0]] |
| lib.js:26:10:26:21 | obj[path[0]] |
| lib.js:26:14:26:17 | path |
| lib.js:26:14:26:20 | path[0] |
| lib.js:30:9:30:52 | args |
| lib.js:30:16:30:52 | Array.p ... uments) |
| lib.js:30:43:30:51 | arguments |
| lib.js:30:43:30:51 | arguments |
| lib.js:32:7:32:20 | path |
| lib.js:32:14:32:17 | args |
| lib.js:32:14:32:20 | args[1] |
| lib.js:34:3:34:14 | obj[path[0]] |
| lib.js:34:3:34:14 | obj[path[0]] |
| lib.js:34:7:34:10 | path |
| lib.js:34:7:34:13 | path[0] |
| lib.js:38:9:38:36 | args |
| lib.js:38:16:38:36 | Array.f ... uments) |
| lib.js:38:27:38:35 | arguments |
| lib.js:38:27:38:35 | arguments |
| lib.js:40:7:40:20 | path |
| lib.js:40:14:40:17 | args |
| lib.js:40:14:40:20 | args[1] |
| lib.js:42:3:42:14 | obj[path[0]] |
| lib.js:42:3:42:14 | obj[path[0]] |
| lib.js:42:7:42:10 | path |
| lib.js:42:7:42:13 | path[0] |
| lib.js:45:13:45:13 | s |
| lib.js:45:13:45:13 | s |
| lib.js:46:10:46:10 | s |
| lib.js:52:9:52:22 | path |
| lib.js:52:16:52:22 | id("x") |
| lib.js:55:11:55:22 | obj[path[0]] |
| lib.js:55:11:55:22 | obj[path[0]] |
| lib.js:55:15:55:18 | path |
| lib.js:55:15:55:21 | path[0] |
| lib.js:59:18:59:18 | s |
| lib.js:59:18:59:18 | s |
| lib.js:61:17:61:17 | s |
| lib.js:68:11:68:26 | path |
| lib.js:68:18:68:26 | this.path |
| lib.js:70:13:70:24 | obj[path[0]] |
| lib.js:70:13:70:24 | obj[path[0]] |
| lib.js:70:17:70:20 | path |
| lib.js:70:17:70:23 | path[0] |
| lib.js:83:7:83:25 | path |
| lib.js:83:14:83:22 | arguments |
| lib.js:83:14:83:22 | arguments |
| lib.js:83:14:83:25 | arguments[1] |
| lib.js:86:7:86:26 | proto |
| lib.js:86:15:86:26 | obj[path[0]] |
| lib.js:86:19:86:22 | path |
| lib.js:86:19:86:25 | path[0] |
| lib.js:87:10:87:14 | proto |
| lib.js:87:10:87:14 | proto |
| lib.js:90:43:90:46 | path |
| lib.js:90:43:90:46 | path |
| lib.js:91:7:91:28 | maybeProto |
| lib.js:91:20:91:28 | obj[path] |
| lib.js:91:24:91:27 | path |
| lib.js:92:3:92:12 | maybeProto |
| lib.js:92:3:92:12 | maybeProto |
| lib.js:95:3:95:12 | maybeProto |
| lib.js:95:3:95:12 | maybeProto |
| lib.js:104:7:104:24 | one |
| lib.js:104:13:104:21 | arguments |
| lib.js:104:13:104:21 | arguments |
| lib.js:104:13:104:24 | arguments[1] |
| lib.js:108:3:108:10 | obj[one] |
| lib.js:108:3:108:10 | obj[one] |
| lib.js:108:7:108:9 | one |
| lib.js:118:29:118:32 | path |
| lib.js:118:29:118:32 | path |
| lib.js:119:13:119:24 | obj[path[0]] |
| lib.js:119:13:119:24 | obj[path[0]] |
| lib.js:119:17:119:20 | path |
| lib.js:119:17:119:23 | path[0] |
| lib.js:127:14:127:17 | path |
| lib.js:127:14:127:17 | path |
| lib.js:128:9:128:20 | obj[path[0]] |
| lib.js:128:9:128:20 | obj[path[0]] |
| lib.js:128:13:128:16 | path |
| lib.js:128:13:128:19 | path[0] |
| otherlib/src/otherlibimpl.js:1:37:1:40 | path |
| otherlib/src/otherlibimpl.js:1:37:1:40 | path |
| otherlib/src/otherlibimpl.js:2:3:2:14 | obj[path[0]] |
| otherlib/src/otherlibimpl.js:2:3:2:14 | obj[path[0]] |
| otherlib/src/otherlibimpl.js:2:7:2:10 | path |
| otherlib/src/otherlibimpl.js:2:7:2:13 | path[0] |
| sublib/other.js:5:28:5:31 | path |
| sublib/other.js:5:28:5:31 | path |
| sublib/other.js:6:7:6:18 | obj[path[0]] |
| sublib/other.js:6:7:6:18 | obj[path[0]] |
| sublib/other.js:6:11:6:14 | path |
| sublib/other.js:6:11:6:17 | path[0] |
| sublib/sub.js:1:37:1:40 | path |
| sublib/sub.js:1:37:1:40 | path |
| sublib/sub.js:2:3:2:14 | obj[path[0]] |
| sublib/sub.js:2:3:2:14 | obj[path[0]] |
| sublib/sub.js:2:7:2:10 | path |
| sublib/sub.js:2:7:2:13 | path[0] |
| tst.js:5:9:5:38 | taint |
| tst.js:5:17:5:38 | String( ... y.data) |
| tst.js:5:24:5:37 | req.query.data |
| tst.js:5:24:5:37 | req.query.data |
| tst.js:8:5:8:17 | object[taint] |
| tst.js:8:5:8:17 | object[taint] |
| tst.js:8:12:8:16 | taint |
| tst.js:9:5:9:17 | object[taint] |
| tst.js:9:5:9:17 | object[taint] |
| tst.js:9:12:9:16 | taint |
| tst.js:12:18:12:30 | object[taint] |
| tst.js:12:25:12:29 | taint |
| tst.js:14:5:14:32 | unsafeG ... taint) |
| tst.js:14:5:14:32 | unsafeG ... taint) |
| tst.js:14:27:14:31 | taint |
| tst.js:33:23:33:25 | obj |
| tst.js:34:5:34:7 | obj |
| tst.js:34:5:34:7 | obj |
| tst.js:39:9:39:11 | obj |
| tst.js:39:9:39:11 | obj |
| tst.js:45:9:45:11 | obj |
| tst.js:45:9:45:11 | obj |
| tst.js:48:9:48:11 | obj |
| tst.js:48:9:48:11 | obj |
| tst.js:77:9:77:38 | taint |
| tst.js:77:17:77:38 | String( ... y.data) |
| tst.js:77:24:77:37 | req.query.data |
| tst.js:77:24:77:37 | req.query.data |
| tst.js:80:5:80:17 | object[taint] |
| tst.js:80:5:80:17 | object[taint] |
| tst.js:80:12:80:16 | taint |
| tst.js:82:5:82:22 | object["" + taint] |
| tst.js:82:5:82:22 | object["" + taint] |
| tst.js:82:12:82:21 | "" + taint |
| tst.js:82:17:82:21 | taint |
| tst.js:87:9:87:21 | object[taint] |
| tst.js:87:9:87:21 | object[taint] |
| tst.js:87:16:87:20 | taint |
| tst.js:94:5:94:37 | obj[req ... ', '')] |
| tst.js:94:5:94:37 | obj[req ... ', '')] |
| tst.js:94:9:94:19 | req.query.x |
| tst.js:94:9:94:19 | req.query.x |
| tst.js:94:9:94:36 | req.que ... _', '') |
| tst.js:97:5:97:46 | obj[req ... g, '')] |
| tst.js:97:5:97:46 | obj[req ... g, '')] |
| tst.js:97:9:97:19 | req.query.x |
| tst.js:97:9:97:19 | req.query.x |
| tst.js:97:9:97:45 | req.que ... /g, '') |
| tst.js:102:9:102:38 | taint |
| tst.js:102:17:102:38 | String( ... y.data) |
| tst.js:102:24:102:37 | req.query.data |
| tst.js:102:24:102:37 | req.query.data |
| tst.js:105:5:105:17 | object[taint] |
| tst.js:105:5:105:17 | object[taint] |
| tst.js:105:12:105:16 | taint |
edges
| lib.js:1:38:1:40 | obj | lib.js:6:7:6:9 | obj |
| lib.js:1:38:1:40 | obj | lib.js:6:7:6:9 | obj |
| lib.js:1:43:1:46 | path | lib.js:2:21:2:24 | path |
| lib.js:1:43:1:46 | path | lib.js:2:21:2:24 | path |
| lib.js:1:43:1:46 | path | lib.js:2:21:2:24 | path |
| lib.js:1:43:1:46 | path | lib.js:11:35:11:38 | path |
| lib.js:1:43:1:46 | path | lib.js:11:35:11:38 | path |
| lib.js:1:43:1:46 | path | lib.js:11:35:11:38 | path |
| lib.js:2:7:2:27 | currentPath | lib.js:11:21:11:31 | currentPath |
| lib.js:2:7:2:27 | currentPath | lib.js:11:21:11:31 | currentPath |
| lib.js:2:21:2:24 | path | lib.js:2:21:2:27 | path[0] |
| lib.js:2:21:2:24 | path | lib.js:2:21:2:27 | path[0] |
| lib.js:2:21:2:27 | path[0] | lib.js:2:7:2:27 | currentPath |
| lib.js:2:21:2:27 | path[0] | lib.js:2:7:2:27 | currentPath |
| lib.js:11:17:11:32 | obj[currentPath] | lib.js:1:38:1:40 | obj |
| lib.js:11:17:11:32 | obj[currentPath] | lib.js:1:38:1:40 | obj |
| lib.js:11:21:11:31 | currentPath | lib.js:11:17:11:32 | obj[currentPath] |
| lib.js:11:21:11:31 | currentPath | lib.js:11:17:11:32 | obj[currentPath] |
| lib.js:11:35:11:38 | path | lib.js:11:35:11:47 | path.slice(1) |
| lib.js:11:35:11:38 | path | lib.js:11:35:11:47 | path.slice(1) |
| lib.js:11:35:11:47 | path.slice(1) | lib.js:1:43:1:46 | path |
| lib.js:11:35:11:47 | path.slice(1) | lib.js:1:43:1:46 | path |
| lib.js:14:38:14:41 | path | lib.js:15:7:15:10 | path |
| lib.js:14:38:14:41 | path | lib.js:15:7:15:10 | path |
| lib.js:15:7:15:10 | path | lib.js:15:7:15:13 | path[0] |
| lib.js:15:7:15:13 | path[0] | lib.js:15:3:15:14 | obj[path[0]] |
| lib.js:15:7:15:13 | path[0] | lib.js:15:3:15:14 | obj[path[0]] |
| lib.js:20:7:20:25 | path | lib.js:22:7:22:10 | path |
| lib.js:20:14:20:22 | arguments | lib.js:20:14:20:25 | arguments[1] |
| lib.js:20:14:20:22 | arguments | lib.js:20:14:20:25 | arguments[1] |
| lib.js:20:14:20:25 | arguments[1] | lib.js:20:7:20:25 | path |
| lib.js:22:7:22:10 | path | lib.js:22:7:22:13 | path[0] |
| lib.js:22:7:22:13 | path[0] | lib.js:22:3:22:14 | obj[path[0]] |
| lib.js:22:7:22:13 | path[0] | lib.js:22:3:22:14 | obj[path[0]] |
| lib.js:25:44:25:47 | path | lib.js:26:14:26:17 | path |
| lib.js:25:44:25:47 | path | lib.js:26:14:26:17 | path |
| lib.js:26:14:26:17 | path | lib.js:26:14:26:20 | path[0] |
| lib.js:26:14:26:20 | path[0] | lib.js:26:10:26:21 | obj[path[0]] |
| lib.js:26:14:26:20 | path[0] | lib.js:26:10:26:21 | obj[path[0]] |
| lib.js:30:9:30:52 | args | lib.js:32:14:32:17 | args |
| lib.js:30:16:30:52 | Array.p ... uments) | lib.js:30:9:30:52 | args |
| lib.js:30:43:30:51 | arguments | lib.js:30:16:30:52 | Array.p ... uments) |
| lib.js:30:43:30:51 | arguments | lib.js:30:16:30:52 | Array.p ... uments) |
| lib.js:30:16:30:52 | reflective call | lib.js:30:16:30:52 | Array.p ... uments) |
| lib.js:30:43:30:51 | arguments | lib.js:30:16:30:52 | reflective call |
| lib.js:32:7:32:20 | path | lib.js:34:7:34:10 | path |
| lib.js:32:14:32:17 | args | lib.js:32:14:32:20 | args[1] |
| lib.js:32:14:32:20 | args[1] | lib.js:32:7:32:20 | path |
| lib.js:34:7:34:10 | path | lib.js:34:7:34:13 | path[0] |
| lib.js:34:7:34:13 | path[0] | lib.js:34:3:34:14 | obj[path[0]] |
| lib.js:34:7:34:13 | path[0] | lib.js:34:3:34:14 | obj[path[0]] |
| lib.js:38:9:38:36 | args | lib.js:40:14:40:17 | args |
| lib.js:38:16:38:36 | Array.f ... uments) | lib.js:38:9:38:36 | args |
| lib.js:38:27:38:35 | arguments | lib.js:38:16:38:36 | Array.f ... uments) |
| lib.js:38:27:38:35 | arguments | lib.js:38:16:38:36 | Array.f ... uments) |
| lib.js:40:7:40:20 | path | lib.js:42:7:42:10 | path |
| lib.js:40:14:40:17 | args | lib.js:40:14:40:20 | args[1] |
| lib.js:40:14:40:20 | args[1] | lib.js:40:7:40:20 | path |
| lib.js:42:7:42:10 | path | lib.js:42:7:42:13 | path[0] |
| lib.js:42:7:42:13 | path[0] | lib.js:42:3:42:14 | obj[path[0]] |
| lib.js:42:7:42:13 | path[0] | lib.js:42:3:42:14 | obj[path[0]] |
| lib.js:45:13:45:13 | s | lib.js:46:10:46:10 | s |
| lib.js:45:13:45:13 | s | lib.js:46:10:46:10 | s |
| lib.js:46:10:46:10 | s | lib.js:52:16:52:22 | id("x") |
| lib.js:52:9:52:22 | path | lib.js:55:15:55:18 | path |
| lib.js:52:16:52:22 | id("x") | lib.js:52:9:52:22 | path |
| lib.js:55:15:55:18 | path | lib.js:55:15:55:21 | path[0] |
| lib.js:55:15:55:21 | path[0] | lib.js:55:11:55:22 | obj[path[0]] |
| lib.js:55:15:55:21 | path[0] | lib.js:55:11:55:22 | obj[path[0]] |
| lib.js:59:18:59:18 | s | lib.js:61:17:61:17 | s |
| lib.js:59:18:59:18 | s | lib.js:61:17:61:17 | s |
| lib.js:61:17:61:17 | s | lib.js:68:11:68:26 | path |
| lib.js:61:17:61:17 | s | lib.js:68:18:68:26 | this.path |
| lib.js:61:17:61:17 | s | lib.js:70:17:70:20 | path |
| lib.js:68:11:68:26 | path | lib.js:70:17:70:20 | path |
| lib.js:68:18:68:26 | this.path | lib.js:68:11:68:26 | path |
| lib.js:70:17:70:20 | path | lib.js:70:17:70:23 | path[0] |
| lib.js:70:17:70:23 | path[0] | lib.js:70:13:70:24 | obj[path[0]] |
| lib.js:70:17:70:23 | path[0] | lib.js:70:13:70:24 | obj[path[0]] |
| lib.js:83:7:83:25 | path | lib.js:86:19:86:22 | path |
| lib.js:83:14:83:22 | arguments | lib.js:83:14:83:25 | arguments[1] |
| lib.js:83:14:83:22 | arguments | lib.js:83:14:83:25 | arguments[1] |
| lib.js:83:14:83:25 | arguments[1] | lib.js:83:7:83:25 | path |
| lib.js:86:7:86:26 | proto | lib.js:87:10:87:14 | proto |
| lib.js:86:7:86:26 | proto | lib.js:87:10:87:14 | proto |
| lib.js:86:15:86:26 | obj[path[0]] | lib.js:86:7:86:26 | proto |
| lib.js:86:19:86:22 | path | lib.js:86:19:86:25 | path[0] |
| lib.js:86:19:86:25 | path[0] | lib.js:86:15:86:26 | obj[path[0]] |
| lib.js:90:43:90:46 | path | lib.js:91:24:91:27 | path |
| lib.js:90:43:90:46 | path | lib.js:91:24:91:27 | path |
| lib.js:91:7:91:28 | maybeProto | lib.js:92:3:92:12 | maybeProto |
| lib.js:91:7:91:28 | maybeProto | lib.js:92:3:92:12 | maybeProto |
| lib.js:91:7:91:28 | maybeProto | lib.js:95:3:95:12 | maybeProto |
| lib.js:91:7:91:28 | maybeProto | lib.js:95:3:95:12 | maybeProto |
| lib.js:91:20:91:28 | obj[path] | lib.js:91:7:91:28 | maybeProto |
| lib.js:91:24:91:27 | path | lib.js:91:20:91:28 | obj[path] |
| lib.js:104:7:104:24 | one | lib.js:108:7:108:9 | one |
| lib.js:104:13:104:21 | arguments | lib.js:104:13:104:24 | arguments[1] |
| lib.js:104:13:104:21 | arguments | lib.js:104:13:104:24 | arguments[1] |
| lib.js:104:13:104:24 | arguments[1] | lib.js:104:7:104:24 | one |
| lib.js:108:7:108:9 | one | lib.js:108:3:108:10 | obj[one] |
| lib.js:108:7:108:9 | one | lib.js:108:3:108:10 | obj[one] |
| lib.js:118:29:118:32 | path | lib.js:119:17:119:20 | path |
| lib.js:118:29:118:32 | path | lib.js:119:17:119:20 | path |
| lib.js:119:17:119:20 | path | lib.js:119:17:119:23 | path[0] |
| lib.js:119:17:119:23 | path[0] | lib.js:119:13:119:24 | obj[path[0]] |
| lib.js:119:17:119:23 | path[0] | lib.js:119:13:119:24 | obj[path[0]] |
| lib.js:127:14:127:17 | path | lib.js:128:13:128:16 | path |
| lib.js:127:14:127:17 | path | lib.js:128:13:128:16 | path |
| lib.js:128:13:128:16 | path | lib.js:128:13:128:19 | path[0] |
| lib.js:128:13:128:19 | path[0] | lib.js:128:9:128:20 | obj[path[0]] |
| lib.js:128:13:128:19 | path[0] | lib.js:128:9:128:20 | obj[path[0]] |
| otherlib/src/otherlibimpl.js:1:37:1:40 | path | otherlib/src/otherlibimpl.js:2:7:2:10 | path |
| otherlib/src/otherlibimpl.js:1:37:1:40 | path | otherlib/src/otherlibimpl.js:2:7:2:10 | path |
| otherlib/src/otherlibimpl.js:2:7:2:10 | path | otherlib/src/otherlibimpl.js:2:7:2:13 | path[0] |
| otherlib/src/otherlibimpl.js:2:7:2:13 | path[0] | otherlib/src/otherlibimpl.js:2:3:2:14 | obj[path[0]] |
| otherlib/src/otherlibimpl.js:2:7:2:13 | path[0] | otherlib/src/otherlibimpl.js:2:3:2:14 | obj[path[0]] |
| sublib/other.js:5:28:5:31 | path | sublib/other.js:6:11:6:14 | path |
| sublib/other.js:5:28:5:31 | path | sublib/other.js:6:11:6:14 | path |
| sublib/other.js:6:11:6:14 | path | sublib/other.js:6:11:6:17 | path[0] |
| sublib/other.js:6:11:6:17 | path[0] | sublib/other.js:6:7:6:18 | obj[path[0]] |
| sublib/other.js:6:11:6:17 | path[0] | sublib/other.js:6:7:6:18 | obj[path[0]] |
| sublib/sub.js:1:37:1:40 | path | sublib/sub.js:2:7:2:10 | path |
| sublib/sub.js:1:37:1:40 | path | sublib/sub.js:2:7:2:10 | path |
| sublib/sub.js:2:7:2:10 | path | sublib/sub.js:2:7:2:13 | path[0] |
| sublib/sub.js:2:7:2:13 | path[0] | sublib/sub.js:2:3:2:14 | obj[path[0]] |
| sublib/sub.js:2:7:2:13 | path[0] | sublib/sub.js:2:3:2:14 | obj[path[0]] |
| tst.js:5:9:5:38 | taint | tst.js:8:12:8:16 | taint |
| tst.js:5:9:5:38 | taint | tst.js:9:12:9:16 | taint |
| tst.js:5:9:5:38 | taint | tst.js:12:25:12:29 | taint |
| tst.js:5:9:5:38 | taint | tst.js:14:27:14:31 | taint |
| tst.js:5:17:5:38 | String( ... y.data) | tst.js:5:9:5:38 | taint |
| tst.js:5:24:5:37 | req.query.data | tst.js:5:17:5:38 | String( ... y.data) |
| tst.js:5:24:5:37 | req.query.data | tst.js:5:17:5:38 | String( ... y.data) |
| tst.js:8:12:8:16 | taint | tst.js:8:5:8:17 | object[taint] |
| tst.js:8:12:8:16 | taint | tst.js:8:5:8:17 | object[taint] |
| tst.js:9:12:9:16 | taint | tst.js:9:5:9:17 | object[taint] |
| tst.js:9:12:9:16 | taint | tst.js:9:5:9:17 | object[taint] |
| tst.js:12:18:12:30 | object[taint] | tst.js:33:23:33:25 | obj |
| tst.js:12:25:12:29 | taint | tst.js:12:18:12:30 | object[taint] |
| tst.js:14:27:14:31 | taint | tst.js:14:5:14:32 | unsafeG ... taint) |
| tst.js:14:27:14:31 | taint | tst.js:14:5:14:32 | unsafeG ... taint) |
| tst.js:33:23:33:25 | obj | tst.js:34:5:34:7 | obj |
| tst.js:14:27:14:31 | taint | tst.js:55:29:55:32 | prop |
| tst.js:33:23:33:25 | obj | tst.js:34:5:34:7 | obj |
| tst.js:33:23:33:25 | obj | tst.js:39:9:39:11 | obj |
| tst.js:33:23:33:25 | obj | tst.js:39:9:39:11 | obj |
| tst.js:33:23:33:25 | obj | tst.js:45:9:45:11 | obj |
| tst.js:33:23:33:25 | obj | tst.js:45:9:45:11 | obj |
| tst.js:33:23:33:25 | obj | tst.js:48:9:48:11 | obj |
| tst.js:33:23:33:25 | obj | tst.js:48:9:48:11 | obj |
| tst.js:55:29:55:32 | prop | tst.js:56:22:56:25 | prop |
| tst.js:56:18:56:26 | obj[prop] | tst.js:56:12:56:33 | obj ? o ... : null |
| tst.js:56:22:56:25 | prop | tst.js:56:18:56:26 | obj[prop] |
| tst.js:77:9:77:38 | taint | tst.js:80:12:80:16 | taint |
| tst.js:77:9:77:38 | taint | tst.js:82:17:82:21 | taint |
| tst.js:77:9:77:38 | taint | tst.js:87:16:87:20 | taint |
| tst.js:77:17:77:38 | String( ... y.data) | tst.js:77:9:77:38 | taint |
| tst.js:77:24:77:37 | req.query.data | tst.js:77:17:77:38 | String( ... y.data) |
| tst.js:77:24:77:37 | req.query.data | tst.js:77:17:77:38 | String( ... y.data) |
| tst.js:80:12:80:16 | taint | tst.js:80:5:80:17 | object[taint] |
| tst.js:80:12:80:16 | taint | tst.js:80:5:80:17 | object[taint] |
| tst.js:82:12:82:21 | "" + taint | tst.js:82:5:82:22 | object["" + taint] |
| tst.js:82:12:82:21 | "" + taint | tst.js:82:5:82:22 | object["" + taint] |
| tst.js:82:17:82:21 | taint | tst.js:82:12:82:21 | "" + taint |
| tst.js:87:16:87:20 | taint | tst.js:87:9:87:21 | object[taint] |
| tst.js:87:16:87:20 | taint | tst.js:87:9:87:21 | object[taint] |
| tst.js:94:9:94:19 | req.query.x | tst.js:94:9:94:36 | req.que ... _', '') |
| tst.js:94:9:94:19 | req.query.x | tst.js:94:9:94:36 | req.que ... _', '') |
| tst.js:94:9:94:36 | req.que ... _', '') | tst.js:94:5:94:37 | obj[req ... ', '')] |
| tst.js:94:9:94:36 | req.que ... _', '') | tst.js:94:5:94:37 | obj[req ... ', '')] |
| tst.js:97:9:97:19 | req.query.x | tst.js:97:9:97:45 | req.que ... /g, '') |
| tst.js:97:9:97:19 | req.query.x | tst.js:97:9:97:45 | req.que ... /g, '') |
| tst.js:97:9:97:45 | req.que ... /g, '') | tst.js:97:5:97:46 | obj[req ... g, '')] |
| tst.js:97:9:97:45 | req.que ... /g, '') | tst.js:97:5:97:46 | obj[req ... g, '')] |
| tst.js:102:9:102:38 | taint | tst.js:105:12:105:16 | taint |
| tst.js:102:17:102:38 | String( ... y.data) | tst.js:102:9:102:38 | taint |
| tst.js:102:24:102:37 | req.query.data | tst.js:102:17:102:38 | String( ... y.data) |
| tst.js:102:24:102:37 | req.query.data | tst.js:102:17:102:38 | String( ... y.data) |
| tst.js:105:12:105:16 | taint | tst.js:105:5:105:17 | object[taint] |
| tst.js:105:12:105:16 | taint | tst.js:105:5:105:17 | object[taint] |
nodes
| lib.js:1:38:1:40 | obj | semmle.label | obj |
| lib.js:1:43:1:46 | path | semmle.label | path |
| lib.js:2:7:2:27 | currentPath | semmle.label | currentPath |
| lib.js:2:21:2:24 | path | semmle.label | path |
| lib.js:2:21:2:27 | path[0] | semmle.label | path[0] |
| lib.js:6:7:6:9 | obj | semmle.label | obj |
| lib.js:11:17:11:32 | obj[currentPath] | semmle.label | obj[currentPath] |
| lib.js:11:21:11:31 | currentPath | semmle.label | currentPath |
| lib.js:14:38:14:41 | path | semmle.label | path |
| lib.js:15:3:15:14 | obj[path[0]] | semmle.label | obj[path[0]] |
| lib.js:15:7:15:10 | path | semmle.label | path |
| lib.js:15:7:15:13 | path[0] | semmle.label | path[0] |
| lib.js:20:7:20:25 | path | semmle.label | path |
| lib.js:20:14:20:22 | arguments | semmle.label | arguments |
| lib.js:20:14:20:25 | arguments[1] | semmle.label | arguments[1] |
| lib.js:22:3:22:14 | obj[path[0]] | semmle.label | obj[path[0]] |
| lib.js:22:7:22:10 | path | semmle.label | path |
| lib.js:22:7:22:13 | path[0] | semmle.label | path[0] |
| lib.js:25:44:25:47 | path | semmle.label | path |
| lib.js:26:10:26:21 | obj[path[0]] | semmle.label | obj[path[0]] |
| lib.js:26:14:26:17 | path | semmle.label | path |
| lib.js:26:14:26:20 | path[0] | semmle.label | path[0] |
| lib.js:30:9:30:52 | args | semmle.label | args |
| lib.js:30:16:30:52 | Array.p ... uments) | semmle.label | Array.p ... uments) |
| lib.js:30:16:30:52 | reflective call | semmle.label | reflective call |
| lib.js:30:43:30:51 | arguments | semmle.label | arguments |
| lib.js:32:7:32:20 | path | semmle.label | path |
| lib.js:32:14:32:17 | args | semmle.label | args |
| lib.js:32:14:32:20 | args[1] | semmle.label | args[1] |
| lib.js:34:3:34:14 | obj[path[0]] | semmle.label | obj[path[0]] |
| lib.js:34:7:34:10 | path | semmle.label | path |
| lib.js:34:7:34:13 | path[0] | semmle.label | path[0] |
| lib.js:38:9:38:36 | args | semmle.label | args |
| lib.js:38:16:38:36 | Array.f ... uments) | semmle.label | Array.f ... uments) |
| lib.js:38:27:38:35 | arguments | semmle.label | arguments |
| lib.js:40:7:40:20 | path | semmle.label | path |
| lib.js:40:14:40:17 | args | semmle.label | args |
| lib.js:40:14:40:20 | args[1] | semmle.label | args[1] |
| lib.js:42:3:42:14 | obj[path[0]] | semmle.label | obj[path[0]] |
| lib.js:42:7:42:10 | path | semmle.label | path |
| lib.js:42:7:42:13 | path[0] | semmle.label | path[0] |
| lib.js:83:7:83:25 | path | semmle.label | path |
| lib.js:83:14:83:22 | arguments | semmle.label | arguments |
| lib.js:83:14:83:25 | arguments[1] | semmle.label | arguments[1] |
| lib.js:86:7:86:26 | proto | semmle.label | proto |
| lib.js:86:15:86:26 | obj[path[0]] | semmle.label | obj[path[0]] |
| lib.js:86:19:86:22 | path | semmle.label | path |
| lib.js:86:19:86:25 | path[0] | semmle.label | path[0] |
| lib.js:87:10:87:14 | proto | semmle.label | proto |
| lib.js:90:43:90:46 | path | semmle.label | path |
| lib.js:91:7:91:28 | maybeProto | semmle.label | maybeProto |
| lib.js:91:20:91:28 | obj[path] | semmle.label | obj[path] |
| lib.js:91:24:91:27 | path | semmle.label | path |
| lib.js:92:3:92:12 | maybeProto | semmle.label | maybeProto |
| lib.js:95:3:95:12 | maybeProto | semmle.label | maybeProto |
| lib.js:104:7:104:24 | one | semmle.label | one |
| lib.js:104:13:104:21 | arguments | semmle.label | arguments |
| lib.js:104:13:104:24 | arguments[1] | semmle.label | arguments[1] |
| lib.js:108:3:108:10 | obj[one] | semmle.label | obj[one] |
| lib.js:108:7:108:9 | one | semmle.label | one |
| lib.js:118:29:118:32 | path | semmle.label | path |
| lib.js:119:13:119:24 | obj[path[0]] | semmle.label | obj[path[0]] |
| lib.js:119:17:119:20 | path | semmle.label | path |
| lib.js:119:17:119:23 | path[0] | semmle.label | path[0] |
| lib.js:127:14:127:17 | path | semmle.label | path |
| lib.js:128:9:128:20 | obj[path[0]] | semmle.label | obj[path[0]] |
| lib.js:128:13:128:16 | path | semmle.label | path |
| lib.js:128:13:128:19 | path[0] | semmle.label | path[0] |
| otherlib/src/otherlibimpl.js:1:37:1:40 | path | semmle.label | path |
| otherlib/src/otherlibimpl.js:2:3:2:14 | obj[path[0]] | semmle.label | obj[path[0]] |
| otherlib/src/otherlibimpl.js:2:7:2:10 | path | semmle.label | path |
| otherlib/src/otherlibimpl.js:2:7:2:13 | path[0] | semmle.label | path[0] |
| sublib/other.js:5:28:5:31 | path | semmle.label | path |
| sublib/other.js:6:7:6:18 | obj[path[0]] | semmle.label | obj[path[0]] |
| sublib/other.js:6:11:6:14 | path | semmle.label | path |
| sublib/other.js:6:11:6:17 | path[0] | semmle.label | path[0] |
| sublib/sub.js:1:37:1:40 | path | semmle.label | path |
| sublib/sub.js:2:3:2:14 | obj[path[0]] | semmle.label | obj[path[0]] |
| sublib/sub.js:2:7:2:10 | path | semmle.label | path |
| sublib/sub.js:2:7:2:13 | path[0] | semmle.label | path[0] |
| tst.js:5:9:5:38 | taint | semmle.label | taint |
| tst.js:5:17:5:38 | String( ... y.data) | semmle.label | String( ... y.data) |
| tst.js:5:24:5:37 | req.query.data | semmle.label | req.query.data |
| tst.js:8:5:8:17 | object[taint] | semmle.label | object[taint] |
| tst.js:8:12:8:16 | taint | semmle.label | taint |
| tst.js:9:5:9:17 | object[taint] | semmle.label | object[taint] |
| tst.js:9:12:9:16 | taint | semmle.label | taint |
| tst.js:12:18:12:30 | object[taint] | semmle.label | object[taint] |
| tst.js:12:25:12:29 | taint | semmle.label | taint |
| tst.js:14:5:14:32 | unsafeG ... taint) | semmle.label | unsafeG ... taint) |
| tst.js:14:27:14:31 | taint | semmle.label | taint |
| tst.js:33:23:33:25 | obj | semmle.label | obj |
| tst.js:34:5:34:7 | obj | semmle.label | obj |
| tst.js:39:9:39:11 | obj | semmle.label | obj |
| tst.js:45:9:45:11 | obj | semmle.label | obj |
| tst.js:48:9:48:11 | obj | semmle.label | obj |
| tst.js:55:29:55:32 | prop | semmle.label | prop |
| tst.js:56:12:56:33 | obj ? o ... : null | semmle.label | obj ? o ... : null |
| tst.js:56:18:56:26 | obj[prop] | semmle.label | obj[prop] |
| tst.js:56:22:56:25 | prop | semmle.label | prop |
| tst.js:77:9:77:38 | taint | semmle.label | taint |
| tst.js:77:17:77:38 | String( ... y.data) | semmle.label | String( ... y.data) |
| tst.js:77:24:77:37 | req.query.data | semmle.label | req.query.data |
| tst.js:80:5:80:17 | object[taint] | semmle.label | object[taint] |
| tst.js:80:12:80:16 | taint | semmle.label | taint |
| tst.js:82:5:82:22 | object["" + taint] | semmle.label | object["" + taint] |
| tst.js:82:12:82:21 | "" + taint | semmle.label | "" + taint |
| tst.js:82:17:82:21 | taint | semmle.label | taint |
| tst.js:87:9:87:21 | object[taint] | semmle.label | object[taint] |
| tst.js:87:16:87:20 | taint | semmle.label | taint |
| tst.js:94:5:94:37 | obj[req ... ', '')] | semmle.label | obj[req ... ', '')] |
| tst.js:94:9:94:19 | req.query.x | semmle.label | req.query.x |
| tst.js:94:9:94:36 | req.que ... _', '') | semmle.label | req.que ... _', '') |
| tst.js:97:5:97:46 | obj[req ... g, '')] | semmle.label | obj[req ... g, '')] |
| tst.js:97:9:97:19 | req.query.x | semmle.label | req.query.x |
| tst.js:97:9:97:45 | req.que ... /g, '') | semmle.label | req.que ... /g, '') |
| tst.js:102:9:102:38 | taint | semmle.label | taint |
| tst.js:102:17:102:38 | String( ... y.data) | semmle.label | String( ... y.data) |
| tst.js:102:24:102:37 | req.query.data | semmle.label | req.query.data |
| tst.js:105:5:105:17 | object[taint] | semmle.label | object[taint] |
| tst.js:105:12:105:16 | taint | semmle.label | taint |
subpaths
| tst.js:14:27:14:31 | taint | tst.js:55:29:55:32 | prop | tst.js:56:12:56:33 | obj ? o ... : null | tst.js:14:5:14:32 | unsafeG ... taint) |
#select
| lib.js:6:7:6:9 | obj | lib.js:1:43:1:46 | path | lib.js:6:7:6:9 | obj | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:1:43:1:46 | path | library input |
| lib.js:15:3:15:14 | obj[path[0]] | lib.js:14:38:14:41 | path | lib.js:15:3:15:14 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:14:38:14:41 | path | library input |
@@ -373,7 +232,6 @@ edges
| lib.js:26:10:26:21 | obj[path[0]] | lib.js:25:44:25:47 | path | lib.js:26:10:26:21 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:25:44:25:47 | path | library input |
| lib.js:34:3:34:14 | obj[path[0]] | lib.js:30:43:30:51 | arguments | lib.js:34:3:34:14 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:30:43:30:51 | arguments | library input |
| lib.js:42:3:42:14 | obj[path[0]] | lib.js:38:27:38:35 | arguments | lib.js:42:3:42:14 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:38:27:38:35 | arguments | library input |
| lib.js:70:13:70:24 | obj[path[0]] | lib.js:59:18:59:18 | s | lib.js:70:13:70:24 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:59:18:59:18 | s | library input |
| lib.js:87:10:87:14 | proto | lib.js:83:14:83:22 | arguments | lib.js:87:10:87:14 | proto | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:83:14:83:22 | arguments | library input |
| lib.js:108:3:108:10 | obj[one] | lib.js:104:13:104:21 | arguments | lib.js:108:3:108:10 | obj[one] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:104:13:104:21 | arguments | library input |
| lib.js:119:13:119:24 | obj[path[0]] | lib.js:118:29:118:32 | path | lib.js:119:13:119:24 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:118:29:118:32 | path | library input |