From 60b179bda2f104cf592d52885a1937dcced53765 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 12 Oct 2023 10:12:19 +0200 Subject: [PATCH 001/514] Shared: add DeduplicatePathGraph Note that there is a separate PR open with this library --- shared/dataflow/codeql/dataflow/DataFlow.qll | 230 +++++++++++++++++++ 1 file changed, 230 insertions(+) diff --git a/shared/dataflow/codeql/dataflow/DataFlow.qll b/shared/dataflow/codeql/dataflow/DataFlow.qll index f7a2429ee8a..d64f9cc4da9 100644 --- a/shared/dataflow/codeql/dataflow/DataFlow.qll +++ b/shared/dataflow/codeql/dataflow/DataFlow.qll @@ -697,4 +697,234 @@ module DataFlowMake { } } } + + /** + * Generates a `PathGraph` in which equivalent path nodes are merged, in order to avoid duplicate paths. + */ + module DeduplicatePathGraph Graph> { + // NOTE: there is a known limitation in that this module cannot see which nodes are sources or sinks. + // This only matters in the rare case where a sink PathNode has a non-empty set of succesors, and there is a + // non-sink PathNode with the same `(node, toString)` value and the same successors, but is transitively + // reachable from a different set of PathNodes. (And conversely for sources). + // + pragma[nomagic] + private InputPathNode getAPathNode(Node node, string toString) { + result.getNode() = node and + Graph::nodes(result, _, toString) + } + + private signature predicate collapseCandidateSig(Node node, string toString); + + private signature predicate stepSig(InputPathNode node1, InputPathNode node2); + + private signature predicate subpathStepSig( + InputPathNode arg, InputPathNode param, InputPathNode ret, InputPathNode out + ); + + /** + * Performs a forward or backward pass computing which `(node, toString)` pairs can subsume their corresponding + * path nodes. + * + * This is similar to automaton minimization, but for an NFA. Since minimizing an NFA is NP-hard (and does not have + * a unique minimal NFA), we operate with the simpler model: for a given `(node, toString)` pair, either all + * corresponding path nodes are merged, or none are merged. + * + * Comments are written as if this checks for outgoing edges and propagates backward, though the module is also + * used to perform the opposite direction. + */ + private module MakeDiscriminatorPass< + collapseCandidateSig/2 collapseCandidate, stepSig/2 step, subpathStepSig/4 subpathStep> + { + /** + * Gets the number of `(node, toString)` pairs reachable in one step from `pathNode`. + */ + private int getOutDegreeFromPathNode(InputPathNode pathNode) { + result = count(Node node, string toString | step(pathNode, getAPathNode(node, toString))) + } + + /** + * Gets the number of `(node2, toString2)` pairs reachable in one step from path nodes corresponding to `(node, toString)`. + */ + private int getOutDegreeFromNode(Node node, string toString) { + result = + strictcount(Node node2, string toString2 | + step(getAPathNode(node, toString), getAPathNode(node2, toString2)) + ) + } + + /** + * Like `getOutDegreeFromPathNode` except counts `subpath` tuples. + */ + private int getSubpathOutDegreeFromPathNode(InputPathNode pathNode) { + result = + count(Node n1, string s1, Node n2, string s2, Node n3, string s3 | + subpathStep(pathNode, getAPathNode(n1, s1), getAPathNode(n2, s2), getAPathNode(n3, s3)) + ) + } + + /** + * Like `getOutDegreeFromNode` except counts `subpath` tuples. + */ + private int getSubpathOutDegreeFromNode(Node node, string toString) { + result = + strictcount(Node n1, string s1, Node n2, string s2, Node n3, string s3 | + subpathStep(getAPathNode(node, toString), getAPathNode(n1, s1), getAPathNode(n2, s2), + getAPathNode(n3, s3)) + ) + } + + /** Gets a successor of `node` including subpath flow-through. */ + InputPathNode stepEx(InputPathNode node) { + step(node, result) + or + subpathStep(node, _, _, result) // assuming the input is pruned properly, all subpaths have flow-through + } + + InputPathNode enterSubpathStep(InputPathNode node) { subpathStep(node, result, _, _) } + + InputPathNode exitSubpathStep(InputPathNode node) { subpathStep(_, _, node, result) } + + /** Holds if `(node, toString)` cannot be collapsed (but was a candidate for being collapsed). */ + predicate discriminatedPair(Node node, string toString, boolean hasEnter) { + collapseCandidate(node, toString) and + hasEnter = false and + ( + // Check if all corresponding PathNodes have the same successor sets when projected to `(node, toString)`. + // To do this, we check that each successor set has the same size as the union of the succesor sets. + // - If the successor sets are equal, then they are also equal to their union, and so have the correct size. + // - Conversely, if two successor sets are not equal, one of them must be missing an element that is present + // in the union, but must still be a subset of the union, and thus be strictly smaller than the union. + getOutDegreeFromPathNode(getAPathNode(node, toString)) < + getOutDegreeFromNode(node, toString) + or + // Same as above but counting associated subpath triples instead + getSubpathOutDegreeFromPathNode(getAPathNode(node, toString)) < + getSubpathOutDegreeFromNode(node, toString) + ) + or + collapseCandidate(node, toString) and + ( + // Retain flow state if one of the successors requires it to be retained + discriminatedPathNode(stepEx(getAPathNode(node, toString)), hasEnter) + or + // Enter a subpath + discriminatedPathNode(enterSubpathStep(getAPathNode(node, toString)), _) and + hasEnter = true + or + // Exit a subpath + discriminatedPathNode(exitSubpathStep(getAPathNode(node, toString)), false) and + hasEnter = false + ) + } + + /** Holds if `pathNode` cannot be collapsed. */ + private predicate discriminatedPathNode(InputPathNode pathNode, boolean hasEnter) { + exists(Node node, string toString | + discriminatedPair(node, toString, hasEnter) and + getAPathNode(node, toString) = pathNode + ) + } + + /** Holds if `(node, toString)` cannot be collapsed (but was a candidate for being collapsed). */ + predicate discriminatedPair(Node node, string toString) { + discriminatedPair(node, toString, _) + } + + /** Holds if `pathNode` cannot be collapsed. */ + predicate discriminatedPathNode(InputPathNode pathNode) { discriminatedPathNode(pathNode, _) } + } + + private predicate initialCandidate(Node node, string toString) { + exists(getAPathNode(node, toString)) + } + + private module Pass1 = + MakeDiscriminatorPass; + + private predicate edgesRev(InputPathNode node1, InputPathNode node2) { + Graph::edges(node2, node1) + } + + private predicate subpathsRev( + InputPathNode n1, InputPathNode n2, InputPathNode n3, InputPathNode n4 + ) { + Graph::subpaths(n4, n3, n2, n1) + } + + private module Pass2 = + MakeDiscriminatorPass; + + private newtype TPathNode = + TPreservedPathNode(InputPathNode node) { Pass2::discriminatedPathNode(node) } or + TCollapsedPathNode(Node node, string toString) { + initialCandidate(node, toString) and + not Pass2::discriminatedPair(node, toString) + } + + /** A node in the path graph after equivalent nodes have been collapsed. */ + class PathNode extends TPathNode { + private Node asCollapsedNode() { this = TCollapsedPathNode(result, _) } + + private InputPathNode asPreservedNode() { this = TPreservedPathNode(result) } + + /** Gets a correspondng node in the original graph. */ + InputPathNode getAnOriginalPathNode() { + exists(Node node, string toString | + this = TCollapsedPathNode(node, toString) and + result = getAPathNode(node, toString) + ) + or + result = this.asPreservedNode() + } + + /** Gets a string representation of this node. */ + string toString() { + result = this.asPreservedNode().toString() or this = TCollapsedPathNode(_, result) + } + + /** + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + this.getAnOriginalPathNode() + .hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } + + /** Gets the corresponding data-flow node. */ + Node getNode() { + result = this.asCollapsedNode() + or + result = this.asPreservedNode().getNode() + } + } + + /** + * Provides the query predicates needed to include a graph in a path-problem query. + */ + module PathGraph implements PathGraphSig { + query predicate nodes(PathNode node, string key, string val) { + Graph::nodes(node.getAnOriginalPathNode(), key, val) + } + + query predicate edges(PathNode node1, PathNode node2) { + Graph::edges(node1.getAnOriginalPathNode(), node2.getAnOriginalPathNode()) + } + + query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) { + // Note: this may look suspiciously simple, but it's not an oversight. Even if the caller needs to retain state, + // it is entirely possible to step through a subpath in which state has been projected away. + Graph::subpaths(arg.getAnOriginalPathNode(), par.getAnOriginalPathNode(), + ret.getAnOriginalPathNode(), out.getAnOriginalPathNode()) + } + } + + // Re-export the PathGraph so the user can import a single module and get both PathNode and the query predicates + import PathGraph + } } From 51ef0e58365df4cbfcbe0f27956a3dbdef408385 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Oct 2023 09:43:45 +0200 Subject: [PATCH 002/514] JS: Move TNode into a cached module --- .../dataflow/internal/DataFlowNode.qll | 56 +++++++++++-------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index 8a688bb573f..db78cae8f0d 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -5,31 +5,39 @@ */ private import javascript +cached +private module Cached { + /** + * The raw data type underlying `DataFlow::Node`. + */ + cached + newtype TNode = + TValueNode(AST::ValueNode nd) or + TSsaDefNode(SsaDefinition d) or + TCapturedVariableNode(LocalVariable v) { v.isCaptured() } or + TPropNode(@property p) or + TRestPatternNode(DestructuringPattern dp, Expr rest) { rest = dp.getRest() } or + TElementPatternNode(ArrayPattern ap, Expr p) { p = ap.getElement(_) } or + TElementNode(ArrayExpr arr, Expr e) { e = arr.getAnElement() } or + TReflectiveCallNode(MethodCallExpr ce, string kind) { + ce.getMethodName() = kind and + (kind = "call" or kind = "apply") + } or + TThisNode(StmtContainer f) { f.(Function).getThisBinder() = f or f instanceof TopLevel } or + TDestructuredModuleImportNode(ImportDeclaration decl) { + exists(decl.getASpecifier().getImportedName()) + } or + THtmlAttributeNode(HTML::Attribute attr) or + TFunctionReturnNode(Function f) or + TExceptionalFunctionReturnNode(Function f) or + TExceptionalInvocationReturnNode(InvokeExpr e) or + TGlobalAccessPathRoot() or + TTemplatePlaceholderTag(Templating::TemplatePlaceholderTag tag) or + TReflectiveParametersNode(Function f) or +} + +import Cached /** * The raw data type underlying `DataFlow::Node`. */ -cached -newtype TNode = - TValueNode(AST::ValueNode nd) or - TSsaDefNode(SsaDefinition d) or - TCapturedVariableNode(LocalVariable v) { v.isCaptured() } or - TPropNode(@property p) or - TRestPatternNode(DestructuringPattern dp, Expr rest) { rest = dp.getRest() } or - TElementPatternNode(ArrayPattern ap, Expr p) { p = ap.getElement(_) } or - TElementNode(ArrayExpr arr, Expr e) { e = arr.getAnElement() } or - TReflectiveCallNode(MethodCallExpr ce, string kind) { - ce.getMethodName() = kind and - (kind = "call" or kind = "apply") - } or - TThisNode(StmtContainer f) { f.(Function).getThisBinder() = f or f instanceof TopLevel } or - TDestructuredModuleImportNode(ImportDeclaration decl) { - exists(decl.getASpecifier().getImportedName()) - } or - THtmlAttributeNode(HTML::Attribute attr) or - TFunctionReturnNode(Function f) or - TExceptionalFunctionReturnNode(Function f) or - TExceptionalInvocationReturnNode(InvokeExpr e) or - TGlobalAccessPathRoot() or - TTemplatePlaceholderTag(Templating::TemplatePlaceholderTag tag) or - TReflectiveParametersNode(Function f) From 79e7aae9f6ccbc698e07a12506e64980cd3428c4 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Oct 2023 09:48:09 +0200 Subject: [PATCH 003/514] JS: Add TEarlyStageNode --- javascript/ql/lib/semmle/javascript/AMD.qll | 19 ++- .../ql/lib/semmle/javascript/NodeJS.qll | 60 +++++--- javascript/ql/lib/semmle/javascript/Paths.qll | 23 +-- .../semmle/javascript/dataflow/DataFlow.qll | 142 ++++++++++-------- .../dataflow/internal/DataFlowNode.qll | 29 +++- .../data/internal/ApiGraphModelsSpecific.qll | 8 +- .../javascript/internal/CachedStages.qll | 26 +++- 7 files changed, 202 insertions(+), 105 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/AMD.qll b/javascript/ql/lib/semmle/javascript/AMD.qll index 20b1c26275a..7bad8eda9e2 100644 --- a/javascript/ql/lib/semmle/javascript/AMD.qll +++ b/javascript/ql/lib/semmle/javascript/AMD.qll @@ -6,6 +6,7 @@ import javascript private import semmle.javascript.internal.CachedStages private import Expressions.ExprHasNoEffect +private import semmle.javascript.dataflow.internal.DataFlowNode /** * Companion module to the `AmdModuleDefinition` class. @@ -78,10 +79,15 @@ class AmdModuleDefinition extends CallExpr instanceof AmdModuleDefinition::Range result instanceof DataFlow::ValueNode } - private DataFlow::Node getFactoryNodeInternal() { - // To avoid recursion, this should not depend on `SourceNode`. - result = DataFlow::valueNode(this.getLastArgument()) or - result = this.getFactoryNodeInternal().getAPredecessor() + /** + * Gets the factory function of this module definition. + */ + Function getFactoryFunction() { TValueNode(result) = this.getFactoryNodeInternal() } + + private EarlyStageNode getFactoryNodeInternal() { + result = TValueNode(this.getLastArgument()) + or + DataFlow::localFlowStep(result, this.getFactoryNodeInternal()) } /** Gets the expression defining this module. */ @@ -132,7 +138,10 @@ class AmdModuleDefinition extends CallExpr instanceof AmdModuleDefinition::Range * Gets the `i`th parameter of the factory function of this module. */ private Parameter getFactoryParameter(int i) { - this.getFactoryNodeInternal().asExpr().(Function).getParameter(i) = result + exists(Function fun | + this.getFactoryNodeInternal() = TValueNode(fun) and + result = fun.getParameter(i) + ) } /** diff --git a/javascript/ql/lib/semmle/javascript/NodeJS.qll b/javascript/ql/lib/semmle/javascript/NodeJS.qll index 221cee084b6..5e12c66bb09 100644 --- a/javascript/ql/lib/semmle/javascript/NodeJS.qll +++ b/javascript/ql/lib/semmle/javascript/NodeJS.qll @@ -4,6 +4,7 @@ import javascript private import NodeModuleResolutionImpl private import semmle.javascript.DynamicPropertyAccess as DynamicPropertyAccess private import semmle.javascript.internal.CachedStages +private import semmle.javascript.dataflow.internal.DataFlowNode /** * A Node.js module. @@ -240,60 +241,69 @@ private class RequireVariable extends Variable { */ private predicate moduleInFile(Module m, File f) { m.getFile() = f } -private predicate isModuleModule(DataFlow::Node nd) { - exists(ImportDeclaration imp | - imp.getImportedPath().getValue() = "module" and - nd = - [ - DataFlow::destructuredModuleImportNode(imp), - DataFlow::valueNode(imp.getASpecifier().(ImportNamespaceSpecifier)) - ] +private predicate isModuleModule(EarlyStageNode nd) { + exists(ImportDeclaration imp | imp.getImportedPath().getValue() = "module" | + nd = TDestructuredModuleImportNode(imp) + or + nd = TValueNode(imp.getASpecifier().(ImportNamespaceSpecifier)) ) or - isModuleModule(nd.getAPredecessor()) + exists(EarlyStageNode other | + isModuleModule(other) and + DataFlow::localFlowStep(other, nd) + ) } -private predicate isCreateRequire(DataFlow::Node nd) { +private predicate isCreateRequire(EarlyStageNode nd) { exists(PropAccess prop | - isModuleModule(prop.getBase().flow()) and + isModuleModule(TValueNode(prop.getBase())) and prop.getPropertyName() = "createRequire" and - nd = prop.flow() + nd = TValueNode(prop) ) or exists(PropertyPattern prop | - isModuleModule(prop.getObjectPattern().flow()) and + isModuleModule(TValueNode(prop.getObjectPattern())) and prop.getName() = "createRequire" and - nd = prop.getValuePattern().flow() + nd = TValueNode(prop.getValuePattern()) ) or exists(ImportDeclaration decl, NamedImportSpecifier spec | decl.getImportedPath().getValue() = "module" and spec = decl.getASpecifier() and spec.getImportedName() = "createRequire" and - nd = spec.flow() + nd = TValueNode(spec) ) or - isCreateRequire(nd.getAPredecessor()) + exists(EarlyStageNode other | + isCreateRequire(other) and + DataFlow::localFlowStep(other, nd) + ) } /** * Holds if `nd` may refer to `require`, either directly or modulo local data flow. */ cached -private predicate isRequire(DataFlow::Node nd) { - nd.asExpr() = any(RequireVariable req).getAnAccess() and - // `mjs` files explicitly disallow `require` - not nd.getFile().getExtension() = "mjs" +private predicate isRequire(EarlyStageNode nd) { + exists(VarAccess access | + access = any(RequireVariable v).getAnAccess() and + nd = TValueNode(access) and + // `mjs` files explicitly disallow `require` + not access.getFile().getExtension() = "mjs" + ) or - isRequire(nd.getAPredecessor()) + exists(EarlyStageNode other | + isRequire(other) and + DataFlow::localFlowStep(other, nd) + ) or // `import { createRequire } from 'module';`. // specialized to ES2015 modules to avoid recursion in the `DataFlow::moduleImport()` predicate and to avoid // negative recursion between `Import.getImportedModuleNode()` and `Import.getImportedModule()`, and // to avoid depending on `SourceNode` as this would make `SourceNode::Range` recursive. exists(CallExpr call | - isCreateRequire(call.getCallee().flow()) and - nd = call.flow() + isCreateRequire(TValueNode(call.getCallee())) and + nd = TValueNode(call) ) } @@ -307,7 +317,7 @@ private predicate isRequire(DataFlow::Node nd) { * ``` */ class Require extends CallExpr, Import { - Require() { isRequire(this.getCallee().flow()) } + Require() { isRequire(TValueNode(this.getCallee())) } override PathExpr getImportedPath() { result = this.getArgument(0) } @@ -401,7 +411,7 @@ private class RequirePath extends PathExprCandidate { this = any(Require req).getArgument(0) or exists(MethodCallExpr reqres | - isRequire(reqres.getReceiver().flow()) and + isRequire(TValueNode(reqres.getReceiver())) and reqres.getMethodName() = "resolve" and this = reqres.getArgument(0) ) diff --git a/javascript/ql/lib/semmle/javascript/Paths.qll b/javascript/ql/lib/semmle/javascript/Paths.qll index 5f8452f5251..66a840e9f26 100644 --- a/javascript/ql/lib/semmle/javascript/Paths.qll +++ b/javascript/ql/lib/semmle/javascript/Paths.qll @@ -4,6 +4,7 @@ */ import javascript +private import semmle.javascript.dataflow.internal.DataFlowNode /** * Internal representation of paths as lists of components. @@ -381,16 +382,16 @@ private class PathExprString extends PathString { } pragma[nomagic] -private DataFlow::Node getAPathExprAlias(PathExpr expr) { - result.getImmediatePredecessor().asExpr() = expr +private EarlyStageNode getAPathExprAlias(PathExpr expr) { + DataFlow::Impl::earlyStageImmediateFlowStep(TValueNode(expr), result) or - result.getImmediatePredecessor() = getAPathExprAlias(expr) + DataFlow::Impl::earlyStageImmediateFlowStep(getAPathExprAlias(expr), result) } private class PathExprFromAlias extends PathExpr { private PathExpr other; - PathExprFromAlias() { this = getAPathExprAlias(other).asExpr() } + PathExprFromAlias() { TValueNode(this) = getAPathExprAlias(other) } override string getValue() { result = other.getValue() } @@ -435,13 +436,15 @@ abstract class PathExprCandidate extends Expr { pragma[nomagic] private Expr getAPart1() { result = this or result = this.getAPart().getAChildExpr() } + private EarlyStageNode getAnAliasedPart1() { + result = TValueNode(this.getAPart1()) + or + DataFlow::Impl::earlyStageImmediateFlowStep(result, this.getAnAliasedPart1()) + } + /** - * Gets an expression that is nested inside this expression. - * - * Equivalent to `getAChildExpr*()`, but useful to enforce a better join order (in spite of - * what the optimizer thinks, there are generally far fewer `PathExprCandidate`s than - * `ConstantString`s). + * Gets an expression that is depended on by an expression nested inside this expression. */ pragma[nomagic] - Expr getAPart() { result = this.getAPart1().flow().getImmediatePredecessor*().asExpr() } + Expr getAPart() { TValueNode(result) = this.getAnAliasedPart1() } } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index d7ddf739362..8c2376ee856 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -179,29 +179,8 @@ module DataFlow { */ cached DataFlow::Node getImmediatePredecessor() { - lvalueFlowStep(result, this) and - not lvalueDefaultFlowStep(_, this) - or immediateFlowStep(result, this) or - // Refinement of variable -> original definition of variable - exists(SsaRefinementNode refinement | - this = TSsaDefNode(refinement) and - result = TSsaDefNode(refinement.getAnInput()) - ) - or - exists(SsaPhiNode phi | - this = TSsaDefNode(phi) and - result = TSsaDefNode(phi.getRephinedVariable()) - ) - or - // IIFE call -> return value of IIFE - exists(Function fun | - localCall(this.asExpr(), fun) and - result = unique(Expr ret | ret = fun.getAReturnedExpr()).flow() and - not fun.getExit().isJoin() // can only reach exit by the return statement - ) - or FlowSteps::identityFunctionStep(result, this) } @@ -783,14 +762,7 @@ module DataFlow { override string getPropertyName() { result = prop.getName() } - override Node getRhs() { - exists(Parameter param, Node paramNode | - param = prop.getParameter() and - parameterNode(paramNode, param) - | - result = paramNode - ) - } + override Node getRhs() { result = TValueNode(prop.getParameter()) } override ControlFlowNode getWriteNode() { result = prop.getParameter() } } @@ -1107,6 +1079,14 @@ module DataFlow { * instead. */ module Impl { + /** + * INTERNAL. DO NOT USE. + * + * An alias for `Node.getImmediatePredecessor` that can be used at an earlier stage + * that does not depend on `DataFlow::Node`. + */ + predicate earlyStageImmediateFlowStep = immediateFlowStep/2; + /** * A data flow node representing a function invocation, either explicitly or reflectively, * and either with or without `new`. @@ -1420,12 +1400,12 @@ module DataFlow { /** * INTERNAL: Use `parameterNode(Parameter)` instead. */ - predicate parameterNode(DataFlow::Node nd, Parameter p) { nd = valueNode(p) } + predicate parameterNode(EarlyStageNode nd, Parameter p) { nd = TValueNode(p) } /** * INTERNAL: Use `thisNode(StmtContainer container)` instead. */ - predicate thisNode(DataFlow::Node node, StmtContainer container) { node = TThisNode(container) } + predicate thisNode(EarlyStageNode node, StmtContainer container) { node = TThisNode(container) } /** * Gets the node representing the receiver of the given function, or `this` in the given top-level. @@ -1487,7 +1467,15 @@ module DataFlow { * _before_ the l-value is assigned to, whereas `DataFlow::lvalueNode()` * represents the value _after_ the assignment. */ - Node lvalueNode(BindingPattern lvalue) { + Node lvalueNode(BindingPattern lvalue) { result = lvalueNodeInternal(lvalue) } + + /** + * INTERNAL: Do not use outside standard library. + * + * Same as `lvalueNode()` except the return type is `EarlyStageNode`, which allows it to be used + * before all data flow nodes have been materialised. + */ + EarlyStageNode lvalueNodeInternal(BindingPattern lvalue) { exists(SsaExplicitDefinition ssa | ssa.defines(lvalue.(LValue).getDefNode(), lvalue.(VarRef).getVariable()) and result = TSsaDefNode(ssa) @@ -1535,31 +1523,31 @@ module DataFlow { * Holds if there is a step from `pred -> succ` due to an assignment * to an expression in l-value position. */ - private predicate lvalueFlowStep(Node pred, Node succ) { + private predicate lvalueFlowStep(EarlyStageNode pred, EarlyStageNode succ) { exists(VarDef def | - pred = valueNode(defSourceNode(def)) and - succ = lvalueNode(def.getTarget()) + pred = TValueNode(defSourceNode(def)) and + succ = lvalueNodeInternal(def.getTarget()) ) or exists(SimpleParameter param | - pred = valueNode(param) and // The value node represents the incoming argument - succ = lvalueNode(param) // The SSA node represents the parameters's local variable + pred = TValueNode(param) and // The value node represents the incoming argument + succ = lvalueNodeInternal(param) // The SSA node represents the parameters's local variable ) or exists(Expr arg, Parameter param | localArgumentPassing(arg, param) and - pred = valueNode(arg) and - succ = valueNode(param) + pred = TValueNode(arg) and + succ = TValueNode(param) ) or exists(PropertyPattern pattern | pred = TPropNode(pattern) and - succ = lvalueNode(pattern.getValuePattern()) + succ = lvalueNodeInternal(pattern.getValuePattern()) ) or exists(Expr element | pred = TElementPatternNode(_, element) and - succ = lvalueNode(element) + succ = lvalueNodeInternal(element) ) } @@ -1567,37 +1555,37 @@ module DataFlow { * Holds if there is a step from `pred -> succ` from the default * value of a destructuring pattern or parameter. */ - private predicate lvalueDefaultFlowStep(Node pred, Node succ) { + private predicate lvalueDefaultFlowStep(EarlyStageNode pred, EarlyStageNode succ) { exists(PropertyPattern pattern | pred = TValueNode(pattern.getDefault()) and - succ = lvalueNode(pattern.getValuePattern()) + succ = lvalueNodeInternal(pattern.getValuePattern()) ) or exists(ArrayPattern array, int i | pred = TValueNode(array.getDefault(i)) and - succ = lvalueNode(array.getElement(i)) + succ = lvalueNodeInternal(array.getElement(i)) ) or exists(Parameter param | pred = TValueNode(param.getDefault()) and - parameterNode(succ, param) + succ = TValueNode(param) ) } /** - * Flow steps shared between `getImmediatePredecessor` and `localFlowStep`. + * Flow steps shared between `immediateFlowStep` and `localFlowStep`. * * Inlining is forced because the two relations are indexed differently. */ pragma[inline] - private predicate immediateFlowStep(Node pred, Node succ) { + private predicate immediateFlowStepShared(EarlyStageNode pred, EarlyStageNode succ) { exists(SsaVariable v | pred = TSsaDefNode(v.getDefinition()) and - succ = valueNode(v.getAUse()) + succ = TValueNode(v.getAUse()) ) or exists(Expr predExpr, Expr succExpr | - pred = valueNode(predExpr) and succ = valueNode(succExpr) + pred = TValueNode(predExpr) and succ = TValueNode(succExpr) | predExpr = succExpr.(ParExpr).getExpression() or @@ -1627,25 +1615,55 @@ module DataFlow { // flow from 'this' parameter into 'this' expressions exists(ThisExpr thiz | pred = TThisNode(thiz.getBindingContainer()) and - succ = valueNode(thiz) + succ = TValueNode(thiz) ) or // `f.call(...)` and `f.apply(...)` evaluate to the result of the reflective call they perform - pred = TReflectiveCallNode(succ.asExpr(), _) + exists(MethodCallExpr call | + pred = TReflectiveCallNode(call, _) and + succ = TValueNode(call) + ) + } + + pragma[nomagic] + private predicate immediateFlowStep(EarlyStageNode pred, EarlyStageNode succ) { + lvalueFlowStep(pred, succ) and + not lvalueDefaultFlowStep(_, succ) + or + immediateFlowStepShared(pred, succ) + or + // Refinement of variable -> original definition of variable + exists(SsaRefinementNode refinement | + succ = TSsaDefNode(refinement) and + pred = TSsaDefNode(refinement.getAnInput()) + ) + or + exists(SsaPhiNode phi | + succ = TSsaDefNode(phi) and + pred = TSsaDefNode(phi.getRephinedVariable()) + ) + or + // IIFE call -> return value of IIFE + exists(Function fun, Expr expr | + succ = TValueNode(expr) and + localCall(expr, fun) and + pred = TValueNode(unique(Expr ret | ret = fun.getAReturnedExpr())) and + not fun.getExit().isJoin() // can only reach exit by the return statement + ) } /** * Holds if data can flow from `pred` to `succ` in one local step. */ cached - predicate localFlowStep(Node pred, Node succ) { - Stages::DataFlowStage::ref() and + predicate localFlowStep(EarlyStageNode pred, EarlyStageNode succ) { + Stages::EarlyDataFlowStage::ref() and // flow from RHS into LHS lvalueFlowStep(pred, succ) or lvalueDefaultFlowStep(pred, succ) or - immediateFlowStep(pred, succ) + immediateFlowStepShared(pred, succ) or // From an assignment or implicit initialization of a captured variable to its flow-insensitive node. exists(SsaDefinition predDef | @@ -1669,7 +1687,7 @@ module DataFlow { ) or exists(Expr predExpr, Expr succExpr | - pred = valueNode(predExpr) and succ = valueNode(succExpr) + pred = TValueNode(predExpr) and succ = TValueNode(succExpr) | predExpr = succExpr.(LogicalBinaryExpr).getAnOperand() or @@ -1683,13 +1701,19 @@ module DataFlow { or // from returned expr to the FunctionReturnNode. exists(Function f | not f.isAsyncOrGenerator() | - DataFlow::functionReturnNode(succ, f) and pred = valueNode(f.getAReturnedExpr()) + succ = TFunctionReturnNode(f) and pred = TValueNode(f.getAReturnedExpr()) ) or // from a reflective params node to a reference to the arguments object. - exists(DataFlow::ReflectiveParametersNode params, Function f | f = params.getFunction() | - succ = f.getArgumentsVariable().getAnAccess().flow() and - pred = params + exists(Function f | + pred = TReflectiveParametersNode(f) and + succ = TValueNode(f.getArgumentsVariable().getAnAccess()) + ) + or + // Pass 'this' into super calls + exists(SuperCall call | + pred = TThisNode(call.getBinder()) and + succ = TConstructorThisArgumentNode(call) ) } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index db78cae8f0d..fc707959086 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -38,6 +38,33 @@ private module Cached { import Cached +private class TEarlyStageNode = + TValueNode or TSsaDefNode or TCapturedVariableNode or TPropNode or TRestPatternNode or + TElementPatternNode or TElementNode or TReflectiveCallNode or TThisNode or + TFunctionSelfReferenceNode or TDestructuredModuleImportNode or THtmlAttributeNode or + TFunctionReturnNode or TExceptionalFunctionReturnNode or TExceptionalInvocationReturnNode or + TGlobalAccessPathRoot or TTemplatePlaceholderTag or TReflectiveParametersNode or + TExprPostUpdateNode or TConstructorThisArgumentNode; + /** - * The raw data type underlying `DataFlow::Node`. + * A data-flow node that is not a flow summary node. + * + * This node exists to avoid an unwanted dependency on flow summaries in some parts of the codebase + * that should not depend on them. + * + * In particular, this dependency chain must not result in negative recursion: + * - Flow summaries can only be created after pruning irrelevant flow summaries + * - To prune irrelevant flow summaries, we must know which packages are imported + * - To know which packages are imported, module systems must be evaluated + * - The AMD and NodeJS module systems rely on data flow to find calls to `require` and similar. + * These module systems must therefore use `EarlyStageNode` instead of `DataFlow::Node`. */ +class EarlyStageNode extends TEarlyStageNode { + string toString() { result = this.(DataFlow::Node).toString() } + + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + this.(DataFlow::Node).hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } +} diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll index 4c9c8e147eb..177c63f9d06 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll @@ -48,11 +48,13 @@ predicate parseTypeString(string rawType, string package, string qualifiedName) * Holds if models describing `package` may be relevant for the analysis of this database. */ predicate isPackageUsed(string package) { - exists(DataFlow::moduleImport(package)) - or package = "global" or - any(DataFlow::SourceNode sn).hasUnderlyingType(package, _) + package = any(JS::Import imp).getImportedPath().getValue() + or + any(JS::TypeName t).hasQualifiedName(package, _) + or + any(JS::TypeAnnotation t).hasQualifiedName(package, _) } bindingset[type] diff --git a/javascript/ql/lib/semmle/javascript/internal/CachedStages.qll b/javascript/ql/lib/semmle/javascript/internal/CachedStages.qll index 459b83f2b99..ce888e77537 100644 --- a/javascript/ql/lib/semmle/javascript/internal/CachedStages.qll +++ b/javascript/ql/lib/semmle/javascript/internal/CachedStages.qll @@ -106,6 +106,30 @@ module Stages { } } + /** + * The part of data flow computed before flow summary nodes. + */ + cached + module EarlyDataFlowStage { + /** + * Always holds. + * Ensures that a predicate is evaluated as part of the early DataFlow stage. + */ + cached + predicate ref() { 1 = 1 } + + /** + * DONT USE! + * Contains references to each predicate that use the above `ref` predicate. + */ + cached + predicate backref() { + 1 = 1 + or + DataFlow::localFlowStep(_, _) + } + } + /** * The `dataflow` stage. */ @@ -128,8 +152,6 @@ module Stages { or exists(AmdModule a) or - DataFlow::localFlowStep(_, _) - or exists(any(DataFlow::SourceNode s).getAPropertyReference("foo")) or exists(any(Expr e).getExceptionTarget()) From b499c6075ae83a2c1ab122705137e7a0f15f56d6 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Oct 2023 09:48:51 +0200 Subject: [PATCH 004/514] JS: Add Contents.qll --- .../javascript/dataflow/Configuration.qll | 6 + .../javascript/dataflow/internal/Contents.qll | 481 ++++++++++++++++++ 2 files changed, 487 insertions(+) create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index 179e1b4dfe5..7895a75de6e 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -766,6 +766,12 @@ module PseudoProperties { bindingset[key] string mapValueKey(string key) { result = pseudoProperty("mapValue", key) } + /** + * Holds if `prop` equals `mapValueKey(key)` for some value of `key`. + */ + bindingset[prop] + predicate isMapValueKey(string prop) { prop.matches("$mapValue|%$") } + /** * Gets a pseudo-property for the location of a map value where the key is `key`. */ diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll new file mode 100644 index 00000000000..55de1efc2d6 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll @@ -0,0 +1,481 @@ +private import javascript +private import semmle.javascript.frameworks.data.internal.AccessPathSyntax as AccessPathSyntax + +module Private { + import Public + + /** + * Gets the largest array index should be propagated precisely through flow summaries. + * + * Note that all known array indices have a corresponding singleton content, but some will + * be collapsed in flow summaries that operate on array elements. + */ + int getMaxPreciseArrayIndex() { result = 9 } + + /** Gets the largest array index should be propagated precisely through flow summaries. */ + int getAPreciseArrayIndex() { result = [0 .. getMaxPreciseArrayIndex()] } + + /** + * Holds if values associated with `key` should be tracked as a individual contents of a `Map` object. + */ + private predicate isKnownMapKey(string key) { + exists(MethodCallExpr call | + call.getMethodName() = "get" and + call.getNumArgument() = 1 and + call.getArgument(0).getStringValue() = key + ) + or + exists(AccessPathSyntax::AccessPathToken token | + token.getName() = "MapValue" and + token.getAnArgument() = key + ) + } + + /** + * A known property name. + */ + class PropertyName extends string { + // Note: unlike the similarly-named class in StepSummary.qll, this class must not depend on DataFlow::Node + PropertyName() { + this = any(PropAccess access).getPropertyName() + or + this = any(Property p).getName() + or + this = any(PropertyPattern p).getName() + or + this = any(GlobalVariable v).getName() + or + this = getAPreciseArrayIndex().toString() + or + exists(AccessPathSyntax::AccessPathToken tok | + tok.getName() = "Member" and this = tok.getAnArgument() + ) + } + + /** Gets the array index corresponding to this property name. */ + pragma[nomagic] + int asArrayIndex() { result = this.toInt() and result >= 0 and this = result.toString() } + } + + cached + newtype TContent = + MkPropertyContent(PropertyName name) or + MkArrayElementUnknown() or // note: array elements with known index are just properties + MkMapKey() or + MkMapValueWithUnknownKey() or + MkMapValueWithKnownKey(string key) { isKnownMapKey(key) } or + MkSetElement() or + MkIteratorElement() or + MkIteratorError() or + MkPromiseValue() or + MkPromiseError() or + MkCapturedContent(LocalVariable v) { v.isCaptured() } + + cached + newtype TContentSet = + MkSingletonContent(Content content) or + MkArrayElementKnown(int index) { index = any(PropertyName name).asArrayIndex() } or + MkArrayElementLowerBound(int index) { index = [0 .. getMaxPreciseArrayIndex() + 1] } or + MkMapValueKnown(string key) { isKnownMapKey(key) } or + MkMapValueAll() or + MkPromiseFilter() or + MkIteratorFilter() or + MkAnyProperty() or + // The following content sets are used exclusively as an intermediate value in flow summaries. + // These are encoded as a ContentSummaryComponent, although the flow graphs we generate are different + // than an ordinary content component. These special content sets should never appear in a step. + MkAwaited() or + MkAnyPropertyDeep() or + MkArrayElementDeep() + + /** + * Holds if `cs` is used to encode a special operation as a content component, but should not + * be treated as an ordinary content component. + */ + predicate isSpecialContentSet(ContentSet cs) { + cs = MkAwaited() or cs = MkAnyPropertyDeep() or cs = MkArrayElementDeep() + } +} + +module Public { + private import Private + + /** + * A storage location on an object, such as a property name. + */ + class Content extends TContent { + /** Gets a string representation of this content. */ + cached + string toString() { + // Note that these strings are visible to the end-user, in the access path of a PathNode. + result = this.asPropertyName() + or + this.isUnknownArrayElement() and + result = "ArrayElement" + or + this = MkMapKey() and + result = "MapKey" + or + this = MkMapValueWithUnknownKey() and + result = "MapValue" + or + exists(string key | + this = MkMapValueWithKnownKey(key) and + result = "MapValue[" + key + "]" + ) + or + this = MkSetElement() and + result = "SetElement" + or + this = MkIteratorElement() and + result = "IteratorElement" + or + this = MkIteratorError() and + result = "IteratorError" + or + this = MkPromiseValue() and + result = "PromiseValue" + or + this = MkPromiseError() and + result = "PromiseError" + or + result = this.asCapturedVariable().getName() + } + + /** Gets the property name represented by this content, if any. */ + string asPropertyName() { this = MkPropertyContent(result) } + + /** Gets the array index represented by this content, if any. */ + pragma[nomagic] + int asArrayIndex() { result = this.asPropertyName().(PropertyName).asArrayIndex() } + + /** Gets the captured variable represented by this content, if any. */ + LocalVariable asCapturedVariable() { this = MkCapturedContent(result) } + + /** Holds if this represents values stored at an unknown array index. */ + predicate isUnknownArrayElement() { this = MkArrayElementUnknown() } + + /** Holds if this represents values stored in a `Map` at an unknown key. */ + predicate isMapValueWithUnknownKey() { this = MkMapValueWithUnknownKey() } + + /** Holds if this represents values stored in a `Map` as the given string key. */ + predicate isMapValueWithKnownKey(string key) { this = MkMapValueWithKnownKey(key) } + } + + /** + * An entity that represents the set of `Content`s being accessed at a read or store operation. + */ + class ContentSet extends TContentSet { + /** Gets a content that may be stored into when storing into this set. */ + pragma[inline] + Content getAStoreContent() { + result = this.asSingleton() + or + // For array element access with known lower bound, just store into the unknown array element + this = ContentSet::arrayElementLowerBound(_) and + result.isUnknownArrayElement() + or + exists(int n | + this = ContentSet::arrayElementKnown(n) and + result.asArrayIndex() = n + ) + or + exists(string key | + this = ContentSet::mapValueWithKnownKey(key) and + result.isMapValueWithKnownKey(key) + ) + or + this = ContentSet::mapValueAll() and + result.isMapValueWithUnknownKey() + } + + /** Gets a content that may be read from when reading from this set. */ + pragma[nomagic] + Content getAReadContent() { + result = this.asSingleton() + or + this = ContentSet::promiseFilter() and + ( + result = MkPromiseValue() + or + result = MkPromiseError() + ) + or + this = ContentSet::iteratorFilter() and + ( + result = MkIteratorElement() + or + result = MkIteratorError() + ) + or + exists(int bound | this = ContentSet::arrayElementLowerBound(bound) | + result.isUnknownArrayElement() + or + result.asArrayIndex() >= bound + ) + or + exists(int n | this = ContentSet::arrayElementKnown(n) | + result.isUnknownArrayElement() + or + result.asArrayIndex() = n + ) + or + exists(string key | this = ContentSet::mapValueWithKnownKey(key) | + result.isMapValueWithUnknownKey() + or + result.isMapValueWithKnownKey(key) + ) + or + this = ContentSet::mapValueAll() and + ( + result.isMapValueWithUnknownKey() + or + result.isMapValueWithKnownKey(_) + ) + or + this = ContentSet::anyProperty() and + ( + result instanceof MkPropertyContent + or + result instanceof MkArrayElementUnknown + ) + } + + /** Gets the singleton content to be accessed. */ + Content asSingleton() { this = MkSingletonContent(result) } + + /** Gets the property name to be accessed. */ + PropertyName asPropertyName() { result = this.asSingleton().asPropertyName() } + + /** Gets the array index to be accessed. */ + int asArrayIndex() { result = this.asSingleton().asArrayIndex() } + + /** + * Gets a string representation of this content set. + */ + string toString() { + result = this.asSingleton().toString() + or + this = ContentSet::promiseFilter() and result = "PromiseFilter" + or + this = ContentSet::iteratorFilter() and result = "IteratorFilter" + or + exists(int bound | + this = ContentSet::arrayElementLowerBound(bound) and + result = "ArrayElement[" + bound + "..]" + ) + or + exists(int n | this = ContentSet::arrayElementKnown(n) and result = "ArrayElement[" + n + "]") + or + this = ContentSet::mapValueAll() and + result = "MapValue" + or + this = ContentSet::anyProperty() and + result = "AnyMember" + or + this = MkAwaited() and result = "Awaited (with coercion)" + or + this = MkAnyPropertyDeep() and result = "AnyMemberDeep" + or + this = MkArrayElementDeep() and result = "ArrayElementDeep" + } + } + + /** + * Companion module to the `ContentSet` class, providing access to various content sets. + */ + module ContentSet { + /** + * A content set containing only the given content. + */ + pragma[inline] + ContentSet singleton(Content content) { result.asSingleton() = content } + + /** + * A content set corresponding to the given property name. + */ + pragma[inline] + ContentSet property(PropertyName name) { result.asSingleton().asPropertyName() = name } + + /** + * A content set that should only be used in `withContent` and `withoutContent` steps, which + * matches the two promise-related contents, `Awaited[value]` and `Awaited[error]`. + */ + ContentSet promiseFilter() { result = MkPromiseFilter() } + + /** + * A content set that should only be used in `withContent` and `withoutContent` steps, which + * matches the two iterator-related contents, `IteratorElement` and `IteratorError`. + */ + ContentSet iteratorFilter() { result = MkIteratorFilter() } + + /** + * A content set describing the result of a resolved promise. + */ + ContentSet promiseValue() { result = singleton(MkPromiseValue()) } + + /** + * A content set describing the error stored in a rejected promise. + */ + ContentSet promiseError() { result = singleton(MkPromiseError()) } + + /** + * A content set describing all array elements, regardless of their index in the array. + */ + ContentSet arrayElement() { result = MkArrayElementLowerBound(0) } + + /** + * A content set describing array elements at index `bound` or greater. + * + * For `bound=0` this gets the same content set as `ContentSet::arrayElement()`, that is, + * the content set describing all array elements. + * + * For large values of `bound` this has no result - see `ContentSet::arrayElementLowerBoundFromInt`. + */ + ContentSet arrayElementLowerBound(int bound) { result = MkArrayElementLowerBound(bound) } + + /** + * A content set describing an access to array index `n`. + * + * This content set reads from element `n` and the unknown element, and stores to index `n`. + * + * For large values of `n` this has no result - see `ContentSet::arrayElementFromInt`. + */ + ContentSet arrayElementKnown(int n) { result = MkArrayElementKnown(n) } + + /** + * The singleton content set describing array elements stored at an unknown index. + */ + ContentSet arrayElementUnknown() { result = singleton(MkArrayElementUnknown()) } + + /** + * Gets a content set describing array elements at index `bound` or greater. + * + * If `bound` is too large, it is truncated to the greatest lower bound we can represent. + */ + bindingset[bound] + ContentSet arrayElementLowerBoundFromInt(int bound) { + result = arrayElementLowerBound(bound.minimum(getMaxPreciseArrayIndex() + 1)) + } + + /** + * Gets the content set describing an access to array index `n`. + * + * If `n` is too large, it is truncated to the greatest lower bound we can represent. + */ + bindingset[n] + ContentSet arrayElementFromInt(int n) { + result = arrayElementKnown(n) + or + not exists(arrayElementKnown(n)) and + result = arrayElementLowerBoundFromInt(n) + } + + /** Gets the content set describing the keys of a `Map` object. */ + ContentSet mapKey() { result = singleton(MkMapKey()) } + + /** Gets the content set describing the values of a `Map` object stored with an unknown key. */ + ContentSet mapValueWithUnknownKey() { result = singleton(MkMapValueWithUnknownKey()) } + + /** + * Gets the content set describing the value of a `Map` object stored with the given known `key`. + * + * This has no result if `key` is not one of the keys we track precisely. See also `mapValueFromKey`. + */ + ContentSet mapValueWithKnownKeyStrict(string key) { result = MkMapValueKnown(key) } + + /** + * Gets the content set describing an access to a map value with the given `key`. + * + * This content set also reads from a value stored with an unknown key. Use `mapValueWithKnownKeyStrict` to strictly + * refer to known keys. + * + * This has no result if `key` is not one of the keys we track precisely. See also `mapValueFromKey`. + */ + ContentSet mapValueWithKnownKey(string key) { result = singleton(MkMapValueWithKnownKey(key)) } + + /** Gets the content set describing all values in a map (with known or unknown key). */ + ContentSet mapValueAll() { result = MkMapValueAll() } + + /** + * Gets the content set describing the value in a `Map` object stored at the given `key`. + * + * If `key` is not one of the keys we track precisely, this is mapped to the unknown key instead. + */ + bindingset[key] + ContentSet mapValueFromKey(string key) { + result = mapValueWithKnownKey(key) + or + not exists(mapValueWithKnownKey(key)) and + result = mapValueWithUnknownKey() + } + + /** Gets the content set describing the elements of a `Set` object. */ + ContentSet setElement() { result = singleton(MkSetElement()) } + + /** Gets the content set describing the elements of an iterator object. */ + ContentSet iteratorElement() { result = singleton(MkIteratorElement()) } + + /** Gets the content set describing the exception to be thrown when attempting to iterate over the given value. */ + ContentSet iteratorError() { result = singleton(MkIteratorError()) } + + /** + * Gets a content set that reads from all ordinary properties. + * + * This includes array elements, but not the contents of `Map`, `Set`, `Promise`, or iterator objects. + * + * This content set has no effect if used in a store step. + */ + ContentSet anyProperty() { result = MkAnyProperty() } + + /** + * Gets a content set corresponding to the pseudo-property `propertyName`. + */ + pragma[nomagic] + private ContentSet fromLegacyPseudoProperty(string propertyName) { + propertyName = Promises::valueProp() and + result = promiseValue() + or + propertyName = Promises::errorProp() and + result = promiseError() + or + propertyName = DataFlow::PseudoProperties::arrayElement() and + result = arrayElement() + or + propertyName = DataFlow::PseudoProperties::iteratorElement() and + result = iteratorElement() + or + propertyName = DataFlow::PseudoProperties::setElement() and + result = setElement() + or + propertyName = DataFlow::PseudoProperties::mapValueAll() and + result = mapValueAll() + or + propertyName = DataFlow::PseudoProperties::mapValueUnknownKey() and + result = mapValueWithUnknownKey() + or + exists(string key | + propertyName = DataFlow::PseudoProperties::mapValueKey(key) and + result = mapValueWithKnownKey(key) + ) + } + + /** + * Gets the content set corresponding to the given property name, where legacy pseudo-properties + * are mapped to their corresponding content sets (which are no longer seen as property names). + */ + bindingset[propertyName] + ContentSet fromLegacyProperty(string propertyName) { + result = fromLegacyPseudoProperty(propertyName) + or + not exists(fromLegacyPseudoProperty(propertyName)) and + ( + // In case a map-value key was contributed via a SharedFlowStep, but we don't have a ContentSet for it, + // convert it to the unknown key. + if DataFlow::PseudoProperties::isMapValueKey(propertyName) + then result = mapValueWithUnknownKey() + else result = property(propertyName) + ) + } + } +} From 21300eef4ca63925e62af8d0f2e3e78dcff37ace Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Oct 2023 09:51:13 +0200 Subject: [PATCH 005/514] JS:Add ConstructorThisArgumentNode --- .../semmle/javascript/dataflow/DataFlow.qll | 18 ++++++++++++++++++ .../dataflow/internal/DataFlowNode.qll | 1 + 2 files changed, 19 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index 8c2376ee856..b86a424697d 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -1055,6 +1055,24 @@ module DataFlow { override string toString() { result = "global access path" } } + /** + * A node representing the value passed as `this` argument in a `new` call or a `super` call. + */ + class ConstructorThisArgumentNode extends TConstructorThisArgumentNode, DataFlow::Node { + private InvokeExpr expr; + + ConstructorThisArgumentNode() { this = TConstructorThisArgumentNode(expr) } + + override string toString() { result = "implicit 'this' argument of " + expr } + + override StmtContainer getContainer() { result = expr.getContainer() } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + expr.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } + } /** * INTERNAL. DO NOT USE. * diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index fc707959086..7cc1088ba27 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -34,6 +34,7 @@ private module Cached { TGlobalAccessPathRoot() or TTemplatePlaceholderTag(Templating::TemplatePlaceholderTag tag) or TReflectiveParametersNode(Function f) or + TConstructorThisArgumentNode(InvokeExpr e) { e instanceof NewExpr or e instanceof SuperCall } or } import Cached From 01952f17bff7e3b21e968c11f611497f8dfa103d Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Oct 2023 09:52:09 +0200 Subject: [PATCH 006/514] JS: Add some missing getContainer() predicates --- .../lib/semmle/javascript/dataflow/DataFlow.qll | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index b86a424697d..b2593781787 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -765,6 +765,8 @@ module DataFlow { override Node getRhs() { result = TValueNode(prop.getParameter()) } override ControlFlowNode getWriteNode() { result = prop.getParameter() } + + override StmtContainer getContainer() { parameter_fields(prop, result, _) } } /** @@ -962,6 +964,12 @@ module DataFlow { override BasicBlock getBasicBlock() { result = function.getExit().getBasicBlock() } + override StmtContainer getContainer() { + // Override this to ensure a container exists even for unreachable returns, + // since an unreachable exit CFG node will not have a basic block + result = function + } + /** * Gets the function corresponding to this exceptional return node. */ @@ -988,6 +996,12 @@ module DataFlow { override BasicBlock getBasicBlock() { result = function.getExit().getBasicBlock() } + override StmtContainer getContainer() { + // Override this to ensure a container exists even for unreachable returns, + // since an unreachable exit CFG node will not have a basic block + result = function + } + /** * Gets the function corresponding to this return node. */ @@ -1386,6 +1400,8 @@ module DataFlow { } override string toString() { result = this.getTag().toString() } + + override StmtContainer getContainer() { result = this.getTag().getInnerTopLevel() } } /** From c839822eb9496955ab904ccffda59196ae3b8fa1 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Oct 2023 10:25:26 +0200 Subject: [PATCH 007/514] JS: Add PostUpdateNode --- .../semmle/javascript/dataflow/DataFlow.qll | 65 +++++++++++++++++++ .../dataflow/internal/DataFlowNode.qll | 12 ++++ .../dataflow/internal/DataFlowPrivate.qll | 29 +++++++++ 3 files changed, 106 insertions(+) create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index b2593781787..11fdc25e6f6 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -25,6 +25,7 @@ private import internal.DataFlowNode private import internal.AnalyzedParameters private import internal.PreCallGraphStep private import semmle.javascript.internal.CachedStages +private import semmle.javascript.dataflow.internal.DataFlowPrivate as Private module DataFlow { /** @@ -247,6 +248,11 @@ module DataFlow { or this.getFallbackTypeAnnotation().getAnUnderlyingType().hasQualifiedName(moduleName, typeName) } + + /** + * Gets the post-update node corresponding to this node, if any. + */ + final PostUpdateNode getPostUpdateNode() { result.getPreUpdateNode() = this } } /** @@ -1087,6 +1093,28 @@ module DataFlow { expr.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) } } + + /** + * A node representing the post-update node corresponding to implicit uses of `this` in a constructor. + */ + private class ConstructorThisPostUpdateNode extends TConstructorThisPostUpdate, DataFlow::Node { + private Function constructor; + + ConstructorThisPostUpdateNode() { this = TConstructorThisPostUpdate(constructor) } + + override string toString() { result = "[post-update] 'this' parameter of " + constructor } + + override StmtContainer getContainer() { result = constructor } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + constructor + .getLocation() + .hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } + } + /** * INTERNAL. DO NOT USE. * @@ -1404,6 +1432,43 @@ module DataFlow { override StmtContainer getContainer() { result = this.getTag().getInnerTopLevel() } } + /** + * A post-update node whose pre-node corresponds to an expression. See `DataFlow::PostUpdateNode` for more details. + */ + class ExprPostUpdateNode extends DataFlow::Node, TExprPostUpdateNode, Private::PostUpdateNode { + private AST::ValueNode expr; + + ExprPostUpdateNode() { this = TExprPostUpdateNode(expr) } + + /** Gets the expression for which this is the post-update node. */ + AST::ValueNode getExpr() { result = expr } + + override StmtContainer getContainer() { result = expr.getContainer() } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + expr.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } + + override string toString() { result = "[post update] " + expr.toString() } + } + + /** + * A post-update node. + * + * This is a data-flow node that represents the new state of an object after its contents have been mutated. + * Most notably such nodes exist for arguments to a call and for the base of a property reference. + */ + class PostUpdateNode extends DataFlow::Node { + PostUpdateNode() { Private::postUpdatePair(_, this) } + + /** + * Gets the corresponding pre-update node, which is usually the argument to a call or the base of a property reference. + */ + final DataFlow::Node getPreUpdateNode() { Private::postUpdatePair(result, this) } + } + /** * INTERNAL. DO NOT USE. * diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index 7cc1088ba27..8f54d3a3496 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -34,7 +34,19 @@ private module Cached { TGlobalAccessPathRoot() or TTemplatePlaceholderTag(Templating::TemplatePlaceholderTag tag) or TReflectiveParametersNode(Function f) or + TExprPostUpdateNode(AST::ValueNode e) { + e = any(InvokeExpr invoke).getAnArgument() or + e = any(PropAccess access).getBase() or + e = any(DestructuringPattern pattern) or + e = any(InvokeExpr invoke).getCallee() or + // We have read steps out of the await operand, so it technically needs a post-update + e = any(AwaitExpr a).getOperand() or + e = any(Function f) or // functions are passed as their own self-reference argument + // RHS of a setter call is an argument, so it needs a post-update node + e = any(Assignment asn | asn.getTarget() instanceof PropAccess).getRhs() + } or TConstructorThisArgumentNode(InvokeExpr e) { e instanceof NewExpr or e instanceof SuperCall } or + TConstructorThisPostUpdate(Constructor ctor) or } import Cached diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll new file mode 100644 index 00000000000..f0f1883468a --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -0,0 +1,29 @@ +private import javascript +private import semmle.javascript.dataflow.internal.DataFlowNode + +class Node = DataFlow::Node; + +class PostUpdateNode = DataFlow::PostUpdateNode; + +cached +predicate postUpdatePair(Node pre, Node post) { + exists(AST::ValueNode expr | + pre = TValueNode(expr) and + post = TExprPostUpdateNode(expr) + ) + or + exists(NewExpr expr | + pre = TConstructorThisArgumentNode(expr) and + post = TValueNode(expr) + ) + or + exists(SuperCall expr | + pre = TConstructorThisArgumentNode(expr) and + post = TConstructorThisPostUpdate(expr.getBinder()) + ) + or + exists(Function constructor | + pre = TThisNode(constructor) and + post = TConstructorThisPostUpdate(constructor) + ) +} From 3455463e7133bb97db86fac9e976bfc043550bba Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Oct 2023 10:06:02 +0200 Subject: [PATCH 008/514] JS: Add instantiation boilerplate Note that this commit won't compile on its own, but putting the boilerplate in its own commit --- javascript/ql/lib/qlpack.yml | 1 + .../dataflow/internal/sharedlib/DataFlow.qll | 4 ++++ .../internal/sharedlib/DataFlowArg.qll | 19 +++++++++++++++++++ .../internal/sharedlib/DataFlowImpl.qll | 3 +++ .../internal/sharedlib/DataFlowImplCommon.qll | 3 +++ .../internal/sharedlib/TaintTracking.qll | 3 +++ 6 files changed, 33 insertions(+) create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlow.qll create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImpl.qll create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImplCommon.qll create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/TaintTracking.qll diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 2b5b69eccf9..6a98353c6cc 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -11,6 +11,7 @@ dependencies: codeql/tutorial: ${workspace} codeql/util: ${workspace} codeql/yaml: ${workspace} + codeql/dataflow: ${workspace} dataExtensions: - semmle/javascript/frameworks/**/model.yml warnOnImplicitThis: true diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlow.qll new file mode 100644 index 00000000000..fda541f1d31 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlow.qll @@ -0,0 +1,4 @@ +private import codeql.dataflow.DataFlow +private import DataFlowArg +import DataFlowMake +import DataFlowImplSpecific::Public diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll new file mode 100644 index 00000000000..6422dca52dd --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll @@ -0,0 +1,19 @@ +private import DataFlowImplSpecific +private import codeql.dataflow.DataFlow as SharedDataFlow +private import codeql.dataflow.TaintTracking as SharedTaintTracking + +module JSDataFlow implements SharedDataFlow::InputSig { + import Private + import Public + + // Explicitly implement signature members that have a default + predicate typeStrongerThan = Private::typeStrongerThan/2; + + predicate neverSkipInPathGraph = Private::neverSkipInPathGraph/1; + + predicate accessPathLimit = Private::accessPathLimit/0; +} + +module JSTaintFlow implements SharedTaintTracking::InputSig { + import semmle.javascript.dataflow.internal.TaintTrackingPrivate +} diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImpl.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImpl.qll new file mode 100644 index 00000000000..1b888d53859 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImpl.qll @@ -0,0 +1,3 @@ +private import codeql.dataflow.internal.DataFlowImpl +private import DataFlowArg +import MakeImpl diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImplCommon.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImplCommon.qll new file mode 100644 index 00000000000..8db21ff168f --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImplCommon.qll @@ -0,0 +1,3 @@ +private import DataFlowArg +private import codeql.dataflow.internal.DataFlowImplCommon +import MakeImplCommon diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/TaintTracking.qll new file mode 100644 index 00000000000..d5f3604202a --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/TaintTracking.qll @@ -0,0 +1,3 @@ +private import codeql.dataflow.TaintTracking +private import DataFlowArg +import TaintFlowMake From 760873c01c4eda6f2ff0ed3534f0a584e1247c76 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 9 Oct 2023 10:18:19 +0200 Subject: [PATCH 009/514] JS: Basic instantiation of shared library --- .../javascript/dataflow/Configuration.qll | 6 +- .../dataflow/internal/DataFlowPrivate.qll | 553 +++++++++++++++++- .../internal/TaintTrackingPrivate.qll | 25 + 3 files changed, 582 insertions(+), 2 deletions(-) create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index 7895a75de6e..414fc3be72c 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -1861,7 +1861,11 @@ class MidPathNode extends PathNode, MkMidNode { * Holds if this node is hidden from paths in path explanation queries, except * in cases where it is the source or sink. */ - predicate isHidden() { + predicate isHidden() { PathNode::shouldNodeBeHidden(nd) } +} + +module PathNode { + predicate shouldNodeBeHidden(DataFlow::Node nd) { // Skip phi, refinement, and capture nodes nd.(DataFlow::SsaDefinitionNode).getSsaVariable().getDefinition() instanceof SsaImplicitDefinition diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index f0f1883468a..25d4af88ffa 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1,10 +1,70 @@ private import javascript +private import semmle.javascript.dataflow.internal.CallGraphs private import semmle.javascript.dataflow.internal.DataFlowNode +private import semmle.javascript.dataflow.internal.FlowSteps as FlowSteps +private import semmle.javascript.dataflow.internal.Contents::Private +private import semmle.javascript.dataflow.internal.VariableCapture +private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon -class Node = DataFlow::Node; +private class Node = DataFlow::Node; class PostUpdateNode = DataFlow::PostUpdateNode; +cached +newtype TReturnKind = + MkNormalReturnKind() or + MkExceptionalReturnKind() + +class ReturnKind extends TReturnKind { + string toString() { + this = MkNormalReturnKind() and result = "return" + or + this = MkExceptionalReturnKind() and result = "exception" + } +} + +private predicate returnNodeImpl(DataFlow::Node node, ReturnKind kind) { + node instanceof TFunctionReturnNode and kind = MkNormalReturnKind() + or + exists(Function fun | + node = TExceptionalFunctionReturnNode(fun) and + kind = MkExceptionalReturnKind() and + // For async/generators, the exception is caught and wrapped in the returned promise/iterator object. + // See the models for AsyncAwait and Generator. + not fun.isAsyncOrGenerator() + ) +} + +private DataFlow::Node getAnOutNodeImpl(DataFlowCall call, ReturnKind kind) { + kind = MkNormalReturnKind() and result = call.asOrdinaryCall() + or + kind = MkExceptionalReturnKind() and result = call.asOrdinaryCall().getExceptionalReturn() + or + kind = MkNormalReturnKind() and result = call.asBoundCall(_) + or + kind = MkExceptionalReturnKind() and result = call.asBoundCall(_).getExceptionalReturn() + or + kind = MkNormalReturnKind() and result = call.asAccessorCall().(DataFlow::PropRead) +} + +class ReturnNode extends DataFlow::Node { + ReturnNode() { returnNodeImpl(this, _) } + + ReturnKind getKind() { returnNodeImpl(this, result) } +} + +/** A node that receives an output from a call. */ +class OutNode extends DataFlow::Node { + OutNode() { this = getAnOutNodeImpl(_, _) } +} + +OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) { result = getAnOutNodeImpl(call, kind) } + +/** + * Base class for classes that should be empty. + */ +abstract private class EmptyType extends DataFlow::Node { } + cached predicate postUpdatePair(Node pre, Node post) { exists(AST::ValueNode expr | @@ -27,3 +87,494 @@ predicate postUpdatePair(Node pre, Node post) { post = TConstructorThisPostUpdate(constructor) ) } + +class CastNode extends DataFlow::Node instanceof EmptyType { } + +cached +newtype TDataFlowCallable = + MkSourceCallable(StmtContainer container) or + +/** + * A callable entity. This is a wrapper around either a `StmtContainer` or a `LibraryCallable`. + */ +class DataFlowCallable extends TDataFlowCallable { + /** Gets a string representation of this callable. */ + string toString() { + result = this.asSourceCallable().toString() + or + result = this.asLibraryCallable() + } + + /** Gets the location of this callable, if it is present in the source code. */ + Location getLocation() { result = this.asSourceCallable().getLocation() } + + /** Gets the corresponding `StmtContainer` if this is a source callable. */ + StmtContainer asSourceCallable() { this = MkSourceCallable(result) } + + /** Gets the corresponding `StmtContainer` if this is a source callable. */ + pragma[nomagic] + StmtContainer asSourceCallableNotExterns() { + this = MkSourceCallable(result) and + not result.inExternsFile() + } + + /** Gets the corresponding `LibraryCallable` if this is a library callable. */ + LibraryCallable asLibraryCallable() { this = MkLibraryCallable(result) } +} + +private predicate isParameterNodeImpl(Node p, DataFlowCallable c, ParameterPosition pos) { + p = c.asSourceCallable().(Function).getParameter(pos.asPositional()).flow() + or + pos.isThis() and p = TThisNode(c.asSourceCallable().(Function)) + or + pos.isFunctionSelfReference() and p = TFunctionSelfReferenceNode(c.asSourceCallable()) + or + pos.isArgumentsArray() and p = TReflectiveParametersNode(c.asSourceCallable()) +} + +predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) { + isParameterNodeImpl(p, c, pos) +} + +private predicate isArgumentNodeImpl(Node n, DataFlowCall call, ArgumentPosition pos) { + n = call.asOrdinaryCall().getArgument(pos.asPositional()) + or + pos.isThis() and n = call.asOrdinaryCall().(DataFlow::CallNode).getReceiver() + or + exists(DataFlow::PartialInvokeNode invoke, DataFlow::Node callback | + call = MkPartialCall(invoke, callback) and + invoke.isPartialArgument(callback, n, pos.asPositional()) + ) + or + pos.isThis() and n = call.asPartialCall().getBoundReceiver() + or + exists(int boundArgs | + n = call.asBoundCall(boundArgs).getArgument(pos.asPositional() - boundArgs) + ) + or + pos.isThis() and n = TConstructorThisArgumentNode(call.asOrdinaryCall().asExpr()) + or + // For now, treat all spread argument as flowing into the 'arguments' array, regardless of preceding arguments + n = call.asOrdinaryCall().getASpreadArgument() and + pos.isArgumentsArray() + or + // receiver of accessor call + pos.isThis() and n = call.asAccessorCall().getBase() + or + // argument to setter (TODO: this has no post-update node) + pos.asPositional() = 0 and n = call.asAccessorCall().(DataFlow::PropWrite).getRhs() +} + +predicate isArgumentNode(ArgumentNode n, DataFlowCall call, ArgumentPosition pos) { + isArgumentNodeImpl(n, call, pos) +} + +DataFlowCallable nodeGetEnclosingCallable(Node node) { + result.asSourceCallable() = node.getContainer() +} + +private newtype TDataFlowType = + TTodoDataFlowType() or + TTodoDataFlowType2() // Add a dummy value to prevent bad functionality-induced joins arising from a type of size 1. + +class DataFlowType extends TDataFlowType { + string toString() { result = "" } +} + +predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() } + +DataFlowType getNodeType(Node node) { result = TTodoDataFlowType() and exists(node) } + +predicate nodeIsHidden(Node node) { + DataFlow::PathNode::shouldNodeBeHidden(node) +} + +predicate neverSkipInPathGraph(Node node) { + // Include the left-hand side of assignments + node = DataFlow::lvalueNode(_) + or + // Include the return-value expression + node.asExpr() = any(Function f).getAReturnedExpr() + or + // Include calls (which may have been modelled as steps) + node.asExpr() instanceof InvokeExpr + or + // Include references to a variable + node.asExpr() instanceof VarRef +} + +string ppReprType(DataFlowType t) { none() } + +pragma[inline] +predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { any() } + +predicate forceHighPrecision(Content c) { none() } + +class ContentApprox = Unit; + +pragma[inline] +ContentApprox getContentApprox(Content c) { exists(result) and exists(c) } + +cached +private newtype TDataFlowCall = + MkOrdinaryCall(DataFlow::InvokeNode node) or + MkPartialCall(DataFlow::PartialInvokeNode node, DataFlow::Node callback) { + callback = node.getACallbackNode() + } or + MkBoundCall(DataFlow::InvokeNode node, int boundArgs) { + FlowSteps::callsBound(node, _, boundArgs) + } or + MkAccessorCall(DataFlow::PropRef node) { + // Some PropRefs can't result in an accessor call, such as Object.defineProperty. + // Restrict to PropRefs that can result in an accessor call. + node = TValueNode(any(PropAccess p)) or + node = TPropNode(any(PropertyPattern p)) + } or + +class DataFlowCall extends TDataFlowCall { + DataFlowCallable getEnclosingCallable() { none() } // Overridden in subclass + + string toString() { none() } // Overridden in subclass + + DataFlow::InvokeNode asOrdinaryCall() { this = MkOrdinaryCall(result) } + + DataFlow::PropRef asAccessorCall() { this = MkAccessorCall(result) } + + DataFlow::PartialInvokeNode asPartialCall() { this = MkPartialCall(result, _) } + + DataFlow::InvokeNode asBoundCall(int boundArgs) { this = MkBoundCall(result, boundArgs) } + + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + none() // Overridden in subclass + } +} + +private class OrdinaryCall extends DataFlowCall, MkOrdinaryCall { + private DataFlow::InvokeNode node; + + OrdinaryCall() { this = MkOrdinaryCall(node) } + + DataFlow::InvokeNode getNode() { result = node } + + override DataFlowCallable getEnclosingCallable() { + result.asSourceCallable() = node.getContainer() + } + + override string toString() { result = node.toString() } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + node.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } +} + +private class PartialCall extends DataFlowCall, MkPartialCall { + private DataFlow::PartialInvokeNode node; + private DataFlow::Node callback; + + PartialCall() { this = MkPartialCall(node, callback) } + + DataFlow::PartialInvokeNode getNode() { result = node } + + DataFlow::Node getCallback() { result = callback } + + override DataFlowCallable getEnclosingCallable() { + result.asSourceCallable() = node.getContainer() + } + + override string toString() { result = node.toString() + " (as partial invocation)" } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + node.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } +} + +private class BoundCall extends DataFlowCall, MkBoundCall { + private DataFlow::InvokeNode node; + private int boundArgs; + + BoundCall() { this = MkBoundCall(node, boundArgs) } + + override DataFlowCallable getEnclosingCallable() { + result.asSourceCallable() = node.getContainer() + } + + override string toString() { + result = node.toString() + " (as call with " + boundArgs + " bound arguments)" + } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + node.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } +} + +private class AccessorCall extends DataFlowCall, MkAccessorCall { + private DataFlow::PropRef ref; + + AccessorCall() { this = MkAccessorCall(ref) } + + override DataFlowCallable getEnclosingCallable() { + result.asSourceCallable() = ref.getContainer() + } + + override string toString() { result = ref.toString() + " (as accessor call)" } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + ref.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } +} + +private int getMaxArity() { + // TODO: account for flow summaries + result = + max(int n | + n = any(InvokeExpr e).getNumArgument() or + n = any(Function f).getNumParameter() or + n = 10 + ) +} + +cached +newtype TParameterPosition = + MkPositionalParameter(int n) { n = [0 .. getMaxArity()] } or + MkPositionalLowerBound(int n) { n = [0 .. getMaxArity()] } or + MkThisParameter() or + MkArgumentsArrayParameter() + +class ParameterPosition extends TParameterPosition { + predicate isPositionalExact() { this instanceof MkPositionalParameter } + + predicate isPositionalLowerBound() { this instanceof MkPositionalLowerBound } + + predicate isPositionalLike() { this.isPositionalExact() or this.isPositionalLowerBound() } + + int asPositional() { this = MkPositionalParameter(result) } + + int asPositionalLowerBound() { this = MkPositionalLowerBound(result) } + + predicate isThis() { this = MkThisParameter() } + + predicate isArgumentsArray() { this = MkArgumentsArrayParameter() } + + string toString() { + result = this.asPositional().toString() + or + result = this.asPositionalLowerBound().toString() + ".." + or + this.isThis() and result = "this" + or + this.isArgumentsArray() and result = "arguments-array" + } +} + +class ArgumentPosition extends ParameterPosition { } + +class DataFlowExpr = Expr; + +Node exprNode(DataFlowExpr expr) { result = DataFlow::exprNode(expr) } + +pragma[nomagic] +predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { + ppos = apos + or + apos.asPositional() >= ppos.asPositionalLowerBound() + or + ppos.asPositional() >= apos.asPositionalLowerBound() + // + // Note: for now, there is no need to match lower bounds agaist lower bounds since we + // are only using these in cases where either the call or callee is generated by a flow summary. +} + +pragma[inline] +DataFlowCallable viableCallable(DataFlowCall node) { + // Note: we never include call edges externs here, as it negatively affects the field-flow branch limit, + // particularly when the call can also target a flow summary. + result.asSourceCallableNotExterns() = node.asOrdinaryCall().getACallee() + or + result.asSourceCallableNotExterns() = + node.(PartialCall).getCallback().getAFunctionValue().getFunction() + or + exists(DataFlow::InvokeNode invoke, int boundArgs | + invoke = node.asBoundCall(boundArgs) and + FlowSteps::callsBound(invoke, result.asSourceCallableNotExterns(), boundArgs) + ) + or + result.asSourceCallableNotExterns() = node.asAccessorCall().getAnAccessorCallee().getFunction() +} + +/** + * Holds if the set of viable implementations that can be called by `call` + * might be improved by knowing the call context. + */ +predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c) { none() } + +/** + * Gets a viable dispatch target of `call` in the context `ctx`. This is + * restricted to those `call`s for which a context might make a difference. + */ +DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { none() } + +bindingset[node1, node2] +pragma[inline_late] +private predicate sameContainer(Node node1, Node node2) { + node1.getContainer() = node2.getContainer() +} + +bindingset[node, fun] +pragma[inline_late] +private predicate sameContainerAsEnclosingContainer(Node node, Function fun) { + node.getContainer() = fun.getEnclosingContainer() +} + +/** + * Holds if there is a value-preserving steps `node1` -> `node2` that might + * be cross function boundaries. + */ +private predicate valuePreservingStep(Node node1, Node node2) { + node1.getASuccessor() = node2 and + or + FlowSteps::propertyFlowStep(node1, node2) + or + FlowSteps::globalFlowStep(node1, node2) + or + node2 = FlowSteps::getThrowTarget(node1) + or + // Step from post-update nodes to local sources of the pre-update node. This emulates how JS usually tracks side effects. + exists(PostUpdateNode postUpdate | + node1 = postUpdate and + node2 = postUpdate.getPreUpdateNode().getALocalSource() and + node1 != node2 and // exclude trivial edges + sameContainer(node1, node2) + ) +} + +predicate simpleLocalFlowStep(Node node1, Node node2) { + valuePreservingStep(node1, node2) and + nodeGetEnclosingCallable(pragma[only_bind_out](node1)) = + nodeGetEnclosingCallable(pragma[only_bind_out](node2)) +} + +predicate localMustFlowStep(Node node1, Node node2) { node1 = node2.getImmediatePredecessor() } + +/** + * Holds if data can flow from `node1` to `node2` through a non-local step + * that does not follow a call edge. For example, a step through a global + * variable. + */ +predicate jumpStep(Node node1, Node node2) { + valuePreservingStep(node1, node2) and + node1.getContainer() != node2.getContainer() +} + +/** + * Holds if data can flow from `node1` to `node2` via a read of `c`. Thus, + * `node1` references an object with a content `c.getAReadContent()` whose + * value ends up in `node2`. + */ +predicate readStep(Node node1, ContentSet c, Node node2) { + exists(DataFlow::PropRead read | + node1 = read.getBase() and + node2 = read + | + c.asPropertyName() = read.getPropertyName() + or + not exists(read.getPropertyName()) and + c = ContentSet::arrayElement() + ) +} + +/** Gets the post-update node for which `node` is the corresponding pre-update node. */ +private Node getPostUpdate(Node node) { result.(PostUpdateNode).getPreUpdateNode() = node } + +/** Gets the post-update node for which node is the pre-update node, if one exists, otherwise gets `node` itself. */ +pragma[inline] +private Node tryGetPostUpdate(Node node) { + result = getPostUpdate(node) + or + not exists(getPostUpdate(node)) and + result = node +} + +/** + * Holds if data can flow from `node1` to `node2` via a store into `c`. Thus, + * `node2` references an object with a content `c.getAStoreContent()` that + * contains the value of `node1`. + */ +predicate storeStep(Node node1, ContentSet c, Node node2) { + exists(DataFlow::PropWrite write | + node1 = write.getRhs() and + c.asPropertyName() = write.getPropertyName() and + // Target the post-update node if one exists (for object literals we do not generate post-update nodes) + node2 = tryGetPostUpdate(write.getBase()) + ) +} + +/** + * Holds if values stored inside content `c` are cleared at node `n`. For example, + * any value stored inside `f` is cleared at the pre-update node associated with `x` + * in `x.f = newValue`. + */ +predicate clearsContent(Node n, ContentSet c) { +} + +/** + * Holds if the value that is being tracked is expected to be stored inside content `c` + * at node `n`. + */ +predicate expectsContent(Node n, ContentSet c) { +} + +/** + * Holds if the node `n` is unreachable when the call context is `call`. + */ +predicate isUnreachableInCall(Node n, DataFlowCall call) { + none() // TODO: could be useful, but not currently implemented for JS +} + +int accessPathLimit() { result = 5 } + +/** + * Holds if flow is allowed to pass from parameter `p` and back to itself as a + * side-effect, resulting in a summary from `p` to itself. + * + * One example would be to allow flow like `p.foo = p.bar;`, which is disallowed + * by default as a heuristic. + */ +predicate allowParameterReturnInSelf(ParameterNode p) { +} + +class LambdaCallKind = Unit; + +/** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */ +predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) { + creation.(DataFlow::FunctionNode).getFunction() = c.asSourceCallable() and exists(kind) +} + +/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */ +predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { + receiver = call.asOrdinaryCall().getCalleeNode() and exists(kind) +} + +/** Extra data-flow steps needed for lambda flow analysis. */ +predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() } + +class ArgumentNode extends DataFlow::Node { + ArgumentNode() { isArgumentNodeImpl(this, _, _) } + + predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { + isArgumentNodeImpl(this, call, pos) + } +} + +class ParameterNode extends DataFlow::Node { + ParameterNode() { isParameterNodeImpl(this, _, _) } +} diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll new file mode 100644 index 00000000000..42c06d318f0 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -0,0 +1,25 @@ +private import javascript +private import semmle.javascript.dataflow.internal.DataFlowPrivate +private import semmle.javascript.dataflow.internal.Contents::Public + +cached +predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { +} + +/** + * Holds if `node` should be a sanitizer in all global taint flow configurations + * but not in local taint. + */ +cached +predicate defaultTaintSanitizer(DataFlow::Node node) { + node instanceof DataFlow::VarAccessBarrier or +} +/** + * Holds if default taint-tracking should allow implicit reads + * of `c` at sinks and inputs to additional taint steps. + */ +bindingset[node] +predicate defaultImplicitTaintRead(DataFlow::Node node, ContentSet c) { + exists(node) and + c = ContentSet::promiseValue() +} From f316da78d2dd86e3d99cd4facdd473bc0cf4533f Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Oct 2023 10:25:36 +0200 Subject: [PATCH 010/514] JS: Add FunctionSelfReferenceNode --- .../javascript/dataflow/Configuration.qll | 2 ++ .../semmle/javascript/dataflow/DataFlow.qll | 24 +++++++++++++++++++ .../dataflow/internal/DataFlowNode.qll | 1 + .../dataflow/internal/DataFlowPrivate.qll | 7 ++++++ 4 files changed, 34 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index 414fc3be72c..d0087dcdca0 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -1888,6 +1888,8 @@ module PathNode { or // Skip captured variable nodes as the successor will be a use of that variable anyway. nd = DataFlow::capturedVariableNode(_) + or + nd instanceof DataFlow::FunctionSelfReferenceNode } } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index 11fdc25e6f6..47fb26937cd 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -1432,6 +1432,30 @@ module DataFlow { override StmtContainer getContainer() { result = this.getTag().getInnerTopLevel() } } + /** + * A node representing the hidden parameter of a function by which a function can refer to itself. + */ + class FunctionSelfReferenceNode extends DataFlow::Node, TFunctionSelfReferenceNode { + private Function function; + + FunctionSelfReferenceNode() { this = TFunctionSelfReferenceNode(function) } + + /** Gets the function. */ + Function getFunction() { result = function } + + override StmtContainer getContainer() { result = function } + + override BasicBlock getBasicBlock() { result = function.getEntryBB() } + + override string toString() { result = "[function self-reference] " + function.toString() } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + function.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } + } + /** * A post-update node whose pre-node corresponds to an expression. See `DataFlow::PostUpdateNode` for more details. */ diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index 8f54d3a3496..bee7b1259b4 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -24,6 +24,7 @@ private module Cached { (kind = "call" or kind = "apply") } or TThisNode(StmtContainer f) { f.(Function).getThisBinder() = f or f instanceof TopLevel } or + TFunctionSelfReferenceNode(Function f) or TDestructuredModuleImportNode(ImportDeclaration decl) { exists(decl.getASpecifier().getImportedName()) } or diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 25d4af88ffa..9a9559e28db 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -152,6 +152,8 @@ private predicate isArgumentNodeImpl(Node n, DataFlowCall call, ArgumentPosition n = call.asBoundCall(boundArgs).getArgument(pos.asPositional() - boundArgs) ) or + pos.isFunctionSelfReference() and n = call.asOrdinaryCall().getCalleeNode() + or pos.isThis() and n = TConstructorThisArgumentNode(call.asOrdinaryCall().asExpr()) or // For now, treat all spread argument as flowing into the 'arguments' array, regardless of preceding arguments @@ -348,6 +350,7 @@ newtype TParameterPosition = MkPositionalParameter(int n) { n = [0 .. getMaxArity()] } or MkPositionalLowerBound(int n) { n = [0 .. getMaxArity()] } or MkThisParameter() or + MkFunctionSelfReferenceParameter() or MkArgumentsArrayParameter() class ParameterPosition extends TParameterPosition { @@ -363,6 +366,8 @@ class ParameterPosition extends TParameterPosition { predicate isThis() { this = MkThisParameter() } + predicate isFunctionSelfReference() { this = MkFunctionSelfReferenceParameter() } + predicate isArgumentsArray() { this = MkArgumentsArrayParameter() } string toString() { @@ -372,6 +377,8 @@ class ParameterPosition extends TParameterPosition { or this.isThis() and result = "this" or + this.isFunctionSelfReference() and result = "function" + or this.isArgumentsArray() and result = "arguments-array" } } From 8dc0800526a88c5a03a3758e01d38d813cb39c2e Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 19:51:41 +0200 Subject: [PATCH 011/514] JS: Add the shared FlowSummaryImpl.qll file --- config/identical-files.json | 3 +- .../internal/sharedlib/FlowSummaryImpl.qll | 1491 +++++++++++++++++ 2 files changed, 1493 insertions(+), 1 deletion(-) create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll diff --git a/config/identical-files.json b/config/identical-files.json index 144031d5a68..836b4c14f58 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -53,8 +53,9 @@ "ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", "swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll" ], - "DataFlow Java/C#/Go/Ruby/Python/Swift Flow Summaries": [ + "DataFlow Java/JS/C#/Go/Ruby/Python/Swift Flow Summaries": [ "java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll", + "javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll", "go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll", "ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll", diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll new file mode 100644 index 00000000000..0aa17c521b4 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll @@ -0,0 +1,1491 @@ +/** + * Provides classes and predicates for defining flow summaries. + * + * The definitions in this file are language-independent, and language-specific + * definitions are passed in via the `DataFlowImplSpecific` and + * `FlowSummaryImplSpecific` modules. + */ + +private import FlowSummaryImplSpecific +private import DataFlowImplSpecific::Private +private import DataFlowImplSpecific::Public +private import DataFlowImplCommon +private import codeql.util.Unit + +/** Provides classes and predicates for defining flow summaries. */ +module Public { + private import Private + + /** + * A component used in a flow summary. + * + * Either a parameter or an argument at a given position, a specific + * content type, or a return kind. + */ + class SummaryComponent extends TSummaryComponent { + /** Gets a textual representation of this component used for MaD models. */ + string getMadRepresentation() { + result = getMadRepresentationSpecific(this) + or + exists(ArgumentPosition pos | + this = TParameterSummaryComponent(pos) and + result = "Parameter[" + getArgumentPosition(pos) + "]" + ) + or + exists(ParameterPosition pos | + this = TArgumentSummaryComponent(pos) and + result = "Argument[" + getParameterPosition(pos) + "]" + ) + or + exists(string synthetic | + this = TSyntheticGlobalSummaryComponent(synthetic) and + result = "SyntheticGlobal[" + synthetic + "]" + ) + or + this = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" + } + + /** Gets a textual representation of this summary component. */ + string toString() { result = this.getMadRepresentation() } + } + + /** Provides predicates for constructing summary components. */ + module SummaryComponent { + /** Gets a summary component for content `c`. */ + SummaryComponent content(ContentSet c) { result = TContentSummaryComponent(c) } + + /** Gets a summary component where data is not allowed to be stored in `c`. */ + SummaryComponent withoutContent(ContentSet c) { result = TWithoutContentSummaryComponent(c) } + + /** Gets a summary component where data must be stored in `c`. */ + SummaryComponent withContent(ContentSet c) { result = TWithContentSummaryComponent(c) } + + /** Gets a summary component for a parameter at position `pos`. */ + SummaryComponent parameter(ArgumentPosition pos) { result = TParameterSummaryComponent(pos) } + + /** Gets a summary component for an argument at position `pos`. */ + SummaryComponent argument(ParameterPosition pos) { result = TArgumentSummaryComponent(pos) } + + /** Gets a summary component for a return of kind `rk`. */ + SummaryComponent return(ReturnKind rk) { result = TReturnSummaryComponent(rk) } + + /** Gets a summary component for synthetic global `sg`. */ + SummaryComponent syntheticGlobal(SyntheticGlobal sg) { + result = TSyntheticGlobalSummaryComponent(sg) + } + + /** + * A synthetic global. This represents some form of global state, which + * summaries can read and write individually. + */ + abstract class SyntheticGlobal extends string { + bindingset[this] + SyntheticGlobal() { any() } + } + } + + /** + * A (non-empty) stack of summary components. + * + * A stack is used to represent where data is read from (input) or where it + * is written to (output). For example, an input stack `[Field f, Argument 0]` + * means that data is read from field `f` from the `0`th argument, while an + * output stack `[Field g, Return]` means that data is written to the field + * `g` of the returned object. + */ + class SummaryComponentStack extends TSummaryComponentStack { + /** Gets the head of this stack. */ + SummaryComponent head() { + this = TSingletonSummaryComponentStack(result) or + this = TConsSummaryComponentStack(result, _) + } + + /** Gets the tail of this stack, if any. */ + SummaryComponentStack tail() { this = TConsSummaryComponentStack(_, result) } + + /** Gets the length of this stack. */ + int length() { + this = TSingletonSummaryComponentStack(_) and result = 1 + or + result = 1 + this.tail().length() + } + + /** Gets the stack obtained by dropping the first `i` elements, if any. */ + SummaryComponentStack drop(int i) { + i = 0 and result = this + or + result = this.tail().drop(i - 1) + } + + /** Holds if this stack contains summary component `c`. */ + predicate contains(SummaryComponent c) { c = this.drop(_).head() } + + /** Gets the bottom element of this stack. */ + SummaryComponent bottom() { + this = TSingletonSummaryComponentStack(result) or result = this.tail().bottom() + } + + /** Gets a textual representation of this stack used for MaD models. */ + string getMadRepresentation() { + exists(SummaryComponent head, SummaryComponentStack tail | + head = this.head() and + tail = this.tail() and + result = tail.getMadRepresentation() + "." + head.getMadRepresentation() + ) + or + exists(SummaryComponent c | + this = TSingletonSummaryComponentStack(c) and + result = c.getMadRepresentation() + ) + } + + /** Gets a textual representation of this stack. */ + string toString() { result = this.getMadRepresentation() } + } + + /** Provides predicates for constructing stacks of summary components. */ + module SummaryComponentStack { + /** Gets a singleton stack containing `c`. */ + SummaryComponentStack singleton(SummaryComponent c) { + result = TSingletonSummaryComponentStack(c) + } + + /** + * Gets the stack obtained by pushing `head` onto `tail`. + * + * Make sure to override `RequiredSummaryComponentStack::required()` in order + * to ensure that the constructed stack exists. + */ + SummaryComponentStack push(SummaryComponent head, SummaryComponentStack tail) { + result = TConsSummaryComponentStack(head, tail) + } + + /** Gets a singleton stack for an argument at position `pos`. */ + SummaryComponentStack argument(ParameterPosition pos) { + result = singleton(SummaryComponent::argument(pos)) + } + + /** Gets a singleton stack representing a return of kind `rk`. */ + SummaryComponentStack return(ReturnKind rk) { result = singleton(SummaryComponent::return(rk)) } + } + + /** + * A class that exists for QL technical reasons only (the IPA type used + * to represent component stacks needs to be bounded). + */ + class RequiredSummaryComponentStack extends Unit { + /** + * Holds if the stack obtained by pushing `head` onto `tail` is required. + */ + abstract predicate required(SummaryComponent head, SummaryComponentStack tail); + } + + /** + * Gets the valid model origin values. + */ + private string getValidModelOrigin() { + result = + [ + "ai", // AI (machine learning) + "df", // Dataflow (model generator) + "tb", // Type based (model generator) + "hq", // Heuristic query + ] + } + + /** + * A class used to represent provenance values for MaD models. + * + * The provenance value is a string of the form `origin-verification` + * (or just `manual`), where `origin` is a value indicating the + * origin of the model, and `verification` is a value indicating, how + * the model was verified. + * + * Examples could be: + * - `df-generated`: A model produced by the model generator, but not verified by a human. + * - `ai-manual`: A model produced by AI, but verified by a human. + */ + class Provenance extends string { + private string verification; + + Provenance() { + exists(string origin | origin = getValidModelOrigin() | + this = origin + "-" + verification and + verification = ["manual", "generated"] + ) + or + this = verification and verification = "manual" + } + + /** + * Holds if this is a valid generated provenance value. + */ + predicate isGenerated() { verification = "generated" } + + /** + * Holds if this is a valid manual provenance value. + */ + predicate isManual() { verification = "manual" } + } + + /** A callable with a flow summary. */ + abstract class SummarizedCallable extends SummarizedCallableBase { + bindingset[this] + SummarizedCallable() { any() } + + /** + * Holds if data may flow from `input` to `output` through this callable. + * + * `preservesValue` indicates whether this is a value-preserving step + * or a taint-step. + * + * Input specifications are restricted to stacks that end with + * `SummaryComponent::argument(_)`, preceded by zero or more + * `SummaryComponent::return(_)` or `SummaryComponent::content(_)` components. + * + * Output specifications are restricted to stacks that end with + * `SummaryComponent::return(_)` or `SummaryComponent::argument(_)`. + * + * Output stacks ending with `SummaryComponent::return(_)` can be preceded by zero + * or more `SummaryComponent::content(_)` components. + * + * Output stacks ending with `SummaryComponent::argument(_)` can be preceded by an + * optional `SummaryComponent::parameter(_)` component, which in turn can be preceded + * by zero or more `SummaryComponent::content(_)` components. + */ + pragma[nomagic] + predicate propagatesFlow( + SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue + ) { + none() + } + + /** + * Holds if there exists a generated summary that applies to this callable. + */ + final predicate hasGeneratedModel() { + exists(Provenance p | p.isGenerated() and this.hasProvenance(p)) + } + + /** + * Holds if all the summaries that apply to this callable are auto generated and not manually created. + * That is, only apply generated models, when there are no manual models. + */ + final predicate applyGeneratedModel() { + this.hasGeneratedModel() and + not this.hasManualModel() + } + + /** + * Holds if there exists a manual summary that applies to this callable. + */ + final predicate hasManualModel() { + exists(Provenance p | p.isManual() and this.hasProvenance(p)) + } + + /** + * Holds if there exists a manual summary that applies to this callable. + * Always apply manual models if they exist. + */ + final predicate applyManualModel() { this.hasManualModel() } + + /** + * Holds if there exists a summary that applies to this callable + * that has provenance `provenance`. + */ + predicate hasProvenance(Provenance provenance) { provenance = "manual" } + } + + /** + * A callable where there is no flow via the callable. + */ + class NeutralSummaryCallable extends NeutralCallable { + NeutralSummaryCallable() { this.getKind() = "summary" } + } + + /** + * A callable that has a neutral model. + */ + class NeutralCallable extends NeutralCallableBase { + private string kind; + private Provenance provenance; + + NeutralCallable() { neutralElement(this, kind, provenance) } + + /** + * Holds if the neutral is auto generated. + */ + final predicate hasGeneratedModel() { provenance.isGenerated() } + + /** + * Holds if there exists a manual neutral that applies to this callable. + */ + final predicate hasManualModel() { provenance.isManual() } + + /** + * Holds if the neutral has provenance `p`. + */ + predicate hasProvenance(Provenance p) { p = provenance } + + /** + * Gets the kind of the neutral. + */ + string getKind() { result = kind } + } +} + +/** + * Provides predicates for compiling flow summaries down to atomic local steps, + * read steps, and store steps. + */ +module Private { + private import Public + import AccessPathSyntax + + newtype TSummaryComponent = + TContentSummaryComponent(ContentSet c) or + TParameterSummaryComponent(ArgumentPosition pos) or + TArgumentSummaryComponent(ParameterPosition pos) or + TReturnSummaryComponent(ReturnKind rk) or + TSyntheticGlobalSummaryComponent(SummaryComponent::SyntheticGlobal sg) or + TWithoutContentSummaryComponent(ContentSet c) or + TWithContentSummaryComponent(ContentSet c) + + private TParameterSummaryComponent callbackSelfParam() { + result = TParameterSummaryComponent(callbackSelfParameterPosition()) + } + + newtype TSummaryComponentStack = + TSingletonSummaryComponentStack(SummaryComponent c) or + TConsSummaryComponentStack(SummaryComponent head, SummaryComponentStack tail) { + any(RequiredSummaryComponentStack x).required(head, tail) + or + any(RequiredSummaryComponentStack x).required(TParameterSummaryComponent(_), tail) and + head = callbackSelfParam() + or + derivedFluentFlowPush(_, _, _, head, tail, _) + } + + pragma[nomagic] + private predicate summary( + SummarizedCallable c, SummaryComponentStack input, SummaryComponentStack output, + boolean preservesValue + ) { + c.propagatesFlow(input, output, preservesValue) + or + // observe side effects of callbacks on input arguments + c.propagatesFlow(output, input, preservesValue) and + preservesValue = true and + isCallbackParameter(input) and + isContentOfArgument(output, _) + or + // flow from the receiver of a callback into the instance-parameter + exists(SummaryComponentStack s, SummaryComponentStack callbackRef | + c.propagatesFlow(s, _, _) or c.propagatesFlow(_, s, _) + | + callbackRef = s.drop(_) and + (isCallbackParameter(callbackRef) or callbackRef.head() = TReturnSummaryComponent(_)) and + input = callbackRef.tail() and + output = TConsSummaryComponentStack(callbackSelfParam(), input) and + preservesValue = true + ) + or + exists(SummaryComponentStack arg, SummaryComponentStack return | + derivedFluentFlow(c, input, arg, return, preservesValue) + | + arg.length() = 1 and + output = return + or + exists(SummaryComponent head, SummaryComponentStack tail | + derivedFluentFlowPush(c, input, arg, head, tail, 0) and + output = SummaryComponentStack::push(head, tail) + ) + ) + or + // Chain together summaries where values get passed into callbacks along the way + exists(SummaryComponentStack mid, boolean preservesValue1, boolean preservesValue2 | + c.propagatesFlow(input, mid, preservesValue1) and + c.propagatesFlow(mid, output, preservesValue2) and + mid.drop(mid.length() - 2) = + SummaryComponentStack::push(TParameterSummaryComponent(_), + SummaryComponentStack::singleton(TArgumentSummaryComponent(_))) and + preservesValue = preservesValue1.booleanAnd(preservesValue2) + ) + } + + /** + * Holds if `c` has a flow summary from `input` to `arg`, where `arg` + * writes to (contents of) arguments at position `pos`, and `c` has a + * value-preserving flow summary from the arguments at position `pos` + * to a return value (`return`). + * + * In such a case, we derive flow from `input` to (contents of) the return + * value. + * + * As an example, this simplifies modeling of fluent methods: + * for `StringBuilder.append(x)` with a specified value flow from qualifier to + * return value and taint flow from argument 0 to the qualifier, then this + * allows us to infer taint flow from argument 0 to the return value. + */ + pragma[nomagic] + private predicate derivedFluentFlow( + SummarizedCallable c, SummaryComponentStack input, SummaryComponentStack arg, + SummaryComponentStack return, boolean preservesValue + ) { + exists(ParameterPosition pos | + summary(c, input, arg, preservesValue) and + isContentOfArgument(arg, pos) and + summary(c, SummaryComponentStack::argument(pos), return, true) and + return.bottom() = TReturnSummaryComponent(_) + ) + } + + pragma[nomagic] + private predicate derivedFluentFlowPush( + SummarizedCallable c, SummaryComponentStack input, SummaryComponentStack arg, + SummaryComponent head, SummaryComponentStack tail, int i + ) { + derivedFluentFlow(c, input, arg, tail, _) and + head = arg.drop(i).head() and + i = arg.length() - 2 + or + exists(SummaryComponent head0, SummaryComponentStack tail0 | + derivedFluentFlowPush(c, input, arg, head0, tail0, i + 1) and + head = arg.drop(i).head() and + tail = SummaryComponentStack::push(head0, tail0) + ) + } + + private predicate isCallbackParameter(SummaryComponentStack s) { + s.head() = TParameterSummaryComponent(_) and exists(s.tail()) + } + + private predicate isContentOfArgument(SummaryComponentStack s, ParameterPosition pos) { + s.head() = TContentSummaryComponent(_) and isContentOfArgument(s.tail(), pos) + or + s = SummaryComponentStack::argument(pos) + } + + private predicate outputState(SummarizedCallable c, SummaryComponentStack s) { + summary(c, _, s, _) + or + exists(SummaryComponentStack out | + outputState(c, out) and + out.head() = TContentSummaryComponent(_) and + s = out.tail() + ) + or + // Add the argument node corresponding to the requested post-update node + inputState(c, s) and isCallbackParameter(s) + } + + private predicate inputState(SummarizedCallable c, SummaryComponentStack s) { + summary(c, s, _, _) + or + exists(SummaryComponentStack inp | inputState(c, inp) and s = inp.tail()) + or + exists(SummaryComponentStack out | + outputState(c, out) and + out.head() = TParameterSummaryComponent(_) and + s = out.tail() + ) + or + // Add the post-update node corresponding to the requested argument node + outputState(c, s) and isCallbackParameter(s) + or + // Add the parameter node for parameter side-effects + outputState(c, s) and s = SummaryComponentStack::argument(_) + } + + private newtype TSummaryNodeState = + TSummaryNodeInputState(SummaryComponentStack s) { inputState(_, s) } or + TSummaryNodeOutputState(SummaryComponentStack s) { outputState(_, s) } + + /** + * A state used to break up (complex) flow summaries into atomic flow steps. + * For a flow summary + * + * ```ql + * propagatesFlow( + * SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue + * ) + * ``` + * + * the following states are used: + * + * - `TSummaryNodeInputState(SummaryComponentStack s)`: + * this state represents that the components in `s` _have been read_ from the + * input. + * - `TSummaryNodeOutputState(SummaryComponentStack s)`: + * this state represents that the components in `s` _remain to be written_ to + * the output. + */ + private class SummaryNodeState extends TSummaryNodeState { + /** Holds if this state is a valid input state for `c`. */ + pragma[nomagic] + predicate isInputState(SummarizedCallable c, SummaryComponentStack s) { + this = TSummaryNodeInputState(s) and + inputState(c, s) + } + + /** Holds if this state is a valid output state for `c`. */ + pragma[nomagic] + predicate isOutputState(SummarizedCallable c, SummaryComponentStack s) { + this = TSummaryNodeOutputState(s) and + outputState(c, s) + } + + /** Gets a textual representation of this state. */ + string toString() { + exists(SummaryComponentStack s | + this = TSummaryNodeInputState(s) and + result = "read: " + s + ) + or + exists(SummaryComponentStack s | + this = TSummaryNodeOutputState(s) and + result = "to write: " + s + ) + } + } + + private newtype TSummaryNode = + TSummaryInternalNode(SummarizedCallable c, SummaryNodeState state) { + summaryNodeRange(c, state) + } or + TSummaryParameterNode(SummarizedCallable c, ParameterPosition pos) { + summaryParameterNodeRange(c, pos) + } + + abstract class SummaryNode extends TSummaryNode { + abstract string toString(); + + abstract SummarizedCallable getSummarizedCallable(); + } + + private class SummaryInternalNode extends SummaryNode, TSummaryInternalNode { + private SummarizedCallable c; + private SummaryNodeState state; + + SummaryInternalNode() { this = TSummaryInternalNode(c, state) } + + override string toString() { result = "[summary] " + state + " in " + c } + + override SummarizedCallable getSummarizedCallable() { result = c } + } + + private class SummaryParamNode extends SummaryNode, TSummaryParameterNode { + private SummarizedCallable c; + private ParameterPosition pos; + + SummaryParamNode() { this = TSummaryParameterNode(c, pos) } + + override string toString() { result = "[summary param] " + pos + " in " + c } + + override SummarizedCallable getSummarizedCallable() { result = c } + } + + /** + * Holds if `state` represents having read from a parameter at position + * `pos` in `c`. In this case we are not synthesizing a data-flow node, + * but instead assume that a relevant parameter node already exists. + */ + private predicate parameterReadState( + SummarizedCallable c, SummaryNodeState state, ParameterPosition pos + ) { + state.isInputState(c, SummaryComponentStack::argument(pos)) + } + + /** + * Holds if a synthesized summary node is needed for the state `state` in summarized + * callable `c`. + */ + private predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) { + state.isInputState(c, _) and + not parameterReadState(c, state, _) + or + state.isOutputState(c, _) + } + + pragma[noinline] + private SummaryNode summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) { + exists(SummaryNodeState state | state.isInputState(c, s) | + result = TSummaryInternalNode(c, state) + or + exists(ParameterPosition pos | + parameterReadState(c, state, pos) and + result = TSummaryParameterNode(c, pos) + ) + ) + } + + pragma[noinline] + private SummaryNode summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) { + exists(SummaryNodeState state | + state.isOutputState(c, s) and + result = TSummaryInternalNode(c, state) + ) + } + + /** + * Holds if a write targets `post`, which is a post-update node for a + * parameter at position `pos` in `c`. + */ + private predicate isParameterPostUpdate( + SummaryNode post, SummarizedCallable c, ParameterPosition pos + ) { + post = summaryNodeOutputState(c, SummaryComponentStack::argument(pos)) + } + + /** Holds if a parameter node at position `pos` is required for `c`. */ + private predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { + parameterReadState(c, _, pos) + or + // Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context + any(SummaryNodeState state).isOutputState(c, SummaryComponentStack::argument(pos)) + } + + private predicate callbackOutput( + SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ReturnKind rk + ) { + any(SummaryNodeState state).isInputState(c, s) and + s.head() = TReturnSummaryComponent(rk) and + receiver = summaryNodeInputState(c, s.tail()) + } + + private predicate callbackInput( + SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ArgumentPosition pos + ) { + any(SummaryNodeState state).isOutputState(c, s) and + s.head() = TParameterSummaryComponent(pos) and + receiver = summaryNodeInputState(c, s.tail()) + } + + /** Holds if a call targeting `receiver` should be synthesized inside `c`. */ + predicate summaryCallbackRange(SummarizedCallable c, SummaryNode receiver) { + callbackOutput(c, _, receiver, _) + or + callbackInput(c, _, receiver, _) + } + + /** + * Gets the type of synthesized summary node `n`. + * + * The type is computed based on the language-specific predicates + * `getContentType()`, `getReturnType()`, `getCallbackParameterType()`, and + * `getCallbackReturnType()`. + */ + DataFlowType summaryNodeType(SummaryNode n) { + exists(SummaryNode pre | + summaryPostUpdateNode(n, pre) and + result = summaryNodeType(pre) + ) + or + exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() | + n = summaryNodeInputState(c, s) and + ( + exists(ContentSet cont | result = getContentType(cont) | + head = TContentSummaryComponent(cont) or + head = TWithContentSummaryComponent(cont) + ) + or + head = TWithoutContentSummaryComponent(_) and + result = summaryNodeType(summaryNodeInputState(c, s.tail())) + or + exists(ReturnKind rk | + head = TReturnSummaryComponent(rk) and + result = + getCallbackReturnType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c), + s.tail())), rk) + ) + or + exists(SummaryComponent::SyntheticGlobal sg | + head = TSyntheticGlobalSummaryComponent(sg) and + result = getSyntheticGlobalType(sg) + ) + or + exists(ParameterPosition pos | + head = TArgumentSummaryComponent(pos) and + result = getParameterType(c, pos) + ) + ) + or + n = summaryNodeOutputState(c, s) and + ( + exists(ContentSet cont | + head = TContentSummaryComponent(cont) and result = getContentType(cont) + ) + or + s.length() = 1 and + exists(ReturnKind rk | + head = TReturnSummaryComponent(rk) and + result = getReturnType(c, rk) + ) + or + exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) | + result = + getCallbackParameterType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c), + s.tail())), pos) + ) + or + exists(SummaryComponent::SyntheticGlobal sg | + head = TSyntheticGlobalSummaryComponent(sg) and + result = getSyntheticGlobalType(sg) + ) + ) + ) + } + + /** Holds if summary node `p` is a parameter with position `pos`. */ + predicate summaryParameterNode(SummaryNode p, ParameterPosition pos) { + p = TSummaryParameterNode(_, pos) + } + + /** Holds if summary node `out` contains output of kind `rk` from call `c`. */ + predicate summaryOutNode(DataFlowCall c, SummaryNode out, ReturnKind rk) { + exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver | + callbackOutput(callable, s, receiver, rk) and + out = summaryNodeInputState(callable, s) and + c = summaryDataFlowCall(receiver) + ) + } + + /** Holds if summary node `arg` is at position `pos` in the call `c`. */ + predicate summaryArgumentNode(DataFlowCall c, SummaryNode arg, ArgumentPosition pos) { + exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver | + callbackInput(callable, s, receiver, pos) and + arg = summaryNodeOutputState(callable, s) and + c = summaryDataFlowCall(receiver) + ) + } + + /** Holds if summary node `post` is a post-update node with pre-update node `pre`. */ + predicate summaryPostUpdateNode(SummaryNode post, SummaryNode pre) { + exists(SummarizedCallable c, ParameterPosition pos | + isParameterPostUpdate(post, c, pos) and + pre = TSummaryParameterNode(c, pos) + ) + or + exists(SummarizedCallable callable, SummaryComponentStack s | + callbackInput(callable, s, _, _) and + pre = summaryNodeOutputState(callable, s) and + post = summaryNodeInputState(callable, s) + ) + } + + /** Holds if summary node `ret` is a return node of kind `rk`. */ + predicate summaryReturnNode(SummaryNode ret, ReturnKind rk) { + exists(SummaryComponentStack s | + ret = summaryNodeOutputState(_, s) and + s = TSingletonSummaryComponentStack(TReturnSummaryComponent(rk)) + ) + } + + /** + * Holds if flow is allowed to pass from parameter `p`, to a return + * node, and back out to `p`. + */ + predicate summaryAllowParameterReturnInSelf(ParamNode p) { + exists(SummarizedCallable c, ParameterPosition ppos | + p.isParameterOf(inject(c), pragma[only_bind_into](ppos)) + | + exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents | + summary(c, inputContents, outputContents, _) and + inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and + outputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) + ) + ) + } + + /** Provides a compilation of flow summaries to atomic data-flow steps. */ + module Steps { + /** + * Holds if there is a local step from `pred` to `succ`, which is synthesized + * from a flow summary. + */ + predicate summaryLocalStep(SummaryNode pred, SummaryNode succ, boolean preservesValue) { + exists( + SummarizedCallable c, SummaryComponentStack inputContents, + SummaryComponentStack outputContents + | + summary(c, inputContents, outputContents, preservesValue) and + pred = summaryNodeInputState(c, inputContents) and + succ = summaryNodeOutputState(c, outputContents) + | + preservesValue = true + or + preservesValue = false and not summary(c, inputContents, outputContents, true) + ) + or + exists(SummarizedCallable c, SummaryComponentStack s | + pred = summaryNodeInputState(c, s.tail()) and + succ = summaryNodeInputState(c, s) and + s.head() = [SummaryComponent::withContent(_), SummaryComponent::withoutContent(_)] and + preservesValue = true + ) + } + + /** + * Holds if there is a read step of content `c` from `pred` to `succ`, which + * is synthesized from a flow summary. + */ + predicate summaryReadStep(SummaryNode pred, ContentSet c, SummaryNode succ) { + exists(SummarizedCallable sc, SummaryComponentStack s | + pred = summaryNodeInputState(sc, s.tail()) and + succ = summaryNodeInputState(sc, s) and + SummaryComponent::content(c) = s.head() + ) + } + + /** + * Holds if there is a store step of content `c` from `pred` to `succ`, which + * is synthesized from a flow summary. + */ + predicate summaryStoreStep(SummaryNode pred, ContentSet c, SummaryNode succ) { + exists(SummarizedCallable sc, SummaryComponentStack s | + pred = summaryNodeOutputState(sc, s) and + succ = summaryNodeOutputState(sc, s.tail()) and + SummaryComponent::content(c) = s.head() + ) + } + + /** + * Holds if there is a jump step from `pred` to `succ`, which is synthesized + * from a flow summary. + */ + predicate summaryJumpStep(SummaryNode pred, SummaryNode succ) { + exists(SummaryComponentStack s | + s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and + pred = summaryNodeOutputState(_, s) and + succ = summaryNodeInputState(_, s) + ) + } + + /** + * Holds if values stored inside content `c` are cleared at `n`. `n` is a + * synthesized summary node, so in order for values to be cleared at calls + * to the relevant method, it is important that flow does not pass over + * the argument, either via use-use flow or def-use flow. + * + * Example: + * + * ``` + * a.b = taint; + * a.clearB(); // assume we have a flow summary for `clearB` that clears `b` on the qualifier + * sink(a.b); + * ``` + * + * In the above, flow should not pass from `a` on the first line (or the second + * line) to `a` on the third line. Instead, there will be synthesized flow from + * `a` on line 2 to the post-update node for `a` on that line (via an intermediate + * node where field `b` is cleared). + */ + predicate summaryClearsContent(SummaryNode n, ContentSet c) { + exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | + n = TSummaryInternalNode(sc, state) and + state.isInputState(sc, stack) and + stack.head() = SummaryComponent::withoutContent(c) + ) + } + + /** + * Holds if the value that is being tracked is expected to be stored inside + * content `c` at `n`. + */ + predicate summaryExpectsContent(SummaryNode n, ContentSet c) { + exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | + n = TSummaryInternalNode(sc, state) and + state.isInputState(sc, stack) and + stack.head() = SummaryComponent::withContent(c) + ) + } + + pragma[noinline] + private predicate viableParam( + DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, SummaryParamNode p + ) { + exists(DataFlowCallable c | + c = inject(sc) and + p = TSummaryParameterNode(sc, ppos) and + c = viableCallable(call) + ) + } + + pragma[nomagic] + private SummaryParamNode summaryArgParam(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { + exists(ParameterPosition ppos | + argumentPositionMatch(call, arg, ppos) and + viableParam(call, sc, ppos, result) + ) + } + + /** + * Holds if `p` can reach `n` in a summarized callable, using only value-preserving + * local steps. `clearsOrExpects` records whether any node on the path from `p` to + * `n` either clears or expects contents. + */ + private predicate paramReachesLocal(SummaryParamNode p, SummaryNode n, boolean clearsOrExpects) { + viableParam(_, _, _, p) and + n = p and + clearsOrExpects = false + or + exists(SummaryNode mid, boolean clearsOrExpectsMid | + paramReachesLocal(p, mid, clearsOrExpectsMid) and + summaryLocalStep(mid, n, true) and + if + summaryClearsContent(n, _) or + summaryExpectsContent(n, _) + then clearsOrExpects = true + else clearsOrExpects = clearsOrExpectsMid + ) + } + + /** + * Holds if use-use flow starting from `arg` should be prohibited. + * + * This is the case when `arg` is the argument of a call that targets a + * flow summary where the corresponding parameter either clears contents + * or expects contents. + */ + pragma[nomagic] + predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) { + exists(SummaryParamNode p, ParameterPosition ppos, SummaryNode ret | + paramReachesLocal(p, ret, true) and + p = summaryArgParam(_, arg, sc) and + p = TSummaryParameterNode(_, pragma[only_bind_into](ppos)) and + isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos)) + ) + } + + pragma[nomagic] + private predicate summaryReturnNodeExt(SummaryNode ret, ReturnKindExt rk) { + summaryReturnNode(ret, rk.(ValueReturnKind).getKind()) + or + exists(SummaryParamNode p, SummaryNode pre, ParameterPosition pos | + paramReachesLocal(p, pre, _) and + summaryPostUpdateNode(ret, pre) and + p = TSummaryParameterNode(_, pos) and + rk.(ParamUpdateReturnKind).getPosition() = pos + ) + } + + bindingset[ret] + private SummaryParamNode summaryArgParamRetOut( + ArgNode arg, SummaryNode ret, OutNodeExt out, SummarizedCallable sc + ) { + exists(DataFlowCall call, ReturnKindExt rk | + result = summaryArgParam(call, arg, sc) and + summaryReturnNodeExt(ret, pragma[only_bind_into](rk)) and + out = pragma[only_bind_into](rk).getAnOutNode(call) + ) + } + + /** + * Holds if `arg` flows to `out` using a simple value-preserving flow + * summary, that is, a flow summary without reads and stores. + * + * NOTE: This step should not be used in global data-flow/taint-tracking, but may + * be useful to include in the exposed local data-flow/taint-tracking relations. + */ + predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) { + exists(ReturnKind rk, SummaryNode ret, DataFlowCall call | + summaryLocalStep(summaryArgParam(call, arg, sc), ret, true) and + summaryReturnNode(ret, pragma[only_bind_into](rk)) and + out = getAnOutNode(call, pragma[only_bind_into](rk)) + ) + } + + /** + * Holds if `arg` flows to `out` using a simple flow summary involving taint + * step, that is, a flow summary without reads and stores. + * + * NOTE: This step should not be used in global data-flow/taint-tracking, but may + * be useful to include in the exposed local data-flow/taint-tracking relations. + */ + predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) { + exists(SummaryNode ret | + summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, false) + ) + } + + /** + * Holds if there is a read(+taint) of `c` from `arg` to `out` using a + * flow summary. + * + * NOTE: This step should not be used in global data-flow/taint-tracking, but may + * be useful to include in the exposed local data-flow/taint-tracking relations. + */ + predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { + exists(SummaryNode mid, SummaryNode ret | + summaryReadStep(summaryArgParamRetOut(arg, ret, out, sc), c, mid) and + summaryLocalStep(mid, ret, _) + ) + } + + /** + * Holds if there is a (taint+)store of `arg` into content `c` of `out` using a + * flow summary. + * + * NOTE: This step should not be used in global data-flow/taint-tracking, but may + * be useful to include in the exposed local data-flow/taint-tracking relations. + */ + predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { + exists(SummaryNode mid, SummaryNode ret | + summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), mid, _) and + summaryStoreStep(mid, c, ret) + ) + } + } + + /** + * Provides a means of translating externally (e.g., MaD) defined flow + * summaries into a `SummarizedCallable`s. + */ + module External { + /** Holds if `spec` is a relevant external specification. */ + private predicate relevantSpec(string spec) { + summaryElement(_, spec, _, _, _) or + summaryElement(_, _, spec, _, _) or + sourceElement(_, spec, _, _) or + sinkElement(_, spec, _, _) + } + + private class AccessPathRange extends AccessPath::Range { + AccessPathRange() { relevantSpec(this) } + } + + /** Holds if specification component `token` parses as parameter `pos`. */ + predicate parseParam(AccessPathToken token, ArgumentPosition pos) { + token.getName() = "Parameter" and + pos = parseParamBody(token.getAnArgument()) + } + + /** Holds if specification component `token` parses as argument `pos`. */ + predicate parseArg(AccessPathToken token, ParameterPosition pos) { + token.getName() = "Argument" and + pos = parseArgBody(token.getAnArgument()) + } + + /** Holds if specification component `token` parses as synthetic global `sg`. */ + predicate parseSynthGlobal(AccessPathToken token, string sg) { + token.getName() = "SyntheticGlobal" and + sg = token.getAnArgument() + } + + private class SyntheticGlobalFromAccessPath extends SummaryComponent::SyntheticGlobal { + SyntheticGlobalFromAccessPath() { parseSynthGlobal(_, this) } + } + + private SummaryComponent interpretComponent(AccessPathToken token) { + exists(ParameterPosition pos | + parseArg(token, pos) and result = SummaryComponent::argument(pos) + ) + or + exists(ArgumentPosition pos | + parseParam(token, pos) and result = SummaryComponent::parameter(pos) + ) + or + token = "ReturnValue" and result = SummaryComponent::return(getReturnValueKind()) + or + exists(string sg | + parseSynthGlobal(token, sg) and result = SummaryComponent::syntheticGlobal(sg) + ) + or + result = interpretComponentSpecific(token) + } + + /** + * Holds if `spec` specifies summary component stack `stack`. + */ + predicate interpretSpec(AccessPath spec, SummaryComponentStack stack) { + interpretSpec(spec, spec.getNumToken(), stack) + } + + /** Holds if the first `n` tokens of `spec` resolves to `stack`. */ + private predicate interpretSpec(AccessPath spec, int n, SummaryComponentStack stack) { + n = 1 and + stack = SummaryComponentStack::singleton(interpretComponent(spec.getToken(0))) + or + exists(SummaryComponent head, SummaryComponentStack tail | + interpretSpec(spec, n, head, tail) and + stack = SummaryComponentStack::push(head, tail) + ) + } + + /** Holds if the first `n` tokens of `spec` resolves to `head` followed by `tail` */ + private predicate interpretSpec( + AccessPath spec, int n, SummaryComponent head, SummaryComponentStack tail + ) { + interpretSpec(spec, n - 1, tail) and + head = interpretComponent(spec.getToken(n - 1)) + } + + private class MkStack extends RequiredSummaryComponentStack { + override predicate required(SummaryComponent head, SummaryComponentStack tail) { + interpretSpec(_, _, head, tail) + } + } + + private class SummarizedCallableExternal extends SummarizedCallable { + SummarizedCallableExternal() { summaryElement(this, _, _, _, _) } + + private predicate relevantSummaryElementGenerated( + AccessPath inSpec, AccessPath outSpec, string kind + ) { + exists(Provenance provenance | + provenance.isGenerated() and + summaryElement(this, inSpec, outSpec, kind, provenance) + ) and + not this.applyManualModel() + } + + private predicate relevantSummaryElement(AccessPath inSpec, AccessPath outSpec, string kind) { + exists(Provenance provenance | + provenance.isManual() and + summaryElement(this, inSpec, outSpec, kind, provenance) + ) + or + this.relevantSummaryElementGenerated(inSpec, outSpec, kind) + } + + override predicate propagatesFlow( + SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue + ) { + exists(AccessPath inSpec, AccessPath outSpec, string kind | + this.relevantSummaryElement(inSpec, outSpec, kind) and + interpretSpec(inSpec, input) and + interpretSpec(outSpec, output) + | + kind = "value" and preservesValue = true + or + kind = "taint" and preservesValue = false + ) + } + + override predicate hasProvenance(Provenance provenance) { + summaryElement(this, _, _, _, provenance) + } + } + + /** Holds if component `c` of specification `spec` cannot be parsed. */ + predicate invalidSpecComponent(AccessPath spec, string c) { + c = spec.getToken(_) and + not exists(interpretComponent(c)) + } + + /** Holds if `provenance` is not a valid provenance value. */ + bindingset[provenance] + predicate invalidProvenance(string provenance) { not provenance instanceof Provenance } + + /** + * Holds if token `part` of specification `spec` has an invalid index. + * E.g., `Argument[-1]`. + */ + predicate invalidIndexComponent(AccessPath spec, AccessPathToken part) { + part = spec.getToken(_) and + part.getName() = ["Parameter", "Argument"] and + AccessPath::parseInt(part.getArgumentList()) < 0 + } + + private predicate inputNeedsReference(AccessPathToken c) { + c.getName() = "Argument" or + inputNeedsReferenceSpecific(c) + } + + private predicate outputNeedsReference(AccessPathToken c) { + c.getName() = ["Argument", "ReturnValue"] or + outputNeedsReferenceSpecific(c) + } + + private predicate sourceElementRef(InterpretNode ref, AccessPath output, string kind) { + exists(SourceOrSinkElement e | + sourceElement(e, output, kind, _) and + if outputNeedsReference(output.getToken(0)) + then e = ref.getCallTarget() + else e = ref.asElement() + ) + } + + private predicate sinkElementRef(InterpretNode ref, AccessPath input, string kind) { + exists(SourceOrSinkElement e | + sinkElement(e, input, kind, _) and + if inputNeedsReference(input.getToken(0)) + then e = ref.getCallTarget() + else e = ref.asElement() + ) + } + + /** Holds if the first `n` tokens of `output` resolve to the given interpretation. */ + private predicate interpretOutput( + AccessPath output, int n, InterpretNode ref, InterpretNode node + ) { + sourceElementRef(ref, output, _) and + n = 0 and + ( + if output = "" + then + // Allow language-specific interpretation of the empty access path + interpretOutputSpecific("", ref, node) + else node = ref + ) + or + exists(InterpretNode mid, AccessPathToken c | + interpretOutput(output, n - 1, ref, mid) and + c = output.getToken(n - 1) + | + exists(ArgumentPosition apos, ParameterPosition ppos | + node.asNode().(PostUpdateNode).getPreUpdateNode().(ArgNode).argumentOf(mid.asCall(), apos) and + parameterMatch(ppos, apos) + | + c = "Argument" or parseArg(c, ppos) + ) + or + exists(ArgumentPosition apos, ParameterPosition ppos | + node.asNode().(ParamNode).isParameterOf(mid.asCallable(), ppos) and + parameterMatch(ppos, apos) + | + c = "Parameter" or parseParam(c, apos) + ) + or + c = "ReturnValue" and + node.asNode() = getAnOutNodeExt(mid.asCall(), TValueReturn(getReturnValueKind())) + or + interpretOutputSpecific(c, mid, node) + ) + } + + /** Holds if the first `n` tokens of `input` resolve to the given interpretation. */ + private predicate interpretInput(AccessPath input, int n, InterpretNode ref, InterpretNode node) { + sinkElementRef(ref, input, _) and + n = 0 and + ( + if input = "" + then + // Allow language-specific interpretation of the empty access path + interpretInputSpecific("", ref, node) + else node = ref + ) + or + exists(InterpretNode mid, AccessPathToken c | + interpretInput(input, n - 1, ref, mid) and + c = input.getToken(n - 1) + | + exists(ArgumentPosition apos, ParameterPosition ppos | + node.asNode().(ArgNode).argumentOf(mid.asCall(), apos) and + parameterMatch(ppos, apos) + | + c = "Argument" or parseArg(c, ppos) + ) + or + exists(ReturnNodeExt ret | + c = "ReturnValue" and + ret = node.asNode() and + ret.getKind().(ValueReturnKind).getKind() = getReturnValueKind() and + mid.asCallable() = getNodeEnclosingCallable(ret) + ) + or + interpretInputSpecific(c, mid, node) + ) + } + + /** + * Holds if `node` is specified as a source with the given kind in a MaD flow + * model. + */ + predicate isSourceNode(InterpretNode node, string kind) { + exists(InterpretNode ref, AccessPath output | + sourceElementRef(ref, output, kind) and + interpretOutput(output, output.getNumToken(), ref, node) + ) + } + + /** + * Holds if `node` is specified as a sink with the given kind in a MaD flow + * model. + */ + predicate isSinkNode(InterpretNode node, string kind) { + exists(InterpretNode ref, AccessPath input | + sinkElementRef(ref, input, kind) and + interpretInput(input, input.getNumToken(), ref, node) + ) + } + } + + /** Provides a query predicate for outputting a set of relevant flow summaries. */ + module TestOutput { + /** A flow summary to include in the `summary/1` query predicate. */ + abstract class RelevantSummarizedCallable instanceof SummarizedCallable { + /** Gets the string representation of this callable used by `summary/1`. */ + abstract string getCallableCsv(); + + /** Holds if flow is propagated between `input` and `output`. */ + predicate relevantSummary( + SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue + ) { + super.propagatesFlow(input, output, preservesValue) + } + + string toString() { result = super.toString() } + } + + /** A model to include in the `neutral/1` query predicate. */ + abstract class RelevantNeutralCallable instanceof NeutralCallable { + /** Gets the string representation of this callable used by `neutral/1`. */ + abstract string getCallableCsv(); + + /** + * Gets the kind of the neutral. + */ + string getKind() { result = super.getKind() } + + string toString() { result = super.toString() } + } + + /** Render the kind in the format used in flow summaries. */ + private string renderKind(boolean preservesValue) { + preservesValue = true and result = "value" + or + preservesValue = false and result = "taint" + } + + private string renderProvenance(SummarizedCallable c) { + if c.applyManualModel() then result = "manual" else c.hasProvenance(result) + } + + private string renderProvenanceNeutral(NeutralCallable c) { + if c.hasManualModel() then result = "manual" else c.hasProvenance(result) + } + + /** + * A query predicate for outputting flow summaries in semi-colon separated format in QL tests. + * The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind;provenance", + * ext is hardcoded to empty. + */ + query predicate summary(string csv) { + exists( + RelevantSummarizedCallable c, SummaryComponentStack input, SummaryComponentStack output, + boolean preservesValue + | + c.relevantSummary(input, output, preservesValue) and + csv = + c.getCallableCsv() // Callable information + + input.getMadRepresentation() + ";" // input + + output.getMadRepresentation() + ";" // output + + renderKind(preservesValue) + ";" // kind + + renderProvenance(c) // provenance + ) + } + + /** + * Holds if a neutral model `csv` exists (semi-colon separated format). Used for testing purposes. + * The syntax is: "namespace;type;name;signature;kind;provenance"", + */ + query predicate neutral(string csv) { + exists(RelevantNeutralCallable c | + csv = + c.getCallableCsv() // Callable information + + c.getKind() + ";" // kind + + renderProvenanceNeutral(c) // provenance + ) + } + } + + /** + * Provides query predicates for rendering the generated data flow graph for + * a summarized callable. + * + * Import this module into a `.ql` file of `@kind graph` to render the graph. + * The graph is restricted to callables from `RelevantSummarizedCallable`. + */ + module RenderSummarizedCallable { + /** A summarized callable to include in the graph. */ + abstract class RelevantSummarizedCallable instanceof SummarizedCallable { + string toString() { result = super.toString() } + } + + private newtype TNodeOrCall = + MkNode(SummaryNode n) { + exists(RelevantSummarizedCallable c | + n = TSummaryInternalNode(c, _) + or + n = TSummaryParameterNode(c, _) + ) + } or + MkCall(DataFlowCall call) { + call = summaryDataFlowCall(_) and + call.getEnclosingCallable() = inject(any(RelevantSummarizedCallable c)) + } + + private class NodeOrCall extends TNodeOrCall { + SummaryNode asNode() { this = MkNode(result) } + + DataFlowCall asCall() { this = MkCall(result) } + + string toString() { + result = this.asNode().toString() + or + result = this.asCall().toString() + } + + /** + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and + startline = 0 and + startcolumn = 0 and + endline = 0 and + endcolumn = 0 + } + } + + query predicate nodes(NodeOrCall n, string key, string val) { + key = "semmle.label" and val = n.toString() + } + + private predicate edgesComponent(NodeOrCall a, NodeOrCall b, string value) { + exists(boolean preservesValue | + Private::Steps::summaryLocalStep(a.asNode(), b.asNode(), preservesValue) and + if preservesValue = true then value = "value" else value = "taint" + ) + or + exists(ContentSet c | + Private::Steps::summaryReadStep(a.asNode(), c, b.asNode()) and + value = "read (" + c + ")" + or + Private::Steps::summaryStoreStep(a.asNode(), c, b.asNode()) and + value = "store (" + c + ")" + or + Private::Steps::summaryClearsContent(a.asNode(), c) and + b = a and + value = "clear (" + c + ")" + or + Private::Steps::summaryExpectsContent(a.asNode(), c) and + b = a and + value = "expect (" + c + ")" + ) + or + summaryPostUpdateNode(b.asNode(), a.asNode()) and + value = "post-update" + or + b.asCall() = summaryDataFlowCall(a.asNode()) and + value = "receiver" + or + exists(ArgumentPosition pos | + summaryArgumentNode(b.asCall(), a.asNode(), pos) and + value = "argument (" + pos + ")" + ) + } + + query predicate edges(NodeOrCall a, NodeOrCall b, string key, string value) { + key = "semmle.label" and + value = strictconcat(string s | edgesComponent(a, b, s) | s, " / ") + } + } +} From 60101f5e6a0ad7d4a14ee5226e77286387e857fd Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 19:58:49 +0200 Subject: [PATCH 012/514] JS: Instantiate flow summary library --- .../javascript/dataflow/FlowSummary.qll | 92 +++++ .../dataflow/internal/DataFlowNode.qll | 2 + .../dataflow/internal/DataFlowPrivate.qll | 103 ++++++ .../dataflow/internal/FlowSummaryPrivate.qll | 339 ++++++++++++++++++ .../internal/TaintTrackingPrivate.qll | 3 + .../sharedlib/DataFlowImplSpecific.qll | 12 + .../sharedlib/FlowSummaryImplSpecific.qll | 1 + 7 files changed, 552 insertions(+) create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImplSpecific.qll create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImplSpecific.qll diff --git a/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll b/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll new file mode 100644 index 00000000000..426f8b75851 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll @@ -0,0 +1,92 @@ +/** Provides classes and predicates for defining flow summaries. */ + +private import javascript +private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as Impl +private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImplSpecific +private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon +private import semmle.javascript.dataflow.internal.DataFlowPrivate + +class SummaryComponent = Impl::Public::SummaryComponent; + +/** Provides predicates for constructing summary components. */ +module SummaryComponent { + private import Impl::Public::SummaryComponent as SC + + predicate parameter = SC::parameter/1; + + predicate argument = SC::argument/1; + + predicate content = SC::content/1; + + predicate withoutContent = SC::withoutContent/1; + + predicate withContent = SC::withContent/1; + + class SyntheticGlobal = SC::SyntheticGlobal; + + /** Gets a summary component that represents a receiver. */ + SummaryComponent receiver() { result = argument(MkThisParameter()) } + + /** Gets a summary component that represents the return value of a call. */ + SummaryComponent return() { result = SC::return(MkNormalReturnKind()) } + + /** Gets a summary component that represents the exception thrown from a call. */ + SummaryComponent exceptionalReturn() { result = SC::return(MkExceptionalReturnKind()) } +} + +class SummaryComponentStack = Impl::Public::SummaryComponentStack; + +/** Provides predicates for constructing stacks of summary components. */ +module SummaryComponentStack { + private import Impl::Public::SummaryComponentStack as SCS + + predicate singleton = SCS::singleton/1; + + predicate push = SCS::push/2; + + predicate argument = SCS::argument/1; + + /** Gets a singleton stack representing a receiver. */ + SummaryComponentStack receiver() { result = singleton(SummaryComponent::receiver()) } + + /** Gets a singleton stack representing the return value of a call. */ + SummaryComponentStack return() { result = singleton(SummaryComponent::return()) } + + /** Gets a singleton stack representing the exception thrown from a call. */ + SummaryComponentStack exceptionalReturn() { + result = singleton(SummaryComponent::exceptionalReturn()) + } +} + +/** A callable with a flow summary, identified by a unique string. */ +abstract class SummarizedCallable extends LibraryCallable, Impl::Public::SummarizedCallable { + bindingset[this] + SummarizedCallable() { any() } + + /** + * Same as + * + * ```ql + * propagatesFlow( + * SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue + * ) + * ``` + * + * but uses an external (string) representation of the input and output stacks. + */ + pragma[nomagic] + predicate propagatesFlowExt(string input, string output, boolean preservesValue) { none() } + + /** + * Gets the synthesized parameter that results from an input specification + * that starts with `Argument[s]` for this library callable. + */ + DataFlow::ParameterNode getParameter(string s) { + exists(ParameterPosition pos | + DataFlowImplCommon::parameterNode(result, MkLibraryCallable(this), pos) and + s = getParameterPosition(pos) + ) + } +} + +class RequiredSummaryComponentStack = Impl::Public::RequiredSummaryComponentStack; diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index bee7b1259b4..22df2f07189 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -5,6 +5,7 @@ */ private import javascript +private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as FlowSummaryImpl cached private module Cached { /** @@ -48,6 +49,7 @@ private module Cached { } or TConstructorThisArgumentNode(InvokeExpr e) { e instanceof NewExpr or e instanceof SuperCall } or TConstructorThisPostUpdate(Constructor ctor) or + TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or } import Cached diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 9a9559e28db..fe222b1cf3d 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -5,11 +5,24 @@ private import semmle.javascript.dataflow.internal.FlowSteps as FlowSteps private import semmle.javascript.dataflow.internal.Contents::Private private import semmle.javascript.dataflow.internal.VariableCapture private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon +private import sharedlib.FlowSummaryImpl as FlowSummaryImpl private class Node = DataFlow::Node; class PostUpdateNode = DataFlow::PostUpdateNode; +class FlowSummaryNode extends DataFlow::Node, TFlowSummaryNode { + FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) } + + /** Gets the summarized callable that this node belongs to. */ + FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() { + result = this.getSummaryNode().getSummarizedCallable() + } + + cached + override string toString() { result = this.getSummaryNode().toString() } +} + cached newtype TReturnKind = MkNormalReturnKind() or @@ -33,6 +46,8 @@ private predicate returnNodeImpl(DataFlow::Node node, ReturnKind kind) { // See the models for AsyncAwait and Generator. not fun.isAsyncOrGenerator() ) + or + FlowSummaryImpl::Private::summaryReturnNode(node.(FlowSummaryNode).getSummaryNode(), kind) } private DataFlow::Node getAnOutNodeImpl(DataFlowCall call, ReturnKind kind) { @@ -45,6 +60,8 @@ private DataFlow::Node getAnOutNodeImpl(DataFlowCall call, ReturnKind kind) { kind = MkExceptionalReturnKind() and result = call.asBoundCall(_).getExceptionalReturn() or kind = MkNormalReturnKind() and result = call.asAccessorCall().(DataFlow::PropRead) + or + FlowSummaryImpl::Private::summaryOutNode(call, result.(FlowSummaryNode).getSummaryNode(), kind) } class ReturnNode extends DataFlow::Node { @@ -86,6 +103,9 @@ predicate postUpdatePair(Node pre, Node post) { pre = TThisNode(constructor) and post = TConstructorThisPostUpdate(constructor) ) + or + FlowSummaryImpl::Private::summaryPostUpdateNode(post.(FlowSummaryNode).getSummaryNode(), + pre.(FlowSummaryNode).getSummaryNode()) } class CastNode extends DataFlow::Node instanceof EmptyType { } @@ -93,6 +113,7 @@ class CastNode extends DataFlow::Node instanceof EmptyType { } cached newtype TDataFlowCallable = MkSourceCallable(StmtContainer container) or + MkLibraryCallable(LibraryCallable callable) /** * A callable entity. This is a wrapper around either a `StmtContainer` or a `LibraryCallable`. @@ -122,6 +143,18 @@ class DataFlowCallable extends TDataFlowCallable { LibraryCallable asLibraryCallable() { this = MkLibraryCallable(result) } } +/** A callable defined in library code, identified by a unique string. */ +abstract class LibraryCallable extends string { + bindingset[this] + LibraryCallable() { any() } + + /** Gets a call to this library callable. */ + DataFlow::InvokeNode getACall() { none() } + + /** Same as `getACall()` except this does not depend on the call graph or API graph. */ + DataFlow::InvokeNode getACallSimple() { none() } +} + private predicate isParameterNodeImpl(Node p, DataFlowCallable c, ParameterPosition pos) { p = c.asSourceCallable().(Function).getParameter(pos.asPositional()).flow() or @@ -130,6 +163,12 @@ private predicate isParameterNodeImpl(Node p, DataFlowCallable c, ParameterPosit pos.isFunctionSelfReference() and p = TFunctionSelfReferenceNode(c.asSourceCallable()) or pos.isArgumentsArray() and p = TReflectiveParametersNode(c.asSourceCallable()) + or + exists(FlowSummaryNode summaryNode | + summaryNode = p and + FlowSummaryImpl::Private::summaryParameterNode(summaryNode.getSummaryNode(), pos) and + c.asLibraryCallable() = summaryNode.getSummarizedCallable() + ) } predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) { @@ -165,6 +204,8 @@ private predicate isArgumentNodeImpl(Node n, DataFlowCall call, ArgumentPosition or // argument to setter (TODO: this has no post-update node) pos.asPositional() = 0 and n = call.asAccessorCall().(DataFlow::PropWrite).getRhs() + or + FlowSummaryImpl::Private::summaryArgumentNode(call, n.(FlowSummaryNode).getSummaryNode(), pos) } predicate isArgumentNode(ArgumentNode n, DataFlowCall call, ArgumentPosition pos) { @@ -173,6 +214,10 @@ predicate isArgumentNode(ArgumentNode n, DataFlowCall call, ArgumentPosition pos DataFlowCallable nodeGetEnclosingCallable(Node node) { result.asSourceCallable() = node.getContainer() + or + result.asLibraryCallable() = node.(FlowSummaryNode).getSummarizedCallable() + or + result.asLibraryCallable() = node.(FlowSummaryIntermediateAwaitStoreNode).getSummarizedCallable() } private newtype TDataFlowType = @@ -189,6 +234,8 @@ DataFlowType getNodeType(Node node) { result = TTodoDataFlowType() and exists(no predicate nodeIsHidden(Node node) { DataFlow::PathNode::shouldNodeBeHidden(node) + or + node instanceof FlowSummaryNode } predicate neverSkipInPathGraph(Node node) { @@ -232,6 +279,11 @@ private newtype TDataFlowCall = node = TValueNode(any(PropAccess p)) or node = TPropNode(any(PropertyPattern p)) } or + MkSummaryCall( + FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver + ) { + FlowSummaryImpl::Private::summaryCallbackRange(c, receiver) + } class DataFlowCall extends TDataFlowCall { DataFlowCallable getEnclosingCallable() { none() } // Overridden in subclass @@ -246,6 +298,13 @@ class DataFlowCall extends TDataFlowCall { DataFlow::InvokeNode asBoundCall(int boundArgs) { this = MkBoundCall(result, boundArgs) } + + predicate isSummaryCall( + FlowSummaryImpl::Public::SummarizedCallable enclosingCallable, + FlowSummaryImpl::Private::SummaryNode receiver + ) { + this = MkSummaryCall(enclosingCallable, receiver) + } predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { @@ -334,6 +393,23 @@ private class AccessorCall extends DataFlowCall, MkAccessorCall { ref.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) } } +class SummaryCall extends DataFlowCall, MkSummaryCall { + private FlowSummaryImpl::Public::SummarizedCallable enclosingCallable; + private FlowSummaryImpl::Private::SummaryNode receiver; + + SummaryCall() { this = MkSummaryCall(enclosingCallable, receiver) } + + override DataFlowCallable getEnclosingCallable() { + result.asLibraryCallable() = enclosingCallable + } + + override string toString() { + result = "[summary] call to " + receiver + " in " + enclosingCallable + } + + /** Gets the receiver node. */ + FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver } +} private int getMaxArity() { // TODO: account for flow summaries @@ -416,6 +492,11 @@ DataFlowCallable viableCallable(DataFlowCall node) { ) or result.asSourceCallableNotExterns() = node.asAccessorCall().getAnAccessorCallee().getFunction() + or + exists(LibraryCallable callable | + result = MkLibraryCallable(callable) and + node.asOrdinaryCall() = [callable.getACall(), callable.getACallSimple()] + ) } /** @@ -455,6 +536,9 @@ private predicate valuePreservingStep(Node node1, Node node2) { or node2 = FlowSteps::getThrowTarget(node1) or + FlowSummaryImpl::Private::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(), + node2.(FlowSummaryNode).getSummaryNode(), true) + or // Step from post-update nodes to local sources of the pre-update node. This emulates how JS usually tracks side effects. exists(PostUpdateNode postUpdate | node1 = postUpdate and @@ -480,6 +564,9 @@ predicate localMustFlowStep(Node node1, Node node2) { node1 = node2.getImmediate predicate jumpStep(Node node1, Node node2) { valuePreservingStep(node1, node2) and node1.getContainer() != node2.getContainer() + or + FlowSummaryImpl::Private::Steps::summaryJumpStep(node1.(FlowSummaryNode).getSummaryNode(), + node2.(FlowSummaryNode).getSummaryNode()) } /** @@ -497,6 +584,13 @@ predicate readStep(Node node1, ContentSet c, Node node2) { not exists(read.getPropertyName()) and c = ContentSet::arrayElement() ) + or + exists(ContentSet contentSet | + FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), + contentSet, node2.(FlowSummaryNode).getSummaryNode()) + | + c = contentSet + ) } /** Gets the post-update node for which `node` is the corresponding pre-update node. */ @@ -523,6 +617,10 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { // Target the post-update node if one exists (for object literals we do not generate post-update nodes) node2 = tryGetPostUpdate(write.getBase()) ) + or + FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c, + node2.(FlowSummaryNode).getSummaryNode()) and + ) } /** @@ -531,6 +629,7 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { * in `x.f = newValue`. */ predicate clearsContent(Node n, ContentSet c) { + FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c) } /** @@ -538,6 +637,7 @@ predicate clearsContent(Node n, ContentSet c) { * at node `n`. */ predicate expectsContent(Node n, ContentSet c) { + FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c) } /** @@ -557,6 +657,7 @@ int accessPathLimit() { result = 5 } * by default as a heuristic. */ predicate allowParameterReturnInSelf(ParameterNode p) { + FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(p) } class LambdaCallKind = Unit; @@ -568,6 +669,8 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) /** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { + call.isSummaryCall(_, receiver.(FlowSummaryNode).getSummaryNode()) and exists(kind) + or receiver = call.asOrdinaryCall().getCalleeNode() and exists(kind) } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll new file mode 100644 index 00000000000..71c79486225 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -0,0 +1,339 @@ +/** + * Provides JS specific classes and predicates for defining flow summaries. + */ + +private import javascript +private import semmle.javascript.dataflow.internal.DataFlowPrivate +private import semmle.javascript.dataflow.internal.Contents::Private +private import semmle.javascript.dataflow.FlowSummary as FlowSummary +private import sharedlib.DataFlowImplCommon +private import sharedlib.FlowSummaryImpl::Private as Private +private import sharedlib.FlowSummaryImpl::Public +import semmle.javascript.frameworks.data.internal.AccessPathSyntax as AccessPathSyntax + +private class Node = DataFlow::Node; + +/** + * A class of callables that are candidates for flow summary modeling. + */ +class SummarizedCallableBase = string; + +/** + * A class of callables that are candidates for neutral modeling. + */ +class NeutralCallableBase = string; + +/** + * Holds if a neutral model exists for `c` of kind `kind` and with provenance `provenance`. + * Note: Neutral models have not been implemented for Javascript. + */ +predicate neutralElement(NeutralCallableBase c, string kind, string provenance) { none() } + +DataFlowCallable inject(SummarizedCallable c) { result.asLibraryCallable() = c } + +/** Gets the parameter position representing a callback itself, if any. */ +ArgumentPosition callbackSelfParameterPosition() { result.isFunctionSelfReference() } + +/** Gets the synthesized data-flow call for `receiver`. */ +SummaryCall summaryDataFlowCall(Private::SummaryNode receiver) { receiver = result.getReceiver() } + +/** Gets the type of content `c`. */ +DataFlowType getContentType(ContentSet c) { any() } + +/** Gets the type of the parameter at the given position. */ +bindingset[c, pos] +DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) { any() } + +/** Gets the return type of kind `rk` for callable `c`. */ +bindingset[c, rk] +DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { any() } + +/** + * Gets the type of the `i`th parameter in a synthesized call that targets a + * callback of type `t`. + */ +bindingset[t, pos] +DataFlowType getCallbackParameterType(DataFlowType t, ArgumentPosition pos) { any() } + +/** + * Gets the return type of kind `rk` in a synthesized call that targets a + * callback of type `t`. + */ +DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { any() } + +/** Gets the type of synthetic global `sg`. */ +DataFlowType getSyntheticGlobalType(SummaryComponent::SyntheticGlobal sg) { any() } + +/** + * Holds if an external flow summary exists for `c` with input specification + * `input`, output specification `output`, kind `kind`, and provenance `provenance`. + */ +predicate summaryElement( + FlowSummary::SummarizedCallable c, string input, string output, string kind, string provenance +) { + exists(boolean preservesValue | + c.propagatesFlowExt(input, output, preservesValue) and + (if preservesValue = true then kind = "value" else kind = "taint") and + provenance = "manual" + ) +} + +/** + * Holds if a neutral summary model exists for `c` with provenance `provenance`, + * which means that there is no flow through `c`. + * Note. Neutral models have not been implemented for JS. + */ +predicate neutralSummaryElement(FlowSummary::SummarizedCallable c, string provenance) { none() } + +pragma[inline] +private SummaryComponent makeContentComponents( + Private::AccessPathToken token, string name, ContentSet contents +) { + token.getName() = name and + result = FlowSummary::SummaryComponent::content(contents) + or + token.getName() = "With" + name and + result = FlowSummary::SummaryComponent::withContent(contents) + or + token.getName() = "Without" + name and + result = FlowSummary::SummaryComponent::withoutContent(contents) +} + +pragma[inline] +private SummaryComponent makePropertyContentComponents( + Private::AccessPathToken token, string name, PropertyName content +) { + result = makeContentComponents(token, name, ContentSet::property(content)) +} + +/** + * Gets the content set corresponding to `Awaited[arg]`. + */ +private ContentSet getPromiseContent(string arg) { + arg = "value" and result = ContentSet::promiseValue() + or + arg = "error" and result = ContentSet::promiseError() +} + +pragma[nomagic] +private predicate positionName(ParameterPosition pos, string operand) { + operand = pos.asPositional().toString() + or + pos.isThis() and operand = "this" + or + pos.isFunctionSelfReference() and operand = "function" + or + pos.isArgumentsArray() and operand = "arguments-array" + or + operand = pos.asPositionalLowerBound() + ".." +} + +/** + * Holds if `operand` desugars to the given `pos`. Only used for parsing. + */ +bindingset[operand] +private predicate desugaredPositionName(ParameterPosition pos, string operand) { + operand = "any" and + pos.asPositionalLowerBound() = 0 + or + pos.asPositional() = AccessPathSyntax::AccessPath::parseInt(operand) // parse closed intervals +} + +bindingset[operand] +private ParameterPosition parsePosition(string operand) { + positionName(result, operand) or desugaredPositionName(result, operand) +} + +/** + * Gets the summary component for specification component `c`, if any. + * + * This covers all the JS-specific components of a flow summary. + */ +SummaryComponent interpretComponentSpecific(Private::AccessPathToken c) { + c.getName() = "Argument" and + result = FlowSummary::SummaryComponent::argument(parsePosition(c.getAnArgument())) + or + c.getName() = "Parameter" and + result = FlowSummary::SummaryComponent::parameter(parsePosition(c.getAnArgument())) + or + result = makePropertyContentComponents(c, "Member", c.getAnArgument()) + or + result = makeContentComponents(c, "Awaited", getPromiseContent(c.getAnArgument())) + or + c.getNumArgument() = 0 and + result = makeContentComponents(c, "ArrayElement", ContentSet::arrayElement()) + or + c.getAnArgument() = "?" and + result = makeContentComponents(c, "ArrayElement", ContentSet::arrayElementUnknown()) + or + exists(int n | + n = c.getAnArgument().toInt() and + result = makeContentComponents(c, "ArrayElement", ContentSet::arrayElementKnown(n)) + or + // ArrayElement[n!] refers to index n, and never the unknown content + c.getAnArgument().regexpCapture("(\\d+)!", 1).toInt() = n and + result = makePropertyContentComponents(c, "ArrayElement", n.toString()) + or + // ArrayElement[n..] refers to index n or greater + n = AccessPathSyntax::AccessPath::parseLowerBound(c.getAnArgument()) and + result = makeContentComponents(c, "ArrayElement", ContentSet::arrayElementLowerBoundFromInt(n)) + ) + or + c.getNumArgument() = 0 and + result = makeContentComponents(c, "SetElement", ContentSet::setElement()) + or + c.getNumArgument() = 0 and + result = makeContentComponents(c, "IteratorElement", ContentSet::iteratorElement()) + or + c.getNumArgument() = 0 and + result = makeContentComponents(c, "IteratorError", ContentSet::iteratorError()) + or + c.getNumArgument() = 0 and + result = makeContentComponents(c, "MapKey", ContentSet::mapKey()) + or + // + // Note: although it is supported internally, we currently do not expose a syntax for MapValue with a known key + // + c.getNumArgument() = 0 and + result = makeContentComponents(c, "MapValue", ContentSet::mapValueAll()) + or + c.getName() = "ReturnValue" and + c.getAnArgument() = "exception" and + result = SummaryComponent::return(MkExceptionalReturnKind()) +} + +private string getMadStringFromContentSetAux(ContentSet cs) { + cs = ContentSet::arrayElement() and + result = "ArrayElement" + or + cs = ContentSet::arrayElementUnknown() and + result = "ArrayElement[?]" + or + exists(int n | + cs = ContentSet::arrayElementLowerBound(n) and + result = "ArrayElement[" + n + "..]" and + n > 0 // n=0 is just 'ArrayElement' + or + cs = ContentSet::arrayElementKnown(n) and + result = "ArrayElement[" + n + "]" + or + n = cs.asPropertyName().toInt() and + n >= 0 and + result = "ArrayElement[" + n + "!]" + ) + or + cs = ContentSet::mapValueAll() and result = "MapValue" + or + cs = ContentSet::mapKey() and result = "MapKey" + or + cs = ContentSet::setElement() and result = "SetElement" + or + cs = ContentSet::iteratorElement() and result = "IteratorElement" + or + cs = ContentSet::iteratorError() and result = "IteratorError" + or + exists(string awaitedArg | + cs = getPromiseContent(awaitedArg) and + result = "Awaited[" + awaitedArg + "]" + ) +} + +private string getMadStringFromContentSet(ContentSet cs) { + result = getMadStringFromContentSetAux(cs) + or + not exists(getMadStringFromContentSetAux(cs)) and + result = "Member[" + cs.asSingleton() + "]" +} + +/** Gets the textual representation of a summary component in the format used for MaD models. */ +string getMadRepresentationSpecific(SummaryComponent sc) { + exists(ContentSet cs | + sc = Private::TContentSummaryComponent(cs) and result = getMadStringFromContentSet(cs) + ) + or + exists(ReturnKind rk | + sc = Private::TReturnSummaryComponent(rk) and + not rk = getReturnValueKind() and + result = "ReturnValue[" + rk + "]" + ) +} + +/** Gets the textual representation of a parameter position in the format used for flow summaries. */ +bindingset[pos] +string getParameterPosition(ParameterPosition pos) { positionName(pos, result) and result != "any" } + +/** Gets the textual representation of an argument position in the format used for flow summaries. */ +bindingset[pos] +string getArgumentPosition(ArgumentPosition pos) { positionName(pos, result) and result != "any" } + +/** Holds if input specification component `c` needs a reference. */ +predicate inputNeedsReferenceSpecific(string c) { none() } + +/** Holds if output specification component `c` needs a reference. */ +predicate outputNeedsReferenceSpecific(string c) { none() } + +/** Gets the return kind corresponding to specification `"ReturnValue"`. */ +MkNormalReturnKind getReturnValueKind() { any() } + +/** + * All definitions in this module are required by the shared implementation + * (for source/sink interpretation), but they are unused for JS, where + * we rely on API graphs instead. + */ +private module UnusedSourceSinkInterpretation { + /** + * Holds if an external source specification exists for `n` with output specification + * `output`, kind `kind`, and provenance `provenance`. + */ + predicate sourceElement(AstNode n, string output, string kind, string provenance) { none() } + + /** + * Holds if an external sink specification exists for `n` with input specification + * `input`, kind `kind` and provenance `provenance`. + */ + predicate sinkElement(AstNode n, string input, string kind, string provenance) { none() } + + class SourceOrSinkElement = AstNode; + + /** An entity used to interpret a source/sink specification. */ + class InterpretNode extends AstNode { + /** Gets the element that this node corresponds to, if any. */ + SourceOrSinkElement asElement() { none() } + + /** Gets the data-flow node that this node corresponds to, if any. */ + Node asNode() { none() } + + /** Gets the call that this node corresponds to, if any. */ + DataFlowCall asCall() { none() } + + /** Gets the callable that this node corresponds to, if any. */ + DataFlowCallable asCallable() { none() } + + /** Gets the target of this call, if any. */ + StmtContainer getCallTarget() { none() } + } + + /** Provides additional sink specification logic. */ + predicate interpretOutputSpecific(string c, InterpretNode mid, InterpretNode node) { none() } + + /** Provides additional source specification logic. */ + predicate interpretInputSpecific(string c, InterpretNode mid, InterpretNode node) { none() } +} + +import UnusedSourceSinkInterpretation + +/** Gets the argument position obtained by parsing `X` in `Parameter[X]`. */ +bindingset[s] +ArgumentPosition parseParamBody(string s) { + s = "this" and result.isThis() + or + s = "function" and result.isFunctionSelfReference() + or + result.asPositional() = AccessPathSyntax::AccessPath::parseInt(s) +} + +/** Gets the parameter position obtained by parsing `X` in `Argument[X]`. */ +bindingset[s] +ParameterPosition parseArgBody(string s) { + result = parseParamBody(s) // Currently these are identical +} diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index 42c06d318f0..aa965e24828 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -1,9 +1,12 @@ private import javascript private import semmle.javascript.dataflow.internal.DataFlowPrivate private import semmle.javascript.dataflow.internal.Contents::Public +private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as FlowSummaryImpl cached predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + FlowSummaryImpl::Private::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(), + node2.(FlowSummaryNode).getSummaryNode(), false) } /** diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImplSpecific.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImplSpecific.qll new file mode 100644 index 00000000000..a8b541c1b31 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImplSpecific.qll @@ -0,0 +1,12 @@ +private import javascript + +// This file provides the input to FlowSummaryImpl.qll, which is shared via identical-files.json. +module Private { + import semmle.javascript.dataflow.internal.DataFlowPrivate +} + +module Public { + import semmle.javascript.dataflow.internal.Contents::Public + + class Node = DataFlow::Node; +} diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImplSpecific.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImplSpecific.qll new file mode 100644 index 00000000000..71b4db2f016 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImplSpecific.qll @@ -0,0 +1 @@ +import semmle.javascript.dataflow.internal.FlowSummaryPrivate From 32070abb27175372a4b9c475d1eaea1530fa19c8 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 19:59:35 +0200 Subject: [PATCH 013/514] JS: Implicitly treat array steps as taint steps --- .../javascript/dataflow/internal/TaintTrackingPrivate.qll | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index aa965e24828..119293d8249 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -7,6 +7,13 @@ cached predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { FlowSummaryImpl::Private::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(), node2.(FlowSummaryNode).getSummaryNode(), false) + or + // Convert steps into and out of array elements to plain taint steps + FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), + ContentSet::arrayElement(), node2.(FlowSummaryNode).getSummaryNode()) + or + FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), + ContentSet::arrayElement(), node2.(FlowSummaryNode).getSummaryNode()) } /** From 293899d64850760e4127860ead8fde3a6c2b669a Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 20:00:09 +0200 Subject: [PATCH 014/514] JS: Add 'Awaited' token --- .../dataflow/internal/DataFlowNode.qll | 3 + .../dataflow/internal/DataFlowPrivate.qll | 61 +++++++++++++++++++ .../dataflow/internal/FlowSummaryPrivate.qll | 7 +++ 3 files changed, 71 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index 22df2f07189..cfc30582877 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -50,6 +50,9 @@ private module Cached { TConstructorThisArgumentNode(InvokeExpr e) { e instanceof NewExpr or e instanceof SuperCall } or TConstructorThisPostUpdate(Constructor ctor) or TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or + TFlowSummaryIntermediateAwaitStoreNode(FlowSummaryImpl::Private::SummaryNode sn) { + FlowSummaryImpl::Private::Steps::summaryStoreStep(sn, MkAwaited(), _) + } or } import Cached diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index fe222b1cf3d..bf78a739507 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -23,6 +23,23 @@ class FlowSummaryNode extends DataFlow::Node, TFlowSummaryNode { override string toString() { result = this.getSummaryNode().toString() } } +class FlowSummaryIntermediateAwaitStoreNode extends DataFlow::Node, + TFlowSummaryIntermediateAwaitStoreNode +{ + FlowSummaryImpl::Private::SummaryNode getSummaryNode() { + this = TFlowSummaryIntermediateAwaitStoreNode(result) + } + + /** Gets the summarized callable that this node belongs to. */ + FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() { + result = this.getSummaryNode().getSummarizedCallable() + } + + override string toString() { + result = this.getSummaryNode().toString() + " [intermediate node for Awaited store]" + } +} + cached newtype TReturnKind = MkNormalReturnKind() or @@ -236,6 +253,8 @@ predicate nodeIsHidden(Node node) { DataFlow::PathNode::shouldNodeBeHidden(node) or node instanceof FlowSummaryNode + or + node instanceof FlowSummaryIntermediateAwaitStoreNode } predicate neverSkipInPathGraph(Node node) { @@ -552,6 +571,21 @@ predicate simpleLocalFlowStep(Node node1, Node node2) { valuePreservingStep(node1, node2) and nodeGetEnclosingCallable(pragma[only_bind_out](node1)) = nodeGetEnclosingCallable(pragma[only_bind_out](node2)) + or + exists(FlowSummaryImpl::Private::SummaryNode input, FlowSummaryImpl::Private::SummaryNode output | + FlowSummaryImpl::Private::Steps::summaryStoreStep(input, MkAwaited(), output) and + node1 = TFlowSummaryNode(input) and + ( + node2 = TFlowSummaryNode(output) and + not node2 instanceof PostUpdateNode // When doing a store-back, do not add the local flow edge + or + node2 = TFlowSummaryIntermediateAwaitStoreNode(input) + ) + or + FlowSummaryImpl::Private::Steps::summaryReadStep(input, MkAwaited(), output) and + node1 = TFlowSummaryNode(input) and + node2 = TFlowSummaryNode(output) + ) } predicate localMustFlowStep(Node node1, Node node2) { node1 = node2.getImmediatePredecessor() } @@ -589,7 +623,11 @@ predicate readStep(Node node1, ContentSet c, Node node2) { FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), contentSet, node2.(FlowSummaryNode).getSummaryNode()) | + not isSpecialContentSet(contentSet) and c = contentSet + or + contentSet = MkAwaited() and + c = ContentSet::promiseValue() ) } @@ -620,6 +658,14 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { or FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c, node2.(FlowSummaryNode).getSummaryNode()) and + not isSpecialContentSet(c) + or + // Store into Awaited + exists(FlowSummaryImpl::Private::SummaryNode input, FlowSummaryImpl::Private::SummaryNode output | + FlowSummaryImpl::Private::Steps::summaryStoreStep(input, MkAwaited(), output) and + node1 = TFlowSummaryIntermediateAwaitStoreNode(input) and + node2 = TFlowSummaryNode(output) and + c = ContentSet::promiseValue() ) } @@ -630,6 +676,15 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { */ predicate clearsContent(Node n, ContentSet c) { FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c) + or + // Clear promise content before storing into promise value, to avoid creating nested promises + n = TFlowSummaryIntermediateAwaitStoreNode(_) and + c = MkPromiseFilter() + or + // After reading from Awaited, the output must not be stored in a promise content + FlowSummaryImpl::Private::Steps::summaryReadStep(_, MkAwaited(), + n.(FlowSummaryNode).getSummaryNode()) and + c = MkPromiseFilter() } /** @@ -638,6 +693,12 @@ predicate clearsContent(Node n, ContentSet c) { */ predicate expectsContent(Node n, ContentSet c) { FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c) + or + // After storing into Awaited, the result must be stored in a promise-content. + // There is a value step from the input directly to this node, hence the need for expectsContent. + FlowSummaryImpl::Private::Steps::summaryStoreStep(_, MkAwaited(), + n.(FlowSummaryNode).getSummaryNode()) and + c = MkPromiseFilter() } /** diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index 71c79486225..32739451ede 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -200,6 +200,11 @@ SummaryComponent interpretComponentSpecific(Private::AccessPathToken c) { c.getName() = "ReturnValue" and c.getAnArgument() = "exception" and result = SummaryComponent::return(MkExceptionalReturnKind()) + or + // Awaited is mapped down to a combination steps that handle coercion and promise-flattening. + c.getName() = "Awaited" and + c.getNumArgument() = 0 and + result = SummaryComponent::content(MkAwaited()) } private string getMadStringFromContentSetAux(ContentSet cs) { @@ -236,6 +241,8 @@ private string getMadStringFromContentSetAux(ContentSet cs) { cs = getPromiseContent(awaitedArg) and result = "Awaited[" + awaitedArg + "]" ) + or + cs = MkAwaited() and result = "Awaited" } private string getMadStringFromContentSet(ContentSet cs) { From 5bccc652c86751f5c00d203258a2610816b81888 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Oct 2023 10:30:28 +0200 Subject: [PATCH 015/514] JS: Move SharedFlowStep to AdditionalFlowSteps.qll NOTE that this commit only moves around code. There are no changes. --- .../dataflow/AdditionalFlowSteps.qll | 114 ++++++++++++++++ .../javascript/dataflow/Configuration.qll | 123 +----------------- 2 files changed, 115 insertions(+), 122 deletions(-) create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll diff --git a/javascript/ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll b/javascript/ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll new file mode 100644 index 00000000000..fb031101088 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll @@ -0,0 +1,114 @@ +private import javascript + +/** + * A data flow edge that should be added to all data flow configurations in + * addition to standard data flow edges. + * + * This class is a singleton, and thus subclasses do not need to specify a characteristic predicate. + * + * Note: For performance reasons, all subclasses of this class should be part + * of the standard library. Override `Configuration::isAdditionalFlowStep` + * for analysis-specific flow steps. + */ +class SharedFlowStep extends Unit { + /** + * Holds if `pred` → `succ` should be considered a data flow edge. + */ + predicate step(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a data flow edge + * transforming values with label `predlbl` to have label `succlbl`. + */ + predicate step( + DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel predlbl, + DataFlow::FlowLabel succlbl + ) { + none() + } + + /** + * Holds if `pred` should be stored in the object `succ` under the property `prop`. + * The object `succ` must be a `DataFlow::SourceNode` for the object wherein the value is stored. + */ + predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { none() } + + /** + * Holds if the property `prop` of the object `pred` should be loaded into `succ`. + */ + predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { none() } + + /** + * Holds if the property `prop` should be copied from the object `pred` to the object `succ`. + */ + predicate loadStoreStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { none() } + + /** + * Holds if the property `loadProp` should be copied from the object `pred` to the property `storeProp` of object `succ`. + */ + predicate loadStoreStep( + DataFlow::Node pred, DataFlow::Node succ, string loadProp, string storeProp + ) { + none() + } +} + +/** + * Contains predicates for accessing the steps contributed by `SharedFlowStep`, `LegacyFlowStep`, and `AdditionalFlowStep` subclasses. + */ +module SharedFlowStep { + /** + * Holds if `pred` → `succ` should be considered a data flow edge. + */ + pragma[inline] + predicate step(DataFlow::Node pred, DataFlow::Node succ) { + any(SharedFlowStep s).step(pred, succ) + } + + /** + * Holds if `pred` should be stored in the object `succ` under the property `prop`. + * The object `succ` must be a `DataFlow::SourceNode` for the object wherein the value is stored. + */ + pragma[inline] + predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { + any(SharedFlowStep s).storeStep(pred, succ, prop) + } + + /** + * Holds if the property `prop` of the object `pred` should be loaded into `succ`. + */ + pragma[inline] + predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { + any(SharedFlowStep s).loadStep(pred, succ, prop) + } + + // The following are aliases for old step predicates that have no corresponding predicate in AdditionalFlowStep + /** + * Holds if `pred` → `succ` should be considered a data flow edge + * transforming values with label `predlbl` to have label `succlbl`. + */ + predicate step( + DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel predlbl, + DataFlow::FlowLabel succlbl + ) { + any(SharedFlowStep s).step(pred, succ, predlbl, succlbl) + } + + /** + * Holds if the property `prop` should be copied from the object `pred` to the object `succ`. + */ + cached + predicate loadStoreStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { + any(SharedFlowStep s).loadStoreStep(pred, succ, prop) + } + + /** + * Holds if the property `loadProp` should be copied from the object `pred` to the property `storeProp` of object `succ`. + */ + cached + predicate loadStoreStep( + DataFlow::Node pred, DataFlow::Node succ, string loadProp, string storeProp + ) { + any(SharedFlowStep s).loadStoreStep(pred, succ, loadProp, storeProp) + } +} diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index d0087dcdca0..c693ebf1206 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -74,6 +74,7 @@ private import internal.AccessPaths private import internal.CallGraphs private import semmle.javascript.Unit private import semmle.javascript.internal.CachedStages +private import AdditionalFlowSteps /** * A data flow tracking configuration for finding inter-procedural paths from @@ -575,128 +576,6 @@ abstract class LabeledBarrierGuardNode extends BarrierGuardNode { override predicate blocks(boolean outcome, Expr e) { none() } } -/** - * A data flow edge that should be added to all data flow configurations in - * addition to standard data flow edges. - * - * This class is a singleton, and thus subclasses do not need to specify a characteristic predicate. - * - * Note: For performance reasons, all subclasses of this class should be part - * of the standard library. Override `Configuration::isAdditionalFlowStep` - * for analysis-specific flow steps. - */ -class SharedFlowStep extends Unit { - /** - * Holds if `pred` → `succ` should be considered a data flow edge. - */ - predicate step(DataFlow::Node pred, DataFlow::Node succ) { none() } - - /** - * Holds if `pred` → `succ` should be considered a data flow edge - * transforming values with label `predlbl` to have label `succlbl`. - */ - predicate step( - DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel predlbl, - DataFlow::FlowLabel succlbl - ) { - none() - } - - /** - * Holds if `pred` should be stored in the object `succ` under the property `prop`. - * The object `succ` must be a `DataFlow::SourceNode` for the object wherein the value is stored. - */ - predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { none() } - - /** - * Holds if the property `prop` of the object `pred` should be loaded into `succ`. - */ - predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { none() } - - /** - * Holds if the property `prop` should be copied from the object `pred` to the object `succ`. - */ - predicate loadStoreStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { none() } - - /** - * Holds if the property `loadProp` should be copied from the object `pred` to the property `storeProp` of object `succ`. - */ - predicate loadStoreStep( - DataFlow::Node pred, DataFlow::Node succ, string loadProp, string storeProp - ) { - none() - } -} - -/** - * Contains predicates for accessing the steps contributed by `SharedFlowStep` subclasses. - */ -cached -module SharedFlowStep { - cached - private module Internal { - // Forces this to be part of the `FlowSteps` stage. - // We use a public predicate in a private module to avoid warnings about this being unused. - cached - predicate forceStage() { Stages::FlowSteps::ref() } - } - - /** - * Holds if `pred` → `succ` should be considered a data flow edge. - */ - cached - predicate step(DataFlow::Node pred, DataFlow::Node succ) { - any(SharedFlowStep s).step(pred, succ) - } - - /** - * Holds if `pred` → `succ` should be considered a data flow edge - * transforming values with label `predlbl` to have label `succlbl`. - */ - cached - predicate step( - DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel predlbl, - DataFlow::FlowLabel succlbl - ) { - any(SharedFlowStep s).step(pred, succ, predlbl, succlbl) - } - - /** - * Holds if `pred` should be stored in the object `succ` under the property `prop`. - * The object `succ` must be a `DataFlow::SourceNode` for the object wherein the value is stored. - */ - cached - predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { - any(SharedFlowStep s).storeStep(pred, succ, prop) - } - - /** - * Holds if the property `prop` of the object `pred` should be loaded into `succ`. - */ - cached - predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { - any(SharedFlowStep s).loadStep(pred, succ, prop) - } - - /** - * Holds if the property `prop` should be copied from the object `pred` to the object `succ`. - */ - cached - predicate loadStoreStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { - any(SharedFlowStep s).loadStoreStep(pred, succ, prop) - } - - /** - * Holds if the property `loadProp` should be copied from the object `pred` to the property `storeProp` of object `succ`. - */ - cached - predicate loadStoreStep( - DataFlow::Node pred, DataFlow::Node succ, string loadProp, string storeProp - ) { - any(SharedFlowStep s).loadStoreStep(pred, succ, loadProp, storeProp) - } -} - /** * A collection of pseudo-properties that are used in multiple files. * From c24a0e00f5058db905abf91ea56fb982228ba55c Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Oct 2023 10:33:17 +0200 Subject: [PATCH 016/514] JS: Move SharedTaintStep to AdditionalTaintSteps.qll NOTE that this commit only moves around code. There are no changes. --- .../dataflow/AdditionalTaintSteps.qll | 250 ++++++++++++++++++ .../javascript/dataflow/TaintTracking.qll | 247 +---------------- 2 files changed, 252 insertions(+), 245 deletions(-) create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll diff --git a/javascript/ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll b/javascript/ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll new file mode 100644 index 00000000000..926f6e1325c --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll @@ -0,0 +1,250 @@ +private import javascript +private import semmle.javascript.internal.CachedStages + +/** + * A taint-propagating data flow edge that should be added to all taint tracking + * configurations in addition to standard data flow edges. + * + * This class is a singleton, and thus subclasses do not need to specify a characteristic predicate. + * + * Note: For performance reasons, all subclasses of this class should be part + * of the standard library. Override `Configuration::isAdditionalTaintStep` + * for analysis-specific taint steps. + * + * This class has multiple kinds of `step` predicates; these all have the same + * effect on taint-tracking configurations. However, the categorization of steps + * allows some data-flow configurations to opt in to specific kinds of taint steps. + */ +class SharedTaintStep extends Unit { + // Each step relation in this class should have a cached version in the `Cached` module + // and be included in the `sharedTaintStep` predicate. + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge. + */ + predicate step(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through URI manipulation. + * + * Does not include string operations that aren't specific to URIs, such + * as concatenation and substring operations. + */ + predicate uriStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge contributed by the heuristics library. + * + * Such steps are provided by the `semmle.javascript.heuristics` libraries + * and will default to be being empty if those libraries are not imported. + */ + predicate heuristicStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through persistent storage. + */ + predicate persistentStorageStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through the heap. + */ + predicate heapStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through arrays. + * + * These steps considers an array to be tainted if it contains tainted elements. + */ + predicate arrayStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through the `state` or `props` or a React component. + */ + predicate viewComponentStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through string concatenation. + */ + predicate stringConcatenationStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through string manipulation (other than concatenation). + */ + predicate stringManipulationStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through data serialization, such as `JSON.stringify`. + */ + predicate serializeStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through data deserialization, such as `JSON.parse`. + */ + predicate deserializeStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through a promise. + * + * These steps consider a promise object to tainted if it can resolve to + * a tainted value. + */ + predicate promiseStep(DataFlow::Node pred, DataFlow::Node succ) { none() } +} + +/** + * Module existing only to ensure all taint steps are cached as a single stage, + * and without the the `Unit` type column. + */ +cached +private module Cached { + cached + predicate forceStage() { + Stages::Taint::ref() + } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge, which doesn't fit into a more specific category. + */ + cached + predicate genericStep(DataFlow::Node pred, DataFlow::Node succ) { + any(SharedTaintStep step).step(pred, succ) + } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge, contribued by the heuristics library. + */ + cached + predicate heuristicStep(DataFlow::Node pred, DataFlow::Node succ) { + any(SharedTaintStep step).heuristicStep(pred, succ) + } + + /** + * Public taint step relations. + */ + cached + module Public { + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through a URI library function. + */ + cached + predicate uriStep(DataFlow::Node pred, DataFlow::Node succ) { + any(SharedTaintStep step).uriStep(pred, succ) + } + + /** + * Holds if `pred -> succ` is a taint propagating data flow edge through persistent storage. + */ + cached + predicate persistentStorageStep(DataFlow::Node pred, DataFlow::Node succ) { + any(SharedTaintStep step).persistentStorageStep(pred, succ) + } + + /** + * Holds if `pred -> succ` is a taint propagating data flow edge through the heap. + */ + cached + predicate heapStep(DataFlow::Node pred, DataFlow::Node succ) { + any(SharedTaintStep step).heapStep(pred, succ) + } + + /** + * Holds if `pred -> succ` is a taint propagating data flow edge through an array. + */ + cached + predicate arrayStep(DataFlow::Node pred, DataFlow::Node succ) { + any(SharedTaintStep step).arrayStep(pred, succ) + } + + /** + * Holds if `pred -> succ` is a taint propagating data flow edge through the + * properties of a view compenent, such as the `state` or `props` of a React component. + */ + cached + predicate viewComponentStep(DataFlow::Node pred, DataFlow::Node succ) { + any(SharedTaintStep step).viewComponentStep(pred, succ) + } + + /** + * Holds if `pred -> succ` is a taint propagating data flow edge through string + * concatenation. + */ + cached + predicate stringConcatenationStep(DataFlow::Node pred, DataFlow::Node succ) { + any(SharedTaintStep step).stringConcatenationStep(pred, succ) + } + + /** + * Holds if `pred -> succ` is a taint propagating data flow edge through string manipulation + * (other than concatenation). + */ + cached + predicate stringManipulationStep(DataFlow::Node pred, DataFlow::Node succ) { + any(SharedTaintStep step).stringManipulationStep(pred, succ) + } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through data serialization, such as `JSON.stringify`. + */ + cached + predicate serializeStep(DataFlow::Node pred, DataFlow::Node succ) { + any(SharedTaintStep step).serializeStep(pred, succ) + } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through data deserialization, such as `JSON.parse`. + */ + cached + predicate deserializeStep(DataFlow::Node pred, DataFlow::Node succ) { + any(SharedTaintStep step).deserializeStep(pred, succ) + } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through a promise. + * + * These steps consider a promise object to tainted if it can resolve to + * a tainted value. + */ + cached + predicate promiseStep(DataFlow::Node pred, DataFlow::Node succ) { + any(SharedTaintStep step).promiseStep(pred, succ) + } + } +} + +import Cached::Public + +/** + * Holds if `pred -> succ` is an edge used by all taint-tracking configurations in + * the old data flow library. + */ +predicate sharedTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + Cached::genericStep(pred, succ) or + Cached::heuristicStep(pred, succ) or + uriStep(pred, succ) or + persistentStorageStep(pred, succ) or + heapStep(pred, succ) or + arrayStep(pred, succ) or + viewComponentStep(pred, succ) or + stringConcatenationStep(pred, succ) or + stringManipulationStep(pred, succ) or + serializeStep(pred, succ) or + deserializeStep(pred, succ) or + promiseStep(pred, succ) +} diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 11ce802ac72..3b62b33c4ad 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -23,6 +23,8 @@ private import semmle.javascript.internal.CachedStages * Provides classes for modeling taint propagation. */ module TaintTracking { + import AdditionalTaintSteps + /** * A data flow tracking configuration that considers taint propagation through * objects, arrays, promises and strings in addition to standard data flow. @@ -228,251 +230,6 @@ module TaintTracking { override predicate sanitizes(boolean outcome, Expr e) { none() } } - /** - * A taint-propagating data flow edge that should be added to all taint tracking - * configurations in addition to standard data flow edges. - * - * This class is a singleton, and thus subclasses do not need to specify a characteristic predicate. - * - * Note: For performance reasons, all subclasses of this class should be part - * of the standard library. Override `Configuration::isAdditionalTaintStep` - * for analysis-specific taint steps. - * - * This class has multiple kinds of `step` predicates; these all have the same - * effect on taint-tracking configurations. However, the categorization of steps - * allows some data-flow configurations to opt in to specific kinds of taint steps. - */ - class SharedTaintStep extends Unit { - // Each step relation in this class should have a cached version in the `Cached` module - // and be included in the `sharedTaintStep` predicate. - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge. - */ - predicate step(DataFlow::Node pred, DataFlow::Node succ) { none() } - - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge through URI manipulation. - * - * Does not include string operations that aren't specific to URIs, such - * as concatenation and substring operations. - */ - predicate uriStep(DataFlow::Node pred, DataFlow::Node succ) { none() } - - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge contributed by the heuristics library. - * - * Such steps are provided by the `semmle.javascript.heuristics` libraries - * and will default to be being empty if those libraries are not imported. - */ - predicate heuristicStep(DataFlow::Node pred, DataFlow::Node succ) { none() } - - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge through persistent storage. - */ - predicate persistentStorageStep(DataFlow::Node pred, DataFlow::Node succ) { none() } - - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge through the heap. - */ - predicate heapStep(DataFlow::Node pred, DataFlow::Node succ) { none() } - - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge through arrays. - * - * These steps considers an array to be tainted if it contains tainted elements. - */ - predicate arrayStep(DataFlow::Node pred, DataFlow::Node succ) { none() } - - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge through the `state` or `props` or a React component. - */ - predicate viewComponentStep(DataFlow::Node pred, DataFlow::Node succ) { none() } - - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge through string concatenation. - */ - predicate stringConcatenationStep(DataFlow::Node pred, DataFlow::Node succ) { none() } - - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge through string manipulation (other than concatenation). - */ - predicate stringManipulationStep(DataFlow::Node pred, DataFlow::Node succ) { none() } - - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge through data serialization, such as `JSON.stringify`. - */ - predicate serializeStep(DataFlow::Node pred, DataFlow::Node succ) { none() } - - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge through data deserialization, such as `JSON.parse`. - */ - predicate deserializeStep(DataFlow::Node pred, DataFlow::Node succ) { none() } - - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge through a promise. - * - * These steps consider a promise object to tainted if it can resolve to - * a tainted value. - */ - predicate promiseStep(DataFlow::Node pred, DataFlow::Node succ) { none() } - } - - /** - * Module existing only to ensure all taint steps are cached as a single stage, - * and without the the `Unit` type column. - */ - cached - private module Cached { - cached - predicate forceStage() { Stages::Taint::ref() } - - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge, which doesn't fit into a more specific category. - */ - cached - predicate genericStep(DataFlow::Node pred, DataFlow::Node succ) { - any(SharedTaintStep step).step(pred, succ) - } - - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge, contribued by the heuristics library. - */ - cached - predicate heuristicStep(DataFlow::Node pred, DataFlow::Node succ) { - any(SharedTaintStep step).heuristicStep(pred, succ) - } - - /** - * Public taint step relations. - */ - cached - module Public { - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge through a URI library function. - */ - cached - predicate uriStep(DataFlow::Node pred, DataFlow::Node succ) { - any(SharedTaintStep step).uriStep(pred, succ) - } - - /** - * Holds if `pred -> succ` is a taint propagating data flow edge through persistent storage. - */ - cached - predicate persistentStorageStep(DataFlow::Node pred, DataFlow::Node succ) { - any(SharedTaintStep step).persistentStorageStep(pred, succ) - } - - /** - * Holds if `pred -> succ` is a taint propagating data flow edge through the heap. - */ - cached - predicate heapStep(DataFlow::Node pred, DataFlow::Node succ) { - any(SharedTaintStep step).heapStep(pred, succ) - } - - /** - * Holds if `pred -> succ` is a taint propagating data flow edge through an array. - */ - cached - predicate arrayStep(DataFlow::Node pred, DataFlow::Node succ) { - any(SharedTaintStep step).arrayStep(pred, succ) - } - - /** - * Holds if `pred -> succ` is a taint propagating data flow edge through the - * properties of a view compenent, such as the `state` or `props` of a React component. - */ - cached - predicate viewComponentStep(DataFlow::Node pred, DataFlow::Node succ) { - any(SharedTaintStep step).viewComponentStep(pred, succ) - } - - /** - * Holds if `pred -> succ` is a taint propagating data flow edge through string - * concatenation. - */ - cached - predicate stringConcatenationStep(DataFlow::Node pred, DataFlow::Node succ) { - any(SharedTaintStep step).stringConcatenationStep(pred, succ) - } - - /** - * Holds if `pred -> succ` is a taint propagating data flow edge through string manipulation - * (other than concatenation). - */ - cached - predicate stringManipulationStep(DataFlow::Node pred, DataFlow::Node succ) { - any(SharedTaintStep step).stringManipulationStep(pred, succ) - } - - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge through data serialization, such as `JSON.stringify`. - */ - cached - predicate serializeStep(DataFlow::Node pred, DataFlow::Node succ) { - any(SharedTaintStep step).serializeStep(pred, succ) - } - - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge through data deserialization, such as `JSON.parse`. - */ - cached - predicate deserializeStep(DataFlow::Node pred, DataFlow::Node succ) { - any(SharedTaintStep step).deserializeStep(pred, succ) - } - - /** - * Holds if `pred` → `succ` should be considered a taint-propagating - * data flow edge through a promise. - * - * These steps consider a promise object to tainted if it can resolve to - * a tainted value. - */ - cached - predicate promiseStep(DataFlow::Node pred, DataFlow::Node succ) { - any(SharedTaintStep step).promiseStep(pred, succ) - } - } - } - - import Cached::Public - - /** - * Holds if `pred -> succ` is an edge used by all taint-tracking configurations. - */ - predicate sharedTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - Cached::genericStep(pred, succ) or - Cached::heuristicStep(pred, succ) or - uriStep(pred, succ) or - persistentStorageStep(pred, succ) or - heapStep(pred, succ) or - arrayStep(pred, succ) or - viewComponentStep(pred, succ) or - stringConcatenationStep(pred, succ) or - stringManipulationStep(pred, succ) or - serializeStep(pred, succ) or - deserializeStep(pred, succ) or - promiseStep(pred, succ) - } - /** Gets a data flow node referring to the client side URL. */ private DataFlow::SourceNode clientSideUrlRef(DataFlow::TypeTracker t) { t.start() and From 1afe06e3a5c2e62d7634a1daa6387369887d7185 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Oct 2023 10:36:11 +0200 Subject: [PATCH 017/514] JS: Add "additional" and "legacy" steps See the comment at the top of AdditionalFlowSteps.qll --- .../dataflow/AdditionalFlowSteps.qll | 274 ++++++++++++++++++ .../javascript/dataflow/Configuration.qll | 8 +- .../semmle/javascript/dataflow/DataFlow.qll | 1 + .../dataflow/internal/DataFlowPrivate.qll | 9 + .../dataflow/internal/FlowSteps.qll | 4 +- 5 files changed, 290 insertions(+), 6 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll b/javascript/ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll index fb031101088..d3935d463f1 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll @@ -1,4 +1,259 @@ +/** + * This contains three step-contribution classes, in order to support graceful deprecation of the old data flow library. + * + * - `class AdditionalFlowStep`: steps used only by the new dataflow library + * - `class LegacyFlowStep`: steps used only by the old data flow library + * - `class SharedFlowStep`: steps used by both + * + * The latter two will be deprecated in the future, but are currently not marked as `deprecated`. + * This is because a library model should be able to support both data flow libraries simultaneously, without itself getting + * deprecation warnings. + * + * To simplify correct consumption of these steps there is a correspondingly-named module for each: + * + * - `module AdditionalFlowStep`: exposes steps from `AdditionalFlowStep` and `SharedFlowStep` subclasses. + * - `module LegacyFlowStep`: exposes steps from `LegacyFlowStep` and `SharedFlowStep` subclasses. + * - `module SharedFlowStep`: exposes steps from all three classes. + * + * This design is intended to simplify consumption of steps, and to ensure existing consumers of `SharedFlowStep` + * outside this codebase will continue to work with as few surprises as possible. + */ + private import javascript +private import semmle.javascript.internal.CachedStages + +/** + * A value-preserving data flow edge that should be used in all data flow configurations in + * addition to standard data flow edges. + * + * This class is a singleton, and thus subclasses do not need to specify a characteristic predicate. + * + * Note: For performance reasons, all subclasses of this class should be part + * of the standard library. Override `Configuration::isAdditionalFlowStep` + * for analysis-specific flow steps. + */ +class AdditionalFlowStep extends Unit { + /** + * Holds if `pred` → `succ` should be considered a value-preserving data flow edge.f + */ + predicate step(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a value-preserving data flow edge that + * crosses calling contexts. + */ + predicate jumpStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` should be stored in the given `content` of the object `succ`. + */ + predicate storeStep(DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ) { + none() + } + + /** + * Holds if the given `content` of the object in `pred` should be read into `succ`. + */ + predicate readStep(DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ) { + none() + } +} + +/** + * Contains predicates for accessing the steps contributed by `AdditionalFlowStep` and `SharedFlowStep` subclasses. + */ +cached +module AdditionalFlowStep { + cached + private module Internal { + // Forces this to be part of the `FlowSteps` stage. + // We use a public predicate in a private module to avoid warnings about this being unused. + cached + predicate forceStage() { Stages::FlowSteps::ref() } + } + + bindingset[a, b] + pragma[inline_late] + private predicate sameContainer(DataFlow::Node a, DataFlow::Node b) { + a.getContainer() = b.getContainer() + } + + /** + * Holds if `pred` → `succ` should be considered a data flow edge. + */ + cached + predicate step(DataFlow::Node pred, DataFlow::Node succ) { + any(AdditionalFlowStep s).step(pred, succ) + or + any(SharedFlowStep s).step(pred, succ) and + sameContainer(pred, succ) + } + + /** + * Holds if `pred` → `succ` should be considered a value-preserving data flow edge that + * crosses calling contexts. + */ + cached + predicate jumpStep(DataFlow::Node pred, DataFlow::Node succ) { + any(AdditionalFlowStep s).jumpStep(pred, succ) + or + any(SharedFlowStep s).step(pred, succ) and + not sameContainer(pred, succ) + } + + /** + * Holds if `pred` should be stored in the object `succ` under the property `prop`. + */ + cached + predicate storeStep(DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ) { + any(AdditionalFlowStep s).storeStep(pred, contents, succ) + or + exists(string prop | + any(SharedFlowStep s).storeStep(pred, succ, prop) and + contents = DataFlow::ContentSet::fromLegacyProperty(prop) + ) + } + + /** + * Holds if the property `prop` of the object `pred` should be read into `succ`. + */ + cached + predicate readStep(DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ) { + any(AdditionalFlowStep s).readStep(pred, contents, succ) + or + exists(string prop | + any(SharedFlowStep s).loadStep(pred, succ, prop) and + contents = DataFlow::ContentSet::fromLegacyProperty(prop) + ) + } +} + +/** + * A data flow edge that is only seen by the old, deprecated data flow library. + * + * This class is typically used when a step has been replaced by a flow summary. Since the old data flow + * library does not support flow summaries, such a step should remain as a legacy step, until the old data flow + * library can be removed. + * + * Note: For performance reasons, all subclasses of this class should be part + * of the standard library. Override `Configuration::isAdditionalFlowStep` + * for analysis-specific flow steps. + */ +class LegacyFlowStep extends Unit { + /** + * Holds if `pred` → `succ` should be considered a data flow edge. + */ + predicate step(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a data flow edge + * transforming values with label `predlbl` to have label `succlbl`. + */ + predicate step( + DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel predlbl, + DataFlow::FlowLabel succlbl + ) { + none() + } + + /** + * Holds if `pred` should be stored in the object `succ` under the property `prop`. + * The object `succ` must be a `DataFlow::SourceNode` for the object wherein the value is stored. + */ + predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { none() } + + /** + * Holds if the property `prop` of the object `pred` should be loaded into `succ`. + */ + predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { none() } + + /** + * Holds if the property `prop` should be copied from the object `pred` to the object `succ`. + */ + predicate loadStoreStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { none() } + + /** + * Holds if the property `loadProp` should be copied from the object `pred` to the property `storeProp` of object `succ`. + */ + predicate loadStoreStep( + DataFlow::Node pred, DataFlow::Node succ, string loadProp, string storeProp + ) { + none() + } +} + +/** + * Contains predicates for accessing the steps contributed by `LegacyFlowStep` and `SharedFlowStep` subclasses. + */ +cached +module LegacyFlowStep { + /** + * Holds if `pred` → `succ` should be considered a data flow edge. + */ + cached + predicate step(DataFlow::Node pred, DataFlow::Node succ) { + any(LegacyFlowStep s).step(pred, succ) + or + any(SharedFlowStep s).step(pred, succ) + } + + /** + * Holds if `pred` → `succ` should be considered a data flow edge + * transforming values with label `predlbl` to have label `succlbl`. + */ + cached + predicate step( + DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel predlbl, + DataFlow::FlowLabel succlbl + ) { + any(LegacyFlowStep s).step(pred, succ, predlbl, succlbl) + or + any(SharedFlowStep s).step(pred, succ, predlbl, succlbl) + } + + /** + * Holds if `pred` should be stored in the object `succ` under the property `prop`. + * The object `succ` must be a `DataFlow::SourceNode` for the object wherein the value is stored. + */ + cached + predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { + any(LegacyFlowStep s).storeStep(pred, succ, prop) + or + any(SharedFlowStep s).storeStep(pred, succ, prop) + } + + /** + * Holds if the property `prop` of the object `pred` should be loaded into `succ`. + */ + cached + predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { + any(LegacyFlowStep s).loadStep(pred, succ, prop) + or + any(SharedFlowStep s).loadStep(pred, succ, prop) + } + + /** + * Holds if the property `prop` should be copied from the object `pred` to the object `succ`. + */ + cached + predicate loadStoreStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { + any(LegacyFlowStep s).loadStoreStep(pred, succ, prop) + or + any(SharedFlowStep s).loadStoreStep(pred, succ, prop) + } + + /** + * Holds if the property `loadProp` should be copied from the object `pred` to the property `storeProp` of object `succ`. + */ + cached + predicate loadStoreStep( + DataFlow::Node pred, DataFlow::Node succ, string loadProp, string storeProp + ) { + any(LegacyFlowStep s).loadStoreStep(pred, succ, loadProp, storeProp) + or + any(SharedFlowStep s).loadStoreStep(pred, succ, loadProp, storeProp) + } +} /** * A data flow edge that should be added to all data flow configurations in @@ -63,6 +318,10 @@ module SharedFlowStep { pragma[inline] predicate step(DataFlow::Node pred, DataFlow::Node succ) { any(SharedFlowStep s).step(pred, succ) + or + any(AdditionalFlowStep s).step(pred, succ) + or + any(LegacyFlowStep s).step(pred, succ) } /** @@ -72,6 +331,11 @@ module SharedFlowStep { pragma[inline] predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { any(SharedFlowStep s).storeStep(pred, succ, prop) + or + any(AdditionalFlowStep s) + .storeStep(pred, DataFlow::ContentSet::property(prop), succ.getALocalUse()) + or + any(LegacyFlowStep s).storeStep(pred, succ, prop) } /** @@ -80,6 +344,10 @@ module SharedFlowStep { pragma[inline] predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { any(SharedFlowStep s).loadStep(pred, succ, prop) + or + any(AdditionalFlowStep s).readStep(pred, DataFlow::ContentSet::property(prop), succ) + or + any(LegacyFlowStep s).loadStep(pred, succ, prop) } // The following are aliases for old step predicates that have no corresponding predicate in AdditionalFlowStep @@ -92,6 +360,8 @@ module SharedFlowStep { DataFlow::FlowLabel succlbl ) { any(SharedFlowStep s).step(pred, succ, predlbl, succlbl) + or + any(LegacyFlowStep s).step(pred, succ, predlbl, succlbl) } /** @@ -100,6 +370,8 @@ module SharedFlowStep { cached predicate loadStoreStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { any(SharedFlowStep s).loadStoreStep(pred, succ, prop) + or + any(LegacyFlowStep s).loadStoreStep(pred, succ, prop) } /** @@ -110,5 +382,7 @@ module SharedFlowStep { DataFlow::Node pred, DataFlow::Node succ, string loadProp, string storeProp ) { any(SharedFlowStep s).loadStoreStep(pred, succ, loadProp, storeProp) + or + any(LegacyFlowStep s).loadStoreStep(pred, succ, loadProp, storeProp) } } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index c693ebf1206..29f55ed01a6 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -1177,7 +1177,7 @@ private string getARelevantProp(DataFlow::Configuration cfg) { private predicate isAdditionalLoadStep( DataFlow::Node pred, DataFlow::Node succ, string prop, DataFlow::Configuration cfg ) { - SharedFlowStep::loadStep(pred, succ, prop) + LegacyFlowStep::loadStep(pred, succ, prop) or cfg.isAdditionalLoadStep(pred, succ, prop) } @@ -1188,7 +1188,7 @@ private predicate isAdditionalLoadStep( private predicate isAdditionalStoreStep( DataFlow::Node pred, DataFlow::Node succ, string prop, DataFlow::Configuration cfg ) { - SharedFlowStep::storeStep(pred, succ, prop) + LegacyFlowStep::storeStep(pred, succ, prop) or cfg.isAdditionalStoreStep(pred, succ, prop) } @@ -1200,13 +1200,13 @@ private predicate isAdditionalLoadStoreStep( DataFlow::Node pred, DataFlow::Node succ, string loadProp, string storeProp, DataFlow::Configuration cfg ) { - SharedFlowStep::loadStoreStep(pred, succ, loadProp, storeProp) + LegacyFlowStep::loadStoreStep(pred, succ, loadProp, storeProp) or cfg.isAdditionalLoadStoreStep(pred, succ, loadProp, storeProp) or loadProp = storeProp and ( - SharedFlowStep::loadStoreStep(pred, succ, loadProp) + LegacyFlowStep::loadStoreStep(pred, succ, loadProp) or cfg.isAdditionalLoadStoreStep(pred, succ, loadProp) ) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index 47fb26937cd..75926baa889 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -1990,5 +1990,6 @@ module DataFlow { import TypeInference import Configuration import TypeTracking + import AdditionalFlowSteps import internal.FunctionWrapperSteps } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index bf78a739507..1b5d84bcce6 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -586,6 +586,9 @@ predicate simpleLocalFlowStep(Node node1, Node node2) { node1 = TFlowSummaryNode(input) and node2 = TFlowSummaryNode(output) ) + or + // NOTE: For consistency with readStep/storeStep, we do not translate these steps to jump steps automatically. + DataFlow::AdditionalFlowStep::step(node1, node2) } predicate localMustFlowStep(Node node1, Node node2) { node1 = node2.getImmediatePredecessor() } @@ -601,6 +604,8 @@ predicate jumpStep(Node node1, Node node2) { or FlowSummaryImpl::Private::Steps::summaryJumpStep(node1.(FlowSummaryNode).getSummaryNode(), node2.(FlowSummaryNode).getSummaryNode()) + or + DataFlow::AdditionalFlowStep::jumpStep(node1, node2) } /** @@ -629,6 +634,8 @@ predicate readStep(Node node1, ContentSet c, Node node2) { contentSet = MkAwaited() and c = ContentSet::promiseValue() ) + or + DataFlow::AdditionalFlowStep::readStep(node1, c, node2) } /** Gets the post-update node for which `node` is the corresponding pre-update node. */ @@ -667,6 +674,8 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { node2 = TFlowSummaryNode(output) and c = ContentSet::promiseValue() ) + or + DataFlow::AdditionalFlowStep::storeStep(node1, c, node2) } /** diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll index e65a38908fe..f64834972c5 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll @@ -41,9 +41,9 @@ predicate localFlowStep( ) { pred = succ.getAPredecessor() and predlbl = succlbl or - DataFlow::SharedFlowStep::step(pred, succ) and predlbl = succlbl + DataFlow::LegacyFlowStep::step(pred, succ) and predlbl = succlbl or - DataFlow::SharedFlowStep::step(pred, succ, predlbl, succlbl) + DataFlow::LegacyFlowStep::step(pred, succ, predlbl, succlbl) or exists(boolean vp | configuration.isAdditionalFlowStep(pred, succ, vp) | vp = true and From 27c7d5004af16e4c07b290f994883bdfe142c936 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Oct 2023 10:37:57 +0200 Subject: [PATCH 018/514] JS: Do the same for additional taint steps --- .../dataflow/AdditionalTaintSteps.qll | 176 ++++++++++++++++++ .../internal/TaintTrackingPrivate.qll | 2 + 2 files changed, 178 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll b/javascript/ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll index 926f6e1325c..86eb6078a72 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll @@ -1,6 +1,28 @@ +/** + * Note: The contents of this file are exposed with the `TaintTracking::` prefix, via an import in `TaintTracking.qll`. + */ + private import javascript private import semmle.javascript.internal.CachedStages +/** + * A taint-propagating data flow edge that should be added to all taint tracking + * configurations, but only those that use the new data flow library. + * + * This class is a singleton, and thus subclasses do not need to specify a characteristic predicate. + * + * Note: For performance reasons, all subclasses of this class should be part + * of the standard library. Override `Configuration::isAdditionalTaintStep` + * for analysis-specific taint steps. + */ +class AdditionalTaintStep extends Unit { + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge. + */ + predicate step(DataFlow::Node pred, DataFlow::Node succ) { none() } +} + /** * A taint-propagating data flow edge that should be added to all taint tracking * configurations in addition to standard data flow edges. @@ -102,6 +124,106 @@ class SharedTaintStep extends Unit { predicate promiseStep(DataFlow::Node pred, DataFlow::Node succ) { none() } } +/** + * A taint-propagating data flow edge that should be used with the old data flow library. + * + * This class is a singleton, and thus subclasses do not need to specify a characteristic predicate. + * + * Note: For performance reasons, all subclasses of this class should be part + * of the standard library. Override `Configuration::isAdditionalTaintStep` + * for analysis-specific taint steps. + * + * This class has multiple kinds of `step` predicates; these all have the same + * effect on taint-tracking configurations. However, the categorization of steps + * allows some data-flow configurations to opt in to specific kinds of taint steps. + */ +class LegacyTaintStep extends Unit { + // Each step relation in this class should have a cached version in the `Cached` module + // and be included in the `sharedTaintStep` predicate. + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge. + */ + predicate step(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through URI manipulation. + * + * Does not include string operations that aren't specific to URIs, such + * as concatenation and substring operations. + */ + predicate uriStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge contributed by the heuristics library. + * + * Such steps are provided by the `semmle.javascript.heuristics` libraries + * and will default to be being empty if those libraries are not imported. + */ + predicate heuristicStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through persistent storage. + */ + predicate persistentStorageStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through the heap. + */ + predicate heapStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through arrays. + * + * These steps considers an array to be tainted if it contains tainted elements. + */ + predicate arrayStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through the `state` or `props` or a React component. + */ + predicate viewComponentStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through string concatenation. + */ + predicate stringConcatenationStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through string manipulation (other than concatenation). + */ + predicate stringManipulationStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through data serialization, such as `JSON.stringify`. + */ + predicate serializeStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through data deserialization, such as `JSON.parse`. + */ + predicate deserializeStep(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if `pred` → `succ` should be considered a taint-propagating + * data flow edge through a promise. + * + * These steps consider a promise object to tainted if it can resolve to + * a tainted value. + */ + predicate promiseStep(DataFlow::Node pred, DataFlow::Node succ) { none() } +} + /** * Module existing only to ensure all taint steps are cached as a single stage, * and without the the `Unit` type column. @@ -110,6 +232,7 @@ cached private module Cached { cached predicate forceStage() { + // TODO: ensure that this stage is only evaluated if using the old data flow library Stages::Taint::ref() } @@ -120,6 +243,8 @@ private module Cached { cached predicate genericStep(DataFlow::Node pred, DataFlow::Node succ) { any(SharedTaintStep step).step(pred, succ) + or + any(LegacyTaintStep step).step(pred, succ) } /** @@ -129,6 +254,8 @@ private module Cached { cached predicate heuristicStep(DataFlow::Node pred, DataFlow::Node succ) { any(SharedTaintStep step).heuristicStep(pred, succ) + or + any(LegacyTaintStep step).heuristicStep(pred, succ) } /** @@ -143,6 +270,8 @@ private module Cached { cached predicate uriStep(DataFlow::Node pred, DataFlow::Node succ) { any(SharedTaintStep step).uriStep(pred, succ) + or + any(LegacyTaintStep step).uriStep(pred, succ) } /** @@ -151,6 +280,8 @@ private module Cached { cached predicate persistentStorageStep(DataFlow::Node pred, DataFlow::Node succ) { any(SharedTaintStep step).persistentStorageStep(pred, succ) + or + any(LegacyTaintStep step).persistentStorageStep(pred, succ) } /** @@ -159,6 +290,8 @@ private module Cached { cached predicate heapStep(DataFlow::Node pred, DataFlow::Node succ) { any(SharedTaintStep step).heapStep(pred, succ) + or + any(LegacyTaintStep step).heapStep(pred, succ) } /** @@ -167,6 +300,8 @@ private module Cached { cached predicate arrayStep(DataFlow::Node pred, DataFlow::Node succ) { any(SharedTaintStep step).arrayStep(pred, succ) + or + any(LegacyTaintStep step).arrayStep(pred, succ) } /** @@ -176,6 +311,8 @@ private module Cached { cached predicate viewComponentStep(DataFlow::Node pred, DataFlow::Node succ) { any(SharedTaintStep step).viewComponentStep(pred, succ) + or + any(LegacyTaintStep step).viewComponentStep(pred, succ) } /** @@ -185,6 +322,8 @@ private module Cached { cached predicate stringConcatenationStep(DataFlow::Node pred, DataFlow::Node succ) { any(SharedTaintStep step).stringConcatenationStep(pred, succ) + or + any(LegacyTaintStep step).stringConcatenationStep(pred, succ) } /** @@ -194,6 +333,8 @@ private module Cached { cached predicate stringManipulationStep(DataFlow::Node pred, DataFlow::Node succ) { any(SharedTaintStep step).stringManipulationStep(pred, succ) + or + any(LegacyTaintStep step).stringManipulationStep(pred, succ) } /** @@ -203,6 +344,8 @@ private module Cached { cached predicate serializeStep(DataFlow::Node pred, DataFlow::Node succ) { any(SharedTaintStep step).serializeStep(pred, succ) + or + any(LegacyTaintStep step).serializeStep(pred, succ) } /** @@ -212,6 +355,8 @@ private module Cached { cached predicate deserializeStep(DataFlow::Node pred, DataFlow::Node succ) { any(SharedTaintStep step).deserializeStep(pred, succ) + or + any(LegacyTaintStep step).deserializeStep(pred, succ) } /** @@ -224,6 +369,8 @@ private module Cached { cached predicate promiseStep(DataFlow::Node pred, DataFlow::Node succ) { any(SharedTaintStep step).promiseStep(pred, succ) + or + any(LegacyTaintStep step).promiseStep(pred, succ) } } } @@ -233,6 +380,8 @@ import Cached::Public /** * Holds if `pred -> succ` is an edge used by all taint-tracking configurations in * the old data flow library. + * + * The new data flow library uses a different set of steps, exposed by `AdditionalTaintStep::step`. */ predicate sharedTaintStep(DataFlow::Node pred, DataFlow::Node succ) { Cached::genericStep(pred, succ) or @@ -248,3 +397,30 @@ predicate sharedTaintStep(DataFlow::Node pred, DataFlow::Node succ) { deserializeStep(pred, succ) or promiseStep(pred, succ) } + +/** + * Contains predicates for accessing the taint steps used by taint-tracking configurations + * in the new data flow library. + */ +module AdditionalTaintStep { + /** + * Holds if `pred` → `succ` is considered a taint-propagating data flow edge when + * using the new data flow library. + */ + cached + predicate step(DataFlow::Node pred, DataFlow::Node succ) { + any(AdditionalTaintStep step).step(pred, succ) or + any(SharedTaintStep step).step(pred, succ) or + any(SharedTaintStep step).heuristicStep(pred, succ) or + any(SharedTaintStep step).uriStep(pred, succ) or + any(SharedTaintStep step).persistentStorageStep(pred, succ) or + any(SharedTaintStep step).heapStep(pred, succ) or + any(SharedTaintStep step).arrayStep(pred, succ) or + any(SharedTaintStep step).viewComponentStep(pred, succ) or + any(SharedTaintStep step).stringConcatenationStep(pred, succ) or + any(SharedTaintStep step).stringManipulationStep(pred, succ) or + any(SharedTaintStep step).serializeStep(pred, succ) or + any(SharedTaintStep step).deserializeStep(pred, succ) or + any(SharedTaintStep step).promiseStep(pred, succ) + } +} diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index 119293d8249..0380cf8202f 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -5,6 +5,8 @@ private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as cached predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + TaintTracking::AdditionalTaintStep::step(node1, node2) + or FlowSummaryImpl::Private::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(), node2.(FlowSummaryNode).getSummaryNode(), false) or From 6037ff553cbaa4938e8f0730b513a1e7735a0bfd Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Oct 2023 10:39:18 +0200 Subject: [PATCH 019/514] JS: Add LegacyPreUpdateStep This contributes to both LegacyFlowStep and SharedTypeTrackingStep. That is, this is for steps that are used by type-tracking and the old data flow library, but not the new data flow library. --- .../dataflow/internal/PreCallGraphStep.qll | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/PreCallGraphStep.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/PreCallGraphStep.qll index 18db549300a..0416dc99a02 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/PreCallGraphStep.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/PreCallGraphStep.qll @@ -90,6 +90,89 @@ module PreCallGraphStep { } } +/** + * Internal extension point for adding legacy flow edges prior to call graph construction + * and type tracking, but where the steps should not be used by the new data flow library. + * + * Steps added here will be added to both `LegacyFlowStep` and `SharedTypeTrackingStep`. + * + * Contributing steps that rely on type tracking will lead to negative recursion. + */ +class LegacyPreCallGraphStep extends Unit { + /** + * Holds if there is a step from `pred` to `succ`. + */ + predicate step(DataFlow::Node pred, DataFlow::Node succ) { none() } + + /** + * Holds if there is a step from `pred` into the `prop` property of `succ`. + */ + predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { none() } + + /** + * Holds if there is a step from the `prop` property of `pred` to `succ`. + */ + predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { none() } + + /** + * Holds if there is a step from the `prop` property of `pred` to the same property in `succ`. + */ + predicate loadStoreStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { none() } + + /** + * Holds if there is a step from the `loadProp` property of `pred` to the `storeProp` property in `succ`. + */ + predicate loadStoreStep( + DataFlow::Node pred, DataFlow::SourceNode succ, string loadProp, string storeProp + ) { + none() + } +} + +module LegacyPreCallGraphStep { + /** + * Holds if there is a step from `pred` to `succ`. + */ + cached + predicate step(DataFlow::Node pred, DataFlow::Node succ) { + any(LegacyPreCallGraphStep s).step(pred, succ) + } + + /** + * Holds if there is a step from `pred` into the `prop` property of `succ`. + */ + cached + predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { + any(LegacyPreCallGraphStep s).storeStep(pred, succ, prop) + } + + /** + * Holds if there is a step from the `prop` property of `pred` to `succ`. + */ + cached + predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { + Stages::TypeTracking::ref() and + any(LegacyPreCallGraphStep s).loadStep(pred, succ, prop) + } + + /** + * Holds if there is a step from the `prop` property of `pred` to the same property in `succ`. + */ + cached + predicate loadStoreStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { + any(LegacyPreCallGraphStep s).loadStoreStep(pred, succ, prop) + } + + /** + * Holds if there is a step from the `loadProp` property of `pred` to the `storeProp` property in `succ`. + */ + predicate loadStoreStep( + DataFlow::Node pred, DataFlow::SourceNode succ, string loadProp, string storeProp + ) { + any(LegacyPreCallGraphStep s).loadStoreStep(pred, succ, loadProp, storeProp) + } +} + private class SharedFlowStepFromPreCallGraph extends DataFlow::SharedFlowStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { PreCallGraphStep::step(pred, succ) @@ -114,26 +197,60 @@ private class SharedFlowStepFromPreCallGraph extends DataFlow::SharedFlowStep { } } +private class LegacyFlowStepFromPreCallGraph extends DataFlow::LegacyFlowStep { + override predicate step(DataFlow::Node pred, DataFlow::Node succ) { + LegacyPreCallGraphStep::step(pred, succ) + } + + override predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { + LegacyPreCallGraphStep::storeStep(pred, succ, prop) + } + + override predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { + LegacyPreCallGraphStep::loadStep(pred, succ, prop) + } + + override predicate loadStoreStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { + LegacyPreCallGraphStep::loadStoreStep(pred, succ, prop) + } + + override predicate loadStoreStep( + DataFlow::Node pred, DataFlow::Node succ, string loadProp, string storeProp + ) { + LegacyPreCallGraphStep::loadStoreStep(pred, succ, loadProp, storeProp) + } +} + private class SharedTypeTrackingStepFromPreCallGraph extends DataFlow::SharedTypeTrackingStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { PreCallGraphStep::step(pred, succ) + or + LegacyPreCallGraphStep::step(pred, succ) } override predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { PreCallGraphStep::storeStep(pred, succ, prop) + or + LegacyPreCallGraphStep::storeStep(pred, succ, prop) } override predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { PreCallGraphStep::loadStep(pred, succ, prop) + or + LegacyPreCallGraphStep::loadStep(pred, succ, prop) } override predicate loadStoreStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { PreCallGraphStep::loadStoreStep(pred, succ, prop) + or + LegacyPreCallGraphStep::loadStoreStep(pred, succ, prop) } override predicate loadStoreStep( DataFlow::Node pred, DataFlow::SourceNode succ, string loadProp, string storeProp ) { PreCallGraphStep::loadStoreStep(pred, succ, loadProp, storeProp) + or + LegacyPreCallGraphStep::loadStoreStep(pred, succ, loadProp, storeProp) } } From 3f20d71a9b1f73fdd30e89543ce02b3cd488fa46 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Oct 2023 10:41:39 +0200 Subject: [PATCH 020/514] JS: Add legacy post-update step This is to ensure getALocalSource() can be replaced by getPostUpdateNode() as the base of a store --- .../javascript/dataflow/internal/FlowSteps.qll | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll index f64834972c5..2ee04b8dbf5 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll @@ -30,6 +30,20 @@ predicate returnExpr(Function f, DataFlow::Node source, DataFlow::Node sink) { not f = any(SetterMethodDeclaration decl).getBody() } +/** + * A step from a post-update node to the local sources of the corresponding pre-update node. + * + * This ensures that `getPostUpdateNode()` can be used in place of `getALocalSource()` when generating + * store steps, and the resulting step will work in both data flow analyses. + */ +pragma[nomagic] +private predicate legacyPostUpdateStep(DataFlow::Node pred, DataFlow::Node succ) { + exists(DataFlow::Node node | + pred = node.getPostUpdateNode() and + succ = node.getALocalSource() + ) +} + /** * Holds if data can flow in one step from `pred` to `succ`, taking * additional steps from the configuration into account. @@ -41,6 +55,8 @@ predicate localFlowStep( ) { pred = succ.getAPredecessor() and predlbl = succlbl or + legacyPostUpdateStep(pred, succ) and predlbl = succlbl + or DataFlow::LegacyFlowStep::step(pred, succ) and predlbl = succlbl or DataFlow::LegacyFlowStep::step(pred, succ, predlbl, succlbl) From 46fec8ea7ee528520ebd14b1b53f48aa4404cbc1 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Oct 2023 10:42:58 +0200 Subject: [PATCH 021/514] JS: Add AdditionalFlowInternal This provides access to more features than we want to expose publicly at the moment, but is useful for modelling certain language features. --- .../internal/AdditionalFlowInternal.qll | 34 +++++++++++++++++++ .../dataflow/internal/DataFlowNode.qll | 5 +++ .../dataflow/internal/DataFlowPrivate.qll | 29 ++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/AdditionalFlowInternal.qll diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/AdditionalFlowInternal.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/AdditionalFlowInternal.qll new file mode 100644 index 00000000000..d7f92ce8dd3 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/AdditionalFlowInternal.qll @@ -0,0 +1,34 @@ +private import javascript +private import semmle.javascript.dataflow.internal.DataFlowNode +private import semmle.javascript.dataflow.internal.DataFlowPrivate + +/** + * Gets a data-flow node synthesized using `AdditionalFlowInternal#needsSynthesizedNode`. + */ +DataFlow::Node getSynthesizedNode(AstNode node, string tag) { + result = TGenericSynthesizedNode(node, tag, _) +} + +/** + * An extension to `AdditionalFlowStep` with additional internal-only predicates. + */ +class AdditionalFlowInternal extends DataFlow::AdditionalFlowStep { + /** + * Holds if a data-flow node should be synthesized for the pair `(node, tag)`. + * + * The node can be obtained using `getSynthesizedNode(node, tag)`. + * + * `container` will be seen as the node's enclosing container. + */ + predicate needsSynthesizedNode(AstNode node, string tag, DataFlowCallable container) { none() } + + /** + * Holds if `node` should only permit flow of values stored in `contents`. + */ + predicate expectsContent(DataFlow::Node node, DataFlow::ContentSet contents) { none() } + + /** + * Holds if `node` should not permit flow of values stored in `contents`. + */ + predicate clearsContent(DataFlow::Node node, DataFlow::ContentSet contents) { none() } +} diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index cfc30582877..5ae1c7e7138 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -5,6 +5,8 @@ */ private import javascript +private import semmle.javascript.dataflow.internal.AdditionalFlowInternal +private import semmle.javascript.dataflow.internal.DataFlowPrivate as DataFlowPrivate private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as FlowSummaryImpl cached private module Cached { @@ -53,6 +55,9 @@ private module Cached { TFlowSummaryIntermediateAwaitStoreNode(FlowSummaryImpl::Private::SummaryNode sn) { FlowSummaryImpl::Private::Steps::summaryStoreStep(sn, MkAwaited(), _) } or + TGenericSynthesizedNode(AstNode node, string tag, DataFlowPrivate::DataFlowCallable container) { + any(AdditionalFlowInternal flow).needsSynthesizedNode(node, tag, container) + } } import Cached diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 1b5d84bcce6..3ee4748ad34 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -2,6 +2,7 @@ private import javascript private import semmle.javascript.dataflow.internal.CallGraphs private import semmle.javascript.dataflow.internal.DataFlowNode private import semmle.javascript.dataflow.internal.FlowSteps as FlowSteps +private import semmle.javascript.dataflow.internal.AdditionalFlowInternal private import semmle.javascript.dataflow.internal.Contents::Private private import semmle.javascript.dataflow.internal.VariableCapture private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon @@ -40,6 +41,26 @@ class FlowSummaryIntermediateAwaitStoreNode extends DataFlow::Node, } } +class GenericSynthesizedNode extends DataFlow::Node, TGenericSynthesizedNode { + private AstNode node; + private string tag; + private DataFlowCallable container; + + GenericSynthesizedNode() { this = TGenericSynthesizedNode(node, tag, container) } + + override StmtContainer getContainer() { result = container.asSourceCallable() } + + override string toString() { result = "[synthetic node] " + tag } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + node.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } + + string getTag() { result = tag } +} + cached newtype TReturnKind = MkNormalReturnKind() or @@ -235,6 +256,8 @@ DataFlowCallable nodeGetEnclosingCallable(Node node) { result.asLibraryCallable() = node.(FlowSummaryNode).getSummarizedCallable() or result.asLibraryCallable() = node.(FlowSummaryIntermediateAwaitStoreNode).getSummarizedCallable() + or + node = TGenericSynthesizedNode(_, _, result) } private newtype TDataFlowType = @@ -255,6 +278,8 @@ predicate nodeIsHidden(Node node) { node instanceof FlowSummaryNode or node instanceof FlowSummaryIntermediateAwaitStoreNode + or + node instanceof GenericSynthesizedNode } predicate neverSkipInPathGraph(Node node) { @@ -694,6 +719,8 @@ predicate clearsContent(Node n, ContentSet c) { FlowSummaryImpl::Private::Steps::summaryReadStep(_, MkAwaited(), n.(FlowSummaryNode).getSummaryNode()) and c = MkPromiseFilter() + or + any(AdditionalFlowInternal flow).clearsContent(n, c) } /** @@ -708,6 +735,8 @@ predicate expectsContent(Node n, ContentSet c) { FlowSummaryImpl::Private::Steps::summaryStoreStep(_, MkAwaited(), n.(FlowSummaryNode).getSummaryNode()) and c = MkPromiseFilter() + or + any(AdditionalFlowInternal flow).expectsContent(n, c) } /** From a31e251529bc5557a77f00365372689dfe98531a Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Oct 2023 13:14:14 +0200 Subject: [PATCH 022/514] JS: Add flow summaries for core methods --- .../dataflow/internal/DataFlowPrivate.qll | 1 + .../flow_summaries/AllFlowSummaries.qll | 1 + .../flow_summaries/AmbiguousCoreMethods.qll | 151 ++++++++++++++++++ .../flow_summaries/FlowSummaryUtil.qll | 15 ++ 4 files changed, 168 insertions(+) create mode 100644 javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll create mode 100644 javascript/ql/lib/semmle/javascript/internal/flow_summaries/AmbiguousCoreMethods.qll create mode 100644 javascript/ql/lib/semmle/javascript/internal/flow_summaries/FlowSummaryUtil.qll diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 3ee4748ad34..693767bb710 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -6,6 +6,7 @@ private import semmle.javascript.dataflow.internal.AdditionalFlowInternal private import semmle.javascript.dataflow.internal.Contents::Private private import semmle.javascript.dataflow.internal.VariableCapture private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon +private import semmle.javascript.internal.flow_summaries.AllFlowSummaries private import sharedlib.FlowSummaryImpl as FlowSummaryImpl private class Node = DataFlow::Node; diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll new file mode 100644 index 00000000000..2af0a73f9a2 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll @@ -0,0 +1 @@ +private import AmbiguousCoreMethods diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AmbiguousCoreMethods.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AmbiguousCoreMethods.qll new file mode 100644 index 00000000000..9c74cc7e33f --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AmbiguousCoreMethods.qll @@ -0,0 +1,151 @@ +/** + * Contains flow summaries for methods with a name that can found on more than one of the core types: Array, String, Map, Set, Promise. + * + * This is an overview of the ambiguous methods and the classes that contain them (not all of these require a flow summary): + * ``` + * at: String, Array + * concat: String, Array + * includes: String, Array + * indexOf: String, Array + * lastIndexOf: String, Array + * slice: String, Array + * entries: Array, Map, Set + * forEach: Array, Map, Set + * keys: Array, Map, Set + * values: Array, Map, Set + * clear: Map, Set + * delete: Map, Set + * has: Map, Set + * ``` + * + * (Promise is absent in the table above as there currently are no name clashes with Promise methods) + */ + +private import javascript +private import semmle.javascript.dataflow.internal.DataFlowNode +private import semmle.javascript.dataflow.FlowSummary +private import FlowSummaryUtil + +class At extends SummarizedCallable { + At() { this = "Array#at / String#at" } + + override InstanceCall getACallSimple() { result.getMethodName() = "at" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[this].ArrayElement" and + output = "ReturnValue" + // + // There is no flow for String#at since we currently consider single-character extraction to be too restrictive + } +} + +class Concat extends SummarizedCallable { + Concat() { this = "Array#concat / String#concat" } + + override InstanceCall getACallSimple() { result.getMethodName() = "concat" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[this,0..].ArrayElement" and + output = "ReturnValue.ArrayElement" + or + preservesValue = false and + input = "Argument[this,0..]" and + output = "ReturnValue" + } +} + +class Slice extends SummarizedCallable { + Slice() { this = "Array#slice / String#slice" } + + override InstanceCall getACallSimple() { result.getMethodName() = "slice" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[this].ArrayElement" and + output = "ReturnValue.ArrayElement" + or + preservesValue = false and + input = "Argument[this]" and + output = "ReturnValue" + } +} + +class Entries extends SummarizedCallable { + Entries() { this = "Array#entries / Map#entries / Set#entries" } + + override InstanceCall getACall() { + result.getMethodName() = "entries" and + result.getNumArgument() = 0 + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[this]." + ["MapKey", "SetElement"] and + output = "ReturnValue.IteratorElement.Member[0]" + or + input = "Argument[this]." + ["ArrayElement", "SetElement", "MapValue"] and + output = "ReturnValue.IteratorElement.Member[1]" + ) + } +} + +class ForEach extends SummarizedCallable { + ForEach() { this = "Array#forEach / Map#forEach / Set#forEach" } + + override InstanceCall getACallSimple() { result.getMethodName() = "forEach" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + /* + * array.forEach(callbackfn, thisArg) + * callbackfn(value, index, array) + */ + + ( + input = "Argument[this]." + ["ArrayElement", "SetElement", "MapValue"] and + output = "Argument[0].Parameter[0]" + or + input = "Argument[this]." + ["MapKey", "SetElement"] and + output = "Argument[0].Parameter[1]" + or + input = "Argument[this]" and + output = "Argument[0].Parameter[2]" // object being iterated over + or + input = "Argument[1]" and // thisArg + output = "Argument[0].Parameter[this]" + ) + } +} + +class Keys extends SummarizedCallable { + Keys() { this = "Array#keys / Map#keys / Set#keys" } + + override InstanceCall getACallSimple() { + result.getMethodName() = "keys" and + result.getNumArgument() = 0 + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[this]." + ["MapKey", "SetElement"] and + output = "ReturnValue.IteratorElement" + } +} + +class Values extends SummarizedCallable { + Values() { this = "Array#values / Map#values / Set#values" } + + override InstanceCall getACallSimple() { + result.getMethodName() = "values" and + result.getNumArgument() = 0 + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[this]." + ["ArrayElement", "SetElement", "MapValue"] and + output = "ReturnValue.IteratorElement" + } +} diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/FlowSummaryUtil.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/FlowSummaryUtil.qll new file mode 100644 index 00000000000..729c76a2662 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/FlowSummaryUtil.qll @@ -0,0 +1,15 @@ +private import javascript +private import semmle.javascript.dataflow.FlowSummary +private import semmle.javascript.dataflow.internal.Contents::Private + +/** + * A method call or a reflective invocation (`call` or `apply`) that takes a receiver. + * + * Note that `DataFlow::MethodCallNode` does not include reflective invocation. + */ +class InstanceCall extends DataFlow::CallNode { + InstanceCall() { exists(this.getReceiver()) } + + /** Gets the name of method being invoked */ + string getMethodName() { result = this.getCalleeName() } +} From 4319b0779853e3a7468db34b99d23fe7801d0ed7 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Oct 2023 13:14:29 +0200 Subject: [PATCH 023/514] JS: Add flow summaries for Arrays --- .../ql/lib/semmle/javascript/Arrays.qll | 32 +- .../flow_summaries/AllFlowSummaries.qll | 1 + .../internal/flow_summaries/Arrays2.qll | 577 ++++++++++++++++++ .../flow_summaries/FlowSummaryUtil.qll | 19 + 4 files changed, 613 insertions(+), 16 deletions(-) create mode 100644 javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays2.qll diff --git a/javascript/ql/lib/semmle/javascript/Arrays.qll b/javascript/ql/lib/semmle/javascript/Arrays.qll index 64ed34ae631..b67a728d0d8 100644 --- a/javascript/ql/lib/semmle/javascript/Arrays.qll +++ b/javascript/ql/lib/semmle/javascript/Arrays.qll @@ -9,7 +9,7 @@ module ArrayTaintTracking { /** * A taint propagating data flow edge caused by the builtin array functions. */ - private class ArrayFunctionTaintStep extends TaintTracking::SharedTaintStep { + private class ArrayFunctionTaintStep extends TaintTracking::LegacyTaintStep { override predicate arrayStep(DataFlow::Node pred, DataFlow::Node succ) { arrayFunctionTaintStep(pred, succ, _) } @@ -114,7 +114,7 @@ private module ArrayDataFlow { * A step modeling the creation of an Array using the `Array.from(x)` method. * The step copies the elements of the argument (set, array, or iterator elements) into the resulting array. */ - private class ArrayFrom extends DataFlow::SharedFlowStep { + private class ArrayFrom extends DataFlow::LegacyFlowStep { override predicate loadStoreStep( DataFlow::Node pred, DataFlow::Node succ, string fromProp, string toProp ) { @@ -134,7 +134,7 @@ private module ArrayDataFlow { * * Such a step can occur both with the `push` and `unshift` methods, or when creating a new array. */ - private class ArrayCopySpread extends DataFlow::SharedFlowStep { + private class ArrayCopySpread extends DataFlow::LegacyFlowStep { override predicate loadStoreStep( DataFlow::Node pred, DataFlow::Node succ, string fromProp, string toProp ) { @@ -155,7 +155,7 @@ private module ArrayDataFlow { /** * A step for storing an element on an array using `arr.push(e)` or `arr.unshift(e)`. */ - private class ArrayAppendStep extends DataFlow::SharedFlowStep { + private class ArrayAppendStep extends DataFlow::LegacyFlowStep { override predicate storeStep(DataFlow::Node element, DataFlow::SourceNode obj, string prop) { prop = arrayElement() and exists(DataFlow::MethodCallNode call | @@ -186,7 +186,7 @@ private module ArrayDataFlow { * A step for reading/writing an element from an array inside a for-loop. * E.g. a read from `foo[i]` to `bar` in `for(var i = 0; i < arr.length; i++) {bar = foo[i]}`. */ - private class ArrayIndexingStep extends DataFlow::SharedFlowStep { + private class ArrayIndexingStep extends DataFlow::LegacyFlowStep { override predicate loadStep(DataFlow::Node obj, DataFlow::Node element, string prop) { exists(ArrayIndexingAccess access | prop = arrayElement() and @@ -208,7 +208,7 @@ private module ArrayDataFlow { * A step for retrieving an element from an array using `.pop()`, `.shift()`, or `.at()`. * E.g. `array.pop()`. */ - private class ArrayPopStep extends DataFlow::SharedFlowStep { + private class ArrayPopStep extends DataFlow::LegacyFlowStep { override predicate loadStep(DataFlow::Node obj, DataFlow::Node element, string prop) { exists(DataFlow::MethodCallNode call | call.getMethodName() = ["pop", "shift", "at"] and @@ -229,7 +229,7 @@ private module ArrayDataFlow { * * And the second parameter in the callback is the array ifself, so there is a `loadStoreStep` from the array to that second parameter. */ - private class ArrayIteration extends PreCallGraphStep { + private class ArrayIteration extends LegacyPreCallGraphStep { override predicate loadStep(DataFlow::Node obj, DataFlow::Node element, string prop) { exists(DataFlow::MethodCallNode call | call.getMethodName() = ["map", "forEach"] and @@ -261,7 +261,7 @@ private module ArrayDataFlow { /** * A step for creating an array and storing the elements in the array. */ - private class ArrayCreationStep extends PreCallGraphStep { + private class ArrayCreationStep extends LegacyPreCallGraphStep { override predicate storeStep(DataFlow::Node element, DataFlow::SourceNode obj, string prop) { exists(DataFlow::ArrayCreationNode array, int i | element = array.getElement(i) and @@ -275,7 +275,7 @@ private module ArrayDataFlow { * A step modeling that `splice` can insert elements into an array. * For example in `array.splice(i, del, e)`: if `e` is tainted, then so is `array */ - private class ArraySpliceStep extends DataFlow::SharedFlowStep { + private class ArraySpliceStep extends DataFlow::LegacyFlowStep { override predicate storeStep(DataFlow::Node element, DataFlow::SourceNode obj, string prop) { exists(DataFlow::MethodCallNode call | call.getMethodName() = "splice" and @@ -290,7 +290,7 @@ private module ArrayDataFlow { * A step for modeling `concat`. * For example in `e = arr1.concat(arr2, arr3)`: if any of the `arr` is tainted, then so is `e`. */ - private class ArrayConcatStep extends DataFlow::SharedFlowStep { + private class ArrayConcatStep extends DataFlow::LegacyFlowStep { override predicate loadStoreStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { exists(DataFlow::MethodCallNode call | call.getMethodName() = "concat" and @@ -304,7 +304,7 @@ private module ArrayDataFlow { /** * A step for modeling that elements from an array `arr` also appear in the result from calling `slice`/`splice`/`filter`. */ - private class ArraySliceStep extends DataFlow::SharedFlowStep { + private class ArraySliceStep extends DataFlow::LegacyFlowStep { override predicate loadStoreStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { exists(DataFlow::MethodCallNode call | call.getMethodName() = ["slice", "splice", "filter"] and @@ -318,7 +318,7 @@ private module ArrayDataFlow { /** * A step modeling that elements from an array `arr` are received by calling `find`. */ - private class ArrayFindStep extends DataFlow::SharedFlowStep { + private class ArrayFindStep extends DataFlow::LegacyFlowStep { override predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { exists(DataFlow::CallNode call | call = arrayFindCall(pred) and @@ -368,7 +368,7 @@ private module ArrayLibraries { /** * A taint step through the `arrify` library, or other libraries that (maybe) convert values into arrays. */ - private class ArrayifyStep extends TaintTracking::SharedTaintStep { + private class ArrayifyStep extends TaintTracking::LegacyTaintStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { exists(API::CallNode call | call = API::moduleImport(["arrify", "array-ify"]).getACall() | pred = call.getArgument(0) and succ = call @@ -388,7 +388,7 @@ private module ArrayLibraries { /** * A taint step for a library that copies the elements of an array into another array. */ - private class ArrayCopyTaint extends TaintTracking::SharedTaintStep { + private class ArrayCopyTaint extends TaintTracking::LegacyTaintStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { exists(DataFlow::CallNode call | call = arrayCopyCall(pred) and @@ -400,7 +400,7 @@ private module ArrayLibraries { /** * A loadStoreStep for a library that copies the elements of an array into another array. */ - private class ArrayCopyLoadStore extends DataFlow::SharedFlowStep { + private class ArrayCopyLoadStore extends DataFlow::LegacyFlowStep { override predicate loadStoreStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { exists(DataFlow::CallNode call | call = arrayCopyCall(pred) and @@ -413,7 +413,7 @@ private module ArrayLibraries { /** * A taint step through a call to `Array.prototype.flat` or a polyfill implementing array flattening. */ - private class ArrayFlatStep extends TaintTracking::SharedTaintStep { + private class ArrayFlatStep extends TaintTracking::LegacyTaintStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { exists(DataFlow::CallNode call | succ = call | call.(DataFlow::MethodCallNode).getMethodName() = "flat" and diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll index 2af0a73f9a2..90f700405c1 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll @@ -1 +1,2 @@ private import AmbiguousCoreMethods +private import Arrays2 diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays2.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays2.qll new file mode 100644 index 00000000000..054e617721e --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays2.qll @@ -0,0 +1,577 @@ +/** + * Contains a summary for relevant methods on arrays, except Array.prototype.join which is currently special-cased in StringConcatenation.qll. + * + * Note that some of Array methods are modelled in `AmbiguousCoreMethods.qll`, and `join` and `toString` are special-cased elsewhere. + */ + +private import javascript +private import semmle.javascript.dataflow.FlowSummary +private import semmle.javascript.dataflow.InferredTypes +private import semmle.javascript.dataflow.internal.DataFlowPrivate as Private +private import FlowSummaryUtil + +pragma[nomagic] +DataFlow::SourceNode arrayConstructorRef() { result = DataFlow::globalVarRef("Array") } + +pragma[nomagic] +private int firstSpreadIndex(ArrayExpr expr) { + result = min(int i | expr.getElement(i) instanceof SpreadElement) +} + +/** + * Store and read steps for an array literal. Since literals are not seen as calls, this is not a flow summary. + * + * In case of spread elements `[x, ...y]`, we generate a read from `y -> ...y` and then a store from `...y` into + * the array literal (to ensure constant-indices get broken up). + */ +class ArrayLiteralStep extends DataFlow::AdditionalFlowStep { + override predicate storeStep( + DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ + ) { + exists(ArrayExpr array, int i | + pred = array.getElement(i).flow() and + succ = array.flow() + | + if i >= firstSpreadIndex(array) + then contents = DataFlow::ContentSet::arrayElement() // after a spread operator, store into unknown indices + else contents = DataFlow::ContentSet::arrayElementFromInt(i) + ) + } + + override predicate readStep( + DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ + ) { + exists(SpreadElement spread | + spread = any(ArrayExpr array).getAnElement() and + pred = spread.getOperand().flow() and + succ = spread.flow() and + contents = DataFlow::ContentSet::arrayElement() + ) + } +} + +pragma[nomagic] +private predicate isForLoopVariable(Variable v) { + v.getADeclarationStatement() = any(ForStmt stmt).getInit() + or + // Handle the somewhat rare case: `for (v; ...; ++v) { ... }` + v.getADeclaration() = any(ForStmt stmt).getInit() +} + +private predicate isLikelyArrayIndex(Expr e) { + // Require that 'e' is of type number and refers to a for-loop variable. + // TODO: This is here to mirror the old behaviour. Experiment with turning the 'and' into an 'or'. + TTNumber() = unique(InferredType type | type = e.flow().analyze().getAType()) and + isForLoopVariable(e.(VarAccess).getVariable()) + or + e.(PropAccess).getPropertyName() = "length" +} + +/** + * A dynamic property store `obj[e] = rhs` seen as a potential array access. + * + * We need to restrict to cases where `e` is likely to be an array index, as + * propagating data between arbitrary unknown property accesses is too imprecise. + */ +class DynamicArrayStoreStep extends DataFlow::AdditionalFlowStep { + override predicate storeStep( + DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ + ) { + exists(Assignment assignment, IndexExpr lvalue | + lvalue = assignment.getLhs() and + not exists(lvalue.getPropertyName()) and + isLikelyArrayIndex(lvalue.getPropertyNameExpr()) and + contents = DataFlow::ContentSet::arrayElement() and + succ.(DataFlow::ExprPostUpdateNode).getPreUpdateNode() = lvalue.getBase().flow() + | + pred = assignment.(Assignment).getRhs().flow() + or + // for compound assignments, use the result of the operator + pred = assignment.(CompoundAssignExpr).flow() + ) + } +} + +class ArrayConstructorSummary extends SummarizedCallable { + ArrayConstructorSummary() { this = "Array constructor" } + + override DataFlow::InvokeNode getACallSimple() { + result = arrayConstructorRef().getAnInvocation() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[0..]" and + output = "ReturnValue.ArrayElement" + or + input = "Argument[arguments-array].WithArrayElement" and + output = "ReturnValue" + ) + or + // TODO: workaround for WithArrayElement not being converted to a taint step + preservesValue = false and + input = "Argument[arguments-array]" and + output = "ReturnValue" + } +} + +class CopyWithin extends SummarizedCallable { + CopyWithin() { this = "Array#copyWithin" } + + override InstanceCall getACallSimple() { result.getMethodName() = "copyWithin" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[this].WithArrayElement" and + output = "ReturnValue" + or + // TODO: workaround for WithArrayElement not being converted to a taint step + preservesValue = false and + input = "Argument[this]" and + output = "ReturnValue" + } +} + +class FlowIntoCallback extends SummarizedCallable { + FlowIntoCallback() { this = "Array method with flow into callback" } + + override InstanceCall getACallSimple() { + result.getMethodName() = ["every", "findIndex", "findLastIndex", "some"] + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[this].ArrayElement" and + output = "Argument[0].Parameter[0]" + or + input = "Argument[1]" and + output = "Argument[0].Parameter[this]" + ) + } +} + +class Filter extends SummarizedCallable { + Filter() { this = "Array#filter" } + + override InstanceCall getACallSimple() { result.getMethodName() = "filter" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[this].ArrayElement" and + output = "Argument[0].Parameter[0]" + or + input = "Argument[1]" and + output = "Argument[0].Parameter[this]" + or + // Note: in case the filter condition acts as a barrier/sanitizer, + // it is up to the query to mark the 'filter' call as a barrier/sanitizer + input = "Argument[this].WithArrayElement" and + output = "ReturnValue" + ) + or + // TODO: workaround for WithArrayElement not being converted to a taint step + preservesValue = false and + input = "Argument[this]" and + output = "ReturnValue" + } +} + +class Fill extends SummarizedCallable { + Fill() { this = "Array#fill" } // TODO: clear contents if no interval is given + + override InstanceCall getACallSimple() { result.getMethodName() = "fill" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[0..]" and + output = ["ReturnValue.ArrayElement", "Argument[this].ArrayElement"] + } +} + +class FindLike extends SummarizedCallable { + FindLike() { this = "Array#find / Array#findLast" } + + override InstanceCall getACallSimple() { result.getMethodName() = ["find", "findLast"] } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[this].ArrayElement" and + output = ["Argument[0].Parameter[0]", "ReturnValue"] + or + input = "Argument[1]" and + output = "Argument[0].Parameter[this]" + ) + } +} + +class FindLibrary extends SummarizedCallable { + FindLibrary() { this = "'array.prototype.find' / 'array-find'" } + + override DataFlow::CallNode getACallSimple() { + result = DataFlow::moduleImport(["array.prototype.find", "array-find"]).getACall() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[0].ArrayElement" and + output = ["Argument[1].Parameter[0]", "ReturnValue"] + or + input = "Argument[2]" and + output = "Argument[1].Parameter[this]" + ) + } +} + +class Flat extends SummarizedCallable { + private int depth; + + Flat() { this = "Array#flat(" + depth + ")" and depth in [1 .. 3] } + + override InstanceCall getACallSimple() { + result.getMethodName() = "flat" and + ( + result.getNumArgument() = 1 and + result.getArgument(0).getIntValue() = depth + or + depth = 1 and + result.getNumArgument() = 0 + ) + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[this]" + concat(int n | n in [0 .. depth] | ".ArrayElement") + or + exists(int partialDepth | partialDepth in [1 .. depth - 1] | + input = + "Argument[this]" + concat(int n | n in [0 .. partialDepth] | ".ArrayElement") + + ".WithoutArrayElement" + ) + ) and + output = "ReturnValue.ArrayElement" + } +} + +class FlatMap extends SummarizedCallable { + FlatMap() { this = "Array#flatMap" } + + override InstanceCall getACallSimple() { result.getMethodName() = "flatMap" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[this].ArrayElement" and + output = "Argument[0].Parameter[0]" + or + input = "Argument[this]" and + output = "Argument[0].Parameter[2]" + or + input = "Argument[1]" and + output = "Argument[0].Parameter[1]" + or + input = "Argument[0].ReturnValue." + ["ArrayElement", "WithoutArrayElement"] and + output = "ReturnValue.ArrayElement" + ) + } +} + +private DataFlow::CallNode arrayFromCall() { + // TODO: update fromAsync model when async iterators are supported + result = arrayConstructorRef().getAMemberCall(["from", "fromAsync"]) + or + result = DataFlow::moduleImport("array-from").getACall() +} + +class From1Arg extends SummarizedCallable { + From1Arg() { this = "Array.from(arg)" } + + override DataFlow::CallNode getACallSimple() { + result = arrayFromCall() and result.getNumArgument() = 1 + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[0].WithArrayElement" and + output = "ReturnValue" + or + input = "Argument[0]." + ["SetElement", "IteratorElement"] and + output = "ReturnValue.ArrayElement" + or + input = "Argument[0].MapKey" and + output = "ReturnValue.ArrayElement.Member[0]" + or + input = "Argument[0].MapValue" and + output = "ReturnValue.ArrayElement.Member[1]" + or + input = "Argument[0].IteratorError" and + output = "ReturnValue[exception]" + ) + or + // TODO: we currently convert ArrayElement read/store steps to taint steps, but this does not + // work for WithArrayElement because it's just an expectsContent node, and there's no way easy + // to omit the expectsContent restriction in taint tracking. + // Work around this for now. + preservesValue = false and + input = "Argument[0]" and + output = "ReturnValue" + } +} + +class FromManyArg extends SummarizedCallable { + FromManyArg() { this = "Array.from(arg, callback, [thisArg])" } + + override DataFlow::CallNode getACallSimple() { + result = arrayFromCall() and + result.getNumArgument() > 1 + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[0]." + ["ArrayElement", "SetElement", "IteratorElement"] and + output = "Argument[1].Parameter[0]" + or + input = "Argument[0].MapKey" and + output = "Argument[1].Parameter[0].Member[0]" + or + input = "Argument[0].MapValue" and + output = "Argument[1].Parameter[0].Member[1]" + or + input = "Argument[1].ReturnValue" and + output = "ReturnValue.ArrayElement" + or + input = "Argument[2]" and + output = "Argument[1].Parameter[this]" + or + input = "Argument[0].IteratorError" and + output = "ReturnValue[exception]" + ) + } +} + +class Map extends SummarizedCallable { + Map() { this = "Array#map" } + + override InstanceCall getACallSimple() { + // Note that this summary may spuriously apply to library methods named `map` such as from lodash/underscore. + // However, this will not cause spurious flow, because for such functions, the first argument will be an array, not a callback, + // and every part of the summary below uses Argument[0] in a way that requires it to be a callback. + result.getMethodName() = "map" + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[this].ArrayElement" and + output = "Argument[0].Parameter[0]" + or + input = "Argument[this]" and + output = "Argument[0].Parameter[2]" + or + input = "Argument[1]" and + output = "Argument[0].Parameter[this]" + or + input = "Argument[0].ReturnValue" and + output = "ReturnValue.ArrayElement" + ) + } +} + +class Of extends SummarizedCallable { + Of() { this = "Array.of" } + + override DataFlow::CallNode getACallSimple() { + result = arrayConstructorRef().getAMemberCall("of") + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[0..]" and + output = "ReturnValue.ArrayElement" + } +} + +class Pop extends SummarizedCallable { + Pop() { this = "Array#pop" } + + override InstanceCall getACallSimple() { result.getMethodName() = "pop" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[this].ArrayElement" and + output = "ReturnValue" + } +} + +class PushLike extends SummarizedCallable { + PushLike() { this = "Array#push / Array#unshift" } + + override InstanceCall getACallSimple() { result.getMethodName() = ["push", "unshift"] } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + // TODO: make it so `arguments-array` is handled without needing to reference it explicitly in every flow-summary + input = ["Argument[0..]", "Argument[arguments-array].ArrayElement"] and + output = "Argument[this].ArrayElement" + } +} + +class ReduceLike extends SummarizedCallable { + ReduceLike() { this = "Array#reduce / Array#reduceRight" } + + override InstanceCall getACallSimple() { result.getMethodName() = ["reduce", "reduceRight"] } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + /* + * Signatures: + * reduce(callbackFn, [initialValue]) + * callbackfn(accumulator, currentValue, index, array) + */ + + ( + input = ["Argument[1]", "Argument[0].ReturnValue"] and + output = "Argument[0].Parameter[0]" // accumulator + or + input = "Argument[this].ArrayElement" and + output = "Argument[0].Parameter[1]" // currentValue + or + input = "Argument[this]" and + output = "Argument[0].Parameter[3]" // array + or + input = "Argument[0].ReturnValue" and + output = "ReturnValue" + ) + } +} + +class Reverse extends SummarizedCallable { + Reverse() { this = "Array#reverse / Array#toReversed" } + + override InstanceCall getACallSimple() { result.getMethodName() = ["reverse", "toReversed"] } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[this].ArrayElement" and + output = "ReturnValue.ArrayElement" + } +} + +class Shift extends SummarizedCallable { + Shift() { this = "Array#shift" } + + override InstanceCall getACallSimple() { result.getMethodName() = "shift" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[this].ArrayElement" and + output = "ReturnValue" + } +} + +class Sort extends SummarizedCallable { + Sort() { this = "Array#sort / Array#toSorted" } + + override InstanceCall getACallSimple() { result.getMethodName() = ["sort", "toSorted"] } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[this].ArrayElement" and + output = "ReturnValue.ArrayElement" + or + input = "Argument[this].ArrayElement" and + output = "Argument[0].Parameter[0,1]" + ) + } +} + +class Splice extends SummarizedCallable { + Splice() { this = "Array#splice" } + + override InstanceCall getACallSimple() { result.getMethodName() = "splice" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[this].ArrayElement" and + output = "ReturnValue.ArrayElement" + or + input = "Argument[2..]" and + output = ["Argument[this].ArrayElement", "ReturnValue.ArrayElement"] + ) + } +} + +class ToSpliced extends SummarizedCallable { + ToSpliced() { this = "Array#toSpliced" } + + override InstanceCall getACallSimple() { result.getMethodName() = "toSpliced" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[this].ArrayElement" and + output = "ReturnValue.ArrayElement" + or + input = "Argument[2..]" and + output = "ReturnValue.ArrayElement" + ) + } +} + +class ArrayCoercionPackage extends FunctionalPackageSummary { + ArrayCoercionPackage() { this = "ArrayCoercionPackage" } + + override string getAPackageName() { result = ["arrify", "array-ify"] } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[0].WithArrayElement" and + output = "ReturnValue" + or + input = "Argument[0].WithoutArrayElement" and + output = "ReturnValue.ArrayElement" + ) + or + // TODO: workaround for WithArrayElement not being converted to a taint step + preservesValue = false and + input = "Argument[0]" and + output = "ReturnValue" + } +} + +class ArrayCopyingPackage extends FunctionalPackageSummary { + ArrayCopyingPackage() { this = "ArrayCopyingPackage" } + + override string getAPackageName() { result = ["array-union", "array-uniq", "uniq"] } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[0..].ArrayElement" and + output = "ReturnValue.ArrayElement" + } +} + +class ArrayFlatteningPackage extends FunctionalPackageSummary { + ArrayFlatteningPackage() { this = "ArrayFlatteningPackage" } + + override string getAPackageName() { + result = ["array-flatten", "arr-flatten", "flatten", "array.prototype.flat"] + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + // TODO: properly support these. For the moment we're just adding parity with the old model + preservesValue = false and + input = "Argument[0..]" and + output = "ReturnValue" + } +} diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/FlowSummaryUtil.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/FlowSummaryUtil.qll index 729c76a2662..46fe61b7a7c 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/FlowSummaryUtil.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/FlowSummaryUtil.qll @@ -13,3 +13,22 @@ class InstanceCall extends DataFlow::CallNode { /** Gets the name of method being invoked */ string getMethodName() { result = this.getCalleeName() } } + +/** + * A summary a function that is the default export from an NPM package. + */ +abstract class FunctionalPackageSummary extends SummarizedCallable { + bindingset[this] + FunctionalPackageSummary() { any() } + + /** Gets a name of a package for which this summary applies. */ + abstract string getAPackageName(); + + override DataFlow::InvokeNode getACallSimple() { + result = DataFlow::moduleImport(this.getAPackageName()).getAnInvocation() + } + + override DataFlow::InvokeNode getACall() { + result = API::moduleImport(this.getAPackageName()).getAnInvocation() + } +} From 5054c43b1816be5976ed70ba9616a7a5914f1b97 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 13 Oct 2023 11:25:39 +0200 Subject: [PATCH 024/514] JS: Add flow summaries/steps for promises and async/await --- .../ql/lib/semmle/javascript/Promises.qll | 18 +- .../flow_summaries/AllFlowSummaries.qll | 2 + .../internal/flow_summaries/AsyncAwait.qll | 104 ++++++ .../flow_summaries/FlowSummaryUtil.qll | 17 + .../internal/flow_summaries/Promises2.qll | 320 ++++++++++++++++++ 5 files changed, 454 insertions(+), 7 deletions(-) create mode 100644 javascript/ql/lib/semmle/javascript/internal/flow_summaries/AsyncAwait.qll create mode 100644 javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises2.qll diff --git a/javascript/ql/lib/semmle/javascript/Promises.qll b/javascript/ql/lib/semmle/javascript/Promises.qll index bb1ee9326d8..c254128f87b 100644 --- a/javascript/ql/lib/semmle/javascript/Promises.qll +++ b/javascript/ql/lib/semmle/javascript/Promises.qll @@ -6,7 +6,9 @@ import javascript private import dataflow.internal.StepSummary /** - * A definition of a `Promise` object. + * A call to the `Promise` constructor, such as `new Promise((resolve, reject) => { ... })`. + * + * This includes calls to the built-in `Promise` constructor as well as promise implementations from known libraries, such as `bluebird`. */ abstract class PromiseDefinition extends DataFlow::SourceNode { /** Gets the executor function of this promise object. */ @@ -196,6 +198,8 @@ module Promises { override string getAProperty() { result = [valueProp(), errorProp()] } } + + predicate promiseConstructorRef = getAPromiseObject/0; } /** @@ -267,7 +271,7 @@ private import semmle.javascript.dataflow.internal.PreCallGraphStep * These steps are for `await p`, `new Promise()`, `Promise.resolve()`, * `Promise.then()`, `Promise.catch()`, and `Promise.finally()`. */ -private class PromiseStep extends PreCallGraphStep { +private class PromiseStep extends LegacyPreCallGraphStep { override predicate loadStep(DataFlow::Node obj, DataFlow::Node element, string prop) { PromiseFlow::loadStep(obj, element, prop) } @@ -459,7 +463,7 @@ module PromiseFlow { } } -private class PromiseTaintStep extends TaintTracking::SharedTaintStep { +private class PromiseTaintStep extends TaintTracking::LegacyTaintStep { override predicate promiseStep(DataFlow::Node pred, DataFlow::Node succ) { // from `x` to `new Promise((res, rej) => res(x))` pred = succ.(PromiseDefinition).getResolveParameter().getACall().getArgument(0) @@ -530,7 +534,7 @@ private module AsyncReturnSteps { /** * A data-flow step for ordinary and exceptional returns from async functions. */ - private class AsyncReturn extends PreCallGraphStep { + private class AsyncReturn extends LegacyPreCallGraphStep { override predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { exists(DataFlow::FunctionNode f | f.getFunction().isAsync() | // ordinary return @@ -548,7 +552,7 @@ private module AsyncReturnSteps { /** * A data-flow step for ordinary return from an async function in a taint configuration. */ - private class AsyncTaintReturn extends TaintTracking::SharedTaintStep { + private class AsyncTaintReturn extends TaintTracking::LegacyTaintStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { exists(Function f | f.isAsync() and @@ -665,7 +669,7 @@ private module ClosurePromise { /** * Taint steps through closure promise methods. */ - private class ClosurePromiseTaintStep extends TaintTracking::SharedTaintStep { + private class ClosurePromiseTaintStep extends TaintTracking::LegacyTaintStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { // static methods in goog.Promise exists(DataFlow::CallNode call, string name | @@ -699,7 +703,7 @@ private module DynamicImportSteps { * let Foo = await import('./foo'); * ``` */ - class DynamicImportStep extends PreCallGraphStep { + class DynamicImportStep extends LegacyPreCallGraphStep { override predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { exists(DynamicImportExpr imprt | pred = imprt.getImportedModule().getAnExportedValue("default") and diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll index 90f700405c1..df293bfd499 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll @@ -1,2 +1,4 @@ private import AmbiguousCoreMethods private import Arrays2 +private import AsyncAwait +private import Promises2 diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AsyncAwait.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AsyncAwait.qll new file mode 100644 index 00000000000..a39b0e6f43d --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AsyncAwait.qll @@ -0,0 +1,104 @@ +/** + * Contains flow steps to model flow through `async` functions and the `await` operator. + */ + +private import javascript +private import semmle.javascript.dataflow.internal.DataFlowNode +private import semmle.javascript.dataflow.internal.AdditionalFlowInternal +private import semmle.javascript.dataflow.internal.DataFlowPrivate + +/** + * Steps modelling flow in an `async` function. + * + * Note about promise-coercion and flattening: + * - `await` preserves non-promise values, e.g. `await "foo"` is just `"foo"`. + * - `return` preserves existing promise values, and boxes other values in a promise. + * + * We rely on `expectsContent` and `clearsContent` to handle coercion/flattening without risk of creating a nested promise object. + * + * The following is a brief overview of the steps we generate: + * ```js + * async function foo() { + * await x; // x --- READ[promise-value] ---> await x + * await x; // x --- VALUE -----------------> await x (has clearsContent) + * await x; // x --- READ[promise-error] ---> exception target + * + * return x; // x --- VALUE --> return node (has expectsContent) + * return x; // x --- VALUE --> synthetic node (clearsContent) --- STORE[promise-value] --> return node + * + * // exceptional return node --> STORE[promise-error] --> return node + * } + * ``` + */ +class AsyncAwait extends AdditionalFlowInternal { + override predicate needsSynthesizedNode(AstNode node, string tag, DataFlowCallable container) { + // We synthesize a clearsContent node to contain the values that need to be boxed in a promise before returning + node.(Function).isAsync() and + container.asSourceCallable() = node and + tag = "async-raw-return" + } + + override predicate clearsContent(DataFlow::Node node, DataFlow::ContentSet contents) { + node = getSynthesizedNode(_, "async-raw-return") and + contents = DataFlow::ContentSet::promiseFilter() + or + // The result of 'await' cannot be a promise. This is needed for the local flow step into 'await' + node.asExpr() instanceof AwaitExpr and + contents = DataFlow::ContentSet::promiseFilter() + } + + override predicate expectsContent(DataFlow::Node node, DataFlow::ContentSet contents) { + // The final return value must be a promise. This is needed for the local flow step into the return node. + exists(Function f | + f.isAsync() and + node = TFunctionReturnNode(f) and + contents = DataFlow::ContentSet::promiseFilter() + ) + } + + override predicate step(DataFlow::Node pred, DataFlow::Node succ) { + exists(AwaitExpr await | + // Allow non-promise values to propagate through await. + pred = await.getOperand().flow() and + succ = await.flow() // clears promise-content + ) + or + exists(Function f | + // To avoid creating a nested promise, flow to two different nodes which only permit promises/non-promises respectively + f.isAsync() and + pred = f.getAReturnedExpr().flow() + | + succ = getSynthesizedNode(f, "async-raw-return") // clears promise-content + or + succ = TFunctionReturnNode(f) // expects promise-content + ) + } + + override predicate readStep( + DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ + ) { + exists(AwaitExpr await | pred = await.getOperand().flow() | + contents = DataFlow::ContentSet::promiseValue() and + succ = await.flow() + or + contents = DataFlow::ContentSet::promiseError() and + succ = await.getExceptionTarget() + ) + } + + override predicate storeStep( + DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ + ) { + exists(Function f | f.isAsync() | + // Box returned non-promise values in a promise + pred = getSynthesizedNode(f, "async-raw-return") and + contents = DataFlow::ContentSet::promiseValue() and + succ = TFunctionReturnNode(f) + or + // Store thrown exceptions in promise-error + pred = TExceptionalFunctionReturnNode(f) and + contents = DataFlow::ContentSet::promiseError() and + succ = TFunctionReturnNode(f) + ) + } +} diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/FlowSummaryUtil.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/FlowSummaryUtil.qll index 46fe61b7a7c..a5df1d4716a 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/FlowSummaryUtil.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/FlowSummaryUtil.qll @@ -32,3 +32,20 @@ abstract class FunctionalPackageSummary extends SummarizedCallable { result = API::moduleImport(this.getAPackageName()).getAnInvocation() } } + +/** + * Gets a content from a set of contents that together represent all valid array indices. + * + * This can be used to generate flow summaries that should preserve precise array indices, + * in cases where `WithArrayElement` is not sufficient. + */ +string getAnArrayContent() { + // Values stored at a known, small index + result = "ArrayElement[" + getAPreciseArrayIndex() + "!]" + or + // Values stored at a known, but large index + result = "ArrayElement[" + (getMaxPreciseArrayIndex() + 1) + "..]" + or + // Values stored at an unknown index + result = "ArrayElement[?]" +} diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises2.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises2.qll new file mode 100644 index 00000000000..9a2a79e8a0a --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises2.qll @@ -0,0 +1,320 @@ +/** + * Contains flow summaries and steps modelling flow through `Promise` objects. + */ + +private import javascript +private import semmle.javascript.dataflow.FlowSummary +private import FlowSummaryUtil + +private DataFlow::SourceNode promiseConstructorRef() { + result = Promises::promiseConstructorRef() + or + result = DataFlow::moduleImport("bluebird") + or + result = DataFlow::moduleMember(["q", "kew", "bluebird"], "Promise") // note: bluebird.Promise == bluebird + or + result = Closure::moduleImport("goog.Promise") +} + +// +// Note that the 'Awaited' token has a special interpretation. +// See a write-up here: https://github.com/github/codeql-javascript-team/issues/423 +// +private class PromiseConstructor extends SummarizedCallable { + PromiseConstructor() { this = "new Promise()" } + + override DataFlow::InvokeNode getACallSimple() { + // Disabled for now. The field-flow branch limit will be negatively affected by having + // calls to multiple variants of `new Promise()`. + none() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + // TODO: when FlowSummaryImpl.qll supports these summaries, remove the workaround in PromiseConstructorWorkaround + // resolve(value) + input = "Argument[0].Parameter[0].Argument[0]" and output = "ReturnValue.Awaited" + or + // reject(value) + input = "Argument[0].Parameter[1].Argument[0]" and output = "ReturnValue.Awaited[error]" + or + // throw from executor + input = "Argument[0].ReturnValue[exception]" and output = "ReturnValue.Awaited[error]" + ) + } +} + +/** + * A workaround to the `PromiseConstructor`, to be used until FlowSummaryImpl.qll has sufficient support + * for callbacks. + */ +module PromiseConstructorWorkaround { + class ResolveSummary extends SummarizedCallable { + ResolveSummary() { this = "new Promise() resolve callback" } + + override DataFlow::InvokeNode getACallSimple() { + result = + promiseConstructorRef().getAnInstantiation().getCallback(0).getParameter(0).getACall() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[0]" and + output = "Argument[function].Member[resolve-value]" + } + } + + class RejectCallback extends SummarizedCallable { + RejectCallback() { this = "new Promise() reject callback" } + + override DataFlow::InvokeNode getACallSimple() { + result = + promiseConstructorRef().getAnInstantiation().getCallback(0).getParameter(1).getACall() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[0]" and + output = "Argument[function].Member[reject-value]" + } + } + + class ConstructorSummary extends SummarizedCallable { + ConstructorSummary() { this = "new Promise() workaround" } + + override DataFlow::InvokeNode getACallSimple() { + result = promiseConstructorRef().getAnInstantiation() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[0].Parameter[0].Member[resolve-value]" and + output = "ReturnValue.Awaited" + or + input = "Argument[0].Parameter[1].Member[reject-value]" and + output = "ReturnValue.Awaited[error]" + or + input = "Argument[0].ReturnValue[exception]" and + output = "ReturnValue.Awaited[error]" + ) + } + } +} + +private class PromiseThen2Arguments extends SummarizedCallable { + PromiseThen2Arguments() { this = "Promise#then() with 2 arguments" } + + override InstanceCall getACallSimple() { + result.getMethodName() = "then" and + result.getNumArgument() = 2 + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[0,1].ReturnValue" and output = "ReturnValue.Awaited" + or + input = "Argument[0,1].ReturnValue[exception]" and output = "ReturnValue.Awaited[error]" + or + input = "Argument[this].Awaited[value]" and output = "Argument[0].Parameter[0]" + or + input = "Argument[this].Awaited[error]" and output = "Argument[1].Parameter[0]" + ) + } +} + +private class PromiseThen1Argument extends SummarizedCallable { + PromiseThen1Argument() { this = "Promise#then() with 1 argument" } + + override InstanceCall getACallSimple() { + result.getMethodName() = "then" and + result.getNumArgument() = 1 + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[0].ReturnValue" and output = "ReturnValue.Awaited" + or + input = "Argument[0].ReturnValue[exception]" and output = "ReturnValue.Awaited[error]" + or + input = "Argument[this].Awaited[value]" and output = "Argument[0].Parameter[0]" + or + input = "Argument[this].WithAwaited[error]" and output = "ReturnValue" + ) + } +} + +private class PromiseCatch extends SummarizedCallable { + PromiseCatch() { this = "Promise#catch()" } + + override InstanceCall getACallSimple() { result.getMethodName() = "catch" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[0].ReturnValue" and output = "ReturnValue.Awaited" + or + input = "Argument[0].ReturnValue[exception]" and output = "ReturnValue.Awaited[error]" + or + input = "Argument[this].Awaited[value]" and output = "ReturnValue.Awaited[value]" + or + input = "Argument[this].Awaited[error]" and output = "Argument[0].Parameter[0]" + ) + } +} + +private class PromiseFinally extends SummarizedCallable { + PromiseFinally() { this = "Promise#finally()" } + + override InstanceCall getACallSimple() { result.getMethodName() = "finally" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[0].ReturnValue.Awaited[error]" and output = "ReturnValue.Awaited[error]" + or + input = "Argument[0].ReturnValue[exception]" and output = "ReturnValue.Awaited[error]" + or + input = "Argument[this].WithAwaited[value,error]" and output = "ReturnValue" + ) + } +} + +private class PromiseResolve extends SummarizedCallable { + PromiseResolve() { this = "Promise.resolve()" } + + override InstanceCall getACallSimple() { + result = promiseConstructorRef().getAMemberCall("resolve") + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[0]" and + output = "ReturnValue.Awaited" + } +} + +private class PromiseReject extends SummarizedCallable { + PromiseReject() { this = "Promise.reject()" } + + override InstanceCall getACallSimple() { + result = promiseConstructorRef().getAMemberCall("reject") + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[0]" and + output = "ReturnValue.Awaited[error]" + } +} + +private class PromiseAll extends SummarizedCallable { + PromiseAll() { this = "Promise.all()" } + + override DataFlow::InvokeNode getACallSimple() { + result = promiseConstructorRef().getAMemberCall("all") + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + exists(string content | content = getAnArrayContent() | + input = "Argument[0]." + content + ".Awaited" and + output = "ReturnValue.Awaited[value]." + content + ) + or + preservesValue = true and + input = "Argument[0].ArrayElement.WithAwaited[error]" and + output = "ReturnValue" + } +} + +private class PromiseAnyLike extends SummarizedCallable { + PromiseAnyLike() { this = "Promise.any() or Promise.race()" } + + override DataFlow::InvokeNode getACallSimple() { + result = promiseConstructorRef().getAMemberCall(["any", "race", "firstFulfilled"]) + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[0].ArrayElement" and + output = "ReturnValue.Awaited" + } +} + +private class PromiseAllSettled extends SummarizedCallable { + PromiseAllSettled() { this = "Promise.allSettled()" } + + override DataFlow::InvokeNode getACallSimple() { + result = promiseConstructorRef().getAMemberCall("allSettled") + or + result = DataFlow::moduleImport("promise.allsettled").getACall() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + exists(string content | content = getAnArrayContent() | + input = "Argument[0]." + content + ".Awaited" and + output = "ReturnValue.Awaited[value]." + content + ".Member[value]" + or + input = "Argument[0]." + content + ".Awaited[error]" and + output = "ReturnValue.Awaited[value]." + content + ".Member[reason]" + ) + } +} + +private class BluebirdMapSeries extends SummarizedCallable { + BluebirdMapSeries() { this = "bluebird.mapSeries" } + + override DataFlow::InvokeNode getACallSimple() { + result = promiseConstructorRef().getAMemberCall("mapSeries") + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[0].Awaited.ArrayElement.Awaited" and + output = "Argument[1].Parameter[0]" + or + input = "Argument[0].Awaited.ArrayElement.WithAwaited[error]" and + output = "ReturnValue" + or + input = "Argument[0].WithAwaited[error]" and + output = "ReturnValue" + or + input = "Argument[1].ReturnValue.Awaited" and + output = "ReturnValue.Awaited.ArrayElement" + or + input = "Argument[1].ReturnValue.WithAwaited[error]" and + output = "ReturnValue" + ) + } +} + +/** + * - `Promise.withResolvers`, a method pending standardization, + * - `goog.Closure.withResolver()` (non-plural spelling) + * - `bluebird.Promise.defer()` + */ +private class PromiseWithResolversLike extends SummarizedCallable { + PromiseWithResolversLike() { this = "Promise.withResolvers()" } + + override DataFlow::InvokeNode getACallSimple() { + result = promiseConstructorRef().getAMemberCall(["withResolver", "withResolvers", "defer"]) + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + // TODO: not currently supported by FlowSummaryImpl.qll + input = "ReturnValue.Member[resolve].Argument[0]" and + output = "ReturnValue.Member[promise].Awaited" + or + input = "ReturnValue.Member[reject].Argument[0]" and + output = "ReturnValue.Member[promise].Awaited[error]" + ) + } +} From f0c2afe39ebd895aa3d02564480e0386320b779c Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Oct 2023 13:18:15 +0200 Subject: [PATCH 025/514] JS: Add flow summaries for maps and sets --- .../ql/lib/semmle/javascript/Collections.qll | 16 +-- .../flow_summaries/AllFlowSummaries.qll | 2 + .../internal/flow_summaries/Maps2.qll | 120 ++++++++++++++++++ .../internal/flow_summaries/Sets2.qll | 46 +++++++ 4 files changed, 176 insertions(+), 8 deletions(-) create mode 100644 javascript/ql/lib/semmle/javascript/internal/flow_summaries/Maps2.qll create mode 100644 javascript/ql/lib/semmle/javascript/internal/flow_summaries/Sets2.qll diff --git a/javascript/ql/lib/semmle/javascript/Collections.qll b/javascript/ql/lib/semmle/javascript/Collections.qll index a0e251554ff..5f54dc57f1b 100644 --- a/javascript/ql/lib/semmle/javascript/Collections.qll +++ b/javascript/ql/lib/semmle/javascript/Collections.qll @@ -16,7 +16,7 @@ private module CollectionDataFlow { /** * A step for `Set.add()` method, which adds an element to a Set. */ - private class SetAdd extends PreCallGraphStep { + private class SetAdd extends LegacyPreCallGraphStep { override predicate storeStep(DataFlow::Node element, DataFlow::SourceNode obj, string prop) { exists(DataFlow::MethodCallNode call | call = obj.getAMethodCall("add") and @@ -29,7 +29,7 @@ private module CollectionDataFlow { /** * A step for the `Set` constructor, which copies any elements from the first argument into the resulting set. */ - private class SetConstructor extends PreCallGraphStep { + private class SetConstructor extends LegacyPreCallGraphStep { override predicate loadStoreStep( DataFlow::Node pred, DataFlow::SourceNode succ, string fromProp, string toProp ) { @@ -49,7 +49,7 @@ private module CollectionDataFlow { * For sets and iterators the l-value are the elements of the set/iterator. * For maps the l-value is a tuple containing a key and a value. */ - private class ForOfStep extends PreCallGraphStep { + private class ForOfStep extends LegacyPreCallGraphStep { override predicate loadStep(DataFlow::Node obj, DataFlow::Node e, string prop) { exists(ForOfStmt forOf | obj = forOf.getIterationDomain().flow() and @@ -73,7 +73,7 @@ private module CollectionDataFlow { /** * A step for a call to `forEach` on a Set or Map. */ - private class SetMapForEach extends PreCallGraphStep { + private class SetMapForEach extends LegacyPreCallGraphStep { override predicate loadStep(DataFlow::Node obj, DataFlow::Node element, string prop) { exists(DataFlow::MethodCallNode call | call.getMethodName() = "forEach" and @@ -88,7 +88,7 @@ private module CollectionDataFlow { * A call to the `get` method on a Map. * If the key of the call to `get` has a known string value, then only the value corresponding to that key will be retrieved. (The known string value is encoded as part of the pseudo-property) */ - private class MapGet extends PreCallGraphStep { + private class MapGet extends LegacyPreCallGraphStep { override predicate loadStep(DataFlow::Node obj, DataFlow::Node element, string prop) { exists(DataFlow::MethodCallNode call | call.getMethodName() = "get" and @@ -108,7 +108,7 @@ private module CollectionDataFlow { * Otherwise the value will be stored into a pseudo-property corresponding to values with unknown keys. * The value will additionally be stored into a pseudo-property corresponding to all values. */ - class MapSet extends PreCallGraphStep { + class MapSet extends LegacyPreCallGraphStep { override predicate storeStep(DataFlow::Node element, DataFlow::SourceNode obj, string prop) { exists(DataFlow::MethodCallNode call | call = obj.getAMethodCall("set") and @@ -121,7 +121,7 @@ private module CollectionDataFlow { /** * A step for a call to `values` on a Map or a Set. */ - private class MapAndSetValues extends PreCallGraphStep { + private class MapAndSetValues extends LegacyPreCallGraphStep { override predicate loadStoreStep( DataFlow::Node pred, DataFlow::SourceNode succ, string fromProp, string toProp ) { @@ -138,7 +138,7 @@ private module CollectionDataFlow { /** * A step for a call to `keys` on a Set. */ - private class SetKeys extends PreCallGraphStep { + private class SetKeys extends LegacyPreCallGraphStep { override predicate loadStoreStep( DataFlow::Node pred, DataFlow::SourceNode succ, string fromProp, string toProp ) { diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll index df293bfd499..d500c953cc7 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll @@ -1,4 +1,6 @@ private import AmbiguousCoreMethods private import Arrays2 private import AsyncAwait +private import Maps2 private import Promises2 +private import Sets2 diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Maps2.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Maps2.qll new file mode 100644 index 00000000000..57d4fb69340 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Maps2.qll @@ -0,0 +1,120 @@ +/** + * Contains flow summaries and steps modelling flow through `Map` objects. + */ + +private import javascript +private import semmle.javascript.dataflow.FlowSummary +private import FlowSummaryUtil + +private DataFlow::SourceNode mapConstructorRef() { result = DataFlow::globalVarRef("Map") } + +class MapConstructor extends SummarizedCallable { + MapConstructor() { this = "Map constructor" } + + override DataFlow::InvokeNode getACallSimple() { + result = mapConstructorRef().getAnInstantiation() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[0]." + ["ArrayElement", "SetElement", "IteratorElement"] + ".Member[0]" and + output = "ReturnValue.MapKey" + or + input = "Argument[0]." + ["ArrayElement", "SetElement", "IteratorElement"] + ".Member[1]" and + output = "ReturnValue.MapValue" + or + input = ["Argument[0].WithMapKey", "Argument[0].WithMapValue"] and + output = "ReturnValue" + ) + } +} + +/** + * A read step for `Map#get`. + * + * This is implemented as a step instead of a flow summary, as we currently do not expose a MaD syntax + * for map values with a known key. + */ +class MapGetStep extends DataFlow::AdditionalFlowStep { + override predicate readStep( + DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ + ) { + exists(DataFlow::MethodCallNode call | + call.getMethodName() = "get" and + call.getNumArgument() = 1 and + pred = call.getReceiver() and + succ = call + | + contents = DataFlow::ContentSet::mapValueFromKey(call.getArgument(0).getStringValue()) + or + not exists(call.getArgument(0).getStringValue()) and + contents = DataFlow::ContentSet::mapValueAll() + ) + } +} + +/** + * A read step for `Map#set`. + * + * This is implemented as a step instead of a flow summary, as we currently do not expose a MaD syntax + * for map values with a known key. + */ +class MapSetStep extends DataFlow::AdditionalFlowStep { + override predicate storeStep( + DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ + ) { + exists(DataFlow::MethodCallNode call | + call.getMethodName() = "set" and + call.getNumArgument() = 2 and + pred = call.getArgument(1) and + succ.(DataFlow::ExprPostUpdateNode).getPreUpdateNode() = call.getReceiver() + | + contents = DataFlow::ContentSet::mapValueFromKey(call.getArgument(0).getStringValue()) + or + not exists(call.getArgument(0).getStringValue()) and + contents = DataFlow::ContentSet::mapValueWithUnknownKey() + ) + } +} + +class MapGet extends SummarizedCallable { + MapGet() { this = "Map#get" } + + override DataFlow::MethodCallNode getACallSimple() { + none() and // Disabled for now - need MaD syntax for known map values + result.getMethodName() = "get" and + result.getNumArgument() = 1 + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[this].MapValue" and + output = "ReturnValue" + } +} + +class MapSet extends SummarizedCallable { + MapSet() { this = "Map#set" } + + override DataFlow::MethodCallNode getACallSimple() { + result.getMethodName() = "set" and + result.getNumArgument() = 2 + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = ["Argument[this].WithMapKey", "Argument[this].WithMapValue"] and + output = "ReturnValue" + or + preservesValue = true and + none() and // Disabled for now - need MaD syntax for known map values + ( + input = "Argument[0]" and + output = "Argument[this].MapKey" + or + input = "Argument[1]" and + output = "Argument[this].MapValue" + ) + } +} diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Sets2.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Sets2.qll new file mode 100644 index 00000000000..1880eb569bf --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Sets2.qll @@ -0,0 +1,46 @@ +/** + * Contains flow summaries and steps modelling flow through `Set` objects. + */ + +private import javascript +private import semmle.javascript.dataflow.FlowSummary +private import FlowSummaryUtil + +private DataFlow::SourceNode setConstructorRef() { result = DataFlow::globalVarRef("Set") } + +class SetConstructor extends SummarizedCallable { + SetConstructor() { this = "Set constructor" } + + override DataFlow::InvokeNode getACallSimple() { + result = setConstructorRef().getAnInstantiation() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[0]." + ["ArrayElement", "SetElement", "IteratorElement"] and + output = "ReturnValue.SetElement" + or + input = "Argument[0].MapKey" and + output = "ReturnValue.SetElement.Member[0]" + or + input = "Argument[0].MapValue" and + output = "ReturnValue.SetElement.Member[1]" + ) + } +} + +class SetAdd extends SummarizedCallable { + SetAdd() { this = "Set#add" } + + override DataFlow::MethodCallNode getACallSimple() { + result.getMethodName() = "add" and + result.getNumArgument() = 1 + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[0]" and + output = "Argument[this].SetElement" + } +} From da3a0de814808c1ba06181d20e623416fbb1faf1 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Oct 2023 15:52:49 +0200 Subject: [PATCH 026/514] JS: Port String#replace to flow summary --- .../javascript/dataflow/TaintTracking.qll | 31 +++++--- .../flow_summaries/AllFlowSummaries.qll | 1 + .../internal/flow_summaries/Strings2.qll | 72 +++++++++++++++++++ 3 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings2.qll diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 3b62b33c4ad..eb58a1d3055 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -409,18 +409,27 @@ module TaintTracking { ]).getACall() and pred = c.getArgument(0) ) + ) + } + } + + /** + * A taint propagating edge for the string `replace` function. + * + * This is a legacy step as it crosses a function boundary, and would thus be converted to a jump step. + */ + private class ReplaceCallbackSteps extends LegacyTaintStep { + override predicate step(DataFlow::Node pred, DataFlow::Node succ) { + // In and out of .replace callbacks + exists(StringReplaceCall call | + // Into the callback if the regexp does not sanitize matches + hasWildcardReplaceRegExp(call) and + pred = call.getReceiver() and + succ = call.getReplacementCallback().getParameter(0) or - // In and out of .replace callbacks - exists(StringReplaceCall call | - // Into the callback if the regexp does not sanitize matches - hasWildcardReplaceRegExp(call) and - pred = call.getReceiver() and - succ = call.getReplacementCallback().getParameter(0) - or - // Out of the callback - pred = call.getReplacementCallback().getReturnNode() and - succ = call - ) + // Out of the callback + pred = call.getReplacementCallback().getReturnNode() and + succ = call ) } } diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll index d500c953cc7..c299f0b0aac 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll @@ -4,3 +4,4 @@ private import AsyncAwait private import Maps2 private import Promises2 private import Sets2 +private import Strings2 diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings2.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings2.qll new file mode 100644 index 00000000000..cfa8688105e --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings2.qll @@ -0,0 +1,72 @@ +/** + * Contains flow summaries and steps modelling flow through string methods. + */ + +private import javascript +private import semmle.javascript.dataflow.FlowSummary + +/** Holds if the given call takes a regexp containing a wildcard. */ +pragma[noinline] +private predicate hasWildcardReplaceRegExp(StringReplaceCall call) { + RegExp::isWildcardLike(call.getRegExp().getRoot().getAChild*()) +} + +/** + * Summary for calls to `.replace` or `.replaceAll` (without a regexp pattern containing a wildcard). + */ +private class StringReplaceNoWildcard extends SummarizedCallable { + StringReplaceNoWildcard() { + this = "String#replace / String#replaceAll (without wildcard pattern)" + } + + override StringReplaceCall getACall() { not hasWildcardReplaceRegExp(result) } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = false and + ( + input = "Argument[this]" and + output = "ReturnValue" + or + input = "Argument[1].ReturnValue" and + output = "ReturnValue" + ) + } +} + +/** + * Summary for calls to `.replace` or `.replaceAll` (with a regexp pattern containing a wildcard). + * + * In this case, the receiver is considered to flow into the callback. + */ +private class StringReplaceWithWildcard extends SummarizedCallable { + StringReplaceWithWildcard() { + this = "String#replace / String#replaceAll (with wildcard pattern)" + } + + override StringReplaceCall getACall() { hasWildcardReplaceRegExp(result) } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = false and + ( + input = "Argument[this]" and + output = ["ReturnValue", "Argument[1].Parameter[0]"] + or + input = "Argument[1].ReturnValue" and + output = "ReturnValue" + ) + } +} + +class StringSplit extends SummarizedCallable { + StringSplit() { this = "String#split" } + + override DataFlow::MethodCallNode getACallSimple() { + result.getMethodName() = "split" and result.getNumArgument() = 1 + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = false and + input = "Argument[this]" and + output = "ReturnValue.ArrayElement" + } +} From 0c2e52baba1f73069072bcdc27d2a21506f7b2bc Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Oct 2023 15:58:51 +0200 Subject: [PATCH 027/514] JS: Summary/steps for iterators and generators --- .../ql/lib/semmle/javascript/Generators.qll | 2 +- .../flow_summaries/AllFlowSummaries.qll | 3 + .../internal/flow_summaries/ForOfLoops.qll | 53 +++++++++++++++++ .../internal/flow_summaries/Generators.qll | 59 +++++++++++++++++++ .../internal/flow_summaries/Iterators2.qll | 29 +++++++++ 5 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 javascript/ql/lib/semmle/javascript/internal/flow_summaries/ForOfLoops.qll create mode 100644 javascript/ql/lib/semmle/javascript/internal/flow_summaries/Generators.qll create mode 100644 javascript/ql/lib/semmle/javascript/internal/flow_summaries/Iterators2.qll diff --git a/javascript/ql/lib/semmle/javascript/Generators.qll b/javascript/ql/lib/semmle/javascript/Generators.qll index 06a19d1cfdf..b2b81ef5c88 100644 --- a/javascript/ql/lib/semmle/javascript/Generators.qll +++ b/javascript/ql/lib/semmle/javascript/Generators.qll @@ -11,7 +11,7 @@ private import semmle.javascript.dataflow.internal.PreCallGraphStep private module GeneratorDataFlow { private import DataFlow::PseudoProperties - private class ArrayIteration extends PreCallGraphStep { + private class ArrayIteration extends LegacyPreCallGraphStep { override predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { exists(DataFlow::FunctionNode f | f.getFunction().isGenerator() | prop = iteratorElement() and diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll index c299f0b0aac..ca8e2aebf69 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll @@ -1,6 +1,9 @@ private import AmbiguousCoreMethods private import Arrays2 private import AsyncAwait +private import ForOfLoops +private import Generators +private import Iterators2 private import Maps2 private import Promises2 private import Sets2 diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ForOfLoops.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ForOfLoops.qll new file mode 100644 index 00000000000..0efe77bcab8 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ForOfLoops.qll @@ -0,0 +1,53 @@ +/** + * Contains flow steps to model flow through `for..of` loops. + */ + +private import javascript +private import semmle.javascript.dataflow.internal.DataFlowNode +private import semmle.javascript.dataflow.internal.AdditionalFlowInternal +private import semmle.javascript.dataflow.internal.DataFlowPrivate + +class ForOfLoopStep extends AdditionalFlowInternal { + override predicate needsSynthesizedNode(AstNode node, string tag, DataFlowCallable container) { + // Intermediate nodes to convert (MapKey, MapValue) to a `[key, value]` array. + node instanceof ForOfStmt and + tag = ["map-key", "map-value"] and + container.asSourceCallable() = node.getContainer() + } + + override predicate readStep( + DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ + ) { + exists(ForOfStmt stmt | pred = stmt.getIterationDomain().flow() | + contents = + [ + DataFlow::ContentSet::arrayElement(), DataFlow::ContentSet::setElement(), + DataFlow::ContentSet::iteratorElement() + ] and + succ = DataFlow::lvalueNode(stmt.getLValue()) + or + contents = DataFlow::ContentSet::mapKey() and + succ = getSynthesizedNode(stmt, "map-key") + or + contents = DataFlow::ContentSet::mapValueAll() and + succ = getSynthesizedNode(stmt, "map-value") + or + contents = DataFlow::ContentSet::iteratorError() and + succ = stmt.getIterationDomain().getExceptionTarget() + ) + } + + override predicate storeStep( + DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ + ) { + exists(ForOfStmt stmt | + pred = getSynthesizedNode(stmt, "map-key") and + contents.asArrayIndex() = 0 + or + pred = getSynthesizedNode(stmt, "map-value") and + contents.asArrayIndex() = 1 + | + succ = DataFlow::lvalueNode(stmt.getLValue()) + ) + } +} diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Generators.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Generators.qll new file mode 100644 index 00000000000..e187b5751cf --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Generators.qll @@ -0,0 +1,59 @@ +/** + * Contains flow steps to model flow through generator functions. + */ + +private import javascript +private import semmle.javascript.dataflow.internal.DataFlowNode +private import semmle.javascript.dataflow.internal.AdditionalFlowInternal + +/** + * Steps modelling flow out of a generator function: + * ```js + * function* foo() { + * yield x; // store 'x' in the return value's IteratorElement + * yield* y; // flow directly to return value, which has expectsContent, so only iterator contents can pass through. + * throw z; // store 'z' in the return value's IteratorError + * } + * ``` + */ +class GeneratorFunctionStep extends AdditionalFlowInternal { + override predicate expectsContent(DataFlow::Node node, DataFlow::ContentSet contents) { + // Ensure that the return value can only return iterator contents. This is needed for 'yield*'. + exists(Function fun | + fun.isGenerator() and + node = TFunctionReturnNode(fun) and + contents = DataFlow::ContentSet::iteratorFilter() + ) + } + + override predicate storeStep( + DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ + ) { + // `yield x`. Store into the return value's iterator element. + exists(Function fun, YieldExpr yield | fun.isGenerator() | + not yield.isDelegating() and + yield.getContainer() = fun and + pred = yield.getOperand().flow() and + contents = DataFlow::ContentSet::iteratorElement() and + succ = TFunctionReturnNode(fun) + ) + or + exists(Function f | f.isGenerator() | + // Store thrown exceptions in the iterator-error + pred = TExceptionalFunctionReturnNode(f) and + succ = TFunctionReturnNode(f) and + contents = DataFlow::ContentSet::iteratorError() + ) + } + + override predicate step(DataFlow::Node pred, DataFlow::Node succ) { + // `yield* x`. Flow into the return value, which has expectsContent, so only iterator contents can pass through. + exists(Function fun, YieldExpr yield | + fun.isGenerator() and + yield.getContainer() = fun and + yield.isDelegating() and + pred = yield.getOperand().flow() and + succ = TFunctionReturnNode(fun) + ) + } +} diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Iterators2.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Iterators2.qll new file mode 100644 index 00000000000..94afac52787 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Iterators2.qll @@ -0,0 +1,29 @@ +/** + * Contains flow summaries and steps modelling flow through iterators. + */ + +private import javascript +private import semmle.javascript.dataflow.internal.DataFlowNode +private import semmle.javascript.dataflow.FlowSummary +private import semmle.javascript.dataflow.internal.AdditionalFlowInternal +private import FlowSummaryUtil + +class IteratorNext extends SummarizedCallable { + IteratorNext() { this = "Iterator#next" } + + override DataFlow::MethodCallNode getACallSimple() { + result.getMethodName() = "next" and + result.getNumArgument() = 0 + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + input = "Argument[this].IteratorElement" and + output = "ReturnValue.Member[value]" + or + input = "Argument[this].IteratorError" and + output = "ReturnValue[exception]" + ) + } +} From e31ae3a1bf50b956d4f203c0a55609cf4c73df19 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Oct 2023 16:01:45 +0200 Subject: [PATCH 028/514] JS: Model JSON.stringify with "deep" read operators --- .../dataflow/internal/DataFlowPrivate.qll | 13 ++++++++++++ .../dataflow/internal/FlowSummaryPrivate.qll | 8 ++++++++ .../flow_summaries/AllFlowSummaries.qll | 1 + .../internal/flow_summaries/JsonStringify.qll | 20 +++++++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 javascript/ql/lib/semmle/javascript/internal/flow_summaries/JsonStringify.qll diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 693767bb710..440f3633201 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -661,6 +661,19 @@ predicate readStep(Node node1, ContentSet c, Node node2) { c = ContentSet::promiseValue() ) or + // For deep reads, generate read edges with a self-loop + exists(Node origin, ContentSet contentSet | + FlowSummaryImpl::Private::Steps::summaryReadStep(origin.(FlowSummaryNode).getSummaryNode(), + contentSet, node2.(FlowSummaryNode).getSummaryNode()) and + node1 = [origin, node2] + | + contentSet = MkAnyPropertyDeep() and + c = ContentSet::anyProperty() + or + contentSet = MkArrayElementDeep() and + c = ContentSet::arrayElement() + ) + or DataFlow::AdditionalFlowStep::readStep(node1, c, node2) } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index 32739451ede..a872dc10135 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -205,6 +205,14 @@ SummaryComponent interpretComponentSpecific(Private::AccessPathToken c) { c.getName() = "Awaited" and c.getNumArgument() = 0 and result = SummaryComponent::content(MkAwaited()) + or + c.getName() = "AnyMemberDeep" and + c.getNumArgument() = 0 and + result = SummaryComponent::content(MkAnyPropertyDeep()) + or + c.getName() = "ArrayElementDeep" and + c.getNumArgument() = 0 and + result = SummaryComponent::content(MkArrayElementDeep()) } private string getMadStringFromContentSetAux(ContentSet cs) { diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll index ca8e2aebf69..9ca967f7354 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll @@ -4,6 +4,7 @@ private import AsyncAwait private import ForOfLoops private import Generators private import Iterators2 +private import JsonStringify private import Maps2 private import Promises2 private import Sets2 diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/JsonStringify.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/JsonStringify.qll new file mode 100644 index 00000000000..86779b8e7ec --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/JsonStringify.qll @@ -0,0 +1,20 @@ +/** + * Contains implicit read steps at the input to any function that converts a deep object to a string, such as `JSON.stringify`. + */ + +private import javascript +private import FlowSummaryUtil +private import semmle.javascript.dataflow.internal.AdditionalFlowInternal +private import semmle.javascript.dataflow.FlowSummary + +private class JsonStringifySummary extends SummarizedCallable { + JsonStringifySummary() { this = "JSON.stringify" } + + override DataFlow::InvokeNode getACall() { result instanceof JsonStringifyCall } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = false and + input = ["Argument[0]", "Argument[0].AnyMemberDeep"] and + output = "ReturnValue" + } +} From 9fef8803ed7874151027daa9674ab705f9b136f4 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 14:39:52 +0200 Subject: [PATCH 029/514] JS: Avoid BarrierGuardNode's range from depending on Configuration --- .../javascript/dataflow/Configuration.qll | 83 ++++++++++--------- 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index 29f55ed01a6..698c823ecdc 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -161,7 +161,7 @@ abstract class Configuration extends string { * Holds if the intermediate flow node `node` is prohibited. */ predicate isBarrier(DataFlow::Node node) { - exists(BarrierGuardNode guard | + exists(BarrierGuardNodeInternal guard | isBarrierGuardInternal(this, guard) and barrierGuardBlocksNode(guard, node, "") ) @@ -201,7 +201,7 @@ abstract class Configuration extends string { * Holds if flow with label `lbl` cannot flow into `node`. */ predicate isLabeledBarrier(DataFlow::Node node, FlowLabel lbl) { - exists(BarrierGuardNode guard | + exists(BarrierGuardNodeInternal guard | isBarrierGuardInternal(this, guard) and barrierGuardBlocksNode(guard, node, lbl) ) @@ -282,10 +282,12 @@ abstract class Configuration extends string { * `isBarrierGuard` or `AdditionalBarrierGuardNode`. */ pragma[nomagic] -private predicate isBarrierGuardInternal(Configuration cfg, BarrierGuardNode guard) { +private predicate isBarrierGuardInternal(Configuration cfg, BarrierGuardNodeInternal guard) { cfg.isBarrierGuard(guard) or guard.(AdditionalBarrierGuardNode).appliesTo(cfg) + or + guard.(DerivedBarrierGuardNode).appliesTo(cfg) } /** @@ -348,6 +350,8 @@ module FlowLabel { FlowLabel taint() { result = "taint" } } +abstract private class BarrierGuardNodeInternal extends DataFlow::Node { } + /** * A node that can act as a barrier when appearing in a condition. * @@ -359,7 +363,7 @@ module FlowLabel { * classes as precise as possible: if two subclasses of `BarrierGuardNode` overlap, their * implementations of `blocks` will _both_ apply to any configuration that includes either of them. */ -abstract class BarrierGuardNode extends DataFlow::Node { +abstract class BarrierGuardNode extends BarrierGuardNodeInternal { /** * Holds if this node blocks expression `e` provided it evaluates to `outcome`. * @@ -373,6 +377,20 @@ abstract class BarrierGuardNode extends DataFlow::Node { predicate blocks(boolean outcome, Expr e, FlowLabel label) { none() } } +/** + * Barrier guards derived from other barrier guards. + */ +abstract private class DerivedBarrierGuardNode extends BarrierGuardNodeInternal { + abstract predicate appliesTo(Configuration cfg); + + /** + * Holds if this node blocks expression `e` from flow of type `label`, provided it evaluates to `outcome`. + * + * `label` is bound to the empty string if it blocks all flow labels. + */ + abstract predicate blocks(boolean outcome, Expr e, string label); +} + /** * Holds if data flow node `guard` acts as a barrier for data flow. * @@ -380,24 +398,20 @@ abstract class BarrierGuardNode extends DataFlow::Node { */ pragma[nomagic] private predicate barrierGuardBlocksExpr( - BarrierGuardNode guard, boolean outcome, Expr test, string label + BarrierGuardNodeInternal guard, boolean outcome, Expr test, string label ) { - guard.blocks(outcome, test) and label = "" + guard.(BarrierGuardNode).blocks(outcome, test) and label = "" or - guard.blocks(outcome, test, label) + guard.(BarrierGuardNode).blocks(outcome, test, label) or - // Handle labelled barrier guard functions specially, to avoid negative recursion - // through the non-abstract 3-argument version of blocks(). - guard.(AdditionalBarrierGuardCall).internalBlocksLabel(outcome, test, label) - or - guard.(CallAgainstEqualityCheck).internalBlocksLabel(outcome, test, label) + guard.(DerivedBarrierGuardNode).blocks(outcome, test, label) } /** * Holds if `guard` may block the flow of a value reachable through exploratory flow. */ pragma[nomagic] -private predicate barrierGuardIsRelevant(BarrierGuardNode guard) { +private predicate barrierGuardIsRelevant(BarrierGuardNodeInternal guard) { exists(Expr e | barrierGuardBlocksExpr(guard, _, e, _) and isRelevantForward(e.flow(), _) @@ -412,7 +426,7 @@ private predicate barrierGuardIsRelevant(BarrierGuardNode guard) { */ pragma[nomagic] private predicate barrierGuardBlocksAccessPath( - BarrierGuardNode guard, boolean outcome, AccessPath ap, string label + BarrierGuardNodeInternal guard, boolean outcome, AccessPath ap, string label ) { barrierGuardIsRelevant(guard) and barrierGuardBlocksExpr(guard, outcome, ap.getAnInstance(), label) @@ -425,7 +439,7 @@ private predicate barrierGuardBlocksAccessPath( */ pragma[nomagic] private predicate barrierGuardBlocksSsaRefinement( - BarrierGuardNode guard, boolean outcome, SsaRefinementNode ref, string label + BarrierGuardNodeInternal guard, boolean outcome, SsaRefinementNode ref, string label ) { barrierGuardIsRelevant(guard) and guard.getEnclosingExpr() = ref.getGuard().getTest() and @@ -441,7 +455,7 @@ private predicate barrierGuardBlocksSsaRefinement( */ pragma[nomagic] private predicate barrierGuardUsedInCondition( - BarrierGuardNode guard, ConditionGuardNode cond, boolean outcome + BarrierGuardNodeInternal guard, ConditionGuardNode cond, boolean outcome ) { barrierGuardIsRelevant(guard) and outcome = cond.getOutcome() and @@ -459,7 +473,9 @@ private predicate barrierGuardUsedInCondition( * `label` is bound to the blocked label, or the empty string if all labels should be blocked. */ pragma[nomagic] -private predicate barrierGuardBlocksNode(BarrierGuardNode guard, DataFlow::Node nd, string label) { +private predicate barrierGuardBlocksNode( + BarrierGuardNodeInternal guard, DataFlow::Node nd, string label +) { // 1) `nd` is a use of a refinement node that blocks its input variable exists(SsaRefinementNode ref, boolean outcome | nd = DataFlow::ssaDefinitionNode(ref) and @@ -483,7 +499,7 @@ private predicate barrierGuardBlocksNode(BarrierGuardNode guard, DataFlow::Node */ pragma[nomagic] private predicate barrierGuardBlocksEdge( - BarrierGuardNode guard, DataFlow::Node pred, DataFlow::Node succ, string label + BarrierGuardNodeInternal guard, DataFlow::Node pred, DataFlow::Node succ, string label ) { exists( SsaVariable input, SsaPhiNode phi, BasicBlock bb, ConditionGuardNode cond, boolean outcome @@ -503,7 +519,7 @@ private predicate barrierGuardBlocksEdge( * This predicate exists to get a better join-order for the `barrierGuardBlocksEdge` predicate above. */ pragma[noinline] -private BasicBlock getADominatedBasicBlock(BarrierGuardNode guard, ConditionGuardNode cond) { +private BasicBlock getADominatedBasicBlock(BarrierGuardNodeInternal guard, ConditionGuardNode cond) { barrierGuardIsRelevant(guard) and guard.getEnclosingExpr() = cond.getTest() and cond.dominates(result) @@ -518,7 +534,7 @@ private BasicBlock getADominatedBasicBlock(BarrierGuardNode guard, ConditionGuar private predicate isBarrierEdgeRaw(Configuration cfg, DataFlow::Node pred, DataFlow::Node succ) { cfg.isBarrierEdge(pred, succ) or - exists(DataFlow::BarrierGuardNode guard | + exists(BarrierGuardNodeInternal guard | cfg.isBarrierGuard(guard) and barrierGuardBlocksEdge(guard, pred, succ, "") ) @@ -548,7 +564,7 @@ private predicate isLabeledBarrierEdgeRaw( ) { cfg.isBarrierEdge(pred, succ, label) or - exists(DataFlow::BarrierGuardNode guard | + exists(BarrierGuardNodeInternal guard | cfg.isBarrierGuard(guard) and barrierGuardBlocksEdge(guard, pred, succ, label) ) @@ -1843,7 +1859,7 @@ module PathGraph { /** * Gets a logical `and` expression, or parenthesized expression, that contains `guard`. */ -private Expr getALogicalAndParent(BarrierGuardNode guard) { +private Expr getALogicalAndParent(BarrierGuardNodeInternal guard) { barrierGuardIsRelevant(guard) and result = guard.asExpr() or result.(LogAndExpr).getAnOperand() = getALogicalAndParent(guard) @@ -1854,7 +1870,7 @@ private Expr getALogicalAndParent(BarrierGuardNode guard) { /** * Gets a logical `or` expression, or parenthesized expression, that contains `guard`. */ -private Expr getALogicalOrParent(BarrierGuardNode guard) { +private Expr getALogicalOrParent(BarrierGuardNodeInternal guard) { barrierGuardIsRelevant(guard) and result = guard.asExpr() or result.(LogOrExpr).getAnOperand() = getALogicalOrParent(guard) @@ -1879,7 +1895,7 @@ abstract class AdditionalBarrierGuardNode extends BarrierGuardNode { */ private class BarrierGuardFunction extends Function { DataFlow::ParameterNode sanitizedParameter; - BarrierGuardNode guard; + BarrierGuardNodeInternal guard; boolean guardOutcome; string label; int paramIndex; @@ -1923,23 +1939,18 @@ private class BarrierGuardFunction extends Function { ) } - /** - * Holds if this function applies to the flow in `cfg`. - */ predicate appliesTo(Configuration cfg) { isBarrierGuardInternal(cfg, guard) } } /** * A call that sanitizes an argument. */ -private class AdditionalBarrierGuardCall extends AdditionalBarrierGuardNode, DataFlow::CallNode { +private class AdditionalBarrierGuardCall extends DerivedBarrierGuardNode, DataFlow::CallNode { BarrierGuardFunction f; AdditionalBarrierGuardCall() { f.isBarrierCall(this, _, _, _) } - override predicate blocks(boolean outcome, Expr e) { f.isBarrierCall(this, e, outcome, "") } - - predicate internalBlocksLabel(boolean outcome, Expr e, DataFlow::FlowLabel label) { + override predicate blocks(boolean outcome, Expr e, string label) { f.isBarrierCall(this, e, outcome, label) } @@ -1955,8 +1966,8 @@ private class AdditionalBarrierGuardCall extends AdditionalBarrierGuardNode, Dat * } * ``` */ -private class CallAgainstEqualityCheck extends AdditionalBarrierGuardNode { - DataFlow::BarrierGuardNode prev; +private class CallAgainstEqualityCheck extends DerivedBarrierGuardNode { + BarrierGuardNodeInternal prev; boolean polarity; CallAgainstEqualityCheck() { @@ -1968,11 +1979,7 @@ private class CallAgainstEqualityCheck extends AdditionalBarrierGuardNode { ) } - override predicate blocks(boolean outcome, Expr e) { - none() // handled by internalBlocksLabel - } - - predicate internalBlocksLabel(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { + override predicate blocks(boolean outcome, Expr e, string lbl) { exists(boolean prevOutcome | barrierGuardBlocksExpr(prev, prevOutcome, e, lbl) and outcome = prevOutcome.booleanXor(polarity) From 3ef478669b62a6b0da1bebfe9b346a04d369b541 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 14:41:59 +0200 Subject: [PATCH 030/514] JS: Collapse some cached stages --- .../javascript/dataflow/internal/DataFlowNode.qll | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index 5ae1c7e7138..c34928f3b59 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -6,6 +6,8 @@ private import javascript private import semmle.javascript.dataflow.internal.AdditionalFlowInternal +private import semmle.javascript.dataflow.internal.Contents::Private +private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon private import semmle.javascript.dataflow.internal.DataFlowPrivate as DataFlowPrivate private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as FlowSummaryImpl cached @@ -58,6 +60,18 @@ private module Cached { TGenericSynthesizedNode(AstNode node, string tag, DataFlowPrivate::DataFlowCallable container) { any(AdditionalFlowInternal flow).needsSynthesizedNode(node, tag, container) } + + cached + private module Backref { + cached + predicate backref() { + DataFlowImplCommon::forceCachingInSameStage() or + exists(any(DataFlow::Node node).toString()) or + exists(any(DataFlow::Node node).getContainer()) or + any(DataFlow::Node node).hasLocationInfo(_, _, _, _, _) or + exists(any(Content c).toString()) + } + } } import Cached From 16df2c31bb4ac690bbed061365ea61acd323bd8e Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 15:10:40 +0200 Subject: [PATCH 031/514] Create DataFlowImplConsistency.qll --- .../internal/DataFlowImplConsistency.qll | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll new file mode 100644 index 00000000000..a4cf0199930 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll @@ -0,0 +1,42 @@ +private import javascript +private import codeql.dataflow.internal.DataFlowImplConsistency +private import sharedlib.DataFlowArg +private import semmle.javascript.dataflow.internal.DataFlowPrivate +private import semmle.javascript.dataflow.internal.DataFlowNode + +private module ConsistencyConfig implements InputSig { + private predicate isAmbientNode(DataFlow::Node node) { + exists(AstNode n | n.isAmbient() | + node = TValueNode(n) or + node = TThisNode(n) or + node = TReflectiveParametersNode(n) or + node = TPropNode(n) or + node = TFunctionSelfReferenceNode(n) or + node = TExceptionalFunctionReturnNode(n) or + node = TExprPostUpdateNode(n) or + node = TExceptionalInvocationReturnNode(n) or + node = TDestructuredModuleImportNode(n) + ) + } + + predicate missingLocationExclude(DataFlow::Node n) { + n instanceof FlowSummaryNode + or + n instanceof FlowSummaryIntermediateAwaitStoreNode + or + n instanceof GenericSynthesizedNode + or + n = DataFlow::globalAccessPathRootPseudoNode() + } + + predicate uniqueNodeLocationExclude(DataFlow::Node n) { missingLocationExclude(n) } + + predicate uniqueEnclosingCallableExclude(DataFlow::Node n) { isAmbientNode(n) } + + predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { + isAmbientNode(call.asOrdinaryCall()) or + isAmbientNode(call.asAccessorCall()) + } +} + +module Consistency = MakeConsistency; From 7bcf8b858babfea0a3e36ce61145954c249e13ac Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 15:15:23 +0200 Subject: [PATCH 032/514] JS: Capture flow --- .../javascript/dataflow/Configuration.qll | 1 + .../dataflow/internal/DataFlowNode.qll | 3 + .../dataflow/internal/DataFlowPrivate.qll | 109 ++++++ .../dataflow/internal/VariableCapture.qll | 323 ++++++++++++++++++ 4 files changed, 436 insertions(+) create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index 698c823ecdc..1788df28d7d 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -1994,6 +1994,7 @@ private class CallAgainstEqualityCheck extends DerivedBarrierGuardNode { * Can be added to a `isBarrier` in a data-flow configuration to block flow through such checks. */ class VarAccessBarrier extends DataFlow::Node { + // TODO: This does not work in dataflow2 when the variable is captured, since the capture-flow library bypasses the refinement node. VarAccessBarrier() { exists(ConditionGuardNode guard, SsaRefinementNode refinement | this = DataFlow::ssaDefinitionNode(refinement) and diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index c34928f3b59..8323bc23314 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -10,6 +10,8 @@ private import semmle.javascript.dataflow.internal.Contents::Private private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon private import semmle.javascript.dataflow.internal.DataFlowPrivate as DataFlowPrivate private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as FlowSummaryImpl +private import semmle.javascript.dataflow.internal.VariableCapture as VariableCapture + cached private module Cached { /** @@ -57,6 +59,7 @@ private module Cached { TFlowSummaryIntermediateAwaitStoreNode(FlowSummaryImpl::Private::SummaryNode sn) { FlowSummaryImpl::Private::Steps::summaryStoreStep(sn, MkAwaited(), _) } or + TSynthCaptureNode(VariableCapture::VariableCaptureOutput::SynthesizedCaptureNode node) or TGenericSynthesizedNode(AstNode node, string tag, DataFlowPrivate::DataFlowCallable container) { any(AdditionalFlowInternal flow).needsSynthesizedNode(node, tag, container) } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 440f3633201..15dda32622b 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -42,6 +42,30 @@ class FlowSummaryIntermediateAwaitStoreNode extends DataFlow::Node, } } +class CaptureNode extends DataFlow::Node, TSynthCaptureNode { + /** Gets the underlying node from the variable-capture library. */ + VariableCaptureOutput::SynthesizedCaptureNode getNode() { + this = TSynthCaptureNode(result) and DataFlowImplCommon::forceCachingInSameStage() + } + + cached + override StmtContainer getContainer() { result = this.getNode().getEnclosingCallable() } + + cached + private string toStringInternal() { result = this.getNode().toString() } + + override string toString() { result = this.toStringInternal() } // cached in parent class + + cached + private Location getLocation() { result = this.getNode().getLocation() } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } +} + class GenericSynthesizedNode extends DataFlow::Node, TGenericSynthesizedNode { private AstNode node; private string tag; @@ -145,6 +169,8 @@ predicate postUpdatePair(Node pre, Node post) { or FlowSummaryImpl::Private::summaryPostUpdateNode(post.(FlowSummaryNode).getSummaryNode(), pre.(FlowSummaryNode).getSummaryNode()) + or + VariableCaptureOutput::capturePostUpdateNode(getClosureNode(post), getClosureNode(pre)) } class CastNode extends DataFlow::Node instanceof EmptyType { } @@ -232,6 +258,15 @@ private predicate isArgumentNodeImpl(Node n, DataFlowCall call, ArgumentPosition or pos.isFunctionSelfReference() and n = call.asOrdinaryCall().getCalleeNode() or + pos.isFunctionSelfReference() and n = call.asImpliedLambdaCall().flow() + or + exists(Function fun | + call.asImpliedLambdaCall() = fun and + CallGraph::impliedReceiverStep(n, TThisNode(fun)) and + sameContainerAsEnclosingContainer(n, fun) and + pos.isThis() + ) + or pos.isThis() and n = TConstructorThisArgumentNode(call.asOrdinaryCall().asExpr()) or // For now, treat all spread argument as flowing into the 'arguments' array, regardless of preceding arguments @@ -280,6 +315,15 @@ predicate nodeIsHidden(Node node) { or node instanceof FlowSummaryIntermediateAwaitStoreNode or + node instanceof CaptureNode + or + // Hide function expressions, as capture-flow causes them to appear in unhelpful ways + // TODO: Instead hide PathNodes with a capture content as the head of its access path? + node.asExpr() instanceof Function + or + // Also hide post-update nodes for function expressions + node.(DataFlow::ExprPostUpdateNode).getExpr() instanceof Function + or node instanceof GenericSynthesizedNode } @@ -324,6 +368,9 @@ private newtype TDataFlowCall = node = TValueNode(any(PropAccess p)) or node = TPropNode(any(PropertyPattern p)) } or + MkImpliedLambdaCall(Function f) { + VariableCaptureConfig::captures(f, _) or CallGraph::impliedReceiverStep(_, TThisNode(f)) + } or MkSummaryCall( FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver ) { @@ -343,6 +390,7 @@ class DataFlowCall extends TDataFlowCall { DataFlow::InvokeNode asBoundCall(int boundArgs) { this = MkBoundCall(result, boundArgs) } + Function asImpliedLambdaCall() { this = MkImpliedLambdaCall(result) } predicate isSummaryCall( FlowSummaryImpl::Public::SummarizedCallable enclosingCallable, @@ -350,6 +398,7 @@ class DataFlowCall extends TDataFlowCall { ) { this = MkSummaryCall(enclosingCallable, receiver) } + predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { @@ -438,6 +487,7 @@ private class AccessorCall extends DataFlowCall, MkAccessorCall { ref.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) } } + class SummaryCall extends DataFlowCall, MkSummaryCall { private FlowSummaryImpl::Public::SummarizedCallable enclosingCallable; private FlowSummaryImpl::Private::SummaryNode receiver; @@ -456,6 +506,30 @@ class SummaryCall extends DataFlowCall, MkSummaryCall { FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver } } +/** + * A call that invokes a lambda with nothing but its self-reference node. + * + * This is to help ensure captured variables can flow into the lambda in cases where + * we can't find its call sites. + */ +private class ImpliedLambdaCall extends DataFlowCall, MkImpliedLambdaCall { + private Function function; + + ImpliedLambdaCall() { this = MkImpliedLambdaCall(function) } + + override string toString() { result = "[implied lambda call] " + function } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + function.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } + + override DataFlowCallable getEnclosingCallable() { + result.asSourceCallable() = function.getEnclosingContainer() + } +} + private int getMaxArity() { // TODO: account for flow summaries result = @@ -542,6 +616,8 @@ DataFlowCallable viableCallable(DataFlowCall node) { result = MkLibraryCallable(callable) and node.asOrdinaryCall() = [callable.getACall(), callable.getACallSimple()] ) + or + result.asSourceCallableNotExterns() = node.asImpliedLambdaCall() } /** @@ -568,12 +644,28 @@ private predicate sameContainerAsEnclosingContainer(Node node, Function fun) { node.getContainer() = fun.getEnclosingContainer() } +/** + * Holds if `node` should be removed from the local data flow graph, but the node + * still exists for use by the legacy data flow library. + */ +pragma[nomagic] +private predicate isBlockedLegacyNode(TCapturedVariableNode node) { + // Ignore captured variable nodes for those variables that are handled by the captured-variable library. + // Note that some variables, such as top-level variables, are still modelled with these nodes (which will result in jump steps). + exists(LocalVariable variable | + node = TCapturedVariableNode(variable) and + variable instanceof VariableCaptureConfig::CapturedVariable + ) +} + /** * Holds if there is a value-preserving steps `node1` -> `node2` that might * be cross function boundaries. */ private predicate valuePreservingStep(Node node1, Node node2) { node1.getASuccessor() = node2 and + not isBlockedLegacyNode(node1) and + not isBlockedLegacyNode(node2) or FlowSteps::propertyFlowStep(node1, node2) or @@ -613,6 +705,8 @@ predicate simpleLocalFlowStep(Node node1, Node node2) { node2 = TFlowSummaryNode(output) ) or + VariableCaptureOutput::localFlowStep(getClosureNode(node1), getClosureNode(node2)) + or // NOTE: For consistency with readStep/storeStep, we do not translate these steps to jump steps automatically. DataFlow::AdditionalFlowStep::step(node1, node2) } @@ -674,6 +768,11 @@ predicate readStep(Node node1, ContentSet c, Node node2) { c = ContentSet::arrayElement() ) or + exists(LocalVariable variable | + VariableCaptureOutput::readStep(getClosureNode(node1), variable, getClosureNode(node2)) and + c.asSingleton() = MkCapturedContent(variable) + ) + or DataFlow::AdditionalFlowStep::readStep(node1, c, node2) } @@ -714,6 +813,11 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { c = ContentSet::promiseValue() ) or + exists(LocalVariable variable | + VariableCaptureOutput::storeStep(getClosureNode(node1), variable, getClosureNode(node2)) and + c.asSingleton() = MkCapturedContent(variable) + ) + or DataFlow::AdditionalFlowStep::storeStep(node1, c, node2) } @@ -771,6 +875,11 @@ int accessPathLimit() { result = 5 } */ predicate allowParameterReturnInSelf(ParameterNode p) { FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(p) + or + exists(Function f | + VariableCaptureOutput::heuristicAllowInstanceParameterReturnInSelf(f) and + p = TFunctionSelfReferenceNode(f) + ) } class LambdaCallKind = Unit; diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll new file mode 100644 index 00000000000..99315bda045 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll @@ -0,0 +1,323 @@ +private import javascript as js +private import semmle.javascript.dataflow.internal.DataFlowNode +private import codeql.dataflow.VariableCapture +private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon + +module VariableCaptureConfig implements InputSig { + private js::Function getLambdaFromVariable(js::LocalVariable variable) { + result.getVariable() = variable + or + result = variable.getAnAssignedExpr() + or + exists(js::ClassDeclStmt cls | + result = cls.getConstructor().getBody() and + variable = cls.getVariable() + ) + } + + additional predicate isTopLevelLike(js::StmtContainer container) { + container instanceof js::TopLevel + or + container = any(js::AmdModuleDefinition mod).getFactoryFunction() + or + isTopLevelLike(container.(js::ImmediatelyInvokedFunctionExpr).getEnclosingContainer()) + or + // Functions declared in a top-level with no parameters and can't generate flow-through, except through 'this' + // which we rule out with a few syntactic checks. In this case we treat its captured variables as singletons. + // NOTE: This was done to prevent a blow-up in fiddlesalad where a function called 'Runtime' captures 7381 variables but is only called once. + exists(js::Function fun | + container = fun and + fun.getNumParameter() = 0 and + isTopLevelLike(fun.getEnclosingContainer()) and + not mayHaveFlowThroughThisArgument(fun) + ) + or + // Container declaring >100 captured variables tend to be singletons and are too expensive anyway + strictcount(js::LocalVariable v | v.isCaptured() and v.getDeclaringContainer() = container) > + 100 + } + + private predicate hasLocalConstructorCall(js::Function fun) { + fun = getLambdaFromVariable(any(js::NewExpr e).getCallee().(js::VarAccess).getVariable()) + } + + private predicate mayHaveFlowThroughThisArgument(js::Function fun) { + any(js::ThisExpr e).getBinder() = fun and + not hasLocalConstructorCall(fun) and // 'this' argument is assumed to be a fresh object + ( + exists(fun.getAReturnedExpr()) + or + exists(js::YieldExpr e | e.getContainer() = fun) + ) + } + + class CapturedVariable extends js::LocalVariable { + CapturedVariable() { + DataFlowImplCommon::forceCachingInSameStage() and + this.isCaptured() and + not isTopLevelLike(this.getDeclaringContainer()) and + // Exclude variables that just contain a function + // TODO: explain why + // TODO: also exclude if only use of variable is to call it. Handles case where variable is just alias for top-level function + not exists(getLambdaFromVariable(this)) + } + + Callable getCallable() { result = this.getDeclaringContainer().getFunctionBoundary() } + } + + additional predicate captures(js::Function fun, CapturedVariable variable) { + ( + variable.getAnAccess().getContainer().getFunctionBoundary() = fun + or + exists(js::Function inner | + captures(inner, variable) and + containsReferenceTo(fun, inner) + ) + ) and + not variable.getDeclaringContainer() = fun + } + + private predicate containsReferenceTo(js::Function fun, js::Function other) { + other.getEnclosingContainer() = fun + or + exists(js::LocalVariable variable | + other = getLambdaFromVariable(variable) and + variable.getAnAccess().getEnclosingFunction() = fun and + fun.getEnclosingContainer() = other.getEnclosingContainer().getEnclosingContainer*() and + other != fun + ) + } + + private js::Function getACapturingFunctionInTree(js::AstNode e) { + result = e and + captures(e, _) + or + not e instanceof js::Function and + result = getACapturingFunctionInTree(e.getAChild()) + } + + /** + * Holds if `decl` declares a variable that is captured by its own initializer, that is, the initializer of `decl`. + * + * For example, the declaration of `obj` below captures itself in its initializer: + * ```js + * const obj = { + * method: () => { ...obj... } + * } + * ``` + * + * The lambda can only observe values of `obj` at one of the aliases of that lambda. Due to limited aliases analysis, + * the only alias we can see is the lambda itself. However, at this stage the `obj` variable is still unassigned, so it + * just sees its implicit initialization, thus failing to capture any real flows through `obj`. + * + * Consider that the similar example does not have this problem: + * + * ```js + * const obj = {}; + * obj.method = () => { ...obj... }; + * ``` + * + * In this case, `obj` has already been assigned at the point of the lambda creation, so we propagate the correct value + * into the lambda. + * + * Our workaround is to make the first example look like the second one, by placing the assignment of + * `obj` before the object literal. We do this whenever a variable captures itself in its initializer. + */ + private predicate isCapturedByOwnInitializer(js::VariableDeclarator decl) { + exists(js::Function function | + function = getACapturingFunctionInTree(decl.getInit()) and + captures(function, decl.getBindingPattern().(js::VarDecl).getVariable()) + ) + } + + class BasicBlock extends js::BasicBlock { + Callable getEnclosingCallable() { result = this.getContainer().getFunctionBoundary() } + } + + class Location = js::Location; + + class Callable extends js::StmtContainer { + predicate isConstructor() { + // TODO: clarify exactly what the library wants to know here as the meaning of "constructor" varies between languages. + // JS constructors should not be seen as "constructors" in this context. + none() + } + } + + class CapturedParameter extends CapturedVariable { + CapturedParameter() { this.isParameter() } + } + + class Expr extends js::AST::ValueNode { + /** Holds if the `i`th node of basic block `bb` evaluates this expression. */ + predicate hasCfgNode(BasicBlock bb, int i) { + // Note: this is overridden for FunctionDeclStmt + bb.getNode(i) = this + } + } + + class VariableRead extends Expr instanceof js::VarAccess, js::RValue { + private CapturedVariable variable; + + VariableRead() { this = variable.getAnAccess() } + + CapturedVariable getVariable() { result = variable } + } + + class ClosureExpr extends Expr { + ClosureExpr() { captures(this, _) } + + predicate hasBody(Callable c) { c = this } + + predicate hasAliasedAccess(Expr e) { + e = this + or + exists(js::LocalVariable variable | + this = getLambdaFromVariable(variable) and + e = variable.getAnAccess() + ) + } + } + + private newtype TVariableWrite = + MkExplicitVariableWrite(js::VarRef pattern) { + exists(js::DataFlow::lvalueNodeInternal(pattern)) and + pattern.getVariable() instanceof CapturedVariable + } or + MkImplicitVariableInit(CapturedVariable v) { not v instanceof CapturedParameter } + + class VariableWrite extends TVariableWrite { + CapturedVariable getVariable() { none() } // Overridden in subclass + + string toString() { none() } // Overridden in subclass + + Location getLocation() { none() } // Overridden in subclass + + predicate hasCfgNode(BasicBlock bb, int i) { none() } // Overridden in subclass + + // note: langauge-specific + js::DataFlow::Node getSource() { none() } // Overridden in subclass + } + + additional class ExplicitVariableWrite extends VariableWrite, MkExplicitVariableWrite { + private js::VarRef pattern; + + ExplicitVariableWrite() { this = MkExplicitVariableWrite(pattern) } + + override CapturedVariable getVariable() { result = pattern.getVariable() } + + override string toString() { result = pattern.toString() } + + /** Gets the location of this write. */ + override Location getLocation() { result = pattern.getLocation() } + + override js::DataFlow::Node getSource() { + // Note: there is not always an expression corresponding to the RHS of the assignment. + // We do however have a data-flow node for this purpose (the lvalue-node). + // We use the pattern as a placeholder here, to be mapped to a data-flow node with `DataFlow::lvalueNode`. + result = js::DataFlow::lvalueNodeInternal(pattern) + } + + /** + * Gets a CFG node that should act at the place where this variable write happens, overriding its "true" CFG node. + */ + private js::ControlFlowNode getCfgNodeOverride() { + exists(js::VariableDeclarator decl | + decl.getBindingPattern() = pattern and + isCapturedByOwnInitializer(decl) and + result = decl.getInit().getFirstControlFlowNode() + ) + } + + /** Holds if the `i`th node of basic block `bb` evaluates this expression. */ + override predicate hasCfgNode(BasicBlock bb, int i) { + bb.getNode(i) = this.getCfgNodeOverride() + or + not exists(this.getCfgNodeOverride()) and + bb.getNode(i) = pattern.(js::LValue).getDefNode() + } + } + + additional class ImplicitVariableInit extends VariableWrite, MkImplicitVariableInit { + private CapturedVariable variable; + + ImplicitVariableInit() { this = MkImplicitVariableInit(variable) } + + override string toString() { result = "[implicit init] " + variable } + + override Location getLocation() { result = variable.getLocation() } + + override CapturedVariable getVariable() { result = variable } + + override predicate hasCfgNode(BasicBlock bb, int i) { + // 'i' would normally be bound to 0, but we lower it to -1 so FunctionDeclStmts can be evaluated + // at index 0. + any(js::SsaImplicitInit def).definesAt(bb, _, variable) and i = -1 + } + } + + BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() } + + BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() } + + predicate entryBlock(BasicBlock bb) { bb instanceof js::EntryBasicBlock } + + predicate exitBlock(BasicBlock bb) { bb.getLastNode() instanceof js::ControlFlowExitNode } +} + +module VariableCaptureOutput = Flow; + +js::DataFlow::Node getNodeFromClosureNode(VariableCaptureOutput::ClosureNode node) { + result = TValueNode(node.(VariableCaptureOutput::ExprNode).getExpr()) + or + result = TValueNode(node.(VariableCaptureOutput::ParameterNode).getParameter().getADeclaration()) // TODO: is this subsumed by the ExprNode case? + or + result = TExprPostUpdateNode(node.(VariableCaptureOutput::ExprPostUpdateNode).getExpr()) + or + // Note: the `this` parameter in the capture library is expected to be a parameter that refers to the lambda object itself, + // which for JS means the `TFunctionSelfReferenceNode`, not `TThisNode` as one might expect. + result = TFunctionSelfReferenceNode(node.(VariableCaptureOutput::ThisParameterNode).getCallable()) + or + result = TSynthCaptureNode(node.(VariableCaptureOutput::SynthesizedCaptureNode)) + or + result = node.(VariableCaptureOutput::VariableWriteSourceNode).getVariableWrite().getSource() +} + +VariableCaptureOutput::ClosureNode getClosureNode(js::DataFlow::Node node) { + node = getNodeFromClosureNode(result) +} + +private module Debug { + private import VariableCaptureConfig + + predicate relevantContainer(js::StmtContainer container) { + container.getEnclosingContainer*().(js::Function).getName() = "exists" + } + + predicate localFlowStep( + VariableCaptureOutput::ClosureNode node1, VariableCaptureOutput::ClosureNode node2 + ) { + VariableCaptureOutput::localFlowStep(node1, node2) + } + + predicate localFlowStepMapped(js::DataFlow::Node node1, js::DataFlow::Node node2) { + localFlowStep(getClosureNode(node1), getClosureNode(node2)) and + relevantContainer(node1.getContainer()) + } + + predicate readBB(VariableRead read, BasicBlock bb, int i) { read.hasCfgNode(bb, i) } + + predicate writeBB(VariableWrite write, BasicBlock bb, int i) { write.hasCfgNode(bb, i) } + + int captureDegree(js::Function fun) { + result = strictcount(CapturedVariable v | captures(fun, v)) + } + + int maxDegree() { result = max(captureDegree(_)) } + + int captureMax(js::Function fun) { result = captureDegree(fun) and result = maxDegree() } + + int captureMax(js::Function fun, CapturedVariable v) { + result = captureDegree(fun) and result = maxDegree() and captures(fun, v) + } +} From 46e4cdc6232604ea7f58138a336d5a222fad8567 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 11:54:43 +0200 Subject: [PATCH 033/514] JS: Disallow consecutive captured contents --- .../semmle/javascript/dataflow/internal/Contents.qll | 12 ++++++++++++ .../javascript/dataflow/internal/DataFlowPrivate.qll | 7 +++++++ .../javascript/dataflow/internal/VariableCapture.qll | 6 +----- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll index 55de1efc2d6..5c87d3c0a51 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll @@ -81,6 +81,7 @@ module Private { MkPromiseFilter() or MkIteratorFilter() or MkAnyProperty() or + MkAnyCapturedContent() or // The following content sets are used exclusively as an intermediate value in flow summaries. // These are encoded as a ContentSummaryComponent, although the flow graphs we generate are different // than an ordinary content component. These special content sets should never appear in a step. @@ -239,6 +240,9 @@ module Public { or result instanceof MkArrayElementUnknown ) + or + this = ContentSet::anyCapturedContent() and + result instanceof Private::MkCapturedContent } /** Gets the singleton content to be accessed. */ @@ -278,6 +282,9 @@ module Public { this = MkAnyPropertyDeep() and result = "AnyMemberDeep" or this = MkArrayElementDeep() and result = "ArrayElementDeep" + or + this = MkAnyCapturedContent() and + result = "AnyCapturedContent" } } @@ -477,5 +484,10 @@ module Public { else result = property(propertyName) ) } + + /** + * Gets a content set that reads from all captured variables stored on a function. + */ + ContentSet anyCapturedContent() { result = Private::MkAnyCapturedContent() } } } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 15dda32622b..0c269a7f152 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -839,6 +839,13 @@ predicate clearsContent(Node n, ContentSet c) { c = MkPromiseFilter() or any(AdditionalFlowInternal flow).clearsContent(n, c) + or + // When a function `f` captures itself, all its access paths can be prefixed by an arbitrary number of `f.f.f...`. + // When multiple functions `f,g` capture each other, these prefixes can become interleaved, like `f.g.f.g...`. + // To avoid creating these trivial prefixes, we never allow two consecutive captured variables in the access path. + // We implement this rule by clearing any captured-content before storing into another captured-content. + VariableCaptureOutput::storeStep(getClosureNode(n), _, _) and + c = MkAnyCapturedContent() } /** diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll index 99315bda045..1b1f50b9ecd 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll @@ -55,11 +55,7 @@ module VariableCaptureConfig implements InputSig { CapturedVariable() { DataFlowImplCommon::forceCachingInSameStage() and this.isCaptured() and - not isTopLevelLike(this.getDeclaringContainer()) and - // Exclude variables that just contain a function - // TODO: explain why - // TODO: also exclude if only use of variable is to call it. Handles case where variable is just alias for top-level function - not exists(getLambdaFromVariable(this)) + not isTopLevelLike(this.getDeclaringContainer()) } Callable getCallable() { result = this.getDeclaringContainer().getFunctionBoundary() } From 06fd9c23591fd06896fa8a3f1c26a061d5219793 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 15:15:51 +0200 Subject: [PATCH 034/514] JS: Add barrier guard library --- .../semmle/javascript/dataflow/DataFlow.qll | 1 + .../dataflow/internal/BarrierGuards.qll | 380 ++++++++++++++++++ 2 files changed, 381 insertions(+) create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index 75926baa889..d60a6c7bb04 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -1992,4 +1992,5 @@ module DataFlow { import TypeTracking import AdditionalFlowSteps import internal.FunctionWrapperSteps + import internal.BarrierGuards } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll new file mode 100644 index 00000000000..8e46ae79558 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll @@ -0,0 +1,380 @@ +/** + * A copy of the barrier guard logic from `Configuration.qll` in the JS data flow library. + * + * This version considers all barrier guards to be relevant. + */ + +private import javascript +private import semmle.javascript.dataflow.internal.AccessPaths + +private signature class BarrierGuardSig 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); +} + +/** + * Converts a barrier guard class to a set of nodes to include in an implementation of `isBarrier(node)`. + */ +module MakeBarrierGuard { + final private class FinalBaseGuard = BaseGuard; + + private class Adapter extends FinalBaseGuard { + predicate blocksExpr(boolean outcome, Expr e, Unit state) { + super.blocksExpr(outcome, e) and exists(state) + } + } + + /** + * Gets a node that is blocked by a barrier guard. + */ + DataFlow::Node getABarrierNode() { + result = MakeStateBarrierGuard::getABarrierNode(_) + } +} + +private signature class LabeledBarrierGuardSig extends DataFlow::Node { + /** + * 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); +} + +/** + * Converts a barrier guard class to a set of nodes to include in an implementation of `isBarrier(node, label)`. + */ +module MakeLabeledBarrierGuard { + final private class FinalBaseGuard = BaseGuard; + + private class Adapter extends FinalBaseGuard { + predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { + super.blocksExpr(outcome, e, label) + } + } + + /** + * Gets a node and flow label that is blocked by a barrier guard. + */ + DataFlow::Node getABarrierNode(DataFlow::FlowLabel label) { + result = MakeStateBarrierGuard::getABarrierNode(label) + } +} + +private signature predicate isBarrierGuardSig(DataFlow::BarrierGuardNode node); + +/** + * Converts a labeled barrier guard class to a set of nodes to include in an implementation of `isBarrier(node)` and `isBarrier(node, label)` + * in a `DataFlow::StateConfigSig` implementation. + */ +module MakeLegacyBarrierGuardLabeled { + final private class FinalNode = DataFlow::Node; + + private class Adapter extends FinalNode instanceof DataFlow::BarrierGuardNode { + Adapter() { isBarrierGuard(this) } + + predicate blocksExpr(boolean outcome, Expr e, string label) { + super.blocks(outcome, e, label) + or + super.blocks(outcome, e) and label = "" + } + } + + private module Guards = MakeStateBarrierGuard; + + /** + * Gets a node that is blocked by a barrier guard. + */ + DataFlow::Node getABarrierNode() { result = Guards::getABarrierNode("") } + + /** + * Gets a node and flow label that is blocked by a barrier guard. + */ + DataFlow::Node getABarrierNode(DataFlow::FlowLabel label) { + result = Guards::getABarrierNode(label) + } +} + +/** + * Converts a barrier guard class to a set of nodes to include in an implementation of `isBarrier(node)` in a `DataFlow::ConfigSig` implementation. + */ +module MakeLegacyBarrierGuard { + final private class FinalNode = DataFlow::Node; + + private class Adapter extends FinalNode instanceof DataFlow::BarrierGuardNode { + Adapter() { isBarrierGuard(this) } + + predicate blocksExpr(boolean outcome, Expr e, string label) { + super.blocks(outcome, e, label) + or + super.blocks(outcome, e) and label = "" + } + } + + private module Guards = MakeStateBarrierGuard; + + /** + * Gets a node that is blocked by a barrier guard. + */ + DataFlow::Node getABarrierNode() { result = Guards::getABarrierNode(["", "data", "taint"]) } +} + +bindingset[this] +private signature class FlowStateSig; + +private module WithFlowState { + signature class BarrierGuardSig extends DataFlow::Node { + /** + * Holds if this node acts as a barrier for `state`, blocking further flow from `e` if `this` evaluates to `outcome`. + */ + predicate blocksExpr(boolean outcome, Expr e, FlowState state); + } +} + +/** + * Converts a barrier guard class to a set of nodes to include in an implementation of `isBarrier(node, state)`. + */ +module MakeStateBarrierGuard< + FlowStateSig FlowState, WithFlowState::BarrierGuardSig BaseGuard> +{ + final private class FinalNode = DataFlow::Node; + + abstract private class BarrierGuard extends FinalNode { + abstract predicate blocksExpr(boolean outcome, Expr test, FlowState state); + } + + class ExplicitBarrierGuard extends BarrierGuard instanceof BaseGuard { + override predicate blocksExpr(boolean outcome, Expr test, FlowState state) { + BaseGuard.super.blocksExpr(outcome, test, state) + } + } + + /** + * Gets a node and flow state that is blocked by a barrier guard. + */ + pragma[nomagic] + DataFlow::Node getABarrierNode(FlowState state) { barrierGuardBlocksNode(_, result, state) } + + // + // ================================================================================================ + // NOTE + // The rest of this file is a copy of the barrier-guard logic in Configuration.qll except: + // - FlowLabel is replaced by FlowState + // - BarrierGuardNode and AdditionalBarrierGuardNode are replaced by the BarrierGuard class defined above + // - `barrierGuardBlocksEdge` is missing as dataflow2 does not support barrier edges + // - `barrierGuardIsRelevant` does not check pruning results as we can't access that from here + // ================================================================================================ + // + /** + * Holds if data flow node `guard` acts as a barrier for data flow. + * + * `state` is bound to the blocked state, or the empty FlowState if all labels should be blocked. + */ + pragma[nomagic] + private predicate barrierGuardBlocksExpr( + BarrierGuard guard, boolean outcome, Expr test, FlowState state + ) { + guard.blocksExpr(outcome, test, state) + } + + /** + * Holds if `guard` may block the flow of a value reachable through exploratory flow. + */ + pragma[nomagic] + private predicate barrierGuardIsRelevant(BarrierGuard guard) { + exists(Expr e | + barrierGuardBlocksExpr(guard, _, e, _) + // All guards are considered relevant (this is the difference from the main JS lib) + // isRelevantForward(e.flow(), _) + ) + } + + /** + * Holds if data flow node `guard` acts as a barrier for data flow due to aliasing through + * an access path. + * + * `state` is bound to the blocked state, or the empty FlowState if all labels should be blocked. + */ + pragma[nomagic] + private predicate barrierGuardBlocksAccessPath( + BarrierGuard guard, boolean outcome, AccessPath ap, FlowState state + ) { + barrierGuardIsRelevant(guard) and + barrierGuardBlocksExpr(guard, outcome, ap.getAnInstance(), state) + } + + /** + * Holds if there exists an input variable of `ref` that blocks the state `state`. + * + * This predicate is outlined to give the optimizer a hint about the join ordering. + */ + pragma[nomagic] + private predicate barrierGuardBlocksSsaRefinement( + BarrierGuard guard, boolean outcome, SsaRefinementNode ref, FlowState state + ) { + barrierGuardIsRelevant(guard) and + guard.getEnclosingExpr() = ref.getGuard().getTest() and + forex(SsaVariable input | input = ref.getAnInput() | + barrierGuardBlocksExpr(guard, outcome, input.getAUse(), state) + ) + } + + /** + * Holds if the result of `guard` is used in the branching condition `cond`. + * + * `outcome` is bound to the outcome of `cond` for join-ordering purposes. + */ + pragma[nomagic] + private predicate barrierGuardUsedInCondition( + BarrierGuard guard, ConditionGuardNode cond, boolean outcome + ) { + barrierGuardIsRelevant(guard) and + outcome = cond.getOutcome() and + ( + cond.getTest() = guard.getEnclosingExpr() + or + cond.getTest().flow().getImmediatePredecessor+() = guard + ) + } + + /** + * Holds if data flow node `nd` acts as a barrier for data flow, possibly due to aliasing + * through an access path. + * + * `state` is bound to the blocked state, or the empty FlowState if all labels should be blocked. + */ + pragma[nomagic] + private predicate barrierGuardBlocksNode(BarrierGuard guard, DataFlow::Node nd, FlowState state) { + // 1) `nd` is a use of a refinement node that blocks its input variable + exists(SsaRefinementNode ref, boolean outcome | + nd = DataFlow::ssaDefinitionNode(ref) and + outcome = ref.getGuard().(ConditionGuardNode).getOutcome() and + barrierGuardBlocksSsaRefinement(guard, outcome, ref, state) + ) + or + // 2) `nd` is an instance of an access path `p`, and dominated by a barrier for `p` + exists(AccessPath p, BasicBlock bb, ConditionGuardNode cond, boolean outcome | + nd = DataFlow::valueNode(p.getAnInstanceIn(bb)) and + barrierGuardUsedInCondition(guard, cond, outcome) and + barrierGuardBlocksAccessPath(guard, outcome, p, state) and + cond.dominates(bb) + ) + } + + /** + * Gets a logical `and` expression, or parenthesized expression, that contains `guard`. + */ + private Expr getALogicalAndParent(BarrierGuard guard) { + barrierGuardIsRelevant(guard) and result = guard.asExpr() + or + result.(LogAndExpr).getAnOperand() = getALogicalAndParent(guard) + or + result.getUnderlyingValue() = getALogicalAndParent(guard) + } + + /** + * Gets a logical `or` expression, or parenthesized expression, that contains `guard`. + */ + private Expr getALogicalOrParent(BarrierGuard guard) { + barrierGuardIsRelevant(guard) and result = guard.asExpr() + or + result.(LogOrExpr).getAnOperand() = getALogicalOrParent(guard) + or + result.getUnderlyingValue() = getALogicalOrParent(guard) + } + + final private class FinalFunction = Function; + + /** + * A function that returns the result of a barrier guard. + */ + private class BarrierGuardFunction extends FinalFunction { + DataFlow::ParameterNode sanitizedParameter; + BarrierGuard guard; + boolean guardOutcome; + FlowState state; + int paramIndex; + + BarrierGuardFunction() { + barrierGuardIsRelevant(guard) and + exists(Expr e | + exists(Expr returnExpr | + returnExpr = guard.asExpr() + or + // ad hoc support for conjunctions: + getALogicalAndParent(guard) = returnExpr and guardOutcome = true + or + // ad hoc support for disjunctions: + getALogicalOrParent(guard) = returnExpr and guardOutcome = false + | + exists(SsaExplicitDefinition ssa | + ssa.getDef().getSource() = returnExpr and + ssa.getVariable().getAUse() = this.getAReturnedExpr() + ) + or + returnExpr = this.getAReturnedExpr() + ) and + sanitizedParameter.flowsToExpr(e) and + barrierGuardBlocksExpr(guard, guardOutcome, e, state) + ) and + sanitizedParameter.getParameter() = this.getParameter(paramIndex) + } + + /** + * Holds if this function sanitizes argument `e` of call `call`, provided the call evaluates to `outcome`. + */ + predicate isBarrierCall(DataFlow::CallNode call, Expr e, boolean outcome, FlowState st) { + exists(DataFlow::Node arg | + DataFlow::argumentPassingStep(pragma[only_bind_into](call), pragma[only_bind_into](arg), + pragma[only_bind_into](this), pragma[only_bind_into](sanitizedParameter)) and + arg.asExpr() = e and + arg = call.getArgument(paramIndex) and + outcome = guardOutcome and + state = st + ) + } + } + + /** + * A call that sanitizes an argument. + */ + private class AdditionalBarrierGuardCall extends BarrierGuard instanceof DataFlow::CallNode { + BarrierGuardFunction f; + + AdditionalBarrierGuardCall() { f.isBarrierCall(this, _, _, _) } + + override predicate blocksExpr(boolean outcome, Expr e, FlowState state) { + f.isBarrierCall(this, e, outcome, state) + } + } + + /** + * A sanitizer where an inner sanitizer is compared against a boolean. + * E.g. (assuming `sanitizes(e)` is an existing sanitizer): + * ```javascript + * if (sanitizes(e) === true) { + * // e is sanitized + * } + * ``` + */ + private class CallAgainstEqualityCheck extends BarrierGuard { + BarrierGuard prev; + boolean polarity; + + CallAgainstEqualityCheck() { + prev instanceof DataFlow::CallNode and + exists(EqualityTest test, BooleanLiteral bool | + this.asExpr() = test and + test.hasOperands(prev.asExpr(), bool) and + polarity = test.getPolarity().booleanXor(bool.getBoolValue()) + ) + } + + override predicate blocksExpr(boolean outcome, Expr e, FlowState state) { + exists(boolean prevOutcome | + barrierGuardBlocksExpr(prev, prevOutcome, e, state) and + outcome = prevOutcome.booleanXor(polarity) + ) + } + } +} From 277292e3b9a60be5e2a9050d6d34e28f2603b3e0 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 12 Oct 2023 12:55:36 +0200 Subject: [PATCH 035/514] JS: Improve performance of barrier guards without pruning --- .../dataflow/internal/AccessPaths.qll | 2 +- .../dataflow/internal/BarrierGuards.qll | 86 ++++++++++++++++--- 2 files changed, 76 insertions(+), 12 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/AccessPaths.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/AccessPaths.qll index 669b53418a5..3bcc36a6577 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/AccessPaths.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/AccessPaths.qll @@ -92,7 +92,7 @@ class AccessPath extends TAccessPath { * Gets an expression in `bb` represented by this access path. */ cached - Expr getAnInstanceIn(BasicBlock bb) { + Expr getAnInstanceIn(ReachableBasicBlock bb) { Stages::DataFlowStage::ref() and exists(SsaVariable var | this = MkSsaRoot(var) and diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll index 8e46ae79558..340a7b9694b 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll @@ -131,6 +131,50 @@ private module WithFlowState { } } +/** + * Projects the dominator tree onto a tree that only considers dominance between `ConditionGuardNode`s. + * + * This exists to speeds up the dominance check for barrier guards acting on an access path, avoiding the following two + * bad join orders: + * + * - Enumerate all basic blocks dominated by a barrier guard, and then find uses of the access path in those blocks. + * - Enumerate all uses of an access path and then select those that are in a dominated block. + * + * Both joins have pathological cases in different benchmarks. + * + * We use a join order that is essentially the first one above, except we only enumerate condition guards, not all the blocks. + */ +cached +private module ConditionGuardDominators { + /** Gets the condition guard that most-immediately dominates `bb`. */ + private ConditionGuardNode getDominatingCondition(ReachableBasicBlock bb) { + result.getBasicBlock() = bb + or + not bb = any(ConditionGuardNode guard).getBasicBlock() and + result = getDominatingCondition(bb.getImmediateDominator()) + } + + private predicate immediateDom(ConditionGuardNode dominator, ConditionGuardNode dominated) { + dominator = getDominatingCondition(dominated.getBasicBlock().getImmediateDominator()) + or + dominator = dominated // make the fastTC below reflexive + } + + /** Gets a condition guard dominated by `node` */ + cached + ConditionGuardNode getADominatedConditionGuard(ConditionGuardNode node) = + fastTC(immediateDom/2)(node, result) + + /** Gets a use of `ap` and binds `guard` to its immediately-dominating condition guard (if any). */ + cached + Expr getAnAccessPathUseUnderCondition(AccessPath ap, ConditionGuardNode guard) { + exists(ReachableBasicBlock bb | + result = ap.getAnInstanceIn(bb) and + guard = getDominatingCondition(bb) + ) + } +} + /** * Converts a barrier guard class to a set of nodes to include in an implementation of `isBarrier(node, state)`. */ @@ -153,7 +197,7 @@ module MakeStateBarrierGuard< * Gets a node and flow state that is blocked by a barrier guard. */ pragma[nomagic] - DataFlow::Node getABarrierNode(FlowState state) { barrierGuardBlocksNode(_, result, state) } + DataFlow::Node getABarrierNode(FlowState state) { barrierGuardBlocksNode(result, state) } // // ================================================================================================ @@ -163,6 +207,7 @@ module MakeStateBarrierGuard< // - BarrierGuardNode and AdditionalBarrierGuardNode are replaced by the BarrierGuard class defined above // - `barrierGuardBlocksEdge` is missing as dataflow2 does not support barrier edges // - `barrierGuardIsRelevant` does not check pruning results as we can't access that from here + // - `barrierGuardBlocksNode` has been rewritten to perform better without pruning. // ================================================================================================ // /** @@ -237,27 +282,46 @@ module MakeStateBarrierGuard< ) } + /** Holds if a barrier guard blocks uses of `ap` in basic blocks dominated by `cond`. */ + pragma[nomagic] + private predicate barrierGuardBlocksAccessPathIn( + AccessPath ap, ConditionGuardNode cond, FlowState state + ) { + exists(BarrierGuard guard, boolean outcome | + barrierGuardBlocksAccessPath(guard, outcome, ap, state) and + barrierGuardUsedInCondition(guard, cond, outcome) + ) + } + + /** + * Holds if `expr` is an access path reference that is blocked by a barrier guard. + */ + pragma[noopt] + private predicate barrierGuardBlocksAccessPathUse(Expr use, FlowState state) { + exists(AccessPath p, ConditionGuardNode cond, ConditionGuardNode useDominator | + barrierGuardBlocksAccessPathIn(p, cond, state) and + useDominator = ConditionGuardDominators::getADominatedConditionGuard(cond) and + use = ConditionGuardDominators::getAnAccessPathUseUnderCondition(p, useDominator) + ) + } + /** * Holds if data flow node `nd` acts as a barrier for data flow, possibly due to aliasing * through an access path. * - * `state` is bound to the blocked state, or the empty FlowState if all labels should be blocked. + * `state` is bound to the blocked state. */ pragma[nomagic] - private predicate barrierGuardBlocksNode(BarrierGuard guard, DataFlow::Node nd, FlowState state) { - // 1) `nd` is a use of a refinement node that blocks its input variable - exists(SsaRefinementNode ref, boolean outcome | + private predicate barrierGuardBlocksNode(DataFlow::Node nd, FlowState state) { + exists(BarrierGuard guard, SsaRefinementNode ref, boolean outcome | nd = DataFlow::ssaDefinitionNode(ref) and outcome = ref.getGuard().(ConditionGuardNode).getOutcome() and barrierGuardBlocksSsaRefinement(guard, outcome, ref, state) ) or - // 2) `nd` is an instance of an access path `p`, and dominated by a barrier for `p` - exists(AccessPath p, BasicBlock bb, ConditionGuardNode cond, boolean outcome | - nd = DataFlow::valueNode(p.getAnInstanceIn(bb)) and - barrierGuardUsedInCondition(guard, cond, outcome) and - barrierGuardBlocksAccessPath(guard, outcome, p, state) and - cond.dominates(bb) + exists(Expr use | + barrierGuardBlocksAccessPathUse(use, state) and + nd = DataFlow::valueNode(use) ) } From 1ed32356394e329de45ad144739014dd79a0a341 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 15:17:26 +0200 Subject: [PATCH 036/514] JS: use BarrierGuards --- .../dataflow/internal/TaintTrackingPrivate.qll | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index 0380cf8202f..03d82ad42ea 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -2,6 +2,7 @@ private import javascript private import semmle.javascript.dataflow.internal.DataFlowPrivate private import semmle.javascript.dataflow.internal.Contents::Public private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as FlowSummaryImpl +private import semmle.javascript.dataflow.internal.BarrierGuards cached predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { @@ -18,6 +19,12 @@ predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) ContentSet::arrayElement(), node2.(FlowSummaryNode).getSummaryNode()) } +private class SanitizerGuardAdapter extends DataFlow::Node instanceof TaintTracking::AdditionalSanitizerGuardNode +{ + // Note: avoid depending on DataFlow::FlowLabel here as it will cause these barriers to be re-evaluated + predicate blocksExpr(boolean outcome, Expr e) { super.sanitizes(outcome, e) } +} + /** * Holds if `node` should be a sanitizer in all global taint flow configurations * but not in local taint. @@ -25,7 +32,9 @@ predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) cached predicate defaultTaintSanitizer(DataFlow::Node node) { node instanceof DataFlow::VarAccessBarrier or + node = MakeBarrierGuard::getABarrierNode() } + /** * Holds if default taint-tracking should allow implicit reads * of `c` at sinks and inputs to additional taint steps. From c924b4a2206d39eeedf13dd9334dab63dd2dbc0f Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 15:32:28 +0200 Subject: [PATCH 037/514] JS: Expose shared API in DataFlow/TaintTracking modules --- javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll | 1 + javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll | 2 ++ 2 files changed, 3 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index d60a6c7bb04..e742227ded4 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -1992,5 +1992,6 @@ module DataFlow { import TypeTracking import AdditionalFlowSteps import internal.FunctionWrapperSteps + import internal.sharedlib.DataFlow import internal.BarrierGuards } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index eb58a1d3055..9e0a2fe5159 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -1033,4 +1033,6 @@ module TaintTracking { override predicate appliesTo(Configuration cfg) { any() } } + + import internal.sharedlib.TaintTracking } From 26f7f9424643d7c4c64da7d0c3db5d3482f1a405 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 15:32:47 +0200 Subject: [PATCH 038/514] JS: Expose default taint steps/sanitizers We need access to these in order to port taint-tracking configurations where only some flow labels should use taint steps. This isn't supported by the shared data flow library. Such queries must therefore be converted to plain data-flow configurations that explicitly add taint steps to the relevant flow states. --- .../javascript/dataflow/TaintTracking.qll | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 9e0a2fe5159..0175acaf3ef 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -18,6 +18,7 @@ private import semmle.javascript.dataflow.internal.FlowSteps as FlowSteps private import semmle.javascript.Unit private import semmle.javascript.dataflow.InferredTypes private import semmle.javascript.internal.CachedStages +private import semmle.javascript.dataflow.internal.TaintTrackingPrivate as TaintTrackingPrivate /** * Provides classes for modeling taint propagation. @@ -1035,4 +1036,22 @@ module TaintTracking { } import internal.sharedlib.TaintTracking + + /** + * Holds if there is a taint step from `node1` to `node2`. + * + * This includes steps between synthesized nodes generated by flow summaries. + */ + pragma[inline] + predicate defaultTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + TaintTrackingPrivate::defaultAdditionalTaintStep(node1, node2) + } + + /** + * Holds if `node` is seen as a barrier for taint-tracking. + */ + pragma[inline] + predicate defaultSanitizer(DataFlow::Node node) { + TaintTrackingPrivate::defaultTaintSanitizer(node) + } } From bc68b6a7f87479ccc44d65a0493813e47aa60209 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 15:41:19 +0200 Subject: [PATCH 039/514] JS: Add AdHocWhitelistSanitizer::getABarrierNode() This sanitizer guard is opt-in, i.e. not an AdditionalSanitizerGuardNode. --- .../ql/lib/semmle/javascript/dataflow/TaintTracking.qll | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 0175acaf3ef..8e1964ac0e3 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -830,12 +830,18 @@ module TaintTracking { this.getNumArgument() = 1 } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + /** Holds if this node blocks flow through `e`, provided it evaluates to `outcome`. */ + predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = this.getArgument(0).asExpr() } } + /** Barrier nodes derived from the `AdHocWhitelistCheckSanitizer` class. */ + module AdHocWhitelistCheckSanitizer = DataFlow::MakeBarrierGuard; + /** A check of the form `if(x in o)`, which sanitizes `x` in its "then" branch. */ class InSanitizer extends AdditionalSanitizerGuardNode, DataFlow::ValueNode { override InExpr astNode; From aa5a2836f557ddc03c5f33f0706891fbcc098074 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:59:08 +0200 Subject: [PATCH 040/514] JS: Update barriers in TaintedObject --- .../javascript/security/TaintedObject.qll | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/TaintedObject.qll b/javascript/ql/lib/semmle/javascript/security/TaintedObject.qll index 3022bded373..22f253e1423 100644 --- a/javascript/ql/lib/semmle/javascript/security/TaintedObject.qll +++ b/javascript/ql/lib/semmle/javascript/security/TaintedObject.qll @@ -81,7 +81,24 @@ module TaintedObject { /** * A sanitizer guard that blocks deep object taint. */ - abstract class SanitizerGuard extends TaintTracking::LabeledSanitizerGuardNode { } + abstract class SanitizerGuard extends TaintTracking::LabeledSanitizerGuardNode { + /** Holds if this node blocks flow through `e`, provided it evaluates to `outcome`. */ + predicate blocksExpr(boolean outcome, Expr e) { none() } + + /** Holds if this node blocks flow of `label` through `e`, provided it evaluates to `outcome`. */ + predicate blocksExpr(boolean outcome, Expr e, FlowLabel label) { none() } + + override predicate sanitizes(boolean outcome, Expr e, FlowLabel label) { + this.blocksExpr(outcome, e, label) + } + + override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + } + + /** + * A sanitizer guard that blocks deep object taint. + */ + module SanitizerGuard = DataFlow::MakeLabeledBarrierGuard; /** * A test of form `typeof x === "something"`, preventing `x` from being an object in some cases. @@ -103,7 +120,7 @@ module TaintedObject { ) } - override predicate sanitizes(boolean outcome, Expr e, FlowLabel label) { + override predicate blocksExpr(boolean outcome, Expr e, FlowLabel label) { polarity = outcome and e = operand and label = label() @@ -117,7 +134,7 @@ module TaintedObject { 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 guard that checks whether an input a valid string identifier using `mongoose.Types.ObjectId.isValid` */ @@ -145,7 +162,7 @@ module TaintedObject { JsonSchemaValidationGuard() { this = call.getAValidationResultAccess(polarity) } - override predicate sanitizes(boolean outcome, Expr e, FlowLabel label) { + override predicate blocksExpr(boolean outcome, Expr e, FlowLabel label) { outcome = polarity and e = call.getInput().asExpr() and label = label() From 449ec72dbe8ae112d22e29466090bea95d9f1e7d Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:19:46 +0200 Subject: [PATCH 041/514] JS: Port experimental queries --- .../adaptivethreatmodeling/TaintedPathATM.qll | 10 +- .../XssThroughDomATM.qll | 4 +- .../Security/CWE-340/TokenBuiltFromUUID.ql | 17 +- .../src/experimental/Security/CWE-918/SSRF.ql | 6 +- .../experimental/Security/CWE-918/SSRF.qll | 48 +++-- .../ql/src/Security/CWE-094/CodeInjection.ql | 6 +- .../Security/CWE-134/TaintedFormatString.ql | 7 +- .../CorsMisconfigurationForCredentials.ql | 7 +- .../CWE-400/RemotePropertyInjection.ql | 8 +- .../Security/CWE-502/UnsafeDeserialization.ql | 7 +- .../heuristics/ql/src/Security/CWE-611/Xxe.ql | 6 +- .../ql/src/Security/CWE-643/XpathInjection.ql | 6 +- .../src/Security/CWE-730/RegExpInjection.ql | 6 +- .../ql/src/Security/CWE-776/XmlBomb.ql | 6 +- .../CWE-915/PrototypePollutingAssignment.ql | 9 +- .../Security/CWE-918/SSRF.expected | 174 +++++------------- 16 files changed, 133 insertions(+), 194 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll index c20eceb0f9c..04b33742a95 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll @@ -53,11 +53,17 @@ class TaintedPathAtmConfig extends AtmConfig { */ private class BarrierGuardNodeAsSanitizerGuardNode extends TaintTracking::LabeledSanitizerGuardNode instanceof TaintedPath::BarrierGuardNode { - override predicate sanitizes(boolean outcome, Expr e) { + override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + predicate blocksExpr(boolean outcome, Expr e) { this.blocks(outcome, e) or this.blocks(outcome, e, _) } - override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { + override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { + this.blocksExpr(outcome, e, lbl) + } + + predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { this.sanitizes(outcome, e) and exists(label) } } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssThroughDomATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssThroughDomATM.qll index 0eeba5d23ad..56397475322 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssThroughDomATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssThroughDomATM.qll @@ -59,7 +59,9 @@ class TypeTestGuard extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNo ) } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + predicate blocksExpr(boolean outcome, Expr e) { polarity = outcome and e = operand } diff --git a/javascript/ql/src/experimental/Security/CWE-340/TokenBuiltFromUUID.ql b/javascript/ql/src/experimental/Security/CWE-340/TokenBuiltFromUUID.ql index a2437fa670c..2f039b8fc3b 100644 --- a/javascript/ql/src/experimental/Security/CWE-340/TokenBuiltFromUUID.ql +++ b/javascript/ql/src/experimental/Security/CWE-340/TokenBuiltFromUUID.ql @@ -14,7 +14,6 @@ import javascript import DataFlow -import DataFlow::PathGraph class PredictableResultSource extends DataFlow::Node { PredictableResultSource() { @@ -38,14 +37,16 @@ class TokenAssignmentValueSink extends DataFlow::Node { } } -class TokenBuiltFromUuidConfig extends TaintTracking::Configuration { - TokenBuiltFromUuidConfig() { this = "TokenBuiltFromUuidConfig" } +module TokenBuiltFromUuidConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof PredictableResultSource } - override predicate isSource(DataFlow::Node source) { source instanceof PredictableResultSource } - - override predicate isSink(DataFlow::Node sink) { sink instanceof TokenAssignmentValueSink } + predicate isSink(DataFlow::Node sink) { sink instanceof TokenAssignmentValueSink } } -from DataFlow::PathNode source, DataFlow::PathNode sink, TokenBuiltFromUuidConfig config -where config.hasFlowPath(source, sink) +module TokenBuiltFromUuidFlow = TaintTracking::Global; + +import TokenBuiltFromUuidFlow::PathGraph + +from TokenBuiltFromUuidFlow::PathNode source, TokenBuiltFromUuidFlow::PathNode sink +where TokenBuiltFromUuidFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Token built from $@.", source.getNode(), "predictable value" diff --git a/javascript/ql/src/experimental/Security/CWE-918/SSRF.ql b/javascript/ql/src/experimental/Security/CWE-918/SSRF.ql index ce4d3f7791c..7ea1826bbfa 100644 --- a/javascript/ql/src/experimental/Security/CWE-918/SSRF.ql +++ b/javascript/ql/src/experimental/Security/CWE-918/SSRF.ql @@ -12,9 +12,9 @@ import javascript import SSRF -import DataFlow::PathGraph +import SsrfFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node request +from SsrfFlow::PathNode source, SsrfFlow::PathNode sink, DataFlow::Node request where - cfg.hasFlowPath(source, sink) and request = sink.getNode().(RequestForgery::Sink).getARequest() + SsrfFlow::flowPath(source, sink) and request = sink.getNode().(RequestForgery::Sink).getARequest() select sink, source, sink, "The URL of this request depends on a user-provided value." diff --git a/javascript/ql/src/experimental/Security/CWE-918/SSRF.qll b/javascript/ql/src/experimental/Security/CWE-918/SSRF.qll index 95d46aad868..da20923ce1a 100644 --- a/javascript/ql/src/experimental/Security/CWE-918/SSRF.qll +++ b/javascript/ql/src/experimental/Security/CWE-918/SSRF.qll @@ -2,42 +2,48 @@ import javascript import semmle.javascript.security.dataflow.RequestForgeryCustomizations import semmle.javascript.security.dataflow.UrlConcatenation -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "SSRF" } +module SsrfConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RequestForgery::Source } - override predicate isSource(DataFlow::Node source) { source instanceof RequestForgery::Source } + predicate isSink(DataFlow::Node sink) { sink instanceof RequestForgery::Sink } - override predicate isSink(DataFlow::Node sink) { sink instanceof RequestForgery::Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof RequestForgery::Sanitizer + predicate isBarrier(DataFlow::Node node) { + node instanceof RequestForgery::Sanitizer or node = Guards::getABarrierNode() } private predicate hasSanitizingSubstring(DataFlow::Node nd) { nd.getStringValue().regexpMatch(".*[?#].*") or - this.hasSanitizingSubstring(StringConcatenation::getAnOperand(nd)) + hasSanitizingSubstring(StringConcatenation::getAnOperand(nd)) or - this.hasSanitizingSubstring(nd.getAPredecessor()) + hasSanitizingSubstring(nd.getAPredecessor()) } private predicate strictSanitizingPrefixEdge(DataFlow::Node source, DataFlow::Node sink) { exists(DataFlow::Node operator, int n | StringConcatenation::taintStep(source, sink, operator, n) and - this.hasSanitizingSubstring(StringConcatenation::getOperand(operator, [0 .. n - 1])) + hasSanitizingSubstring(StringConcatenation::getOperand(operator, [0 .. n - 1])) ) } - override predicate isSanitizerOut(DataFlow::Node node) { - this.strictSanitizingPrefixEdge(node, _) - } + predicate isBarrierOut(DataFlow::Node node) { strictSanitizingPrefixEdge(node, _) } - override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode nd) { + private predicate isBarrierGuard(DataFlow::BarrierGuardNode nd) { nd instanceof IntegerCheck or nd instanceof ValidatorCheck or nd instanceof TernaryOperatorSanitizerGuard } + + private module Guards = DataFlow::MakeLegacyBarrierGuard; +} + +module SsrfFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `SsrfFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { + Configuration() { this = "SSRF" } } /** @@ -104,7 +110,9 @@ class TernaryOperatorSanitizerGuard extends TaintTracking::SanitizerGuardNode { not this.asExpr() instanceof LogicalBinaryExpr } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + predicate blocksExpr(boolean outcome, Expr e) { not this.asExpr() instanceof LogNotExpr and originalGuard.sanitizes(outcome, e) or @@ -126,7 +134,9 @@ class TernaryOperatorSanitizerGuard extends TaintTracking::SanitizerGuardNode { class IntegerCheck extends TaintTracking::SanitizerGuardNode, DataFlow::CallNode { IntegerCheck() { this = DataFlow::globalVarRef("Number").getAMemberCall("isInteger") } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = this.getArgument(0).asExpr() } @@ -149,7 +159,9 @@ class ValidatorCheck extends TaintTracking::SanitizerGuardNode, DataFlow::CallNo ) } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = this.getArgument(0).asExpr() } diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-094/CodeInjection.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-094/CodeInjection.ql index 89d7d253f41..34ebe06f68c 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-094/CodeInjection.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-094/CodeInjection.ql @@ -17,10 +17,10 @@ import javascript import semmle.javascript.security.dataflow.CodeInjectionQuery -import DataFlow::PathGraph +import CodeInjectionFlow::PathGraph import semmle.javascript.heuristics.AdditionalSources -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource +from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink +where CodeInjectionFlow::flowPath(source, sink) and source.getNode() instanceof HeuristicSource select sink.getNode(), source, sink, sink.getNode().(Sink).getMessagePrefix() + " depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-134/TaintedFormatString.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-134/TaintedFormatString.ql index 883f8292c75..8ba7a1273ea 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-134/TaintedFormatString.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-134/TaintedFormatString.ql @@ -13,10 +13,11 @@ import javascript import semmle.javascript.security.dataflow.TaintedFormatStringQuery -import DataFlow::PathGraph +import TaintedFormatStringFlow::PathGraph import semmle.javascript.heuristics.AdditionalSources -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource +from TaintedFormatStringFlow::PathNode source, TaintedFormatStringFlow::PathNode sink +where + TaintedFormatStringFlow::flowPath(source, sink) and source.getNode() instanceof HeuristicSource select sink.getNode(), source, sink, "Format string depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-346/CorsMisconfigurationForCredentials.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-346/CorsMisconfigurationForCredentials.ql index 3448e4e99b6..02677fd6a9e 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-346/CorsMisconfigurationForCredentials.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-346/CorsMisconfigurationForCredentials.ql @@ -15,11 +15,12 @@ import javascript import semmle.javascript.security.dataflow.CorsMisconfigurationForCredentialsQuery -import DataFlow::PathGraph import semmle.javascript.heuristics.AdditionalSources +import CorsMisconfigurationFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource +from CorsMisconfigurationFlow::PathNode source, CorsMisconfigurationFlow::PathNode sink +where + CorsMisconfigurationFlow::flowPath(source, sink) and source.getNode() instanceof HeuristicSource select sink.getNode(), source, sink, "$@ leak vulnerability due to a $@.", sink.getNode().(Sink).getCredentialsHeader(), "Credential", source.getNode(), "misconfigured CORS header value" diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-400/RemotePropertyInjection.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-400/RemotePropertyInjection.ql index fd707ae8faa..7118c49f2e2 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-400/RemotePropertyInjection.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-400/RemotePropertyInjection.ql @@ -15,10 +15,12 @@ import javascript import semmle.javascript.security.dataflow.RemotePropertyInjectionQuery -import DataFlow::PathGraph +import RemotePropertyInjectionFlow::PathGraph import semmle.javascript.heuristics.AdditionalSources -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource +from RemotePropertyInjectionFlow::PathNode source, RemotePropertyInjectionFlow::PathNode sink +where + RemotePropertyInjectionFlow::flowPath(source, sink) and + source.getNode() instanceof HeuristicSource select sink.getNode(), source, sink, sink.getNode().(Sink).getMessage() + " depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-502/UnsafeDeserialization.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-502/UnsafeDeserialization.ql index 24939f49b0d..8acde1f396e 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-502/UnsafeDeserialization.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-502/UnsafeDeserialization.ql @@ -14,10 +14,11 @@ import javascript import semmle.javascript.security.dataflow.UnsafeDeserializationQuery -import DataFlow::PathGraph +import UnsafeDeserializationFlow::PathGraph import semmle.javascript.heuristics.AdditionalSources -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource +from UnsafeDeserializationFlow::PathNode source, UnsafeDeserializationFlow::PathNode sink +where + UnsafeDeserializationFlow::flowPath(source, sink) and source.getNode() instanceof HeuristicSource select sink.getNode(), source, sink, "Unsafe deserialization depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-611/Xxe.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-611/Xxe.ql index cbfaa33ca51..262c9d52fe0 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-611/Xxe.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-611/Xxe.ql @@ -15,11 +15,11 @@ import javascript import semmle.javascript.security.dataflow.XxeQuery -import DataFlow::PathGraph +import XxeFlow::PathGraph import semmle.javascript.heuristics.AdditionalSources -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource +from XxeFlow::PathNode source, XxeFlow::PathNode sink +where XxeFlow::flowPath(source, sink) and source.getNode() instanceof HeuristicSource select sink.getNode(), source, sink, "XML parsing depends on a $@ without guarding against external entity expansion.", source.getNode(), "user-provided value" diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-643/XpathInjection.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-643/XpathInjection.ql index 0a00511c86b..c7cd82938cc 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-643/XpathInjection.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-643/XpathInjection.ql @@ -14,10 +14,10 @@ import javascript import semmle.javascript.security.dataflow.XpathInjectionQuery -import DataFlow::PathGraph +import XpathInjectionFlow::PathGraph import semmle.javascript.heuristics.AdditionalSources -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource +from XpathInjectionFlow::PathNode source, XpathInjectionFlow::PathNode sink +where XpathInjectionFlow::flowPath(source, sink) and source.getNode() instanceof HeuristicSource select sink.getNode(), source, sink, "XPath expression depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-730/RegExpInjection.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-730/RegExpInjection.ql index de302e53871..b0e761257cb 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-730/RegExpInjection.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-730/RegExpInjection.ql @@ -16,10 +16,10 @@ import javascript import semmle.javascript.security.dataflow.RegExpInjectionQuery -import DataFlow::PathGraph +import RegExpInjectionFlow::PathGraph import semmle.javascript.heuristics.AdditionalSources -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource +from RegExpInjectionFlow::PathNode source, RegExpInjectionFlow::PathNode sink +where RegExpInjectionFlow::flowPath(source, sink) and source.getNode() instanceof HeuristicSource select sink.getNode(), source, sink, "This regular expression is constructed from a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-776/XmlBomb.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-776/XmlBomb.ql index 1c05ba2424f..dacaa08a1b2 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-776/XmlBomb.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-776/XmlBomb.ql @@ -15,11 +15,11 @@ import javascript import semmle.javascript.security.dataflow.XmlBombQuery -import DataFlow::PathGraph +import XmlBombFlow::PathGraph import semmle.javascript.heuristics.AdditionalSources -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource +from XmlBombFlow::PathNode source, XmlBombFlow::PathNode sink +where XmlBombFlow::flowPath(source, sink) and source.getNode() instanceof HeuristicSource select sink.getNode(), source, sink, "XML parsing depends on a $@ without guarding against uncontrolled entity expansion.", source.getNode(), "user-provided value" diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-915/PrototypePollutingAssignment.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-915/PrototypePollutingAssignment.ql index eae399ea00f..a939794e375 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-915/PrototypePollutingAssignment.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-915/PrototypePollutingAssignment.ql @@ -20,11 +20,14 @@ import javascript import semmle.javascript.security.dataflow.PrototypePollutingAssignmentQuery -import DataFlow::PathGraph +import PrototypePollutingAssignmentFlow::PathGraph import semmle.javascript.heuristics.AdditionalSources -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource +from + PrototypePollutingAssignmentFlow::PathNode source, PrototypePollutingAssignmentFlow::PathNode sink +where + PrototypePollutingAssignmentFlow::flowPath(source, sink) and + source.getNode() instanceof HeuristicSource select sink, source, sink, "This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@.", source.getNode(), source.getNode().(Source).describe() diff --git a/javascript/ql/test/experimental/Security/CWE-918/SSRF.expected b/javascript/ql/test/experimental/Security/CWE-918/SSRF.expected index 848264b661b..6546ece2568 100644 --- a/javascript/ql/test/experimental/Security/CWE-918/SSRF.expected +++ b/javascript/ql/test/experimental/Security/CWE-918/SSRF.expected @@ -1,157 +1,67 @@ -nodes -| check-domain.js:16:9:16:27 | url | -| check-domain.js:16:15:16:27 | req.query.url | -| check-domain.js:16:15:16:27 | req.query.url | -| check-domain.js:17:13:17:15 | url | -| check-domain.js:17:13:17:15 | url | -| check-domain.js:26:15:26:27 | req.query.url | -| check-domain.js:26:15:26:27 | req.query.url | -| check-domain.js:26:15:26:27 | req.query.url | -| check-middleware.js:9:13:9:43 | "test.c ... tainted | -| check-middleware.js:9:13:9:43 | "test.c ... tainted | -| check-middleware.js:9:27:9:43 | req.query.tainted | -| check-middleware.js:9:27:9:43 | req.query.tainted | -| check-path.js:19:13:19:43 | 'test.c ... tainted | -| check-path.js:19:13:19:43 | 'test.c ... tainted | -| check-path.js:19:27:19:43 | req.query.tainted | -| check-path.js:19:27:19:43 | req.query.tainted | -| check-path.js:23:13:23:45 | `/addre ... inted}` | -| check-path.js:23:13:23:45 | `/addre ... inted}` | -| check-path.js:23:27:23:43 | req.query.tainted | -| check-path.js:23:27:23:43 | req.query.tainted | -| check-path.js:33:15:33:45 | 'test.c ... tainted | -| check-path.js:33:15:33:45 | 'test.c ... tainted | -| check-path.js:33:29:33:45 | req.query.tainted | -| check-path.js:33:29:33:45 | req.query.tainted | -| check-path.js:37:15:37:45 | 'test.c ... tainted | -| check-path.js:37:15:37:45 | 'test.c ... tainted | -| check-path.js:37:29:37:45 | req.query.tainted | -| check-path.js:37:29:37:45 | req.query.tainted | -| check-path.js:45:13:45:44 | `${base ... inted}` | -| check-path.js:45:13:45:44 | `${base ... inted}` | -| check-path.js:45:26:45:42 | req.query.tainted | -| check-path.js:45:26:45:42 | req.query.tainted | -| check-regex.js:16:15:16:45 | "test.c ... tainted | -| check-regex.js:16:15:16:45 | "test.c ... tainted | -| check-regex.js:16:29:16:45 | req.query.tainted | -| check-regex.js:16:29:16:45 | req.query.tainted | -| check-regex.js:24:15:24:42 | baseURL ... tainted | -| check-regex.js:24:15:24:42 | baseURL ... tainted | -| check-regex.js:24:25:24:42 | req.params.tainted | -| check-regex.js:24:25:24:42 | req.params.tainted | -| check-regex.js:31:15:31:45 | "test.c ... tainted | -| check-regex.js:31:15:31:45 | "test.c ... tainted | -| check-regex.js:31:29:31:45 | req.query.tainted | -| check-regex.js:31:29:31:45 | req.query.tainted | -| check-regex.js:34:15:34:42 | baseURL ... tainted | -| check-regex.js:34:15:34:42 | baseURL ... tainted | -| check-regex.js:34:25:34:42 | req.params.tainted | -| check-regex.js:34:25:34:42 | req.params.tainted | -| check-regex.js:41:13:41:43 | "test.c ... tainted | -| check-regex.js:41:13:41:43 | "test.c ... tainted | -| check-regex.js:41:27:41:43 | req.query.tainted | -| check-regex.js:41:27:41:43 | req.query.tainted | -| check-validator.js:15:15:15:45 | "test.c ... tainted | -| check-validator.js:15:15:15:45 | "test.c ... tainted | -| check-validator.js:15:29:15:45 | req.query.tainted | -| check-validator.js:15:29:15:45 | req.query.tainted | -| check-validator.js:27:15:27:45 | "test.c ... tainted | -| check-validator.js:27:15:27:45 | "test.c ... tainted | -| check-validator.js:27:29:27:45 | req.query.tainted | -| check-validator.js:27:29:27:45 | req.query.tainted | -| check-validator.js:50:15:50:45 | "test.c ... tainted | -| check-validator.js:50:15:50:45 | "test.c ... tainted | -| check-validator.js:50:29:50:45 | req.query.tainted | -| check-validator.js:50:29:50:45 | req.query.tainted | -| check-validator.js:54:9:54:37 | numberURL | -| check-validator.js:54:21:54:37 | req.query.tainted | -| check-validator.js:54:21:54:37 | req.query.tainted | -| check-validator.js:59:15:59:45 | "test.c ... tainted | -| check-validator.js:59:15:59:45 | "test.c ... tainted | -| check-validator.js:59:29:59:45 | req.query.tainted | -| check-validator.js:59:29:59:45 | req.query.tainted | -| check-validator.js:62:15:62:37 | "test.c ... mberURL | -| check-validator.js:62:15:62:37 | "test.c ... mberURL | -| check-validator.js:62:29:62:37 | numberURL | -| check-validator.js:68:15:68:45 | "test.c ... tainted | -| check-validator.js:68:15:68:45 | "test.c ... tainted | -| check-validator.js:68:29:68:45 | req.query.tainted | -| check-validator.js:68:29:68:45 | req.query.tainted | edges | check-domain.js:16:9:16:27 | url | check-domain.js:17:13:17:15 | url | -| check-domain.js:16:9:16:27 | url | check-domain.js:17:13:17:15 | url | | check-domain.js:16:15:16:27 | req.query.url | check-domain.js:16:9:16:27 | url | -| check-domain.js:16:15:16:27 | req.query.url | check-domain.js:16:9:16:27 | url | -| check-domain.js:26:15:26:27 | req.query.url | check-domain.js:26:15:26:27 | req.query.url | -| check-middleware.js:9:27:9:43 | req.query.tainted | check-middleware.js:9:13:9:43 | "test.c ... tainted | -| check-middleware.js:9:27:9:43 | req.query.tainted | check-middleware.js:9:13:9:43 | "test.c ... tainted | -| check-middleware.js:9:27:9:43 | req.query.tainted | check-middleware.js:9:13:9:43 | "test.c ... tainted | | check-middleware.js:9:27:9:43 | req.query.tainted | check-middleware.js:9:13:9:43 | "test.c ... tainted | | check-path.js:19:27:19:43 | req.query.tainted | check-path.js:19:13:19:43 | 'test.c ... tainted | -| check-path.js:19:27:19:43 | req.query.tainted | check-path.js:19:13:19:43 | 'test.c ... tainted | -| check-path.js:19:27:19:43 | req.query.tainted | check-path.js:19:13:19:43 | 'test.c ... tainted | -| check-path.js:19:27:19:43 | req.query.tainted | check-path.js:19:13:19:43 | 'test.c ... tainted | -| check-path.js:23:27:23:43 | req.query.tainted | check-path.js:23:13:23:45 | `/addre ... inted}` | -| check-path.js:23:27:23:43 | req.query.tainted | check-path.js:23:13:23:45 | `/addre ... inted}` | -| check-path.js:23:27:23:43 | req.query.tainted | check-path.js:23:13:23:45 | `/addre ... inted}` | | check-path.js:23:27:23:43 | req.query.tainted | check-path.js:23:13:23:45 | `/addre ... inted}` | | check-path.js:33:29:33:45 | req.query.tainted | check-path.js:33:15:33:45 | 'test.c ... tainted | -| check-path.js:33:29:33:45 | req.query.tainted | check-path.js:33:15:33:45 | 'test.c ... tainted | -| check-path.js:33:29:33:45 | req.query.tainted | check-path.js:33:15:33:45 | 'test.c ... tainted | -| check-path.js:33:29:33:45 | req.query.tainted | check-path.js:33:15:33:45 | 'test.c ... tainted | -| check-path.js:37:29:37:45 | req.query.tainted | check-path.js:37:15:37:45 | 'test.c ... tainted | -| check-path.js:37:29:37:45 | req.query.tainted | check-path.js:37:15:37:45 | 'test.c ... tainted | -| check-path.js:37:29:37:45 | req.query.tainted | check-path.js:37:15:37:45 | 'test.c ... tainted | | check-path.js:37:29:37:45 | req.query.tainted | check-path.js:37:15:37:45 | 'test.c ... tainted | | check-path.js:45:26:45:42 | req.query.tainted | check-path.js:45:13:45:44 | `${base ... inted}` | -| check-path.js:45:26:45:42 | req.query.tainted | check-path.js:45:13:45:44 | `${base ... inted}` | -| check-path.js:45:26:45:42 | req.query.tainted | check-path.js:45:13:45:44 | `${base ... inted}` | -| check-path.js:45:26:45:42 | req.query.tainted | check-path.js:45:13:45:44 | `${base ... inted}` | -| check-regex.js:16:29:16:45 | req.query.tainted | check-regex.js:16:15:16:45 | "test.c ... tainted | -| check-regex.js:16:29:16:45 | req.query.tainted | check-regex.js:16:15:16:45 | "test.c ... tainted | -| check-regex.js:16:29:16:45 | req.query.tainted | check-regex.js:16:15:16:45 | "test.c ... tainted | | check-regex.js:16:29:16:45 | req.query.tainted | check-regex.js:16:15:16:45 | "test.c ... tainted | | check-regex.js:24:25:24:42 | req.params.tainted | check-regex.js:24:15:24:42 | baseURL ... tainted | -| check-regex.js:24:25:24:42 | req.params.tainted | check-regex.js:24:15:24:42 | baseURL ... tainted | -| check-regex.js:24:25:24:42 | req.params.tainted | check-regex.js:24:15:24:42 | baseURL ... tainted | -| check-regex.js:24:25:24:42 | req.params.tainted | check-regex.js:24:15:24:42 | baseURL ... tainted | -| check-regex.js:31:29:31:45 | req.query.tainted | check-regex.js:31:15:31:45 | "test.c ... tainted | -| check-regex.js:31:29:31:45 | req.query.tainted | check-regex.js:31:15:31:45 | "test.c ... tainted | -| check-regex.js:31:29:31:45 | req.query.tainted | check-regex.js:31:15:31:45 | "test.c ... tainted | | check-regex.js:31:29:31:45 | req.query.tainted | check-regex.js:31:15:31:45 | "test.c ... tainted | | check-regex.js:34:25:34:42 | req.params.tainted | check-regex.js:34:15:34:42 | baseURL ... tainted | -| check-regex.js:34:25:34:42 | req.params.tainted | check-regex.js:34:15:34:42 | baseURL ... tainted | -| check-regex.js:34:25:34:42 | req.params.tainted | check-regex.js:34:15:34:42 | baseURL ... tainted | -| check-regex.js:34:25:34:42 | req.params.tainted | check-regex.js:34:15:34:42 | baseURL ... tainted | -| check-regex.js:41:27:41:43 | req.query.tainted | check-regex.js:41:13:41:43 | "test.c ... tainted | -| check-regex.js:41:27:41:43 | req.query.tainted | check-regex.js:41:13:41:43 | "test.c ... tainted | -| check-regex.js:41:27:41:43 | req.query.tainted | check-regex.js:41:13:41:43 | "test.c ... tainted | | check-regex.js:41:27:41:43 | req.query.tainted | check-regex.js:41:13:41:43 | "test.c ... tainted | | check-validator.js:15:29:15:45 | req.query.tainted | check-validator.js:15:15:15:45 | "test.c ... tainted | -| check-validator.js:15:29:15:45 | req.query.tainted | check-validator.js:15:15:15:45 | "test.c ... tainted | -| check-validator.js:15:29:15:45 | req.query.tainted | check-validator.js:15:15:15:45 | "test.c ... tainted | -| check-validator.js:15:29:15:45 | req.query.tainted | check-validator.js:15:15:15:45 | "test.c ... tainted | | check-validator.js:27:29:27:45 | req.query.tainted | check-validator.js:27:15:27:45 | "test.c ... tainted | -| check-validator.js:27:29:27:45 | req.query.tainted | check-validator.js:27:15:27:45 | "test.c ... tainted | -| check-validator.js:27:29:27:45 | req.query.tainted | check-validator.js:27:15:27:45 | "test.c ... tainted | -| check-validator.js:27:29:27:45 | req.query.tainted | check-validator.js:27:15:27:45 | "test.c ... tainted | -| check-validator.js:50:29:50:45 | req.query.tainted | check-validator.js:50:15:50:45 | "test.c ... tainted | -| check-validator.js:50:29:50:45 | req.query.tainted | check-validator.js:50:15:50:45 | "test.c ... tainted | -| check-validator.js:50:29:50:45 | req.query.tainted | check-validator.js:50:15:50:45 | "test.c ... tainted | | check-validator.js:50:29:50:45 | req.query.tainted | check-validator.js:50:15:50:45 | "test.c ... tainted | | check-validator.js:54:9:54:37 | numberURL | check-validator.js:62:29:62:37 | numberURL | | check-validator.js:54:21:54:37 | req.query.tainted | check-validator.js:54:9:54:37 | numberURL | -| check-validator.js:54:21:54:37 | req.query.tainted | check-validator.js:54:9:54:37 | numberURL | -| check-validator.js:59:29:59:45 | req.query.tainted | check-validator.js:59:15:59:45 | "test.c ... tainted | -| check-validator.js:59:29:59:45 | req.query.tainted | check-validator.js:59:15:59:45 | "test.c ... tainted | -| check-validator.js:59:29:59:45 | req.query.tainted | check-validator.js:59:15:59:45 | "test.c ... tainted | | check-validator.js:59:29:59:45 | req.query.tainted | check-validator.js:59:15:59:45 | "test.c ... tainted | | check-validator.js:62:29:62:37 | numberURL | check-validator.js:62:15:62:37 | "test.c ... mberURL | -| check-validator.js:62:29:62:37 | numberURL | check-validator.js:62:15:62:37 | "test.c ... mberURL | -| check-validator.js:68:29:68:45 | req.query.tainted | check-validator.js:68:15:68:45 | "test.c ... tainted | -| check-validator.js:68:29:68:45 | req.query.tainted | check-validator.js:68:15:68:45 | "test.c ... tainted | -| check-validator.js:68:29:68:45 | req.query.tainted | check-validator.js:68:15:68:45 | "test.c ... tainted | | check-validator.js:68:29:68:45 | req.query.tainted | check-validator.js:68:15:68:45 | "test.c ... tainted | +nodes +| check-domain.js:16:9:16:27 | url | semmle.label | url | +| check-domain.js:16:15:16:27 | req.query.url | semmle.label | req.query.url | +| check-domain.js:17:13:17:15 | url | semmle.label | url | +| check-domain.js:26:15:26:27 | req.query.url | semmle.label | req.query.url | +| check-middleware.js:9:13:9:43 | "test.c ... tainted | semmle.label | "test.c ... tainted | +| check-middleware.js:9:27:9:43 | req.query.tainted | semmle.label | req.query.tainted | +| check-path.js:19:13:19:43 | 'test.c ... tainted | semmle.label | 'test.c ... tainted | +| check-path.js:19:27:19:43 | req.query.tainted | semmle.label | req.query.tainted | +| check-path.js:23:13:23:45 | `/addre ... inted}` | semmle.label | `/addre ... inted}` | +| check-path.js:23:27:23:43 | req.query.tainted | semmle.label | req.query.tainted | +| check-path.js:33:15:33:45 | 'test.c ... tainted | semmle.label | 'test.c ... tainted | +| check-path.js:33:29:33:45 | req.query.tainted | semmle.label | req.query.tainted | +| check-path.js:37:15:37:45 | 'test.c ... tainted | semmle.label | 'test.c ... tainted | +| check-path.js:37:29:37:45 | req.query.tainted | semmle.label | req.query.tainted | +| check-path.js:45:13:45:44 | `${base ... inted}` | semmle.label | `${base ... inted}` | +| check-path.js:45:26:45:42 | req.query.tainted | semmle.label | req.query.tainted | +| check-regex.js:16:15:16:45 | "test.c ... tainted | semmle.label | "test.c ... tainted | +| check-regex.js:16:29:16:45 | req.query.tainted | semmle.label | req.query.tainted | +| check-regex.js:24:15:24:42 | baseURL ... tainted | semmle.label | baseURL ... tainted | +| check-regex.js:24:25:24:42 | req.params.tainted | semmle.label | req.params.tainted | +| check-regex.js:31:15:31:45 | "test.c ... tainted | semmle.label | "test.c ... tainted | +| check-regex.js:31:29:31:45 | req.query.tainted | semmle.label | req.query.tainted | +| check-regex.js:34:15:34:42 | baseURL ... tainted | semmle.label | baseURL ... tainted | +| check-regex.js:34:25:34:42 | req.params.tainted | semmle.label | req.params.tainted | +| check-regex.js:41:13:41:43 | "test.c ... tainted | semmle.label | "test.c ... tainted | +| check-regex.js:41:27:41:43 | req.query.tainted | semmle.label | req.query.tainted | +| check-validator.js:15:15:15:45 | "test.c ... tainted | semmle.label | "test.c ... tainted | +| check-validator.js:15:29:15:45 | req.query.tainted | semmle.label | req.query.tainted | +| check-validator.js:27:15:27:45 | "test.c ... tainted | semmle.label | "test.c ... tainted | +| check-validator.js:27:29:27:45 | req.query.tainted | semmle.label | req.query.tainted | +| check-validator.js:50:15:50:45 | "test.c ... tainted | semmle.label | "test.c ... tainted | +| check-validator.js:50:29:50:45 | req.query.tainted | semmle.label | req.query.tainted | +| check-validator.js:54:9:54:37 | numberURL | semmle.label | numberURL | +| check-validator.js:54:21:54:37 | req.query.tainted | semmle.label | req.query.tainted | +| check-validator.js:59:15:59:45 | "test.c ... tainted | semmle.label | "test.c ... tainted | +| check-validator.js:59:29:59:45 | req.query.tainted | semmle.label | req.query.tainted | +| check-validator.js:62:15:62:37 | "test.c ... mberURL | semmle.label | "test.c ... mberURL | +| check-validator.js:62:29:62:37 | numberURL | semmle.label | numberURL | +| check-validator.js:68:15:68:45 | "test.c ... tainted | semmle.label | "test.c ... tainted | +| check-validator.js:68:29:68:45 | req.query.tainted | semmle.label | req.query.tainted | +subpaths #select | check-domain.js:17:13:17:15 | url | check-domain.js:16:15:16:27 | req.query.url | check-domain.js:17:13:17:15 | url | The URL of this request depends on a user-provided value. | | check-domain.js:26:15:26:27 | req.query.url | check-domain.js:26:15:26:27 | req.query.url | check-domain.js:26:15:26:27 | req.query.url | The URL of this request depends on a user-provided value. | From ccd6d3dcd7ead062b89c034ef9b807c8607faa5a Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:31:23 +0200 Subject: [PATCH 042/514] JS: Port example queries --- .../dataflow/BackendIdor/BackendIdor.ql | 30 +++++++++---------- .../DecodingAfterSanitization.ql | 22 +++++++------- .../DecodingAfterSanitizationGeneralized.ql | 26 ++++++++-------- .../queries/dataflow/EvalTaint/EvalTaint.ql | 17 ++++++----- .../dataflow/EvalTaint/EvalTaintPath.ql | 20 +++++++------ .../InformationDisclosure.ql | 30 ++++++++++--------- .../queries/dataflow/StoredXss/StoredXss.ql | 6 ++-- .../StoredXss/StoredXssTypeTracking.ql | 6 ++-- .../TemplateInjection/TemplateInjection.ql | 20 ++++++------- 9 files changed, 93 insertions(+), 84 deletions(-) diff --git a/javascript/ql/examples/queries/dataflow/BackendIdor/BackendIdor.ql b/javascript/ql/examples/queries/dataflow/BackendIdor/BackendIdor.ql index 322cccd5d2b..92f5dad50c7 100644 --- a/javascript/ql/examples/queries/dataflow/BackendIdor/BackendIdor.ql +++ b/javascript/ql/examples/queries/dataflow/BackendIdor/BackendIdor.ql @@ -9,42 +9,42 @@ */ import javascript -import DataFlow -import DataFlow::PathGraph /** * A taint-tracking configuration that tracks user-controlled values into a 'userId' property sent to a backend service. */ -class IdorTaint extends TaintTracking::Configuration { - IdorTaint() { this = "IdorTaint" } +module IdorTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node instanceof RemoteFlowSource } - override predicate isSource(Node node) { node instanceof RemoteFlowSource } + predicate isSink(DataFlow::Node node) { exists(ClientRequest req | node = req.getADataNode()) } - override predicate isSink(Node node) { exists(ClientRequest req | node = req.getADataNode()) } - - override predicate isAdditionalTaintStep(Node pred, Node succ) { + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { // Step from x -> { userId: x } - succ.(SourceNode).getAPropertyWrite("userId").getRhs() = pred + succ.(DataFlow::SourceNode).getAPropertyWrite("userId").getRhs() = pred } - override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode node) { + predicate isBarrier(DataFlow::Node node) { // After a check like `if (userId === session.user.id)`, the userId is considered safe. - node instanceof EqualityGuard + node = DataFlow::MakeBarrierGuard::getABarrierNode() } } /** * A sanitizer for values that have successfully been compared to another value. */ -class EqualityGuard extends TaintTracking::SanitizerGuardNode, ValueNode { +class EqualityGuard extends DataFlow::ValueNode { override EqualityTest astNode; - override predicate sanitizes(boolean outcome, Expr e) { + predicate blocksExpr(boolean outcome, Expr e) { e = astNode.getAnOperand() and outcome = astNode.getPolarity() } } -from IdorTaint cfg, PathNode source, PathNode sink -where cfg.hasFlowPath(source, sink) +module IdorTaintFlow = TaintTracking::Global; + +import IdorTaintFlow::PathGraph + +from IdorTaintFlow::PathNode source, IdorTaintFlow::PathNode sink +where IdorTaintFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Unauthenticated user ID from $@.", source.getNode(), "here" diff --git a/javascript/ql/examples/queries/dataflow/DecodingAfterSanitization/DecodingAfterSanitization.ql b/javascript/ql/examples/queries/dataflow/DecodingAfterSanitization/DecodingAfterSanitization.ql index d21cc4531fc..b83ee8aaee9 100644 --- a/javascript/ql/examples/queries/dataflow/DecodingAfterSanitization/DecodingAfterSanitization.ql +++ b/javascript/ql/examples/queries/dataflow/DecodingAfterSanitization/DecodingAfterSanitization.ql @@ -9,23 +9,25 @@ */ import javascript -import DataFlow -import DataFlow::PathGraph -class DecodingAfterSanitization extends TaintTracking::Configuration { - DecodingAfterSanitization() { this = "DecodingAfterSanitization" } +module DecodingAfterSanitizationConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { + node.(DataFlow::CallNode).getCalleeName() = "escapeHtml" + } - override predicate isSource(Node node) { node.(CallNode).getCalleeName() = "escapeHtml" } - - override predicate isSink(Node node) { - exists(CallNode call | + predicate isSink(DataFlow::Node node) { + exists(DataFlow::CallNode call | call.getCalleeName().matches("decodeURI%") and node = call.getArgument(0) ) } } -from DecodingAfterSanitization cfg, PathNode source, PathNode sink -where cfg.hasFlowPath(source, sink) +module DecodingAfterSanitizationFlow = TaintTracking::Global; + +import DecodingAfterSanitizationFlow::PathGraph + +from DecodingAfterSanitizationFlow::PathNode source, DecodingAfterSanitizationFlow::PathNode sink +where DecodingAfterSanitizationFlow::flowPath(source, sink) select sink.getNode(), source, sink, "URI decoding invalidates the HTML sanitization performed $@.", source.getNode(), "here" diff --git a/javascript/ql/examples/queries/dataflow/DecodingAfterSanitization/DecodingAfterSanitizationGeneralized.ql b/javascript/ql/examples/queries/dataflow/DecodingAfterSanitization/DecodingAfterSanitizationGeneralized.ql index 257872c2752..d10799a8916 100644 --- a/javascript/ql/examples/queries/dataflow/DecodingAfterSanitization/DecodingAfterSanitizationGeneralized.ql +++ b/javascript/ql/examples/queries/dataflow/DecodingAfterSanitization/DecodingAfterSanitizationGeneralized.ql @@ -9,16 +9,14 @@ */ import javascript -import DataFlow -import DataFlow::PathGraph /** * A call to a function that may introduce HTML meta-characters by * replacing `%3C` or `\u003C` with `<`. */ -class DecodingCall extends CallNode { +class DecodingCall extends DataFlow::CallNode { string kind; - Node input; + DataFlow::Node input; DecodingCall() { this.getCalleeName().matches("decodeURI%") and @@ -33,20 +31,24 @@ class DecodingCall extends CallNode { string getKind() { result = kind } /** Gets the input being decoded. */ - Node getInput() { result = input } + DataFlow::Node getInput() { result = input } } -class DecodingAfterSanitization extends TaintTracking::Configuration { - DecodingAfterSanitization() { this = "DecodingAfterSanitization" } +module DecodingAfterSanitizationConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node instanceof HtmlSanitizerCall } - override predicate isSource(Node node) { node instanceof HtmlSanitizerCall } - - override predicate isSink(Node node) { node = any(DecodingCall c).getInput() } + predicate isSink(DataFlow::Node node) { node = any(DecodingCall c).getInput() } } -from DecodingAfterSanitization cfg, PathNode source, PathNode sink, DecodingCall decoder +module DecodingAfterSanitizationFlow = TaintTracking::Global; + +import DecodingAfterSanitizationFlow::PathGraph + +from + DecodingAfterSanitizationFlow::PathNode source, DecodingAfterSanitizationFlow::PathNode sink, + DecodingCall decoder where - cfg.hasFlowPath(source, sink) and + DecodingAfterSanitizationFlow::flowPath(source, sink) and decoder.getInput() = sink.getNode() select sink.getNode(), source, sink, decoder.getKind() + " invalidates $@.", source.getNode(), "this HTML sanitization" diff --git a/javascript/ql/examples/queries/dataflow/EvalTaint/EvalTaint.ql b/javascript/ql/examples/queries/dataflow/EvalTaint/EvalTaint.ql index 72208237445..2990b3dcf8f 100644 --- a/javascript/ql/examples/queries/dataflow/EvalTaint/EvalTaint.ql +++ b/javascript/ql/examples/queries/dataflow/EvalTaint/EvalTaint.ql @@ -8,16 +8,17 @@ */ import javascript -import DataFlow -class EvalTaint extends TaintTracking::Configuration { - EvalTaint() { this = "EvalTaint" } +module EvalTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node instanceof RemoteFlowSource } - override predicate isSource(Node node) { node instanceof RemoteFlowSource } - - override predicate isSink(Node node) { node = globalVarRef("eval").getACall().getArgument(0) } + predicate isSink(DataFlow::Node node) { + node = DataFlow::globalVarRef("eval").getACall().getArgument(0) + } } -from EvalTaint cfg, Node source, Node sink -where cfg.hasFlow(source, sink) +module EvalTaintFlow = TaintTracking::Global; + +from DataFlow::Node source, DataFlow::Node sink +where EvalTaintFlow::flow(source, sink) select sink, "Eval with user-controlled input from $@.", source, "here" diff --git a/javascript/ql/examples/queries/dataflow/EvalTaint/EvalTaintPath.ql b/javascript/ql/examples/queries/dataflow/EvalTaint/EvalTaintPath.ql index 1b07ed151bd..ca49748bd1d 100644 --- a/javascript/ql/examples/queries/dataflow/EvalTaint/EvalTaintPath.ql +++ b/javascript/ql/examples/queries/dataflow/EvalTaint/EvalTaintPath.ql @@ -9,18 +9,20 @@ */ import javascript -import DataFlow -import DataFlow::PathGraph -class EvalTaint extends TaintTracking::Configuration { - EvalTaint() { this = "EvalTaint" } +module EvalTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node instanceof RemoteFlowSource } - override predicate isSource(Node node) { node instanceof RemoteFlowSource } - - override predicate isSink(Node node) { node = globalVarRef("eval").getACall().getArgument(0) } + predicate isSink(DataFlow::Node node) { + node = DataFlow::globalVarRef("eval").getACall().getArgument(0) + } } -from EvalTaint cfg, PathNode source, PathNode sink -where cfg.hasFlowPath(source, sink) +module EvalTaintFlow = TaintTracking::Global; + +import EvalTaintFlow::PathGraph + +from EvalTaintFlow::PathNode source, EvalTaintFlow::PathNode sink +where EvalTaintFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Eval with user-controlled input from $@.", source.getNode(), "here" diff --git a/javascript/ql/examples/queries/dataflow/InformationDisclosure/InformationDisclosure.ql b/javascript/ql/examples/queries/dataflow/InformationDisclosure/InformationDisclosure.ql index 1fe76a178e2..64a1c6c801f 100644 --- a/javascript/ql/examples/queries/dataflow/InformationDisclosure/InformationDisclosure.ql +++ b/javascript/ql/examples/queries/dataflow/InformationDisclosure/InformationDisclosure.ql @@ -9,8 +9,6 @@ */ import javascript -import DataFlow -import DataFlow::PathGraph /** * A dataflow configuration that tracks authentication tokens ("authKey") @@ -26,33 +24,37 @@ import DataFlow::PathGraph * }), '*'); * ``` */ -class AuthKeyTracking extends DataFlow::Configuration { - AuthKeyTracking() { this = "AuthKeyTracking" } +module AuthKeyTrackingConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { + node.(DataFlow::PropRead).getPropertyName() = "authKey" + } - override predicate isSource(Node node) { node.(PropRead).getPropertyName() = "authKey" } - - override predicate isSink(Node node) { - exists(MethodCallNode call | + predicate isSink(DataFlow::Node node) { + exists(DataFlow::MethodCallNode call | call.getMethodName() = "postMessage" and call.getArgument(1).getStringValue() = "*" and // no restriction on target origin call.getArgument(0) = node ) } - override predicate isAdditionalFlowStep(Node pred, Node succ) { + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { // Step into objects: x -> { f: x } - succ.(SourceNode).getAPropertyWrite().getRhs() = pred + succ.(DataFlow::SourceNode).getAPropertyWrite().getRhs() = pred or // Step through JSON serialization: x -> JSON.stringify(x) // Note: TaintTracking::Configuration includes this step by default, but not DataFlow::Configuration - exists(CallNode call | - call = globalVarRef("JSON").getAMethodCall("stringify") and + exists(DataFlow::CallNode call | + call = DataFlow::globalVarRef("JSON").getAMethodCall("stringify") and pred = call.getArgument(0) and succ = call ) } } -from AuthKeyTracking cfg, PathNode source, PathNode sink -where cfg.hasFlowPath(source, sink) +module AuthKeyTracking = DataFlow::Global; + +import AuthKeyTracking::PathGraph + +from AuthKeyTracking::PathNode source, AuthKeyTracking::PathNode sink +where AuthKeyTracking::flowPath(source, sink) select sink.getNode(), source, sink, "Message leaks the authKey from $@.", source.getNode(), "here" diff --git a/javascript/ql/examples/queries/dataflow/StoredXss/StoredXss.ql b/javascript/ql/examples/queries/dataflow/StoredXss/StoredXss.ql index c31095d4995..09cbd049200 100644 --- a/javascript/ql/examples/queries/dataflow/StoredXss/StoredXss.ql +++ b/javascript/ql/examples/queries/dataflow/StoredXss/StoredXss.ql @@ -9,7 +9,7 @@ import javascript import semmle.javascript.security.dataflow.StoredXssQuery -import DataFlow::PathGraph +import StoredXssFlow::PathGraph /** * The data returned from a MySQL query, such as the `data` parameter in this example: @@ -31,6 +31,6 @@ class MysqlSource extends Source { } } -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from StoredXssFlow::PathNode source, StoredXssFlow::PathNode sink +where StoredXssFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Stored XSS from $@.", source.getNode(), "database value." diff --git a/javascript/ql/examples/queries/dataflow/StoredXss/StoredXssTypeTracking.ql b/javascript/ql/examples/queries/dataflow/StoredXss/StoredXssTypeTracking.ql index f10479daf93..e92667a8c0f 100644 --- a/javascript/ql/examples/queries/dataflow/StoredXss/StoredXssTypeTracking.ql +++ b/javascript/ql/examples/queries/dataflow/StoredXss/StoredXssTypeTracking.ql @@ -10,7 +10,7 @@ import javascript import semmle.javascript.security.dataflow.StoredXssQuery -import DataFlow::PathGraph +import StoredXssFlow::PathGraph /** * Gets an instance of `mysql.createConnection()`, tracked globally. @@ -45,6 +45,6 @@ class MysqlSource extends Source { MysqlSource() { this = mysqlConnection().getAMethodCall("query").getCallback(1).getParameter(1) } } -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from StoredXssFlow::PathNode source, StoredXssFlow::PathNode sink +where StoredXssFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Stored XSS from $@.", source.getNode(), "database value." diff --git a/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql b/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql index b146b19e54d..51aa6c6a7c3 100644 --- a/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql +++ b/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql @@ -8,8 +8,6 @@ */ import javascript -import DataFlow -import DataFlow::PathGraph /** * Gets the name of an unescaped placeholder in a lodash template. @@ -21,13 +19,11 @@ string getAPlaceholderInString(string s) { result = s.regexpCapture(".*<%=\\s*([a-zA-Z0-9_]+)\\s*%>.*", 1) } -class TemplateInjection extends TaintTracking::Configuration { - TemplateInjection() { this = "TemplateInjection" } +module TemplateInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node instanceof RemoteFlowSource } - override predicate isSource(Node node) { node instanceof RemoteFlowSource } - - override predicate isSink(Node node) { - exists(CallNode call, string placeholder | + predicate isSink(DataFlow::Node node) { + exists(DataFlow::CallNode call, string placeholder | call = LodashUnderscore::member("template").getACall() and placeholder = getAPlaceholderInString(call.getArgument(0).getStringValue()) and node = call.getOptionArgument(1, placeholder) @@ -35,7 +31,11 @@ class TemplateInjection extends TaintTracking::Configuration { } } -from TemplateInjection cfg, PathNode source, PathNode sink -where cfg.hasFlowPath(source, sink) +module TemplateInjectionFlow = TaintTracking::Global; + +import TemplateInjectionFlow::PathGraph + +from TemplateInjectionFlow::PathNode source, TemplateInjectionFlow::PathNode sink +where TemplateInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "User-controlled value from $@ occurs unescaped in a lodash template.", source.getNode(), "here." From 17233a67493f2fbcf57e90a8a82fccf595e92bc9 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:11:54 +0200 Subject: [PATCH 043/514] JS: Port CommandInjection --- .../dataflow/CommandInjectionQuery.qll | 44 +- .../src/Security/CWE-078/CommandInjection.ql | 12 +- .../CommandInjection.expected | 436 ++++++------------ 3 files changed, 181 insertions(+), 311 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CommandInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CommandInjectionQuery.qll index c8e11e04477..bb93c6320f1 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CommandInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CommandInjectionQuery.qll @@ -11,25 +11,41 @@ import javascript import CommandInjectionCustomizations::CommandInjection import IndirectCommandArgument +/** + * Holds if `sink` is a data flow sink for command-injection vulnerabilities, and + * the alert should be placed at the node `highlight`. + */ +predicate isSinkWithHighlight(DataFlow::Node sink, DataFlow::Node highlight) { + sink instanceof Sink and highlight = sink + or + isIndirectCommandArgument(sink, highlight) +} + /** * A taint-tracking configuration for reasoning about command-injection vulnerabilities. */ -class Configuration extends TaintTracking::Configuration { +module CommandInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { isSinkWithHighlight(sink, _) } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint-tracking for reasoning about command-injection vulnerabilities. + */ +module CommandInjectionFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `CommandInjectionFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "CommandInjection" } - override predicate isSource(DataFlow::Node source) { source instanceof Source } + override predicate isSource(DataFlow::Node source) { CommandInjectionConfig::isSource(source) } - /** - * Holds if `sink` is a data flow sink for command-injection vulnerabilities, and - * the alert should be placed at the node `highlight`. - */ - predicate isSinkWithHighlight(DataFlow::Node sink, DataFlow::Node highlight) { - sink instanceof Sink and highlight = sink - or - isIndirectCommandArgument(sink, highlight) - } + override predicate isSink(DataFlow::Node sink) { CommandInjectionConfig::isSink(sink) } - override predicate isSink(DataFlow::Node sink) { this.isSinkWithHighlight(sink, _) } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } + override predicate isSanitizer(DataFlow::Node node) { CommandInjectionConfig::isBarrier(node) } } diff --git a/javascript/ql/src/Security/CWE-078/CommandInjection.ql b/javascript/ql/src/Security/CWE-078/CommandInjection.ql index f09a93c4d40..b1e14622304 100644 --- a/javascript/ql/src/Security/CWE-078/CommandInjection.ql +++ b/javascript/ql/src/Security/CWE-078/CommandInjection.ql @@ -15,16 +15,16 @@ import javascript import semmle.javascript.security.dataflow.CommandInjectionQuery -import DataFlow::PathGraph +import CommandInjectionFlow::PathGraph from - Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node highlight, - Source sourceNode + CommandInjectionFlow::PathNode source, CommandInjectionFlow::PathNode sink, + DataFlow::Node highlight, Source sourceNode where - cfg.hasFlowPath(source, sink) and + CommandInjectionFlow::flowPath(source, sink) and ( - if cfg.isSinkWithHighlight(sink.getNode(), _) - then cfg.isSinkWithHighlight(sink.getNode(), highlight) + if isSinkWithHighlight(sink.getNode(), _) + then isSinkWithHighlight(sink.getNode(), highlight) else highlight = sink.getNode() ) and sourceNode = source.getNode() diff --git a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected index fb8bc60e673..6126cef4888 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected @@ -1,370 +1,224 @@ -nodes -| actions.js:8:9:8:57 | title | -| actions.js:8:17:8:57 | github. ... t.title | -| actions.js:8:17:8:57 | github. ... t.title | -| actions.js:9:8:9:22 | `echo ${title}` | -| actions.js:9:8:9:22 | `echo ${title}` | -| actions.js:9:16:9:20 | title | -| actions.js:18:9:18:63 | head_ref | -| actions.js:18:20:18:63 | github. ... ead.ref | -| actions.js:18:20:18:63 | github. ... ead.ref | -| actions.js:19:14:19:31 | `echo ${head_ref}` | -| actions.js:19:14:19:31 | `echo ${head_ref}` | -| actions.js:19:22:19:29 | head_ref | -| child_process-test.js:6:9:6:49 | cmd | -| child_process-test.js:6:15:6:38 | url.par ... , true) | -| child_process-test.js:6:15:6:44 | url.par ... ).query | -| child_process-test.js:6:15:6:49 | url.par ... ry.path | -| child_process-test.js:6:15:6:49 | url.par ... ry.path | -| child_process-test.js:6:25:6:31 | req.url | -| child_process-test.js:6:25:6:31 | req.url | -| child_process-test.js:17:13:17:15 | cmd | -| child_process-test.js:17:13:17:15 | cmd | -| child_process-test.js:18:17:18:19 | cmd | -| child_process-test.js:18:17:18:19 | cmd | -| child_process-test.js:19:17:19:19 | cmd | -| child_process-test.js:19:17:19:19 | cmd | -| child_process-test.js:20:21:20:23 | cmd | -| child_process-test.js:20:21:20:23 | cmd | -| child_process-test.js:21:14:21:16 | cmd | -| child_process-test.js:21:14:21:16 | cmd | -| child_process-test.js:22:18:22:20 | cmd | -| child_process-test.js:22:18:22:20 | cmd | -| child_process-test.js:23:13:23:15 | cmd | -| child_process-test.js:23:13:23:15 | cmd | -| child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | -| child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | -| child_process-test.js:25:21:25:23 | cmd | -| child_process-test.js:39:26:39:28 | cmd | -| child_process-test.js:39:26:39:28 | cmd | -| child_process-test.js:43:15:43:17 | cmd | -| child_process-test.js:43:15:43:17 | cmd | -| child_process-test.js:48:15:48:17 | cmd | -| child_process-test.js:48:15:48:17 | cmd | -| child_process-test.js:53:15:53:17 | cmd | -| child_process-test.js:53:15:53:17 | cmd | -| child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | -| child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | -| child_process-test.js:56:46:56:57 | ["bar", cmd] | -| child_process-test.js:56:54:56:56 | cmd | -| child_process-test.js:56:54:56:56 | cmd | -| child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) | -| child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) | -| child_process-test.js:57:46:57:48 | cmd | -| child_process-test.js:73:9:73:49 | cmd | -| child_process-test.js:73:15:73:38 | url.par ... , true) | -| child_process-test.js:73:15:73:44 | url.par ... ).query | -| child_process-test.js:73:15:73:49 | url.par ... ry.path | -| child_process-test.js:73:25:73:31 | req.url | -| child_process-test.js:73:25:73:31 | req.url | -| child_process-test.js:75:29:75:31 | cmd | -| child_process-test.js:75:29:75:31 | cmd | -| child_process-test.js:83:19:83:36 | req.query.fileName | -| child_process-test.js:83:19:83:36 | req.query.fileName | -| child_process-test.js:83:19:83:36 | req.query.fileName | -| child_process-test.js:94:11:94:35 | "ping " ... ms.host | -| child_process-test.js:94:11:94:35 | "ping " ... ms.host | -| child_process-test.js:94:21:94:30 | ctx.params | -| child_process-test.js:94:21:94:30 | ctx.params | -| child_process-test.js:94:21:94:35 | ctx.params.host | -| exec-sh2.js:9:17:9:23 | command | -| exec-sh2.js:10:40:10:46 | command | -| exec-sh2.js:10:40:10:46 | command | -| exec-sh2.js:14:9:14:49 | cmd | -| exec-sh2.js:14:15:14:38 | url.par ... , true) | -| exec-sh2.js:14:15:14:44 | url.par ... ).query | -| exec-sh2.js:14:15:14:49 | url.par ... ry.path | -| exec-sh2.js:14:25:14:31 | req.url | -| exec-sh2.js:14:25:14:31 | req.url | -| exec-sh2.js:15:12:15:14 | cmd | -| exec-sh.js:13:17:13:23 | command | -| exec-sh.js:15:44:15:50 | command | -| exec-sh.js:15:44:15:50 | command | -| exec-sh.js:19:9:19:49 | cmd | -| exec-sh.js:19:15:19:38 | url.par ... , true) | -| exec-sh.js:19:15:19:44 | url.par ... ).query | -| exec-sh.js:19:15:19:49 | url.par ... ry.path | -| exec-sh.js:19:25:19:31 | req.url | -| exec-sh.js:19:25:19:31 | req.url | -| exec-sh.js:20:12:20:14 | cmd | -| execSeries.js:3:20:3:22 | arr | -| execSeries.js:6:14:6:16 | arr | -| execSeries.js:6:14:6:21 | arr[i++] | -| execSeries.js:13:19:13:26 | commands | -| execSeries.js:14:13:14:20 | commands | -| execSeries.js:14:24:14:30 | command | -| execSeries.js:14:41:14:47 | command | -| execSeries.js:14:41:14:47 | command | -| execSeries.js:18:7:18:58 | cmd | -| execSeries.js:18:13:18:47 | require ... , true) | -| execSeries.js:18:13:18:53 | require ... ).query | -| execSeries.js:18:13:18:58 | require ... ry.path | -| execSeries.js:18:34:18:40 | req.url | -| execSeries.js:18:34:18:40 | req.url | -| execSeries.js:19:12:19:16 | [cmd] | -| execSeries.js:19:13:19:15 | cmd | -| form-parsers.js:9:8:9:39 | "touch ... nalname | -| form-parsers.js:9:8:9:39 | "touch ... nalname | -| form-parsers.js:9:19:9:26 | req.file | -| form-parsers.js:9:19:9:26 | req.file | -| form-parsers.js:9:19:9:39 | req.fil ... nalname | -| form-parsers.js:13:3:13:11 | req.files | -| form-parsers.js:13:3:13:11 | req.files | -| form-parsers.js:13:21:13:24 | file | -| form-parsers.js:14:10:14:37 | "touch ... nalname | -| form-parsers.js:14:10:14:37 | "touch ... nalname | -| form-parsers.js:14:21:14:24 | file | -| form-parsers.js:14:21:14:37 | file.originalname | -| form-parsers.js:24:48:24:55 | filename | -| form-parsers.js:24:48:24:55 | filename | -| form-parsers.js:25:10:25:28 | "touch " + filename | -| form-parsers.js:25:10:25:28 | "touch " + filename | -| form-parsers.js:25:21:25:28 | filename | -| form-parsers.js:35:25:35:30 | fields | -| form-parsers.js:35:25:35:30 | fields | -| form-parsers.js:36:10:36:31 | "touch ... ds.name | -| form-parsers.js:36:10:36:31 | "touch ... ds.name | -| form-parsers.js:36:21:36:26 | fields | -| form-parsers.js:36:21:36:31 | fields.name | -| form-parsers.js:40:26:40:31 | fields | -| form-parsers.js:40:26:40:31 | fields | -| form-parsers.js:41:10:41:31 | "touch ... ds.name | -| form-parsers.js:41:10:41:31 | "touch ... ds.name | -| form-parsers.js:41:21:41:26 | fields | -| form-parsers.js:41:21:41:31 | fields.name | -| form-parsers.js:52:34:52:39 | fields | -| form-parsers.js:52:34:52:39 | fields | -| form-parsers.js:53:10:53:31 | "touch ... ds.name | -| form-parsers.js:53:10:53:31 | "touch ... ds.name | -| form-parsers.js:53:21:53:26 | fields | -| form-parsers.js:53:21:53:31 | fields.name | -| form-parsers.js:58:30:58:33 | part | -| form-parsers.js:58:30:58:33 | part | -| form-parsers.js:59:10:59:33 | "touch ... ilename | -| form-parsers.js:59:10:59:33 | "touch ... ilename | -| form-parsers.js:59:21:59:24 | part | -| form-parsers.js:59:21:59:33 | part.filename | -| other.js:5:9:5:49 | cmd | -| other.js:5:15:5:38 | url.par ... , true) | -| other.js:5:15:5:44 | url.par ... ).query | -| other.js:5:15:5:49 | url.par ... ry.path | -| other.js:5:25:5:31 | req.url | -| other.js:5:25:5:31 | req.url | -| other.js:7:33:7:35 | cmd | -| other.js:7:33:7:35 | cmd | -| other.js:8:28:8:30 | cmd | -| other.js:8:28:8:30 | cmd | -| other.js:9:32:9:34 | cmd | -| other.js:9:32:9:34 | cmd | -| other.js:10:29:10:31 | cmd | -| other.js:10:29:10:31 | cmd | -| other.js:11:29:11:31 | cmd | -| other.js:11:29:11:31 | cmd | -| other.js:12:27:12:29 | cmd | -| other.js:12:27:12:29 | cmd | -| other.js:14:28:14:30 | cmd | -| other.js:14:28:14:30 | cmd | -| other.js:15:34:15:36 | cmd | -| other.js:15:34:15:36 | cmd | -| other.js:16:21:16:23 | cmd | -| other.js:16:21:16:23 | cmd | -| other.js:17:27:17:29 | cmd | -| other.js:17:27:17:29 | cmd | -| other.js:18:22:18:24 | cmd | -| other.js:18:22:18:24 | cmd | -| other.js:19:36:19:38 | cmd | -| other.js:19:36:19:38 | cmd | -| other.js:22:21:22:23 | cmd | -| other.js:22:21:22:23 | cmd | -| other.js:23:28:23:30 | cmd | -| other.js:23:28:23:30 | cmd | -| other.js:26:34:26:36 | cmd | -| other.js:26:34:26:36 | cmd | -| other.js:28:27:28:29 | cmd | -| other.js:28:27:28:29 | cmd | -| other.js:30:33:30:35 | cmd | -| other.js:30:33:30:35 | cmd | -| other.js:34:44:34:46 | cmd | -| other.js:34:44:34:46 | cmd | -| third-party-command-injection.js:5:20:5:26 | command | -| third-party-command-injection.js:5:20:5:26 | command | -| third-party-command-injection.js:6:21:6:27 | command | -| third-party-command-injection.js:6:21:6:27 | command | edges | actions.js:8:9:8:57 | title | actions.js:9:16:9:20 | title | | actions.js:8:17:8:57 | github. ... t.title | actions.js:8:9:8:57 | title | -| actions.js:8:17:8:57 | github. ... t.title | actions.js:8:9:8:57 | title | -| actions.js:9:16:9:20 | title | actions.js:9:8:9:22 | `echo ${title}` | | actions.js:9:16:9:20 | title | actions.js:9:8:9:22 | `echo ${title}` | | actions.js:18:9:18:63 | head_ref | actions.js:19:22:19:29 | head_ref | | actions.js:18:20:18:63 | github. ... ead.ref | actions.js:18:9:18:63 | head_ref | -| actions.js:18:20:18:63 | github. ... ead.ref | actions.js:18:9:18:63 | head_ref | -| actions.js:19:22:19:29 | head_ref | actions.js:19:14:19:31 | `echo ${head_ref}` | | actions.js:19:22:19:29 | head_ref | actions.js:19:14:19:31 | `echo ${head_ref}` | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:17:13:17:15 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:17:13:17:15 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:18:17:18:19 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:18:17:18:19 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:19:17:19:19 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:19:17:19:19 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:20:21:20:23 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:20:21:20:23 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:21:14:21:16 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:21:14:21:16 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:22:18:22:20 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:22:18:22:20 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:23:13:23:15 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:23:13:23:15 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:25:21:25:23 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:39:26:39:28 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:39:26:39:28 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:43:15:43:17 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:43:15:43:17 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:48:15:48:17 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:48:15:48:17 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:53:15:53:17 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:53:15:53:17 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:56:54:56:56 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:56:54:56:56 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:57:46:57:48 | cmd | -| child_process-test.js:6:15:6:38 | url.par ... , true) | child_process-test.js:6:15:6:44 | url.par ... ).query | -| child_process-test.js:6:15:6:44 | url.par ... ).query | child_process-test.js:6:15:6:49 | url.par ... ry.path | -| child_process-test.js:6:15:6:44 | url.par ... ).query | child_process-test.js:6:15:6:49 | url.par ... ry.path | +| child_process-test.js:6:15:6:38 | url.par ... , true) | child_process-test.js:6:9:6:49 | cmd | +| child_process-test.js:6:15:6:38 | url.par ... , true) | child_process-test.js:6:15:6:49 | url.par ... ry.path | +| child_process-test.js:6:15:6:38 | url.par ... , true) | child_process-test.js:6:15:6:49 | url.par ... ry.path | | child_process-test.js:6:15:6:49 | url.par ... ry.path | child_process-test.js:6:9:6:49 | cmd | | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:6:15:6:38 | url.par ... , true) | -| child_process-test.js:6:25:6:31 | req.url | child_process-test.js:6:15:6:38 | url.par ... , true) | -| child_process-test.js:25:21:25:23 | cmd | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | | child_process-test.js:25:21:25:23 | cmd | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | | child_process-test.js:56:46:56:57 | ["bar", cmd] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | -| child_process-test.js:56:46:56:57 | ["bar", cmd] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | +| child_process-test.js:56:46:56:57 | ["bar", cmd] [1] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | +| child_process-test.js:56:54:56:56 | cmd | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | | child_process-test.js:56:54:56:56 | cmd | child_process-test.js:56:46:56:57 | ["bar", cmd] | -| child_process-test.js:57:46:57:48 | cmd | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) | +| child_process-test.js:56:54:56:56 | cmd | child_process-test.js:56:46:56:57 | ["bar", cmd] [1] | | child_process-test.js:57:46:57:48 | cmd | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) | | child_process-test.js:73:9:73:49 | cmd | child_process-test.js:75:29:75:31 | cmd | -| child_process-test.js:73:9:73:49 | cmd | child_process-test.js:75:29:75:31 | cmd | -| child_process-test.js:73:15:73:38 | url.par ... , true) | child_process-test.js:73:15:73:44 | url.par ... ).query | -| child_process-test.js:73:15:73:44 | url.par ... ).query | child_process-test.js:73:15:73:49 | url.par ... ry.path | -| child_process-test.js:73:15:73:49 | url.par ... ry.path | child_process-test.js:73:9:73:49 | cmd | +| child_process-test.js:73:15:73:38 | url.par ... , true) | child_process-test.js:73:9:73:49 | cmd | | child_process-test.js:73:25:73:31 | req.url | child_process-test.js:73:15:73:38 | url.par ... , true) | -| child_process-test.js:73:25:73:31 | req.url | child_process-test.js:73:15:73:38 | url.par ... , true) | -| child_process-test.js:83:19:83:36 | req.query.fileName | child_process-test.js:83:19:83:36 | req.query.fileName | -| child_process-test.js:94:21:94:30 | ctx.params | child_process-test.js:94:21:94:35 | ctx.params.host | -| child_process-test.js:94:21:94:30 | ctx.params | child_process-test.js:94:21:94:35 | ctx.params.host | -| child_process-test.js:94:21:94:35 | ctx.params.host | child_process-test.js:94:11:94:35 | "ping " ... ms.host | -| child_process-test.js:94:21:94:35 | ctx.params.host | child_process-test.js:94:11:94:35 | "ping " ... ms.host | -| exec-sh2.js:9:17:9:23 | command | exec-sh2.js:10:40:10:46 | command | +| child_process-test.js:94:21:94:30 | ctx.params | child_process-test.js:94:11:94:35 | "ping " ... ms.host | | exec-sh2.js:9:17:9:23 | command | exec-sh2.js:10:40:10:46 | command | | exec-sh2.js:14:9:14:49 | cmd | exec-sh2.js:15:12:15:14 | cmd | -| exec-sh2.js:14:15:14:38 | url.par ... , true) | exec-sh2.js:14:15:14:44 | url.par ... ).query | -| exec-sh2.js:14:15:14:44 | url.par ... ).query | exec-sh2.js:14:15:14:49 | url.par ... ry.path | -| exec-sh2.js:14:15:14:49 | url.par ... ry.path | exec-sh2.js:14:9:14:49 | cmd | -| exec-sh2.js:14:25:14:31 | req.url | exec-sh2.js:14:15:14:38 | url.par ... , true) | +| exec-sh2.js:14:15:14:38 | url.par ... , true) | exec-sh2.js:14:9:14:49 | cmd | | exec-sh2.js:14:25:14:31 | req.url | exec-sh2.js:14:15:14:38 | url.par ... , true) | | exec-sh2.js:15:12:15:14 | cmd | exec-sh2.js:9:17:9:23 | command | | exec-sh.js:13:17:13:23 | command | exec-sh.js:15:44:15:50 | command | -| exec-sh.js:13:17:13:23 | command | exec-sh.js:15:44:15:50 | command | | exec-sh.js:19:9:19:49 | cmd | exec-sh.js:20:12:20:14 | cmd | -| exec-sh.js:19:15:19:38 | url.par ... , true) | exec-sh.js:19:15:19:44 | url.par ... ).query | -| exec-sh.js:19:15:19:44 | url.par ... ).query | exec-sh.js:19:15:19:49 | url.par ... ry.path | -| exec-sh.js:19:15:19:49 | url.par ... ry.path | exec-sh.js:19:9:19:49 | cmd | -| exec-sh.js:19:25:19:31 | req.url | exec-sh.js:19:15:19:38 | url.par ... , true) | +| exec-sh.js:19:15:19:38 | url.par ... , true) | exec-sh.js:19:9:19:49 | cmd | | exec-sh.js:19:25:19:31 | req.url | exec-sh.js:19:15:19:38 | url.par ... , true) | | exec-sh.js:20:12:20:14 | cmd | exec-sh.js:13:17:13:23 | command | +| execSeries.js:3:20:3:22 | arr | execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr] | | execSeries.js:3:20:3:22 | arr | execSeries.js:6:14:6:16 | arr | +| execSeries.js:3:20:3:22 | arr [0] | execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr, 0] | +| execSeries.js:3:20:3:22 | arr [0] | execSeries.js:6:14:6:16 | arr [0] | +| execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr, 0] | execSeries.js:6:14:6:16 | arr [0] | +| execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr] | execSeries.js:6:14:6:16 | arr | | execSeries.js:6:14:6:16 | arr | execSeries.js:6:14:6:21 | arr[i++] | +| execSeries.js:6:14:6:16 | arr [0] | execSeries.js:6:14:6:21 | arr[i++] | | execSeries.js:6:14:6:21 | arr[i++] | execSeries.js:14:24:14:30 | command | | execSeries.js:13:19:13:26 | commands | execSeries.js:14:13:14:20 | commands | +| execSeries.js:13:19:13:26 | commands [0] | execSeries.js:14:13:14:20 | commands [0] | | execSeries.js:14:13:14:20 | commands | execSeries.js:3:20:3:22 | arr | -| execSeries.js:14:13:14:20 | commands | execSeries.js:14:24:14:30 | command | -| execSeries.js:14:24:14:30 | command | execSeries.js:14:41:14:47 | command | +| execSeries.js:14:13:14:20 | commands [0] | execSeries.js:3:20:3:22 | arr [0] | | execSeries.js:14:24:14:30 | command | execSeries.js:14:41:14:47 | command | | execSeries.js:18:7:18:58 | cmd | execSeries.js:19:13:19:15 | cmd | -| execSeries.js:18:13:18:47 | require ... , true) | execSeries.js:18:13:18:53 | require ... ).query | -| execSeries.js:18:13:18:53 | require ... ).query | execSeries.js:18:13:18:58 | require ... ry.path | -| execSeries.js:18:13:18:58 | require ... ry.path | execSeries.js:18:7:18:58 | cmd | -| execSeries.js:18:34:18:40 | req.url | execSeries.js:18:13:18:47 | require ... , true) | +| execSeries.js:18:13:18:47 | require ... , true) | execSeries.js:18:7:18:58 | cmd | | execSeries.js:18:34:18:40 | req.url | execSeries.js:18:13:18:47 | require ... , true) | | execSeries.js:19:12:19:16 | [cmd] | execSeries.js:13:19:13:26 | commands | +| execSeries.js:19:12:19:16 | [cmd] [0] | execSeries.js:13:19:13:26 | commands [0] | | execSeries.js:19:13:19:15 | cmd | execSeries.js:19:12:19:16 | [cmd] | -| form-parsers.js:9:19:9:26 | req.file | form-parsers.js:9:19:9:39 | req.fil ... nalname | -| form-parsers.js:9:19:9:26 | req.file | form-parsers.js:9:19:9:39 | req.fil ... nalname | -| form-parsers.js:9:19:9:39 | req.fil ... nalname | form-parsers.js:9:8:9:39 | "touch ... nalname | -| form-parsers.js:9:19:9:39 | req.fil ... nalname | form-parsers.js:9:8:9:39 | "touch ... nalname | -| form-parsers.js:13:3:13:11 | req.files | form-parsers.js:13:21:13:24 | file | +| execSeries.js:19:13:19:15 | cmd | execSeries.js:19:12:19:16 | [cmd] [0] | +| form-parsers.js:9:19:9:26 | req.file | form-parsers.js:9:8:9:39 | "touch ... nalname | | form-parsers.js:13:3:13:11 | req.files | form-parsers.js:13:21:13:24 | file | | form-parsers.js:13:21:13:24 | file | form-parsers.js:14:21:14:24 | file | -| form-parsers.js:14:21:14:24 | file | form-parsers.js:14:21:14:37 | file.originalname | -| form-parsers.js:14:21:14:37 | file.originalname | form-parsers.js:14:10:14:37 | "touch ... nalname | -| form-parsers.js:14:21:14:37 | file.originalname | form-parsers.js:14:10:14:37 | "touch ... nalname | -| form-parsers.js:24:48:24:55 | filename | form-parsers.js:25:21:25:28 | filename | +| form-parsers.js:14:21:14:24 | file | form-parsers.js:14:10:14:37 | "touch ... nalname | | form-parsers.js:24:48:24:55 | filename | form-parsers.js:25:21:25:28 | filename | | form-parsers.js:25:21:25:28 | filename | form-parsers.js:25:10:25:28 | "touch " + filename | -| form-parsers.js:25:21:25:28 | filename | form-parsers.js:25:10:25:28 | "touch " + filename | | form-parsers.js:35:25:35:30 | fields | form-parsers.js:36:21:36:26 | fields | -| form-parsers.js:35:25:35:30 | fields | form-parsers.js:36:21:36:26 | fields | -| form-parsers.js:36:21:36:26 | fields | form-parsers.js:36:21:36:31 | fields.name | -| form-parsers.js:36:21:36:31 | fields.name | form-parsers.js:36:10:36:31 | "touch ... ds.name | -| form-parsers.js:36:21:36:31 | fields.name | form-parsers.js:36:10:36:31 | "touch ... ds.name | +| form-parsers.js:36:21:36:26 | fields | form-parsers.js:36:10:36:31 | "touch ... ds.name | | form-parsers.js:40:26:40:31 | fields | form-parsers.js:41:21:41:26 | fields | -| form-parsers.js:40:26:40:31 | fields | form-parsers.js:41:21:41:26 | fields | -| form-parsers.js:41:21:41:26 | fields | form-parsers.js:41:21:41:31 | fields.name | -| form-parsers.js:41:21:41:31 | fields.name | form-parsers.js:41:10:41:31 | "touch ... ds.name | -| form-parsers.js:41:21:41:31 | fields.name | form-parsers.js:41:10:41:31 | "touch ... ds.name | +| form-parsers.js:41:21:41:26 | fields | form-parsers.js:41:10:41:31 | "touch ... ds.name | | form-parsers.js:52:34:52:39 | fields | form-parsers.js:53:21:53:26 | fields | -| form-parsers.js:52:34:52:39 | fields | form-parsers.js:53:21:53:26 | fields | -| form-parsers.js:53:21:53:26 | fields | form-parsers.js:53:21:53:31 | fields.name | -| form-parsers.js:53:21:53:31 | fields.name | form-parsers.js:53:10:53:31 | "touch ... ds.name | -| form-parsers.js:53:21:53:31 | fields.name | form-parsers.js:53:10:53:31 | "touch ... ds.name | +| form-parsers.js:53:21:53:26 | fields | form-parsers.js:53:10:53:31 | "touch ... ds.name | | form-parsers.js:58:30:58:33 | part | form-parsers.js:59:21:59:24 | part | -| form-parsers.js:58:30:58:33 | part | form-parsers.js:59:21:59:24 | part | -| form-parsers.js:59:21:59:24 | part | form-parsers.js:59:21:59:33 | part.filename | -| form-parsers.js:59:21:59:33 | part.filename | form-parsers.js:59:10:59:33 | "touch ... ilename | -| form-parsers.js:59:21:59:33 | part.filename | form-parsers.js:59:10:59:33 | "touch ... ilename | -| other.js:5:9:5:49 | cmd | other.js:7:33:7:35 | cmd | +| form-parsers.js:59:21:59:24 | part | form-parsers.js:59:10:59:33 | "touch ... ilename | | other.js:5:9:5:49 | cmd | other.js:7:33:7:35 | cmd | | other.js:5:9:5:49 | cmd | other.js:8:28:8:30 | cmd | -| other.js:5:9:5:49 | cmd | other.js:8:28:8:30 | cmd | -| other.js:5:9:5:49 | cmd | other.js:9:32:9:34 | cmd | | other.js:5:9:5:49 | cmd | other.js:9:32:9:34 | cmd | | other.js:5:9:5:49 | cmd | other.js:10:29:10:31 | cmd | -| other.js:5:9:5:49 | cmd | other.js:10:29:10:31 | cmd | -| other.js:5:9:5:49 | cmd | other.js:11:29:11:31 | cmd | | other.js:5:9:5:49 | cmd | other.js:11:29:11:31 | cmd | | other.js:5:9:5:49 | cmd | other.js:12:27:12:29 | cmd | -| other.js:5:9:5:49 | cmd | other.js:12:27:12:29 | cmd | -| other.js:5:9:5:49 | cmd | other.js:14:28:14:30 | cmd | | other.js:5:9:5:49 | cmd | other.js:14:28:14:30 | cmd | | other.js:5:9:5:49 | cmd | other.js:15:34:15:36 | cmd | -| other.js:5:9:5:49 | cmd | other.js:15:34:15:36 | cmd | -| other.js:5:9:5:49 | cmd | other.js:16:21:16:23 | cmd | | other.js:5:9:5:49 | cmd | other.js:16:21:16:23 | cmd | | other.js:5:9:5:49 | cmd | other.js:17:27:17:29 | cmd | -| other.js:5:9:5:49 | cmd | other.js:17:27:17:29 | cmd | -| other.js:5:9:5:49 | cmd | other.js:18:22:18:24 | cmd | | other.js:5:9:5:49 | cmd | other.js:18:22:18:24 | cmd | | other.js:5:9:5:49 | cmd | other.js:19:36:19:38 | cmd | -| other.js:5:9:5:49 | cmd | other.js:19:36:19:38 | cmd | -| other.js:5:9:5:49 | cmd | other.js:22:21:22:23 | cmd | | other.js:5:9:5:49 | cmd | other.js:22:21:22:23 | cmd | | other.js:5:9:5:49 | cmd | other.js:23:28:23:30 | cmd | -| other.js:5:9:5:49 | cmd | other.js:23:28:23:30 | cmd | -| other.js:5:9:5:49 | cmd | other.js:26:34:26:36 | cmd | | other.js:5:9:5:49 | cmd | other.js:26:34:26:36 | cmd | | other.js:5:9:5:49 | cmd | other.js:28:27:28:29 | cmd | -| other.js:5:9:5:49 | cmd | other.js:28:27:28:29 | cmd | -| other.js:5:9:5:49 | cmd | other.js:30:33:30:35 | cmd | | other.js:5:9:5:49 | cmd | other.js:30:33:30:35 | cmd | | other.js:5:9:5:49 | cmd | other.js:34:44:34:46 | cmd | -| other.js:5:9:5:49 | cmd | other.js:34:44:34:46 | cmd | -| other.js:5:15:5:38 | url.par ... , true) | other.js:5:15:5:44 | url.par ... ).query | -| other.js:5:15:5:44 | url.par ... ).query | other.js:5:15:5:49 | url.par ... ry.path | -| other.js:5:15:5:49 | url.par ... ry.path | other.js:5:9:5:49 | cmd | -| other.js:5:25:5:31 | req.url | other.js:5:15:5:38 | url.par ... , true) | +| other.js:5:15:5:38 | url.par ... , true) | other.js:5:9:5:49 | cmd | | other.js:5:25:5:31 | req.url | other.js:5:15:5:38 | url.par ... , true) | | third-party-command-injection.js:5:20:5:26 | command | third-party-command-injection.js:6:21:6:27 | command | -| third-party-command-injection.js:5:20:5:26 | command | third-party-command-injection.js:6:21:6:27 | command | -| third-party-command-injection.js:5:20:5:26 | command | third-party-command-injection.js:6:21:6:27 | command | -| third-party-command-injection.js:5:20:5:26 | command | third-party-command-injection.js:6:21:6:27 | command | +nodes +| actions.js:8:9:8:57 | title | semmle.label | title | +| actions.js:8:17:8:57 | github. ... t.title | semmle.label | github. ... t.title | +| actions.js:9:8:9:22 | `echo ${title}` | semmle.label | `echo ${title}` | +| actions.js:9:16:9:20 | title | semmle.label | title | +| actions.js:18:9:18:63 | head_ref | semmle.label | head_ref | +| actions.js:18:20:18:63 | github. ... ead.ref | semmle.label | github. ... ead.ref | +| actions.js:19:14:19:31 | `echo ${head_ref}` | semmle.label | `echo ${head_ref}` | +| actions.js:19:22:19:29 | head_ref | semmle.label | head_ref | +| child_process-test.js:6:9:6:49 | cmd | semmle.label | cmd | +| child_process-test.js:6:15:6:38 | url.par ... , true) | semmle.label | url.par ... , true) | +| child_process-test.js:6:15:6:49 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| child_process-test.js:6:15:6:49 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| child_process-test.js:6:25:6:31 | req.url | semmle.label | req.url | +| child_process-test.js:17:13:17:15 | cmd | semmle.label | cmd | +| child_process-test.js:18:17:18:19 | cmd | semmle.label | cmd | +| child_process-test.js:19:17:19:19 | cmd | semmle.label | cmd | +| child_process-test.js:20:21:20:23 | cmd | semmle.label | cmd | +| child_process-test.js:21:14:21:16 | cmd | semmle.label | cmd | +| child_process-test.js:22:18:22:20 | cmd | semmle.label | cmd | +| child_process-test.js:23:13:23:15 | cmd | semmle.label | cmd | +| child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | semmle.label | "foo" + cmd + "bar" | +| child_process-test.js:25:21:25:23 | cmd | semmle.label | cmd | +| child_process-test.js:39:26:39:28 | cmd | semmle.label | cmd | +| child_process-test.js:43:15:43:17 | cmd | semmle.label | cmd | +| child_process-test.js:48:15:48:17 | cmd | semmle.label | cmd | +| child_process-test.js:53:15:53:17 | cmd | semmle.label | cmd | +| child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | semmle.label | ['/C', ... , cmd]) | +| child_process-test.js:56:46:56:57 | ["bar", cmd] | semmle.label | ["bar", cmd] | +| child_process-test.js:56:46:56:57 | ["bar", cmd] [1] | semmle.label | ["bar", cmd] [1] | +| child_process-test.js:56:54:56:56 | cmd | semmle.label | cmd | +| child_process-test.js:56:54:56:56 | cmd | semmle.label | cmd | +| child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) | semmle.label | ['/C', ... at(cmd) | +| child_process-test.js:57:46:57:48 | cmd | semmle.label | cmd | +| child_process-test.js:73:9:73:49 | cmd | semmle.label | cmd | +| child_process-test.js:73:15:73:38 | url.par ... , true) | semmle.label | url.par ... , true) | +| child_process-test.js:73:25:73:31 | req.url | semmle.label | req.url | +| child_process-test.js:75:29:75:31 | cmd | semmle.label | cmd | +| child_process-test.js:83:19:83:36 | req.query.fileName | semmle.label | req.query.fileName | +| child_process-test.js:94:11:94:35 | "ping " ... ms.host | semmle.label | "ping " ... ms.host | +| child_process-test.js:94:21:94:30 | ctx.params | semmle.label | ctx.params | +| exec-sh2.js:9:17:9:23 | command | semmle.label | command | +| exec-sh2.js:10:40:10:46 | command | semmle.label | command | +| exec-sh2.js:14:9:14:49 | cmd | semmle.label | cmd | +| exec-sh2.js:14:15:14:38 | url.par ... , true) | semmle.label | url.par ... , true) | +| exec-sh2.js:14:25:14:31 | req.url | semmle.label | req.url | +| exec-sh2.js:15:12:15:14 | cmd | semmle.label | cmd | +| exec-sh.js:13:17:13:23 | command | semmle.label | command | +| exec-sh.js:15:44:15:50 | command | semmle.label | command | +| exec-sh.js:19:9:19:49 | cmd | semmle.label | cmd | +| exec-sh.js:19:15:19:38 | url.par ... , true) | semmle.label | url.par ... , true) | +| exec-sh.js:19:25:19:31 | req.url | semmle.label | req.url | +| exec-sh.js:20:12:20:14 | cmd | semmle.label | cmd | +| execSeries.js:3:20:3:22 | arr | semmle.label | arr | +| execSeries.js:3:20:3:22 | arr [0] | semmle.label | arr [0] | +| execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr, 0] | semmle.label | (functi ... );\\n }) [arr, 0] | +| execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr] | semmle.label | (functi ... );\\n }) [arr] | +| execSeries.js:6:14:6:16 | arr | semmle.label | arr | +| execSeries.js:6:14:6:16 | arr [0] | semmle.label | arr [0] | +| execSeries.js:6:14:6:21 | arr[i++] | semmle.label | arr[i++] | +| execSeries.js:13:19:13:26 | commands | semmle.label | commands | +| execSeries.js:13:19:13:26 | commands [0] | semmle.label | commands [0] | +| execSeries.js:14:13:14:20 | commands | semmle.label | commands | +| execSeries.js:14:13:14:20 | commands [0] | semmle.label | commands [0] | +| execSeries.js:14:24:14:30 | command | semmle.label | command | +| execSeries.js:14:41:14:47 | command | semmle.label | command | +| execSeries.js:18:7:18:58 | cmd | semmle.label | cmd | +| execSeries.js:18:13:18:47 | require ... , true) | semmle.label | require ... , true) | +| execSeries.js:18:34:18:40 | req.url | semmle.label | req.url | +| execSeries.js:19:12:19:16 | [cmd] | semmle.label | [cmd] | +| execSeries.js:19:12:19:16 | [cmd] [0] | semmle.label | [cmd] [0] | +| execSeries.js:19:13:19:15 | cmd | semmle.label | cmd | +| form-parsers.js:9:8:9:39 | "touch ... nalname | semmle.label | "touch ... nalname | +| form-parsers.js:9:19:9:26 | req.file | semmle.label | req.file | +| form-parsers.js:13:3:13:11 | req.files | semmle.label | req.files | +| form-parsers.js:13:21:13:24 | file | semmle.label | file | +| form-parsers.js:14:10:14:37 | "touch ... nalname | semmle.label | "touch ... nalname | +| form-parsers.js:14:21:14:24 | file | semmle.label | file | +| form-parsers.js:24:48:24:55 | filename | semmle.label | filename | +| form-parsers.js:25:10:25:28 | "touch " + filename | semmle.label | "touch " + filename | +| form-parsers.js:25:21:25:28 | filename | semmle.label | filename | +| form-parsers.js:35:25:35:30 | fields | semmle.label | fields | +| form-parsers.js:36:10:36:31 | "touch ... ds.name | semmle.label | "touch ... ds.name | +| form-parsers.js:36:21:36:26 | fields | semmle.label | fields | +| form-parsers.js:40:26:40:31 | fields | semmle.label | fields | +| form-parsers.js:41:10:41:31 | "touch ... ds.name | semmle.label | "touch ... ds.name | +| form-parsers.js:41:21:41:26 | fields | semmle.label | fields | +| form-parsers.js:52:34:52:39 | fields | semmle.label | fields | +| form-parsers.js:53:10:53:31 | "touch ... ds.name | semmle.label | "touch ... ds.name | +| form-parsers.js:53:21:53:26 | fields | semmle.label | fields | +| form-parsers.js:58:30:58:33 | part | semmle.label | part | +| form-parsers.js:59:10:59:33 | "touch ... ilename | semmle.label | "touch ... ilename | +| form-parsers.js:59:21:59:24 | part | semmle.label | part | +| other.js:5:9:5:49 | cmd | semmle.label | cmd | +| other.js:5:15:5:38 | url.par ... , true) | semmle.label | url.par ... , true) | +| other.js:5:25:5:31 | req.url | semmle.label | req.url | +| other.js:7:33:7:35 | cmd | semmle.label | cmd | +| other.js:8:28:8:30 | cmd | semmle.label | cmd | +| other.js:9:32:9:34 | cmd | semmle.label | cmd | +| other.js:10:29:10:31 | cmd | semmle.label | cmd | +| other.js:11:29:11:31 | cmd | semmle.label | cmd | +| other.js:12:27:12:29 | cmd | semmle.label | cmd | +| other.js:14:28:14:30 | cmd | semmle.label | cmd | +| other.js:15:34:15:36 | cmd | semmle.label | cmd | +| other.js:16:21:16:23 | cmd | semmle.label | cmd | +| other.js:17:27:17:29 | cmd | semmle.label | cmd | +| other.js:18:22:18:24 | cmd | semmle.label | cmd | +| other.js:19:36:19:38 | cmd | semmle.label | cmd | +| other.js:22:21:22:23 | cmd | semmle.label | cmd | +| other.js:23:28:23:30 | cmd | semmle.label | cmd | +| other.js:26:34:26:36 | cmd | semmle.label | cmd | +| other.js:28:27:28:29 | cmd | semmle.label | cmd | +| other.js:30:33:30:35 | cmd | semmle.label | cmd | +| other.js:34:44:34:46 | cmd | semmle.label | cmd | +| third-party-command-injection.js:5:20:5:26 | command | semmle.label | command | +| third-party-command-injection.js:6:21:6:27 | command | semmle.label | command | +subpaths #select | actions.js:9:8:9:22 | `echo ${title}` | actions.js:8:17:8:57 | github. ... t.title | actions.js:9:8:9:22 | `echo ${title}` | This command line depends on a $@. | actions.js:8:17:8:57 | github. ... t.title | user-provided value | | actions.js:19:14:19:31 | `echo ${head_ref}` | actions.js:18:20:18:63 | github. ... ead.ref | actions.js:19:14:19:31 | `echo ${head_ref}` | This command line depends on a $@. | actions.js:18:20:18:63 | github. ... ead.ref | user-provided value | From fcfab5238e4bcde13202e6dc7aa80a20609f9907 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:21:39 +0200 Subject: [PATCH 044/514] JS: Port CodeInjection --- .../security/dataflow/CodeInjectionQuery.qll | 28 +- .../ql/src/Security/CWE-094/CodeInjection.ql | 6 +- .../Templating/CodeInjection.expected | 151 +++---- .../CodeInjection/CodeInjection.expected | 384 +++++------------- 4 files changed, 165 insertions(+), 404 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionQuery.qll index ea57dd73588..811a9575504 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionQuery.qll @@ -13,7 +13,28 @@ import CodeInjectionCustomizations::CodeInjection /** * A taint-tracking configuration for reasoning about code injection vulnerabilities. */ -class Configuration extends TaintTracking::Configuration { +module CodeInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + // HTML sanitizers are insufficient protection against code injection + node1 = node2.(HtmlSanitizerCall).getInput() + } +} + +/** + * Taint-tracking for reasoning about code injection vulnerabilities. + */ +module CodeInjectionFlow = TaintTracking::Global; + +/** + * DEPRRECATED. Use the `CodeInjectionFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "CodeInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -25,8 +46,7 @@ class Configuration extends TaintTracking::Configuration { node instanceof Sanitizer } - override predicate isAdditionalTaintStep(DataFlow::Node src, DataFlow::Node trg) { - // HTML sanitizers are insufficient protection against code injection - src = trg.(HtmlSanitizerCall).getInput() + override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + CodeInjectionConfig::isAdditionalFlowStep(node1, node2) } } diff --git a/javascript/ql/src/Security/CWE-094/CodeInjection.ql b/javascript/ql/src/Security/CWE-094/CodeInjection.ql index a4ed71e2949..c08f75bb673 100644 --- a/javascript/ql/src/Security/CWE-094/CodeInjection.ql +++ b/javascript/ql/src/Security/CWE-094/CodeInjection.ql @@ -16,9 +16,9 @@ import javascript import semmle.javascript.security.dataflow.CodeInjectionQuery -import DataFlow::PathGraph +import CodeInjectionFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink +where CodeInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, sink.getNode().(Sink).getMessagePrefix() + " depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/library-tests/frameworks/Templating/CodeInjection.expected b/javascript/ql/test/library-tests/frameworks/Templating/CodeInjection.expected index 48b2111a4a2..de308fdabdf 100644 --- a/javascript/ql/test/library-tests/frameworks/Templating/CodeInjection.expected +++ b/javascript/ql/test/library-tests/frameworks/Templating/CodeInjection.expected @@ -1,140 +1,83 @@ -nodes -| app.js:15:30:15:58 | req.que ... tedCode | -| app.js:15:30:15:58 | req.que ... tedCode | -| app.js:17:25:17:48 | req.que ... shSink1 | -| app.js:17:25:17:48 | req.que ... shSink1 | -| app.js:19:35:19:68 | req.que ... rString | -| app.js:19:35:19:68 | req.que ... rString | -| app.js:34:30:34:58 | req.que ... tedCode | -| app.js:34:30:34:58 | req.que ... tedCode | -| app.js:36:25:36:48 | req.que ... shSink1 | -| app.js:36:25:36:48 | req.que ... shSink1 | -| app.js:38:35:38:68 | req.que ... rString | -| app.js:38:35:38:68 | req.que ... rString | -| app.js:53:30:53:58 | req.que ... tedCode | -| app.js:53:30:53:58 | req.que ... tedCode | -| app.js:54:33:54:64 | req.que ... CodeRaw | -| app.js:54:33:54:64 | req.que ... CodeRaw | -| app.js:56:25:56:48 | req.que ... shSink1 | -| app.js:56:25:56:48 | req.que ... shSink1 | -| app.js:58:35:58:68 | req.que ... rString | -| app.js:58:35:58:68 | req.que ... rString | -| app.js:59:38:59:74 | req.que ... ringRaw | -| app.js:59:38:59:74 | req.que ... ringRaw | -| app.js:65:22:65:42 | req.que ... pedHtml | -| app.js:65:22:65:42 | req.que ... pedHtml | -| app.js:66:18:66:34 | req.query.rawHtml | -| app.js:66:18:66:34 | req.query.rawHtml | -| views/angularjs_include.ejs:2:5:2:22 | <%= escapedHtml %> | -| views/angularjs_include.ejs:2:5:2:22 | <%= escapedHtml %> | -| views/angularjs_include.ejs:2:9:2:19 | escapedHtml | -| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | -| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | -| views/angularjs_include.ejs:3:9:3:15 | rawHtml | -| views/angularjs_sinks.ejs:3:9:3:26 | <%= escapedHtml %> | -| views/angularjs_sinks.ejs:3:9:3:26 | <%= escapedHtml %> | -| views/angularjs_sinks.ejs:3:13:3:23 | escapedHtml | -| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | -| views/ejs_sinks.ejs:13:39:13:64 | <%= dataInGeneratedCode %> | -| views/ejs_sinks.ejs:13:39:13:64 | <%= dataInGeneratedCode %> | -| views/ejs_sinks.ejs:13:43:13:61 | dataInGeneratedCode | -| views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> | -| views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> | -| views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 | -| views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> | -| views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> | -| views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString | -| views/hbs_sinks.hbs:25:39:25:63 | {{ dataInGeneratedCode }} | -| views/hbs_sinks.hbs:25:39:25:63 | {{ dataInGeneratedCode }} | -| views/hbs_sinks.hbs:25:42:25:60 | dataInGeneratedCode | -| views/hbs_sinks.hbs:28:19:28:38 | {{ backslashSink1 }} | -| views/hbs_sinks.hbs:28:19:28:38 | {{ backslashSink1 }} | -| views/hbs_sinks.hbs:28:22:28:35 | backslashSink1 | -| views/hbs_sinks.hbs:33:39:33:68 | {{ dataInEventHandlerString }} | -| views/hbs_sinks.hbs:33:39:33:68 | {{ dataInEventHandlerString }} | -| views/hbs_sinks.hbs:33:42:33:65 | dataInE ... rString | -| views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} | -| views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} | -| views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode | -| views/njk_sinks.njk:14:42:14:76 | {{ dataInGeneratedCodeRaw \| safe }} | -| views/njk_sinks.njk:14:42:14:76 | {{ dataInGeneratedCodeRaw \| safe }} | -| views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | -| views/njk_sinks.njk:14:45:14:73 | dataInG ... \| safe | -| views/njk_sinks.njk:17:19:17:38 | {{ backslashSink1 }} | -| views/njk_sinks.njk:17:19:17:38 | {{ backslashSink1 }} | -| views/njk_sinks.njk:17:22:17:35 | backslashSink1 | -| views/njk_sinks.njk:22:39:22:68 | {{ dataInEventHandlerString }} | -| views/njk_sinks.njk:22:39:22:68 | {{ dataInEventHandlerString }} | -| views/njk_sinks.njk:22:42:22:65 | dataInE ... rString | -| views/njk_sinks.njk:23:39:23:78 | {{ dataInEventHandlerStringRaw \| safe }} | -| views/njk_sinks.njk:23:39:23:78 | {{ dataInEventHandlerStringRaw \| safe }} | -| views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | -| views/njk_sinks.njk:23:42:23:75 | dataInE ... \| safe | edges | app.js:15:30:15:58 | req.que ... tedCode | views/ejs_sinks.ejs:13:43:13:61 | dataInGeneratedCode | -| app.js:15:30:15:58 | req.que ... tedCode | views/ejs_sinks.ejs:13:43:13:61 | dataInGeneratedCode | -| app.js:17:25:17:48 | req.que ... shSink1 | views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 | | app.js:17:25:17:48 | req.que ... shSink1 | views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 | | app.js:19:35:19:68 | req.que ... rString | views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString | -| app.js:19:35:19:68 | req.que ... rString | views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString | -| app.js:34:30:34:58 | req.que ... tedCode | views/hbs_sinks.hbs:25:42:25:60 | dataInGeneratedCode | | app.js:34:30:34:58 | req.que ... tedCode | views/hbs_sinks.hbs:25:42:25:60 | dataInGeneratedCode | | app.js:36:25:36:48 | req.que ... shSink1 | views/hbs_sinks.hbs:28:22:28:35 | backslashSink1 | -| app.js:36:25:36:48 | req.que ... shSink1 | views/hbs_sinks.hbs:28:22:28:35 | backslashSink1 | -| app.js:38:35:38:68 | req.que ... rString | views/hbs_sinks.hbs:33:42:33:65 | dataInE ... rString | | app.js:38:35:38:68 | req.que ... rString | views/hbs_sinks.hbs:33:42:33:65 | dataInE ... rString | | app.js:53:30:53:58 | req.que ... tedCode | views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode | -| app.js:53:30:53:58 | req.que ... tedCode | views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode | -| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | | app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | | app.js:56:25:56:48 | req.que ... shSink1 | views/njk_sinks.njk:17:22:17:35 | backslashSink1 | -| app.js:56:25:56:48 | req.que ... shSink1 | views/njk_sinks.njk:17:22:17:35 | backslashSink1 | -| app.js:58:35:58:68 | req.que ... rString | views/njk_sinks.njk:22:42:22:65 | dataInE ... rString | | app.js:58:35:58:68 | req.que ... rString | views/njk_sinks.njk:22:42:22:65 | dataInE ... rString | | app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | -| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | -| app.js:65:22:65:42 | req.que ... pedHtml | views/angularjs_include.ejs:2:9:2:19 | escapedHtml | | app.js:65:22:65:42 | req.que ... pedHtml | views/angularjs_include.ejs:2:9:2:19 | escapedHtml | | app.js:65:22:65:42 | req.que ... pedHtml | views/angularjs_sinks.ejs:3:13:3:23 | escapedHtml | -| app.js:65:22:65:42 | req.que ... pedHtml | views/angularjs_sinks.ejs:3:13:3:23 | escapedHtml | -| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:9:3:15 | rawHtml | | app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:9:3:15 | rawHtml | | app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | -| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | -| views/angularjs_include.ejs:2:9:2:19 | escapedHtml | views/angularjs_include.ejs:2:5:2:22 | <%= escapedHtml %> | | views/angularjs_include.ejs:2:9:2:19 | escapedHtml | views/angularjs_include.ejs:2:5:2:22 | <%= escapedHtml %> | | views/angularjs_include.ejs:3:9:3:15 | rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | -| views/angularjs_include.ejs:3:9:3:15 | rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | -| views/angularjs_sinks.ejs:3:13:3:23 | escapedHtml | views/angularjs_sinks.ejs:3:9:3:26 | <%= escapedHtml %> | | views/angularjs_sinks.ejs:3:13:3:23 | escapedHtml | views/angularjs_sinks.ejs:3:9:3:26 | <%= escapedHtml %> | | views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/ejs_sinks.ejs:13:43:13:61 | dataInGeneratedCode | views/ejs_sinks.ejs:13:39:13:64 | <%= dataInGeneratedCode %> | | views/ejs_sinks.ejs:13:43:13:61 | dataInGeneratedCode | views/ejs_sinks.ejs:13:39:13:64 | <%= dataInGeneratedCode %> | | views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 | views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> | -| views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 | views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> | -| views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString | views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> | | views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString | views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> | | views/hbs_sinks.hbs:25:42:25:60 | dataInGeneratedCode | views/hbs_sinks.hbs:25:39:25:63 | {{ dataInGeneratedCode }} | -| views/hbs_sinks.hbs:25:42:25:60 | dataInGeneratedCode | views/hbs_sinks.hbs:25:39:25:63 | {{ dataInGeneratedCode }} | -| views/hbs_sinks.hbs:28:22:28:35 | backslashSink1 | views/hbs_sinks.hbs:28:19:28:38 | {{ backslashSink1 }} | | views/hbs_sinks.hbs:28:22:28:35 | backslashSink1 | views/hbs_sinks.hbs:28:19:28:38 | {{ backslashSink1 }} | | views/hbs_sinks.hbs:33:42:33:65 | dataInE ... rString | views/hbs_sinks.hbs:33:39:33:68 | {{ dataInEventHandlerString }} | -| views/hbs_sinks.hbs:33:42:33:65 | dataInE ... rString | views/hbs_sinks.hbs:33:39:33:68 | {{ dataInEventHandlerString }} | -| views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode | views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} | | views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode | views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} | | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | views/njk_sinks.njk:14:45:14:73 | dataInG ... \| safe | | views/njk_sinks.njk:14:45:14:73 | dataInG ... \| safe | views/njk_sinks.njk:14:42:14:76 | {{ dataInGeneratedCodeRaw \| safe }} | -| views/njk_sinks.njk:14:45:14:73 | dataInG ... \| safe | views/njk_sinks.njk:14:42:14:76 | {{ dataInGeneratedCodeRaw \| safe }} | | views/njk_sinks.njk:17:22:17:35 | backslashSink1 | views/njk_sinks.njk:17:19:17:38 | {{ backslashSink1 }} | -| views/njk_sinks.njk:17:22:17:35 | backslashSink1 | views/njk_sinks.njk:17:19:17:38 | {{ backslashSink1 }} | -| views/njk_sinks.njk:22:42:22:65 | dataInE ... rString | views/njk_sinks.njk:22:39:22:68 | {{ dataInEventHandlerString }} | | views/njk_sinks.njk:22:42:22:65 | dataInE ... rString | views/njk_sinks.njk:22:39:22:68 | {{ dataInEventHandlerString }} | | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | views/njk_sinks.njk:23:42:23:75 | dataInE ... \| safe | | views/njk_sinks.njk:23:42:23:75 | dataInE ... \| safe | views/njk_sinks.njk:23:39:23:78 | {{ dataInEventHandlerStringRaw \| safe }} | -| views/njk_sinks.njk:23:42:23:75 | dataInE ... \| safe | views/njk_sinks.njk:23:39:23:78 | {{ dataInEventHandlerStringRaw \| safe }} | +nodes +| app.js:15:30:15:58 | req.que ... tedCode | semmle.label | req.que ... tedCode | +| app.js:17:25:17:48 | req.que ... shSink1 | semmle.label | req.que ... shSink1 | +| app.js:19:35:19:68 | req.que ... rString | semmle.label | req.que ... rString | +| app.js:34:30:34:58 | req.que ... tedCode | semmle.label | req.que ... tedCode | +| app.js:36:25:36:48 | req.que ... shSink1 | semmle.label | req.que ... shSink1 | +| app.js:38:35:38:68 | req.que ... rString | semmle.label | req.que ... rString | +| app.js:53:30:53:58 | req.que ... tedCode | semmle.label | req.que ... tedCode | +| app.js:54:33:54:64 | req.que ... CodeRaw | semmle.label | req.que ... CodeRaw | +| app.js:56:25:56:48 | req.que ... shSink1 | semmle.label | req.que ... shSink1 | +| app.js:58:35:58:68 | req.que ... rString | semmle.label | req.que ... rString | +| app.js:59:38:59:74 | req.que ... ringRaw | semmle.label | req.que ... ringRaw | +| app.js:65:22:65:42 | req.que ... pedHtml | semmle.label | req.que ... pedHtml | +| app.js:66:18:66:34 | req.query.rawHtml | semmle.label | req.query.rawHtml | +| views/angularjs_include.ejs:2:5:2:22 | <%= escapedHtml %> | semmle.label | <%= escapedHtml %> | +| views/angularjs_include.ejs:2:9:2:19 | escapedHtml | semmle.label | escapedHtml | +| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | semmle.label | <%- rawHtml %> | +| views/angularjs_include.ejs:3:9:3:15 | rawHtml | semmle.label | rawHtml | +| views/angularjs_sinks.ejs:3:9:3:26 | <%= escapedHtml %> | semmle.label | <%= escapedHtml %> | +| views/angularjs_sinks.ejs:3:13:3:23 | escapedHtml | semmle.label | escapedHtml | +| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | semmle.label | <%- rawHtml %> | +| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | semmle.label | rawHtml | +| views/ejs_sinks.ejs:13:39:13:64 | <%= dataInGeneratedCode %> | semmle.label | <%= dataInGeneratedCode %> | +| views/ejs_sinks.ejs:13:43:13:61 | dataInGeneratedCode | semmle.label | dataInGeneratedCode | +| views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> | semmle.label | <%= backslashSink1 %> | +| views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 | semmle.label | backslashSink1 | +| views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> | semmle.label | <%= dataInEventHandlerString %> | +| views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString | semmle.label | dataInE ... rString | +| views/hbs_sinks.hbs:25:39:25:63 | {{ dataInGeneratedCode }} | semmle.label | {{ dataInGeneratedCode }} | +| views/hbs_sinks.hbs:25:42:25:60 | dataInGeneratedCode | semmle.label | dataInGeneratedCode | +| views/hbs_sinks.hbs:28:19:28:38 | {{ backslashSink1 }} | semmle.label | {{ backslashSink1 }} | +| views/hbs_sinks.hbs:28:22:28:35 | backslashSink1 | semmle.label | backslashSink1 | +| views/hbs_sinks.hbs:33:39:33:68 | {{ dataInEventHandlerString }} | semmle.label | {{ dataInEventHandlerString }} | +| views/hbs_sinks.hbs:33:42:33:65 | dataInE ... rString | semmle.label | dataInE ... rString | +| views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} | semmle.label | {{ dataInGeneratedCode }} | +| views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode | semmle.label | dataInGeneratedCode | +| views/njk_sinks.njk:14:42:14:76 | {{ dataInGeneratedCodeRaw \| safe }} | semmle.label | {{ dataInGeneratedCodeRaw \| safe }} | +| views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | semmle.label | dataInG ... CodeRaw | +| views/njk_sinks.njk:14:45:14:73 | dataInG ... \| safe | semmle.label | dataInG ... \| safe | +| views/njk_sinks.njk:17:19:17:38 | {{ backslashSink1 }} | semmle.label | {{ backslashSink1 }} | +| views/njk_sinks.njk:17:22:17:35 | backslashSink1 | semmle.label | backslashSink1 | +| views/njk_sinks.njk:22:39:22:68 | {{ dataInEventHandlerString }} | semmle.label | {{ dataInEventHandlerString }} | +| views/njk_sinks.njk:22:42:22:65 | dataInE ... rString | semmle.label | dataInE ... rString | +| views/njk_sinks.njk:23:39:23:78 | {{ dataInEventHandlerStringRaw \| safe }} | semmle.label | {{ dataInEventHandlerStringRaw \| safe }} | +| views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | semmle.label | dataInE ... ringRaw | +| views/njk_sinks.njk:23:42:23:75 | dataInE ... \| safe | semmle.label | dataInE ... \| safe | +subpaths #select | views/angularjs_include.ejs:2:5:2:22 | <%= escapedHtml %> | app.js:65:22:65:42 | req.que ... pedHtml | views/angularjs_include.ejs:2:5:2:22 | <%= escapedHtml %> | This AngularJS template, which may contain code, depends on a $@. | app.js:65:22:65:42 | req.que ... pedHtml | user-provided value | | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | This AngularJS template, which may contain code, depends on a $@. | app.js:66:18:66:34 | req.query.rawHtml | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected index 1193c5e33bc..10d2e8e6f18 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected @@ -1,335 +1,133 @@ -nodes -| NoSQLCodeInjection.js:18:24:18:31 | req.body | -| NoSQLCodeInjection.js:18:24:18:31 | req.body | -| NoSQLCodeInjection.js:18:24:18:37 | req.body.query | -| NoSQLCodeInjection.js:18:24:18:37 | req.body.query | -| NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | -| NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | -| NoSQLCodeInjection.js:19:36:19:43 | req.body | -| NoSQLCodeInjection.js:19:36:19:43 | req.body | -| NoSQLCodeInjection.js:19:36:19:48 | req.body.name | -| NoSQLCodeInjection.js:22:24:22:48 | "name = ... dy.name | -| NoSQLCodeInjection.js:22:24:22:48 | "name = ... dy.name | -| NoSQLCodeInjection.js:22:36:22:43 | req.body | -| NoSQLCodeInjection.js:22:36:22:43 | req.body | -| NoSQLCodeInjection.js:22:36:22:48 | req.body.name | -| actions.js:4:10:4:50 | github. ... message | -| actions.js:4:10:4:50 | github. ... message | -| actions.js:4:10:4:50 | github. ... message | -| angularjs.js:10:22:10:36 | location.search | -| angularjs.js:10:22:10:36 | location.search | -| angularjs.js:10:22:10:36 | location.search | -| angularjs.js:13:23:13:37 | location.search | -| angularjs.js:13:23:13:37 | location.search | -| angularjs.js:13:23:13:37 | location.search | -| angularjs.js:16:28:16:42 | location.search | -| angularjs.js:16:28:16:42 | location.search | -| angularjs.js:16:28:16:42 | location.search | -| angularjs.js:19:22:19:36 | location.search | -| angularjs.js:19:22:19:36 | location.search | -| angularjs.js:19:22:19:36 | location.search | -| angularjs.js:22:27:22:41 | location.search | -| angularjs.js:22:27:22:41 | location.search | -| angularjs.js:22:27:22:41 | location.search | -| angularjs.js:25:23:25:37 | location.search | -| angularjs.js:25:23:25:37 | location.search | -| angularjs.js:25:23:25:37 | location.search | -| angularjs.js:28:33:28:47 | location.search | -| angularjs.js:28:33:28:47 | location.search | -| angularjs.js:28:33:28:47 | location.search | -| angularjs.js:31:28:31:42 | location.search | -| angularjs.js:31:28:31:42 | location.search | -| angularjs.js:31:28:31:42 | location.search | -| angularjs.js:34:18:34:32 | location.search | -| angularjs.js:34:18:34:32 | location.search | -| angularjs.js:34:18:34:32 | location.search | -| angularjs.js:40:18:40:32 | location.search | -| angularjs.js:40:18:40:32 | location.search | -| angularjs.js:40:18:40:32 | location.search | -| angularjs.js:44:17:44:31 | location.search | -| angularjs.js:44:17:44:31 | location.search | -| angularjs.js:44:17:44:31 | location.search | -| angularjs.js:47:16:47:30 | location.search | -| angularjs.js:47:16:47:30 | location.search | -| angularjs.js:47:16:47:30 | location.search | -| angularjs.js:50:22:50:36 | location.search | -| angularjs.js:50:22:50:36 | location.search | -| angularjs.js:50:22:50:36 | location.search | -| angularjs.js:53:32:53:46 | location.search | -| angularjs.js:53:32:53:46 | location.search | -| angularjs.js:53:32:53:46 | location.search | -| express.js:7:24:7:69 | "return ... + "];" | -| express.js:7:24:7:69 | "return ... + "];" | -| express.js:7:44:7:62 | req.param("wobble") | -| express.js:7:44:7:62 | req.param("wobble") | -| express.js:9:34:9:79 | "return ... + "];" | -| express.js:9:34:9:79 | "return ... + "];" | -| express.js:9:54:9:72 | req.param("wobble") | -| express.js:9:54:9:72 | req.param("wobble") | -| express.js:12:8:12:53 | "return ... + "];" | -| express.js:12:8:12:53 | "return ... + "];" | -| express.js:12:28:12:46 | req.param("wobble") | -| express.js:12:28:12:46 | req.param("wobble") | -| express.js:15:22:15:54 | req.par ... ction") | -| express.js:15:22:15:54 | req.par ... ction") | -| express.js:15:22:15:54 | req.par ... ction") | -| express.js:17:30:17:53 | req.par ... cript") | -| express.js:17:30:17:53 | req.par ... cript") | -| express.js:17:30:17:53 | req.par ... cript") | -| express.js:19:37:19:70 | req.par ... odule") | -| express.js:19:37:19:70 | req.par ... odule") | -| express.js:19:37:19:70 | req.par ... odule") | -| express.js:21:19:21:48 | req.par ... ntext") | -| express.js:21:19:21:48 | req.par ... ntext") | -| express.js:21:19:21:48 | req.par ... ntext") | -| express.js:26:9:26:35 | taint | -| express.js:26:17:26:35 | req.param("wobble") | -| express.js:26:17:26:35 | req.param("wobble") | -| express.js:27:34:27:38 | taint | -| express.js:27:34:27:38 | taint | -| express.js:34:9:34:35 | taint | -| express.js:34:17:34:35 | req.param("wobble") | -| express.js:34:17:34:35 | req.param("wobble") | -| express.js:43:15:43:19 | taint | -| express.js:43:15:43:19 | taint | -| express.js:49:30:49:32 | msg | -| express.js:49:30:49:32 | msg | -| express.js:50:10:50:12 | msg | -| express.js:50:10:50:12 | msg | -| module.js:9:16:9:29 | req.query.code | -| module.js:9:16:9:29 | req.query.code | -| module.js:9:16:9:29 | req.query.code | -| module.js:11:17:11:30 | req.query.code | -| module.js:11:17:11:30 | req.query.code | -| module.js:11:17:11:30 | req.query.code | -| react-native.js:7:7:7:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:8:32:8:38 | tainted | -| react-native.js:8:32:8:38 | tainted | -| react-native.js:10:23:10:29 | tainted | -| react-native.js:10:23:10:29 | tainted | -| react.js:10:56:10:77 | documen ... on.hash | -| react.js:10:56:10:77 | documen ... on.hash | -| react.js:10:56:10:77 | documen ... on.hash | -| template-sinks.js:18:9:18:31 | tainted | -| template-sinks.js:18:19:18:31 | req.query.foo | -| template-sinks.js:18:19:18:31 | req.query.foo | -| template-sinks.js:20:17:20:23 | tainted | -| template-sinks.js:20:17:20:23 | tainted | -| template-sinks.js:21:16:21:22 | tainted | -| template-sinks.js:21:16:21:22 | tainted | -| template-sinks.js:22:18:22:24 | tainted | -| template-sinks.js:22:18:22:24 | tainted | -| template-sinks.js:23:17:23:23 | tainted | -| template-sinks.js:23:17:23:23 | tainted | -| template-sinks.js:24:18:24:24 | tainted | -| template-sinks.js:24:18:24:24 | tainted | -| template-sinks.js:25:16:25:22 | tainted | -| template-sinks.js:25:16:25:22 | tainted | -| template-sinks.js:26:27:26:33 | tainted | -| template-sinks.js:26:27:26:33 | tainted | -| template-sinks.js:27:21:27:27 | tainted | -| template-sinks.js:27:21:27:27 | tainted | -| template-sinks.js:28:17:28:23 | tainted | -| template-sinks.js:28:17:28:23 | tainted | -| template-sinks.js:29:24:29:30 | tainted | -| template-sinks.js:29:24:29:30 | tainted | -| template-sinks.js:30:21:30:27 | tainted | -| template-sinks.js:30:21:30:27 | tainted | -| template-sinks.js:31:19:31:25 | tainted | -| template-sinks.js:31:19:31:25 | tainted | -| template-sinks.js:32:16:32:22 | tainted | -| template-sinks.js:32:16:32:22 | tainted | -| template-sinks.js:33:17:33:23 | tainted | -| template-sinks.js:33:17:33:23 | tainted | -| tst.js:2:6:2:27 | documen ... on.href | -| tst.js:2:6:2:27 | documen ... on.href | -| tst.js:2:6:2:83 | documen ... t=")+8) | -| tst.js:2:6:2:83 | documen ... t=")+8) | -| tst.js:5:12:5:33 | documen ... on.hash | -| tst.js:5:12:5:33 | documen ... on.hash | -| tst.js:5:12:5:33 | documen ... on.hash | -| tst.js:14:10:14:33 | documen ... .search | -| tst.js:14:10:14:33 | documen ... .search | -| tst.js:14:10:14:74 | documen ... , "$1") | -| tst.js:14:10:14:74 | documen ... , "$1") | -| tst.js:17:21:17:42 | documen ... on.hash | -| tst.js:17:21:17:42 | documen ... on.hash | -| tst.js:17:21:17:42 | documen ... on.hash | -| tst.js:20:30:20:51 | documen ... on.hash | -| tst.js:20:30:20:51 | documen ... on.hash | -| tst.js:20:30:20:51 | documen ... on.hash | -| tst.js:23:6:23:46 | atob(do ... ing(1)) | -| tst.js:23:6:23:46 | atob(do ... ing(1)) | -| tst.js:23:11:23:32 | documen ... on.hash | -| tst.js:23:11:23:32 | documen ... on.hash | -| tst.js:23:11:23:45 | documen ... ring(1) | -| tst.js:26:26:26:40 | location.search | -| tst.js:26:26:26:40 | location.search | -| tst.js:26:26:26:53 | locatio ... ring(1) | -| tst.js:26:26:26:53 | locatio ... ring(1) | -| tst.js:29:9:29:82 | source | -| tst.js:29:18:29:41 | documen ... .search | -| tst.js:29:18:29:41 | documen ... .search | -| tst.js:29:18:29:82 | documen ... , "$1") | -| tst.js:31:18:31:23 | source | -| tst.js:31:18:31:23 | source | -| tst.js:33:14:33:19 | source | -| tst.js:33:14:33:19 | source | -| tst.js:35:28:35:33 | source | -| tst.js:35:28:35:33 | source | -| tst.js:37:33:37:38 | source | -| tst.js:37:33:37:38 | source | -| webix/webix.html:3:16:3:37 | documen ... on.hash | -| webix/webix.html:3:16:3:37 | documen ... on.hash | -| webix/webix.html:3:16:3:37 | documen ... on.hash | -| webix/webix.html:4:26:4:47 | documen ... on.hash | -| webix/webix.html:4:26:4:47 | documen ... on.hash | -| webix/webix.html:4:26:4:47 | documen ... on.hash | -| webix/webix.html:5:47:5:68 | documen ... on.hash | -| webix/webix.html:5:47:5:68 | documen ... on.hash | -| webix/webix.html:5:47:5:68 | documen ... on.hash | -| webix/webix.js:3:12:3:33 | documen ... on.hash | -| webix/webix.js:3:12:3:33 | documen ... on.hash | -| webix/webix.js:3:12:3:33 | documen ... on.hash | -| webix/webix.js:4:22:4:43 | documen ... on.hash | -| webix/webix.js:4:22:4:43 | documen ... on.hash | -| webix/webix.js:4:22:4:43 | documen ... on.hash | -| webix/webix.js:5:43:5:64 | documen ... on.hash | -| webix/webix.js:5:43:5:64 | documen ... on.hash | -| webix/webix.js:5:43:5:64 | documen ... on.hash | edges | NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | -| NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | -| NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | -| NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | -| NoSQLCodeInjection.js:19:36:19:43 | req.body | NoSQLCodeInjection.js:19:36:19:48 | req.body.name | -| NoSQLCodeInjection.js:19:36:19:43 | req.body | NoSQLCodeInjection.js:19:36:19:48 | req.body.name | -| NoSQLCodeInjection.js:19:36:19:48 | req.body.name | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | -| NoSQLCodeInjection.js:19:36:19:48 | req.body.name | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | -| NoSQLCodeInjection.js:22:36:22:43 | req.body | NoSQLCodeInjection.js:22:36:22:48 | req.body.name | -| NoSQLCodeInjection.js:22:36:22:43 | req.body | NoSQLCodeInjection.js:22:36:22:48 | req.body.name | -| NoSQLCodeInjection.js:22:36:22:48 | req.body.name | NoSQLCodeInjection.js:22:24:22:48 | "name = ... dy.name | -| NoSQLCodeInjection.js:22:36:22:48 | req.body.name | NoSQLCodeInjection.js:22:24:22:48 | "name = ... dy.name | -| actions.js:4:10:4:50 | github. ... message | actions.js:4:10:4:50 | github. ... message | -| angularjs.js:10:22:10:36 | location.search | angularjs.js:10:22:10:36 | location.search | -| angularjs.js:13:23:13:37 | location.search | angularjs.js:13:23:13:37 | location.search | -| angularjs.js:16:28:16:42 | location.search | angularjs.js:16:28:16:42 | location.search | -| angularjs.js:19:22:19:36 | location.search | angularjs.js:19:22:19:36 | location.search | -| angularjs.js:22:27:22:41 | location.search | angularjs.js:22:27:22:41 | location.search | -| angularjs.js:25:23:25:37 | location.search | angularjs.js:25:23:25:37 | location.search | -| angularjs.js:28:33:28:47 | location.search | angularjs.js:28:33:28:47 | location.search | -| angularjs.js:31:28:31:42 | location.search | angularjs.js:31:28:31:42 | location.search | -| angularjs.js:34:18:34:32 | location.search | angularjs.js:34:18:34:32 | location.search | -| angularjs.js:40:18:40:32 | location.search | angularjs.js:40:18:40:32 | location.search | -| angularjs.js:44:17:44:31 | location.search | angularjs.js:44:17:44:31 | location.search | -| angularjs.js:47:16:47:30 | location.search | angularjs.js:47:16:47:30 | location.search | -| angularjs.js:50:22:50:36 | location.search | angularjs.js:50:22:50:36 | location.search | -| angularjs.js:53:32:53:46 | location.search | angularjs.js:53:32:53:46 | location.search | -| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | -| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | -| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | +| NoSQLCodeInjection.js:19:36:19:43 | req.body | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | +| NoSQLCodeInjection.js:22:36:22:43 | req.body | NoSQLCodeInjection.js:22:24:22:48 | "name = ... dy.name | | express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | | express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | -| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | -| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | -| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | | express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | -| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | -| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | -| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | -| express.js:15:22:15:54 | req.par ... ction") | express.js:15:22:15:54 | req.par ... ction") | -| express.js:17:30:17:53 | req.par ... cript") | express.js:17:30:17:53 | req.par ... cript") | -| express.js:19:37:19:70 | req.par ... odule") | express.js:19:37:19:70 | req.par ... odule") | -| express.js:21:19:21:48 | req.par ... ntext") | express.js:21:19:21:48 | req.par ... ntext") | -| express.js:26:9:26:35 | taint | express.js:27:34:27:38 | taint | | express.js:26:9:26:35 | taint | express.js:27:34:27:38 | taint | | express.js:26:17:26:35 | req.param("wobble") | express.js:26:9:26:35 | taint | -| express.js:26:17:26:35 | req.param("wobble") | express.js:26:9:26:35 | taint | -| express.js:34:9:34:35 | taint | express.js:43:15:43:19 | taint | | express.js:34:9:34:35 | taint | express.js:43:15:43:19 | taint | | express.js:34:17:34:35 | req.param("wobble") | express.js:34:9:34:35 | taint | -| express.js:34:17:34:35 | req.param("wobble") | express.js:34:9:34:35 | taint | | express.js:49:30:49:32 | msg | express.js:50:10:50:12 | msg | -| express.js:49:30:49:32 | msg | express.js:50:10:50:12 | msg | -| express.js:49:30:49:32 | msg | express.js:50:10:50:12 | msg | -| express.js:49:30:49:32 | msg | express.js:50:10:50:12 | msg | -| module.js:9:16:9:29 | req.query.code | module.js:9:16:9:29 | req.query.code | -| module.js:11:17:11:30 | req.query.code | module.js:11:17:11:30 | req.query.code | -| react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted | | react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted | | react-native.js:7:7:7:33 | tainted | react-native.js:10:23:10:29 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:10:23:10:29 | tainted | | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | -| react.js:10:56:10:77 | documen ... on.hash | react.js:10:56:10:77 | documen ... on.hash | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:20:17:20:23 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:20:17:20:23 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:21:16:21:22 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:21:16:21:22 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:22:18:22:24 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:22:18:22:24 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:23:17:23:23 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:23:17:23:23 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:24:18:24:24 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:24:18:24:24 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:25:16:25:22 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:25:16:25:22 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:26:27:26:33 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:26:27:26:33 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:27:21:27:27 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:27:21:27:27 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:28:17:28:23 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:28:17:28:23 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:29:24:29:30 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:29:24:29:30 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:30:21:30:27 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:30:21:30:27 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:31:19:31:25 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:31:19:31:25 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:32:16:32:22 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:32:16:32:22 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:33:17:33:23 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:33:17:33:23 | tainted | -| template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:18:9:18:31 | tainted | | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:18:9:18:31 | tainted | | tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | -| tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | -| tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | -| tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | -| tst.js:5:12:5:33 | documen ... on.hash | tst.js:5:12:5:33 | documen ... on.hash | | tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | -| tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | -| tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | -| tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | -| tst.js:17:21:17:42 | documen ... on.hash | tst.js:17:21:17:42 | documen ... on.hash | -| tst.js:20:30:20:51 | documen ... on.hash | tst.js:20:30:20:51 | documen ... on.hash | -| tst.js:23:11:23:32 | documen ... on.hash | tst.js:23:11:23:45 | documen ... ring(1) | | tst.js:23:11:23:32 | documen ... on.hash | tst.js:23:11:23:45 | documen ... ring(1) | | tst.js:23:11:23:45 | documen ... ring(1) | tst.js:23:6:23:46 | atob(do ... ing(1)) | -| tst.js:23:11:23:45 | documen ... ring(1) | tst.js:23:6:23:46 | atob(do ... ing(1)) | -| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | -| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | -| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | | tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | | tst.js:29:9:29:82 | source | tst.js:31:18:31:23 | source | -| tst.js:29:9:29:82 | source | tst.js:31:18:31:23 | source | -| tst.js:29:9:29:82 | source | tst.js:33:14:33:19 | source | | tst.js:29:9:29:82 | source | tst.js:33:14:33:19 | source | | tst.js:29:9:29:82 | source | tst.js:35:28:35:33 | source | -| tst.js:29:9:29:82 | source | tst.js:35:28:35:33 | source | | tst.js:29:9:29:82 | source | tst.js:37:33:37:38 | source | -| tst.js:29:9:29:82 | source | tst.js:37:33:37:38 | source | -| tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") | | tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") | | tst.js:29:18:29:82 | documen ... , "$1") | tst.js:29:9:29:82 | source | -| webix/webix.html:3:16:3:37 | documen ... on.hash | webix/webix.html:3:16:3:37 | documen ... on.hash | -| webix/webix.html:4:26:4:47 | documen ... on.hash | webix/webix.html:4:26:4:47 | documen ... on.hash | -| webix/webix.html:5:47:5:68 | documen ... on.hash | webix/webix.html:5:47:5:68 | documen ... on.hash | -| webix/webix.js:3:12:3:33 | documen ... on.hash | webix/webix.js:3:12:3:33 | documen ... on.hash | -| webix/webix.js:4:22:4:43 | documen ... on.hash | webix/webix.js:4:22:4:43 | documen ... on.hash | -| webix/webix.js:5:43:5:64 | documen ... on.hash | webix/webix.js:5:43:5:64 | documen ... on.hash | +nodes +| NoSQLCodeInjection.js:18:24:18:31 | req.body | semmle.label | req.body | +| NoSQLCodeInjection.js:18:24:18:37 | req.body.query | semmle.label | req.body.query | +| NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | semmle.label | "name = ... dy.name | +| NoSQLCodeInjection.js:19:36:19:43 | req.body | semmle.label | req.body | +| NoSQLCodeInjection.js:22:24:22:48 | "name = ... dy.name | semmle.label | "name = ... dy.name | +| NoSQLCodeInjection.js:22:36:22:43 | req.body | semmle.label | req.body | +| actions.js:4:10:4:50 | github. ... message | semmle.label | github. ... message | +| angularjs.js:10:22:10:36 | location.search | semmle.label | location.search | +| angularjs.js:13:23:13:37 | location.search | semmle.label | location.search | +| angularjs.js:16:28:16:42 | location.search | semmle.label | location.search | +| angularjs.js:19:22:19:36 | location.search | semmle.label | location.search | +| angularjs.js:22:27:22:41 | location.search | semmle.label | location.search | +| angularjs.js:25:23:25:37 | location.search | semmle.label | location.search | +| angularjs.js:28:33:28:47 | location.search | semmle.label | location.search | +| angularjs.js:31:28:31:42 | location.search | semmle.label | location.search | +| angularjs.js:34:18:34:32 | location.search | semmle.label | location.search | +| angularjs.js:40:18:40:32 | location.search | semmle.label | location.search | +| angularjs.js:44:17:44:31 | location.search | semmle.label | location.search | +| angularjs.js:47:16:47:30 | location.search | semmle.label | location.search | +| angularjs.js:50:22:50:36 | location.search | semmle.label | location.search | +| angularjs.js:53:32:53:46 | location.search | semmle.label | location.search | +| express.js:7:24:7:69 | "return ... + "];" | semmle.label | "return ... + "];" | +| express.js:7:44:7:62 | req.param("wobble") | semmle.label | req.param("wobble") | +| express.js:9:34:9:79 | "return ... + "];" | semmle.label | "return ... + "];" | +| express.js:9:54:9:72 | req.param("wobble") | semmle.label | req.param("wobble") | +| express.js:12:8:12:53 | "return ... + "];" | semmle.label | "return ... + "];" | +| express.js:12:28:12:46 | req.param("wobble") | semmle.label | req.param("wobble") | +| express.js:15:22:15:54 | req.par ... ction") | semmle.label | req.par ... ction") | +| express.js:17:30:17:53 | req.par ... cript") | semmle.label | req.par ... cript") | +| express.js:19:37:19:70 | req.par ... odule") | semmle.label | req.par ... odule") | +| express.js:21:19:21:48 | req.par ... ntext") | semmle.label | req.par ... ntext") | +| express.js:26:9:26:35 | taint | semmle.label | taint | +| express.js:26:17:26:35 | req.param("wobble") | semmle.label | req.param("wobble") | +| express.js:27:34:27:38 | taint | semmle.label | taint | +| express.js:34:9:34:35 | taint | semmle.label | taint | +| express.js:34:17:34:35 | req.param("wobble") | semmle.label | req.param("wobble") | +| express.js:43:15:43:19 | taint | semmle.label | taint | +| express.js:49:30:49:32 | msg | semmle.label | msg | +| express.js:50:10:50:12 | msg | semmle.label | msg | +| module.js:9:16:9:29 | req.query.code | semmle.label | req.query.code | +| module.js:11:17:11:30 | req.query.code | semmle.label | req.query.code | +| react-native.js:7:7:7:33 | tainted | semmle.label | tainted | +| react-native.js:7:17:7:33 | req.param("code") | semmle.label | req.param("code") | +| react-native.js:8:32:8:38 | tainted | semmle.label | tainted | +| react-native.js:10:23:10:29 | tainted | semmle.label | tainted | +| react.js:10:56:10:77 | documen ... on.hash | semmle.label | documen ... on.hash | +| template-sinks.js:18:9:18:31 | tainted | semmle.label | tainted | +| template-sinks.js:18:19:18:31 | req.query.foo | semmle.label | req.query.foo | +| template-sinks.js:20:17:20:23 | tainted | semmle.label | tainted | +| template-sinks.js:21:16:21:22 | tainted | semmle.label | tainted | +| template-sinks.js:22:18:22:24 | tainted | semmle.label | tainted | +| template-sinks.js:23:17:23:23 | tainted | semmle.label | tainted | +| template-sinks.js:24:18:24:24 | tainted | semmle.label | tainted | +| template-sinks.js:25:16:25:22 | tainted | semmle.label | tainted | +| template-sinks.js:26:27:26:33 | tainted | semmle.label | tainted | +| template-sinks.js:27:21:27:27 | tainted | semmle.label | tainted | +| template-sinks.js:28:17:28:23 | tainted | semmle.label | tainted | +| template-sinks.js:29:24:29:30 | tainted | semmle.label | tainted | +| template-sinks.js:30:21:30:27 | tainted | semmle.label | tainted | +| template-sinks.js:31:19:31:25 | tainted | semmle.label | tainted | +| template-sinks.js:32:16:32:22 | tainted | semmle.label | tainted | +| template-sinks.js:33:17:33:23 | tainted | semmle.label | tainted | +| tst.js:2:6:2:27 | documen ... on.href | semmle.label | documen ... on.href | +| tst.js:2:6:2:83 | documen ... t=")+8) | semmle.label | documen ... t=")+8) | +| tst.js:5:12:5:33 | documen ... on.hash | semmle.label | documen ... on.hash | +| tst.js:14:10:14:33 | documen ... .search | semmle.label | documen ... .search | +| tst.js:14:10:14:74 | documen ... , "$1") | semmle.label | documen ... , "$1") | +| tst.js:17:21:17:42 | documen ... on.hash | semmle.label | documen ... on.hash | +| tst.js:20:30:20:51 | documen ... on.hash | semmle.label | documen ... on.hash | +| tst.js:23:6:23:46 | atob(do ... ing(1)) | semmle.label | atob(do ... ing(1)) | +| tst.js:23:11:23:32 | documen ... on.hash | semmle.label | documen ... on.hash | +| tst.js:23:11:23:45 | documen ... ring(1) | semmle.label | documen ... ring(1) | +| tst.js:26:26:26:40 | location.search | semmle.label | location.search | +| tst.js:26:26:26:53 | locatio ... ring(1) | semmle.label | locatio ... ring(1) | +| tst.js:29:9:29:82 | source | semmle.label | source | +| tst.js:29:18:29:41 | documen ... .search | semmle.label | documen ... .search | +| tst.js:29:18:29:82 | documen ... , "$1") | semmle.label | documen ... , "$1") | +| tst.js:31:18:31:23 | source | semmle.label | source | +| tst.js:33:14:33:19 | source | semmle.label | source | +| tst.js:35:28:35:33 | source | semmle.label | source | +| tst.js:37:33:37:38 | source | semmle.label | source | +| webix/webix.html:3:16:3:37 | documen ... on.hash | semmle.label | documen ... on.hash | +| webix/webix.html:4:26:4:47 | documen ... on.hash | semmle.label | documen ... on.hash | +| webix/webix.html:5:47:5:68 | documen ... on.hash | semmle.label | documen ... on.hash | +| webix/webix.js:3:12:3:33 | documen ... on.hash | semmle.label | documen ... on.hash | +| webix/webix.js:4:22:4:43 | documen ... on.hash | semmle.label | documen ... on.hash | +| webix/webix.js:5:43:5:64 | documen ... on.hash | semmle.label | documen ... on.hash | +subpaths #select | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | This code execution depends on a $@. | NoSQLCodeInjection.js:18:24:18:31 | req.body | user-provided value | | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | NoSQLCodeInjection.js:19:36:19:43 | req.body | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | This code execution depends on a $@. | NoSQLCodeInjection.js:19:36:19:43 | req.body | user-provided value | From 65e9706c8e6e9e423eb43a1ddb4ac326bbcb8172 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:22:38 +0200 Subject: [PATCH 045/514] JS: Port TaintedPath --- .../dataflow/TaintedPathCustomizations.qll | 57 +- .../security/dataflow/TaintedPathQuery.qll | 41 +- .../ql/src/Security/CWE-022/TaintedPath.ql | 6 +- .../CWE-022/TaintedPath/Consistency.ql | 6 + .../CWE-022/TaintedPath/TaintedPath.expected | 10420 +--------------- .../CWE-022/TaintedPath/other-fs-libraries.js | 4 + .../CWE-022/TaintedPath/sharedlib-repro.js | 35 + .../TaintedPath/tainted-promise-steps.js | 15 + 8 files changed, 655 insertions(+), 9929 deletions(-) create mode 100644 javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/sharedlib-repro.js create mode 100644 javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/tainted-promise-steps.js diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll index cd1bb80fce4..77227841c42 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll @@ -31,7 +31,28 @@ module TaintedPath { /** * A barrier guard for tainted-path vulnerabilities. */ - abstract class BarrierGuardNode extends DataFlow::LabeledBarrierGuardNode { } + 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) + } + } + + deprecated class BarrierGuardNode = BarrierGuard; module Label { /** @@ -345,10 +366,10 @@ module TaintedPath { * * This is relevant for paths that are known to be normalized. */ - class StartsWithDotDotSanitizer extends BarrierGuardNode instanceof StringOps::StartsWith { + class StartsWithDotDotSanitizer extends BarrierGuard instanceof StringOps::StartsWith { StartsWithDotDotSanitizer() { isDotDotSlashPrefix(super.getSubstring()) } - override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel label) { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { // Sanitize in the false case for: // .startsWith(".") // .startsWith("..") @@ -365,12 +386,12 @@ module TaintedPath { /** * A check of the form `whitelist.includes(x)` or equivalent, which sanitizes `x` in its "then" branch. */ - class MembershipTestBarrierGuard extends BarrierGuardNode { + class MembershipTestBarrierGuard extends BarrierGuard { MembershipCandidate candidate; MembershipTestBarrierGuard() { this = candidate.getTest() } - override predicate blocks(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { candidate = e.flow() and candidate.getTestPolarity() = outcome } @@ -380,7 +401,7 @@ module TaintedPath { * A check of form `x.startsWith(dir)` that sanitizes normalized absolute paths, since it is then * known to be in a subdirectory of `dir`. */ - class StartsWithDirSanitizer extends BarrierGuardNode { + class StartsWithDirSanitizer extends BarrierGuard { StringOps::StartsWith startsWith; StartsWithDirSanitizer() { @@ -390,7 +411,7 @@ module TaintedPath { not startsWith.getSubstring().getStringValue() = "/" } - override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel label) { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { outcome = startsWith.getPolarity() and e = startsWith.getBaseString().asExpr() and exists(Label::PosixPath posixPath | posixPath = label | @@ -404,7 +425,7 @@ module TaintedPath { * A call to `path.isAbsolute` as a sanitizer for relative paths in true branch, * and a sanitizer for absolute paths in the false branch. */ - class IsAbsoluteSanitizer extends BarrierGuardNode { + class IsAbsoluteSanitizer extends BarrierGuard { DataFlow::Node operand; boolean polarity; boolean negatable; @@ -425,7 +446,7 @@ module TaintedPath { ) // !x.startsWith("/home") does not guarantee that x is not absolute } - override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel label) { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { e = operand.asExpr() and exists(Label::PosixPath posixPath | posixPath = label | outcome = polarity and posixPath.isRelative() @@ -440,10 +461,10 @@ module TaintedPath { /** * An expression of form `x.includes("..")` or similar. */ - class ContainsDotDotSanitizer extends BarrierGuardNode instanceof StringOps::Includes { + class ContainsDotDotSanitizer extends BarrierGuard instanceof StringOps::Includes { ContainsDotDotSanitizer() { isDotDotSlashPrefix(super.getSubstring()) } - override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel label) { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { e = super.getBaseString().asExpr() and outcome = super.getPolarity().booleanNot() and label.(Label::PosixPath).canContainDotDotSlash() // can still be bypassed by normalized absolute path @@ -453,10 +474,10 @@ module TaintedPath { /** * An expression of form `x.matches(/\.\./)` or similar. */ - class ContainsDotDotRegExpSanitizer extends BarrierGuardNode instanceof StringOps::RegExpTest { + class ContainsDotDotRegExpSanitizer extends BarrierGuard instanceof StringOps::RegExpTest { ContainsDotDotRegExpSanitizer() { super.getRegExp().getAMatchedString() = [".", "..", "../"] } - override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel label) { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { e = super.getStringOperand().asExpr() and outcome = super.getPolarity().booleanNot() and label.(Label::PosixPath).canContainDotDotSlash() // can still be bypassed by normalized absolute path @@ -484,7 +505,7 @@ module TaintedPath { * } * ``` */ - class RelativePathStartsWithSanitizer extends BarrierGuardNode { + class RelativePathStartsWithSanitizer extends BarrierGuard { StringOps::StartsWith startsWith; DataFlow::CallNode pathCall; string member; @@ -506,7 +527,7 @@ module TaintedPath { (not member = "relative" or isDotDotSlashPrefix(startsWith.getSubstring())) } - override predicate blocks(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { member = "relative" and e = this.maybeGetPathSuffix(pathCall.getArgument(1)).asExpr() and outcome = startsWith.getPolarity().booleanNot() @@ -542,7 +563,7 @@ module TaintedPath { * An expression of form `isInside(x, y)` or similar, where `isInside` is * a library check for the relation between `x` and `y`. */ - class IsInsideCheckSanitizer extends BarrierGuardNode { + class IsInsideCheckSanitizer extends BarrierGuard { DataFlow::Node checked; boolean onlyNormalizedAbsolutePaths; @@ -558,7 +579,7 @@ module TaintedPath { ) } - override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel label) { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { ( onlyNormalizedAbsolutePaths = true and label.(Label::PosixPath).isNormalized() and @@ -750,8 +771,6 @@ module TaintedPath { ) ) or - TaintTracking::promiseStep(src, dst) and srclabel = dstlabel - or TaintTracking::persistentStorageStep(src, dst) and srclabel = dstlabel or exists(DataFlow::PropRead read | read = dst | diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathQuery.qll index 914c63543f5..365a784bd9d 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathQuery.qll @@ -8,7 +8,7 @@ */ import javascript -import TaintedPathCustomizations::TaintedPath +private import TaintedPathCustomizations::TaintedPath // Materialize flow labels private class ConcretePosixPath extends Label::PosixPath { @@ -22,7 +22,44 @@ private class ConcreteSplitPath extends Label::SplitPath { /** * A taint-tracking configuration for reasoning about tainted-path vulnerabilities. */ -class Configuration extends DataFlow::Configuration { +module TaintedPathConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; + + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel state) { + state = source.(Source).getAFlowLabel() + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel state) { + state = sink.(Sink).getAFlowLabel() + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel label) { + node instanceof Sanitizer and exists(label) + or + node = DataFlow::MakeLabeledBarrierGuard::getABarrierNode(label) + } + + predicate isBarrier(DataFlow::Node node) { + node = DataFlow::MakeBarrierGuard::getABarrierNode() + } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowLabel state1, DataFlow::Node node2, + DataFlow::FlowLabel state2 + ) { + isAdditionalTaintedPathFlowStep(node1, node2, state1, state2) + } +} + +/** + * Taint-tracking for reasoning about tainted-path vulnerabilities. + */ +module TaintedPathFlow = DataFlow::GlobalWithState; + +/** + * DEPRECATED. Use the `TaintedPathFlow` module instead. + */ +deprecated class Configuration extends DataFlow::Configuration { Configuration() { this = "TaintedPath" } override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { diff --git a/javascript/ql/src/Security/CWE-022/TaintedPath.ql b/javascript/ql/src/Security/CWE-022/TaintedPath.ql index e3ea395c480..b5864519932 100644 --- a/javascript/ql/src/Security/CWE-022/TaintedPath.ql +++ b/javascript/ql/src/Security/CWE-022/TaintedPath.ql @@ -17,9 +17,9 @@ import javascript import semmle.javascript.security.dataflow.TaintedPathQuery -import DataFlow::PathGraph +import DataFlow::DeduplicatePathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from PathNode source, PathNode sink +where TaintedPathFlow::flowPath(source.getAnOriginalPathNode(), sink.getAnOriginalPathNode()) select sink.getNode(), source, sink, "This path depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.ql index d5230981801..fae97fdf6d0 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.ql @@ -1,3 +1,9 @@ import javascript import semmle.javascript.security.dataflow.TaintedPathQuery import testUtilities.ConsistencyChecking + +class TaintedPathConsistency extends ConsistencyConfiguration { + TaintedPathConsistency() { this = "TaintedPathConsistency" } + + override DataFlow::Node getAnAlert() { TaintedPathFlow::flowTo(result) } +} diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected index 2d1692dce00..66decf408d2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected @@ -1,10305 +1,911 @@ nodes -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:20:7:26 | req.url | -| TaintedPath-es6.js:7:20:7:26 | req.url | -| TaintedPath-es6.js:7:20:7:26 | req.url | -| TaintedPath-es6.js:7:20:7:26 | req.url | -| TaintedPath-es6.js:7:20:7:26 | req.url | -| TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:24:9:30 | req.url | -| TaintedPath.js:9:24:9:30 | req.url | -| TaintedPath.js:9:24:9:30 | req.url | -| TaintedPath.js:9:24:9:30 | req.url | -| TaintedPath.js:9:24:9:30 | req.url | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:20:38:26 | req.url | -| TaintedPath.js:38:20:38:26 | req.url | -| TaintedPath.js:38:20:38:26 | req.url | -| TaintedPath.js:38:20:38:26 | req.url | -| TaintedPath.js:38:20:38:26 | req.url | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:63:77:69 | req.url | -| TaintedPath.js:77:63:77:69 | req.url | -| TaintedPath.js:77:63:77:69 | req.url | -| TaintedPath.js:77:63:77:69 | req.url | -| TaintedPath.js:77:63:77:69 | req.url | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:61:78:67 | req.url | -| TaintedPath.js:78:61:78:67 | req.url | -| TaintedPath.js:78:61:78:67 | req.url | -| TaintedPath.js:78:61:78:67 | req.url | -| TaintedPath.js:78:61:78:67 | req.url | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:60:79:66 | req.url | -| TaintedPath.js:79:60:79:66 | req.url | -| TaintedPath.js:79:60:79:66 | req.url | -| TaintedPath.js:79:60:79:66 | req.url | -| TaintedPath.js:79:60:79:66 | req.url | -| TaintedPath.js:87:48:87:60 | req.params[0] | -| TaintedPath.js:87:48:87:60 | req.params[0] | -| TaintedPath.js:87:48:87:60 | req.params[0] | -| TaintedPath.js:87:48:87:60 | req.params[0] | -| TaintedPath.js:87:48:87:60 | req.params[0] | -| TaintedPath.js:87:48:87:60 | req.params[0] | -| TaintedPath.js:95:30:95:31 | ev | -| TaintedPath.js:95:30:95:31 | ev | -| TaintedPath.js:95:30:95:31 | ev | -| TaintedPath.js:95:30:95:31 | ev | -| TaintedPath.js:95:30:95:31 | ev | -| TaintedPath.js:96:24:96:25 | ev | -| TaintedPath.js:96:24:96:25 | ev | -| TaintedPath.js:96:24:96:25 | ev | -| TaintedPath.js:96:24:96:25 | ev | -| TaintedPath.js:96:24:96:30 | ev.data | -| TaintedPath.js:96:24:96:30 | ev.data | -| TaintedPath.js:96:24:96:30 | ev.data | -| TaintedPath.js:96:24:96:30 | ev.data | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:23:100:29 | req.url | -| TaintedPath.js:100:23:100:29 | req.url | -| TaintedPath.js:100:23:100:29 | req.url | -| TaintedPath.js:100:23:100:29 | req.url | -| TaintedPath.js:100:23:100:29 | req.url | -| TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:23:136:29 | req.url | -| TaintedPath.js:136:23:136:29 | req.url | -| TaintedPath.js:136:23:136:29 | req.url | -| TaintedPath.js:136:23:136:29 | req.url | -| TaintedPath.js:136:23:136:29 | req.url | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:24:142:30 | req.url | -| TaintedPath.js:142:24:142:30 | req.url | -| TaintedPath.js:142:24:142:30 | req.url | -| TaintedPath.js:142:24:142:30 | req.url | -| TaintedPath.js:142:24:142:30 | req.url | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:146:7:146:29 | split | -| TaintedPath.js:146:7:146:29 | split | -| TaintedPath.js:146:7:146:29 | split | -| TaintedPath.js:146:7:146:29 | split | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:148:19:148:23 | split | -| TaintedPath.js:148:19:148:23 | split | -| TaintedPath.js:148:19:148:23 | split | -| TaintedPath.js:148:19:148:23 | split | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:152:19:152:23 | split | -| TaintedPath.js:152:19:152:23 | split | -| TaintedPath.js:152:19:152:23 | split | -| TaintedPath.js:152:19:152:23 | split | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:32 | split | -| TaintedPath.js:153:28:153:32 | split | -| TaintedPath.js:153:28:153:32 | split | -| TaintedPath.js:153:28:153:32 | split | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:155:7:155:38 | concatted | -| TaintedPath.js:155:7:155:38 | concatted | -| TaintedPath.js:155:7:155:38 | concatted | -| TaintedPath.js:155:7:155:38 | concatted | -| TaintedPath.js:155:19:155:38 | prefix.concat(split) | -| TaintedPath.js:155:19:155:38 | prefix.concat(split) | -| TaintedPath.js:155:19:155:38 | prefix.concat(split) | -| TaintedPath.js:155:19:155:38 | prefix.concat(split) | -| TaintedPath.js:155:33:155:37 | split | -| TaintedPath.js:155:33:155:37 | split | -| TaintedPath.js:155:33:155:37 | split | -| TaintedPath.js:155:33:155:37 | split | -| TaintedPath.js:156:19:156:27 | concatted | -| TaintedPath.js:156:19:156:27 | concatted | -| TaintedPath.js:156:19:156:27 | concatted | -| TaintedPath.js:156:19:156:27 | concatted | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:158:7:158:39 | concatted2 | -| TaintedPath.js:158:7:158:39 | concatted2 | -| TaintedPath.js:158:7:158:39 | concatted2 | -| TaintedPath.js:158:7:158:39 | concatted2 | -| TaintedPath.js:158:20:158:24 | split | -| TaintedPath.js:158:20:158:24 | split | -| TaintedPath.js:158:20:158:24 | split | -| TaintedPath.js:158:20:158:24 | split | -| TaintedPath.js:158:20:158:39 | split.concat(prefix) | -| TaintedPath.js:158:20:158:39 | split.concat(prefix) | -| TaintedPath.js:158:20:158:39 | split.concat(prefix) | -| TaintedPath.js:158:20:158:39 | split.concat(prefix) | -| TaintedPath.js:159:19:159:28 | concatted2 | -| TaintedPath.js:159:19:159:28 | concatted2 | -| TaintedPath.js:159:19:159:28 | concatted2 | -| TaintedPath.js:159:19:159:28 | concatted2 | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:161:19:161:23 | split | -| TaintedPath.js:161:19:161:23 | split | -| TaintedPath.js:161:19:161:23 | split | -| TaintedPath.js:161:19:161:23 | split | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:24:166:30 | req.url | -| TaintedPath.js:166:24:166:30 | req.url | -| TaintedPath.js:166:24:166:30 | req.url | -| TaintedPath.js:166:24:166:30 | req.url | -| TaintedPath.js:166:24:166:30 | req.url | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | -| TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:38:203:44 | req.url | -| TaintedPath.js:203:38:203:44 | req.url | -| TaintedPath.js:203:38:203:44 | req.url | -| TaintedPath.js:203:38:203:44 | req.url | -| TaintedPath.js:203:38:203:44 | req.url | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | -| TaintedPath.js:204:51:204:57 | req.url | -| TaintedPath.js:204:51:204:57 | req.url | -| TaintedPath.js:204:51:204:57 | req.url | -| TaintedPath.js:204:51:204:57 | req.url | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:44:206:50 | req.url | -| TaintedPath.js:206:44:206:50 | req.url | -| TaintedPath.js:206:44:206:50 | req.url | -| TaintedPath.js:206:44:206:50 | req.url | -| TaintedPath.js:206:44:206:50 | req.url | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:24:211:30 | req.url | -| TaintedPath.js:211:24:211:30 | req.url | -| TaintedPath.js:211:24:211:30 | req.url | -| TaintedPath.js:211:24:211:30 | req.url | -| TaintedPath.js:211:24:211:30 | req.url | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| express.js:8:20:8:32 | req.query.bar | -| express.js:8:20:8:32 | req.query.bar | -| express.js:8:20:8:32 | req.query.bar | -| express.js:8:20:8:32 | req.query.bar | -| express.js:8:20:8:32 | req.query.bar | -| express.js:8:20:8:32 | req.query.bar | -| handlebars.js:10:51:10:58 | filePath | -| handlebars.js:10:51:10:58 | filePath | -| handlebars.js:10:51:10:58 | filePath | -| handlebars.js:10:51:10:58 | filePath | -| handlebars.js:11:32:11:39 | filePath | -| handlebars.js:11:32:11:39 | filePath | -| handlebars.js:11:32:11:39 | filePath | -| handlebars.js:11:32:11:39 | filePath | -| handlebars.js:11:32:11:39 | filePath | -| handlebars.js:13:73:13:80 | filePath | -| handlebars.js:13:73:13:80 | filePath | -| handlebars.js:13:73:13:80 | filePath | -| handlebars.js:13:73:13:80 | filePath | -| handlebars.js:15:25:15:32 | filePath | -| handlebars.js:15:25:15:32 | filePath | -| handlebars.js:15:25:15:32 | filePath | -| handlebars.js:15:25:15:32 | filePath | -| handlebars.js:15:25:15:32 | filePath | -| handlebars.js:29:46:29:60 | req.params.path | -| handlebars.js:29:46:29:60 | req.params.path | -| handlebars.js:29:46:29:60 | req.params.path | -| handlebars.js:29:46:29:60 | req.params.path | -| handlebars.js:29:46:29:60 | req.params.path | -| handlebars.js:43:15:43:29 | req.params.path | -| handlebars.js:43:15:43:29 | req.params.path | -| handlebars.js:43:15:43:29 | req.params.path | -| handlebars.js:43:15:43:29 | req.params.path | -| handlebars.js:43:15:43:29 | req.params.path | -| normalizedPaths.js:11:7:11:27 | path | -| normalizedPaths.js:11:7:11:27 | path | -| normalizedPaths.js:11:7:11:27 | path | -| normalizedPaths.js:11:7:11:27 | path | -| normalizedPaths.js:11:14:11:27 | req.query.path | -| normalizedPaths.js:11:14:11:27 | req.query.path | -| normalizedPaths.js:11:14:11:27 | req.query.path | -| normalizedPaths.js:11:14:11:27 | req.query.path | -| normalizedPaths.js:11:14:11:27 | req.query.path | -| normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:14:19:14:29 | './' + path | -| normalizedPaths.js:14:19:14:29 | './' + path | -| normalizedPaths.js:14:19:14:29 | './' + path | -| normalizedPaths.js:14:19:14:29 | './' + path | -| normalizedPaths.js:14:26:14:29 | path | -| normalizedPaths.js:14:26:14:29 | path | -| normalizedPaths.js:14:26:14:29 | path | -| normalizedPaths.js:15:19:15:22 | path | -| normalizedPaths.js:15:19:15:22 | path | -| normalizedPaths.js:15:19:15:22 | path | -| normalizedPaths.js:15:19:15:22 | path | -| normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:16:35:16:38 | path | -| normalizedPaths.js:16:35:16:38 | path | -| normalizedPaths.js:16:35:16:38 | path | -| normalizedPaths.js:16:35:16:38 | path | -| normalizedPaths.js:17:19:17:57 | pathMod ... , path) | -| normalizedPaths.js:17:19:17:57 | pathMod ... , path) | -| normalizedPaths.js:17:19:17:57 | pathMod ... , path) | -| normalizedPaths.js:17:19:17:57 | pathMod ... , path) | -| normalizedPaths.js:17:53:17:56 | path | -| normalizedPaths.js:17:53:17:56 | path | -| normalizedPaths.js:17:53:17:56 | path | -| normalizedPaths.js:21:7:21:49 | path | -| normalizedPaths.js:21:7:21:49 | path | -| normalizedPaths.js:21:7:21:49 | path | -| normalizedPaths.js:21:7:21:49 | path | -| normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:21:35:21:48 | req.query.path | -| normalizedPaths.js:21:35:21:48 | req.query.path | -| normalizedPaths.js:21:35:21:48 | req.query.path | -| normalizedPaths.js:21:35:21:48 | req.query.path | -| normalizedPaths.js:21:35:21:48 | req.query.path | -| normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:24:19:24:29 | './' + path | -| normalizedPaths.js:24:19:24:29 | './' + path | -| normalizedPaths.js:24:19:24:29 | './' + path | -| normalizedPaths.js:24:26:24:29 | path | -| normalizedPaths.js:24:26:24:29 | path | -| normalizedPaths.js:25:19:25:22 | path | -| normalizedPaths.js:25:19:25:22 | path | -| normalizedPaths.js:25:19:25:22 | path | -| normalizedPaths.js:25:19:25:22 | path | -| normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:26:35:26:38 | path | -| normalizedPaths.js:26:35:26:38 | path | -| normalizedPaths.js:26:35:26:38 | path | -| normalizedPaths.js:26:35:26:38 | path | -| normalizedPaths.js:27:19:27:57 | pathMod ... , path) | -| normalizedPaths.js:27:19:27:57 | pathMod ... , path) | -| normalizedPaths.js:27:19:27:57 | pathMod ... , path) | -| normalizedPaths.js:27:53:27:56 | path | -| normalizedPaths.js:27:53:27:56 | path | -| normalizedPaths.js:31:7:31:49 | path | -| normalizedPaths.js:31:7:31:49 | path | -| normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | -| normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | -| normalizedPaths.js:31:35:31:48 | req.query.path | -| normalizedPaths.js:31:35:31:48 | req.query.path | -| normalizedPaths.js:31:35:31:48 | req.query.path | -| normalizedPaths.js:36:19:36:22 | path | -| normalizedPaths.js:36:19:36:22 | path | -| normalizedPaths.js:36:19:36:22 | path | -| normalizedPaths.js:41:21:41:24 | path | -| normalizedPaths.js:41:21:41:24 | path | -| normalizedPaths.js:41:21:41:24 | path | -| normalizedPaths.js:54:7:54:49 | path | -| normalizedPaths.js:54:7:54:49 | path | -| normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | -| normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | -| normalizedPaths.js:54:35:54:48 | req.query.path | -| normalizedPaths.js:54:35:54:48 | req.query.path | -| normalizedPaths.js:54:35:54:48 | req.query.path | -| normalizedPaths.js:59:19:59:22 | path | -| normalizedPaths.js:59:19:59:22 | path | -| normalizedPaths.js:59:19:59:22 | path | -| normalizedPaths.js:63:19:63:22 | path | -| normalizedPaths.js:63:19:63:22 | path | -| normalizedPaths.js:63:19:63:38 | path + "/index.html" | -| normalizedPaths.js:63:19:63:38 | path + "/index.html" | -| normalizedPaths.js:63:19:63:38 | path + "/index.html" | -| normalizedPaths.js:68:21:68:24 | path | -| normalizedPaths.js:68:21:68:24 | path | -| normalizedPaths.js:68:21:68:24 | path | -| normalizedPaths.js:73:7:73:56 | path | -| normalizedPaths.js:73:7:73:56 | path | -| normalizedPaths.js:73:7:73:56 | path | -| normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | -| normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | -| normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | -| normalizedPaths.js:73:35:73:55 | './' + ... ry.path | -| normalizedPaths.js:73:35:73:55 | './' + ... ry.path | -| normalizedPaths.js:73:35:73:55 | './' + ... ry.path | -| normalizedPaths.js:73:42:73:55 | req.query.path | -| normalizedPaths.js:73:42:73:55 | req.query.path | -| normalizedPaths.js:73:42:73:55 | req.query.path | -| normalizedPaths.js:73:42:73:55 | req.query.path | -| normalizedPaths.js:78:22:78:25 | path | -| normalizedPaths.js:78:22:78:25 | path | -| normalizedPaths.js:78:22:78:25 | path | -| normalizedPaths.js:78:22:78:25 | path | -| normalizedPaths.js:82:7:82:27 | path | -| normalizedPaths.js:82:7:82:27 | path | -| normalizedPaths.js:82:14:82:27 | req.query.path | -| normalizedPaths.js:82:14:82:27 | req.query.path | -| normalizedPaths.js:82:14:82:27 | req.query.path | -| normalizedPaths.js:87:29:87:32 | path | -| normalizedPaths.js:87:29:87:32 | path | -| normalizedPaths.js:87:29:87:32 | path | -| normalizedPaths.js:90:31:90:34 | path | -| normalizedPaths.js:90:31:90:34 | path | -| normalizedPaths.js:94:7:94:49 | path | -| normalizedPaths.js:94:7:94:49 | path | -| normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | -| normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | -| normalizedPaths.js:94:35:94:48 | req.query.path | -| normalizedPaths.js:94:35:94:48 | req.query.path | -| normalizedPaths.js:94:35:94:48 | req.query.path | -| normalizedPaths.js:99:29:99:32 | path | -| normalizedPaths.js:99:29:99:32 | path | -| normalizedPaths.js:99:29:99:32 | path | -| normalizedPaths.js:117:7:117:44 | path | -| normalizedPaths.js:117:7:117:44 | path | -| normalizedPaths.js:117:7:117:44 | path | -| normalizedPaths.js:117:7:117:44 | path | -| normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | -| normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | -| normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | -| normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | -| normalizedPaths.js:117:30:117:43 | req.query.path | -| normalizedPaths.js:117:30:117:43 | req.query.path | -| normalizedPaths.js:117:30:117:43 | req.query.path | -| normalizedPaths.js:117:30:117:43 | req.query.path | -| normalizedPaths.js:117:30:117:43 | req.query.path | -| normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:35:120:38 | path | -| normalizedPaths.js:120:35:120:38 | path | -| normalizedPaths.js:120:35:120:38 | path | -| normalizedPaths.js:120:35:120:38 | path | -| normalizedPaths.js:130:7:130:49 | path | -| normalizedPaths.js:130:7:130:49 | path | -| normalizedPaths.js:130:7:130:49 | path | -| normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | -| normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | -| normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | -| normalizedPaths.js:130:35:130:48 | req.query.path | -| normalizedPaths.js:130:35:130:48 | req.query.path | -| normalizedPaths.js:130:35:130:48 | req.query.path | -| normalizedPaths.js:130:35:130:48 | req.query.path | -| normalizedPaths.js:135:21:135:24 | path | -| normalizedPaths.js:135:21:135:24 | path | -| normalizedPaths.js:135:21:135:24 | path | -| normalizedPaths.js:135:21:135:24 | path | -| normalizedPaths.js:139:7:139:62 | path | -| normalizedPaths.js:139:7:139:62 | path | -| normalizedPaths.js:139:7:139:62 | path | -| normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | -| normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | -| normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | -| normalizedPaths.js:139:48:139:61 | req.query.path | -| normalizedPaths.js:139:48:139:61 | req.query.path | -| normalizedPaths.js:139:48:139:61 | req.query.path | -| normalizedPaths.js:139:48:139:61 | req.query.path | -| normalizedPaths.js:144:21:144:24 | path | -| normalizedPaths.js:144:21:144:24 | path | -| normalizedPaths.js:144:21:144:24 | path | -| normalizedPaths.js:144:21:144:24 | path | -| normalizedPaths.js:148:7:148:58 | path | -| normalizedPaths.js:148:7:148:58 | path | -| normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | -| normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | -| normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | -| normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | -| normalizedPaths.js:148:44:148:57 | req.query.path | -| normalizedPaths.js:148:44:148:57 | req.query.path | -| normalizedPaths.js:148:44:148:57 | req.query.path | -| normalizedPaths.js:151:21:151:24 | path | -| normalizedPaths.js:151:21:151:24 | path | -| normalizedPaths.js:151:21:151:24 | path | -| normalizedPaths.js:153:21:153:24 | path | -| normalizedPaths.js:153:21:153:24 | path | -| normalizedPaths.js:153:21:153:24 | path | -| normalizedPaths.js:160:7:160:49 | path | -| normalizedPaths.js:160:7:160:49 | path | -| normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | -| normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | -| normalizedPaths.js:160:35:160:48 | req.query.path | -| normalizedPaths.js:160:35:160:48 | req.query.path | -| normalizedPaths.js:160:35:160:48 | req.query.path | -| normalizedPaths.js:165:19:165:22 | path | -| normalizedPaths.js:165:19:165:22 | path | -| normalizedPaths.js:165:19:165:22 | path | -| normalizedPaths.js:170:21:170:24 | path | -| normalizedPaths.js:170:21:170:24 | path | -| normalizedPaths.js:170:21:170:24 | path | -| normalizedPaths.js:174:7:174:27 | path | -| normalizedPaths.js:174:7:174:27 | path | -| normalizedPaths.js:174:7:174:27 | path | -| normalizedPaths.js:174:7:174:27 | path | -| normalizedPaths.js:174:14:174:27 | req.query.path | -| normalizedPaths.js:174:14:174:27 | req.query.path | -| normalizedPaths.js:174:14:174:27 | req.query.path | -| normalizedPaths.js:174:14:174:27 | req.query.path | -| normalizedPaths.js:174:14:174:27 | req.query.path | -| normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:187:21:187:24 | path | -| normalizedPaths.js:187:21:187:24 | path | -| normalizedPaths.js:187:21:187:24 | path | -| normalizedPaths.js:189:21:189:24 | path | -| normalizedPaths.js:189:21:189:24 | path | -| normalizedPaths.js:189:21:189:24 | path | -| normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:194:21:194:24 | path | -| normalizedPaths.js:194:21:194:24 | path | -| normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:201:7:201:49 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | -| normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | -| normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | -| normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | -| normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | -| normalizedPaths.js:201:45:201:48 | path | -| normalizedPaths.js:201:45:201:48 | path | -| normalizedPaths.js:201:45:201:48 | path | -| normalizedPaths.js:201:45:201:48 | path | -| normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:214:7:214:49 | path | -| normalizedPaths.js:214:7:214:49 | path | -| normalizedPaths.js:214:7:214:49 | path | -| normalizedPaths.js:214:7:214:49 | path | -| normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:214:35:214:48 | req.query.path | -| normalizedPaths.js:214:35:214:48 | req.query.path | -| normalizedPaths.js:214:35:214:48 | req.query.path | -| normalizedPaths.js:214:35:214:48 | req.query.path | -| normalizedPaths.js:214:35:214:48 | req.query.path | -| normalizedPaths.js:219:3:219:33 | path | -| normalizedPaths.js:219:3:219:33 | path | -| normalizedPaths.js:219:3:219:33 | path | -| normalizedPaths.js:219:3:219:33 | path | -| normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | -| normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | -| normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | -| normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | -| normalizedPaths.js:219:29:219:32 | path | -| normalizedPaths.js:219:29:219:32 | path | -| normalizedPaths.js:219:29:219:32 | path | -| normalizedPaths.js:219:29:219:32 | path | -| normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:226:7:226:70 | path | -| normalizedPaths.js:226:7:226:70 | path | -| normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | -| normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | -| normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | -| normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | -| normalizedPaths.js:226:35:226:48 | req.query.path | -| normalizedPaths.js:226:35:226:48 | req.query.path | -| normalizedPaths.js:226:35:226:48 | req.query.path | -| normalizedPaths.js:228:21:228:24 | path | -| normalizedPaths.js:228:21:228:24 | path | -| normalizedPaths.js:228:21:228:24 | path | -| normalizedPaths.js:236:7:236:47 | path | -| normalizedPaths.js:236:7:236:47 | path | -| normalizedPaths.js:236:7:236:47 | path | -| normalizedPaths.js:236:7:236:47 | path | -| normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | -| normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | -| normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | -| normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | -| normalizedPaths.js:236:33:236:46 | req.query.path | -| normalizedPaths.js:236:33:236:46 | req.query.path | -| normalizedPaths.js:236:33:236:46 | req.query.path | -| normalizedPaths.js:236:33:236:46 | req.query.path | -| normalizedPaths.js:236:33:236:46 | req.query.path | -| normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:254:7:254:47 | path | -| normalizedPaths.js:254:7:254:47 | path | -| normalizedPaths.js:254:7:254:47 | path | -| normalizedPaths.js:254:7:254:47 | path | -| normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:254:33:254:46 | req.query.path | -| normalizedPaths.js:254:33:254:46 | req.query.path | -| normalizedPaths.js:254:33:254:46 | req.query.path | -| normalizedPaths.js:254:33:254:46 | req.query.path | -| normalizedPaths.js:254:33:254:46 | req.query.path | -| normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:267:7:267:42 | newpath | -| normalizedPaths.js:267:7:267:42 | newpath | -| normalizedPaths.js:267:7:267:42 | newpath | -| normalizedPaths.js:267:7:267:42 | newpath | -| normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | -| normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | -| normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | -| normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | -| normalizedPaths.js:267:38:267:41 | path | -| normalizedPaths.js:267:38:267:41 | path | -| normalizedPaths.js:267:38:267:41 | path | -| normalizedPaths.js:267:38:267:41 | path | -| normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:275:7:275:42 | newpath | -| normalizedPaths.js:275:7:275:42 | newpath | -| normalizedPaths.js:275:7:275:42 | newpath | -| normalizedPaths.js:275:7:275:42 | newpath | -| normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | -| normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | -| normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | -| normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | -| normalizedPaths.js:275:38:275:41 | path | -| normalizedPaths.js:275:38:275:41 | path | -| normalizedPaths.js:275:38:275:41 | path | -| normalizedPaths.js:275:38:275:41 | path | -| normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:283:7:283:42 | newpath | -| normalizedPaths.js:283:7:283:42 | newpath | -| normalizedPaths.js:283:7:283:42 | newpath | -| normalizedPaths.js:283:7:283:42 | newpath | -| normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | -| normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | -| normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | -| normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | -| normalizedPaths.js:283:38:283:41 | path | -| normalizedPaths.js:283:38:283:41 | path | -| normalizedPaths.js:283:38:283:41 | path | -| normalizedPaths.js:283:38:283:41 | path | -| normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:291:7:291:42 | newpath | -| normalizedPaths.js:291:7:291:42 | newpath | -| normalizedPaths.js:291:7:291:42 | newpath | -| normalizedPaths.js:291:7:291:42 | newpath | -| normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | -| normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | -| normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | -| normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | -| normalizedPaths.js:291:38:291:41 | path | -| normalizedPaths.js:291:38:291:41 | path | -| normalizedPaths.js:291:38:291:41 | path | -| normalizedPaths.js:291:38:291:41 | path | -| normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:303:6:303:26 | path | -| normalizedPaths.js:303:6:303:26 | path | -| normalizedPaths.js:303:6:303:26 | path | -| normalizedPaths.js:303:6:303:26 | path | -| normalizedPaths.js:303:13:303:26 | req.query.path | -| normalizedPaths.js:303:13:303:26 | req.query.path | -| normalizedPaths.js:303:13:303:26 | req.query.path | -| normalizedPaths.js:303:13:303:26 | req.query.path | -| normalizedPaths.js:303:13:303:26 | req.query.path | -| normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:313:19:313:22 | path | -| normalizedPaths.js:313:19:313:22 | path | -| normalizedPaths.js:313:19:313:22 | path | -| normalizedPaths.js:313:19:313:22 | path | -| normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:320:6:320:49 | normalizedPath | -| normalizedPaths.js:320:6:320:49 | normalizedPath | -| normalizedPaths.js:320:6:320:49 | normalizedPath | -| normalizedPaths.js:320:23:320:49 | pathMod ... , path) | -| normalizedPaths.js:320:23:320:49 | pathMod ... , path) | -| normalizedPaths.js:320:23:320:49 | pathMod ... , path) | -| normalizedPaths.js:320:45:320:48 | path | -| normalizedPaths.js:320:45:320:48 | path | -| normalizedPaths.js:320:45:320:48 | path | -| normalizedPaths.js:325:19:325:32 | normalizedPath | -| normalizedPaths.js:325:19:325:32 | normalizedPath | -| normalizedPaths.js:325:19:325:32 | normalizedPath | -| normalizedPaths.js:325:19:325:32 | normalizedPath | -| normalizedPaths.js:332:19:332:32 | normalizedPath | -| normalizedPaths.js:332:19:332:32 | normalizedPath | -| normalizedPaths.js:332:19:332:32 | normalizedPath | -| normalizedPaths.js:332:19:332:32 | normalizedPath | -| normalizedPaths.js:339:6:339:46 | path | -| normalizedPaths.js:339:6:339:46 | path | -| normalizedPaths.js:339:6:339:46 | path | -| normalizedPaths.js:339:6:339:46 | path | -| normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:339:32:339:45 | req.query.path | -| normalizedPaths.js:339:32:339:45 | req.query.path | -| normalizedPaths.js:339:32:339:45 | req.query.path | -| normalizedPaths.js:339:32:339:45 | req.query.path | -| normalizedPaths.js:339:32:339:45 | req.query.path | -| normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:354:14:354:27 | req.query.path | -| normalizedPaths.js:354:14:354:27 | req.query.path | -| normalizedPaths.js:354:14:354:27 | req.query.path | -| normalizedPaths.js:354:14:354:27 | req.query.path | -| normalizedPaths.js:354:14:354:27 | req.query.path | -| normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:358:7:358:51 | requestPath | -| normalizedPaths.js:358:7:358:51 | requestPath | -| normalizedPaths.js:358:7:358:51 | requestPath | -| normalizedPaths.js:358:21:358:51 | pathMod ... , path) | -| normalizedPaths.js:358:21:358:51 | pathMod ... , path) | -| normalizedPaths.js:358:21:358:51 | pathMod ... , path) | -| normalizedPaths.js:358:47:358:50 | path | -| normalizedPaths.js:358:47:358:50 | path | -| normalizedPaths.js:358:47:358:50 | path | -| normalizedPaths.js:363:21:363:31 | requestPath | -| normalizedPaths.js:363:21:363:31 | requestPath | -| normalizedPaths.js:363:21:363:31 | requestPath | -| normalizedPaths.js:363:21:363:31 | requestPath | -| normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:377:14:377:27 | req.query.path | -| normalizedPaths.js:377:14:377:27 | req.query.path | -| normalizedPaths.js:377:14:377:27 | req.query.path | -| normalizedPaths.js:377:14:377:27 | req.query.path | -| normalizedPaths.js:377:14:377:27 | req.query.path | -| normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:381:25:381:28 | path | -| normalizedPaths.js:381:25:381:28 | path | -| normalizedPaths.js:381:25:381:28 | path | -| normalizedPaths.js:381:25:381:28 | path | -| normalizedPaths.js:385:7:385:46 | path | -| normalizedPaths.js:385:7:385:46 | path | -| normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | -| normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | -| normalizedPaths.js:385:35:385:45 | req.query.x | -| normalizedPaths.js:385:35:385:45 | req.query.x | -| normalizedPaths.js:385:35:385:45 | req.query.x | -| normalizedPaths.js:388:19:388:22 | path | -| normalizedPaths.js:388:19:388:22 | path | -| normalizedPaths.js:388:19:388:22 | path | -| normalizedPaths.js:399:21:399:24 | path | -| normalizedPaths.js:399:21:399:24 | path | -| normalizedPaths.js:399:21:399:24 | path | -| normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | -| normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | -| normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | -| normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | -| normalizedPaths.js:407:45:407:55 | req.query.x | -| normalizedPaths.js:407:45:407:55 | req.query.x | -| normalizedPaths.js:407:45:407:55 | req.query.x | -| normalizedPaths.js:407:45:407:55 | req.query.x | -| normalizedPaths.js:407:45:407:66 | req.que ... it('/') | -| normalizedPaths.js:407:45:407:66 | req.que ... it('/') | -| normalizedPaths.js:407:45:407:66 | req.que ... it('/') | -| normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | -| normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | -| normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | -| normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | -| normalizedPaths.js:408:38:408:48 | req.query.x | -| normalizedPaths.js:408:38:408:48 | req.query.x | -| normalizedPaths.js:408:38:408:48 | req.query.x | -| normalizedPaths.js:408:38:408:48 | req.query.x | -| normalizedPaths.js:408:38:408:59 | req.que ... it('/') | -| normalizedPaths.js:408:38:408:59 | req.que ... it('/') | -| normalizedPaths.js:408:38:408:59 | req.que ... it('/') | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:24:9:30 | req.url | -| other-fs-libraries.js:9:24:9:30 | req.url | -| other-fs-libraries.js:9:24:9:30 | req.url | -| other-fs-libraries.js:9:24:9:30 | req.url | -| other-fs-libraries.js:9:24:9:30 | req.url | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:24:38:30 | req.url | -| other-fs-libraries.js:38:24:38:30 | req.url | -| other-fs-libraries.js:38:24:38:30 | req.url | -| other-fs-libraries.js:38:24:38:30 | req.url | -| other-fs-libraries.js:38:24:38:30 | req.url | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:24:49:30 | req.url | -| other-fs-libraries.js:49:24:49:30 | req.url | -| other-fs-libraries.js:49:24:49:30 | req.url | -| other-fs-libraries.js:49:24:49:30 | req.url | -| other-fs-libraries.js:49:24:49:30 | req.url | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:24:68:30 | req.url | -| other-fs-libraries.js:68:24:68:30 | req.url | -| other-fs-libraries.js:68:24:68:30 | req.url | -| other-fs-libraries.js:68:24:68:30 | req.url | -| other-fs-libraries.js:68:24:68:30 | req.url | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:24:77:30 | req.url | -| other-fs-libraries.js:77:24:77:30 | req.url | -| other-fs-libraries.js:77:24:77:30 | req.url | -| other-fs-libraries.js:77:24:77:30 | req.url | -| other-fs-libraries.js:77:24:77:30 | req.url | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| prettier.js:6:11:6:28 | p | -| prettier.js:6:11:6:28 | p | -| prettier.js:6:11:6:28 | p | -| prettier.js:6:11:6:28 | p | -| prettier.js:6:13:6:13 | p | -| prettier.js:6:13:6:13 | p | -| prettier.js:6:13:6:13 | p | -| prettier.js:6:13:6:13 | p | -| prettier.js:6:13:6:13 | p | -| prettier.js:7:28:7:28 | p | -| prettier.js:7:28:7:28 | p | -| prettier.js:7:28:7:28 | p | -| prettier.js:7:28:7:28 | p | -| prettier.js:7:28:7:28 | p | -| prettier.js:11:44:11:44 | p | -| prettier.js:11:44:11:44 | p | -| prettier.js:11:44:11:44 | p | -| prettier.js:11:44:11:44 | p | -| prettier.js:11:44:11:44 | p | -| pupeteer.js:5:9:5:71 | tainted | -| pupeteer.js:5:9:5:71 | tainted | -| pupeteer.js:5:9:5:71 | tainted | -| pupeteer.js:5:19:5:71 | "dir/" ... t.data" | -| pupeteer.js:5:19:5:71 | "dir/" ... t.data" | -| pupeteer.js:5:19:5:71 | "dir/" ... t.data" | -| pupeteer.js:5:28:5:53 | parseTo ... t).name | -| pupeteer.js:5:28:5:53 | parseTo ... t).name | -| pupeteer.js:5:28:5:53 | parseTo ... t).name | -| pupeteer.js:5:28:5:53 | parseTo ... t).name | -| pupeteer.js:9:28:9:34 | tainted | -| pupeteer.js:9:28:9:34 | tainted | -| pupeteer.js:9:28:9:34 | tainted | -| pupeteer.js:9:28:9:34 | tainted | -| pupeteer.js:13:37:13:43 | tainted | -| pupeteer.js:13:37:13:43 | tainted | -| pupeteer.js:13:37:13:43 | tainted | -| pupeteer.js:13:37:13:43 | tainted | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:24:6:30 | req.url | -| tainted-access-paths.js:6:24:6:30 | req.url | -| tainted-access-paths.js:6:24:6:30 | req.url | -| tainted-access-paths.js:6:24:6:30 | req.url | -| tainted-access-paths.js:6:24:6:30 | req.url | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:24:39:30 | req.url | -| tainted-access-paths.js:39:24:39:30 | req.url | -| tainted-access-paths.js:39:24:39:30 | req.url | -| tainted-access-paths.js:39:24:39:30 | req.url | -| tainted-access-paths.js:39:24:39:30 | req.url | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:24:48:30 | req.url | -| tainted-access-paths.js:48:24:48:30 | req.url | -| tainted-access-paths.js:48:24:48:30 | req.url | -| tainted-access-paths.js:48:24:48:30 | req.url | -| tainted-access-paths.js:48:24:48:30 | req.url | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-require.js:7:19:7:37 | req.param("module") | -| tainted-require.js:7:19:7:37 | req.param("module") | -| tainted-require.js:7:19:7:37 | req.param("module") | -| tainted-require.js:7:19:7:37 | req.param("module") | -| tainted-require.js:7:19:7:37 | req.param("module") | -| tainted-require.js:7:19:7:37 | req.param("module") | -| tainted-require.js:12:29:12:47 | req.param("module") | -| tainted-require.js:12:29:12:47 | req.param("module") | -| tainted-require.js:12:29:12:47 | req.param("module") | -| tainted-require.js:12:29:12:47 | req.param("module") | -| tainted-require.js:12:29:12:47 | req.param("module") | -| tainted-require.js:12:29:12:47 | req.param("module") | -| tainted-require.js:14:11:14:29 | req.param("module") | -| tainted-require.js:14:11:14:29 | req.param("module") | -| tainted-require.js:14:11:14:29 | req.param("module") | -| tainted-require.js:14:11:14:29 | req.param("module") | -| tainted-require.js:14:11:14:29 | req.param("module") | -| tainted-require.js:14:11:14:29 | req.param("module") | -| tainted-sendFile.js:8:16:8:33 | req.param("gimme") | -| tainted-sendFile.js:8:16:8:33 | req.param("gimme") | -| tainted-sendFile.js:8:16:8:33 | req.param("gimme") | -| tainted-sendFile.js:8:16:8:33 | req.param("gimme") | -| tainted-sendFile.js:10:16:10:33 | req.param("gimme") | -| tainted-sendFile.js:10:16:10:33 | req.param("gimme") | -| tainted-sendFile.js:10:16:10:33 | req.param("gimme") | -| tainted-sendFile.js:10:16:10:33 | req.param("gimme") | -| tainted-sendFile.js:18:43:18:58 | req.param("dir") | -| tainted-sendFile.js:18:43:18:58 | req.param("dir") | -| tainted-sendFile.js:18:43:18:58 | req.param("dir") | -| tainted-sendFile.js:18:43:18:58 | req.param("dir") | -| tainted-sendFile.js:18:43:18:58 | req.param("dir") | -| tainted-sendFile.js:18:43:18:58 | req.param("dir") | -| tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:37:24:48 | req.params.x | -| tainted-sendFile.js:24:37:24:48 | req.params.x | -| tainted-sendFile.js:24:37:24:48 | req.params.x | -| tainted-sendFile.js:24:37:24:48 | req.params.x | -| tainted-sendFile.js:24:37:24:48 | req.params.x | -| tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:34:25:45 | req.params.x | -| tainted-sendFile.js:25:34:25:45 | req.params.x | -| tainted-sendFile.js:25:34:25:45 | req.params.x | -| tainted-sendFile.js:25:34:25:45 | req.params.x | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:24:6:30 | req.url | -| tainted-string-steps.js:6:24:6:30 | req.url | -| tainted-string-steps.js:6:24:6:30 | req.url | -| tainted-string-steps.js:6:24:6:30 | req.url | -| tainted-string-steps.js:6:24:6:30 | req.url | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| torrents.js:5:6:5:38 | name | -| torrents.js:5:6:5:38 | name | -| torrents.js:5:6:5:38 | name | -| torrents.js:5:13:5:38 | parseTo ... t).name | -| torrents.js:5:13:5:38 | parseTo ... t).name | -| torrents.js:5:13:5:38 | parseTo ... t).name | -| torrents.js:5:13:5:38 | parseTo ... t).name | -| torrents.js:6:6:6:45 | loc | -| torrents.js:6:6:6:45 | loc | -| torrents.js:6:6:6:45 | loc | -| torrents.js:6:12:6:45 | dir + " ... t.data" | -| torrents.js:6:12:6:45 | dir + " ... t.data" | -| torrents.js:6:12:6:45 | dir + " ... t.data" | -| torrents.js:6:24:6:27 | name | -| torrents.js:6:24:6:27 | name | -| torrents.js:6:24:6:27 | name | -| torrents.js:7:25:7:27 | loc | -| torrents.js:7:25:7:27 | loc | -| torrents.js:7:25:7:27 | loc | -| torrents.js:7:25:7:27 | loc | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:24:9:30 | req.url | -| typescript.ts:9:24:9:30 | req.url | -| typescript.ts:9:24:9:30 | req.url | -| typescript.ts:9:24:9:30 | req.url | -| typescript.ts:9:24:9:30 | req.url | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| views.js:1:43:1:55 | req.params[0] | -| views.js:1:43:1:55 | req.params[0] | -| views.js:1:43:1:55 | req.params[0] | -| views.js:1:43:1:55 | req.params[0] | -| views.js:1:43:1:55 | req.params[0] | -| views.js:1:43:1:55 | req.params[0] | +| TaintedPath-es6.js:7:7:7:44 | path | semmle.label | path | +| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | semmle.label | parse(req.url, true) | +| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | semmle.label | parse(r ... ).query | +| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | semmle.label | parse(r ... ry.path | +| TaintedPath-es6.js:7:20:7:26 | req.url | semmle.label | req.url | +| TaintedPath-es6.js:10:26:10:45 | join("public", path) | semmle.label | join("public", path) | +| TaintedPath-es6.js:10:41:10:44 | path | semmle.label | path | +| TaintedPath.js:9:7:9:48 | path | semmle.label | path | +| TaintedPath.js:9:14:9:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| TaintedPath.js:9:14:9:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| TaintedPath.js:9:14:9:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| TaintedPath.js:9:24:9:30 | req.url | semmle.label | req.url | +| TaintedPath.js:12:29:12:32 | path | semmle.label | path | +| TaintedPath.js:15:29:15:48 | "/home/user/" + path | semmle.label | "/home/user/" + path | +| TaintedPath.js:15:45:15:48 | path | semmle.label | path | +| TaintedPath.js:18:33:18:36 | path | semmle.label | path | +| TaintedPath.js:21:33:21:36 | path | semmle.label | path | +| TaintedPath.js:24:33:24:36 | path | semmle.label | path | +| TaintedPath.js:33:31:33:34 | path | semmle.label | path | +| TaintedPath.js:38:3:38:44 | path | semmle.label | path | +| TaintedPath.js:38:10:38:33 | url.par ... , true) | semmle.label | url.par ... , true) | +| TaintedPath.js:38:10:38:39 | url.par ... ).query | semmle.label | url.par ... ).query | +| TaintedPath.js:38:10:38:44 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| TaintedPath.js:38:20:38:26 | req.url | semmle.label | req.url | +| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | semmle.label | pathMod ... e(path) | +| TaintedPath.js:42:48:42:51 | path | semmle.label | path | +| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | semmle.label | pathMod ... n(path) | +| TaintedPath.js:46:45:46:48 | path | semmle.label | path | +| TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | semmle.label | pathMod ... ath, z) | +| TaintedPath.js:48:51:48:54 | path | semmle.label | path | +| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | semmle.label | pathMod ... e(path) | +| TaintedPath.js:50:50:50:53 | path | semmle.label | path | +| TaintedPath.js:52:29:52:56 | pathMod ... , path) | semmle.label | pathMod ... , path) | +| TaintedPath.js:52:52:52:55 | path | semmle.label | path | +| TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | semmle.label | pathMod ... ath, x) | +| TaintedPath.js:54:49:54:52 | path | semmle.label | path | +| TaintedPath.js:56:29:56:52 | pathMod ... e(path) | semmle.label | pathMod ... e(path) | +| TaintedPath.js:56:48:56:51 | path | semmle.label | path | +| TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | semmle.label | pathMod ... ath, z) | +| TaintedPath.js:58:54:58:57 | path | semmle.label | path | +| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | semmle.label | pathMod ... h(path) | +| TaintedPath.js:60:57:60:60 | path | semmle.label | path | +| TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | semmle.label | Cookie.get("unsafe") | +| TaintedPath.js:77:31:77:70 | require ... eq.url) | semmle.label | require ... eq.url) | +| TaintedPath.js:77:31:77:76 | require ... ).query | semmle.label | require ... ).query | +| TaintedPath.js:77:63:77:69 | req.url | semmle.label | req.url | +| TaintedPath.js:78:31:78:68 | require ... eq.url) | semmle.label | require ... eq.url) | +| TaintedPath.js:78:31:78:74 | require ... ).query | semmle.label | require ... ).query | +| TaintedPath.js:78:61:78:67 | req.url | semmle.label | req.url | +| TaintedPath.js:79:31:79:67 | require ... eq.url) | semmle.label | require ... eq.url) | +| TaintedPath.js:79:31:79:73 | require ... ).query | semmle.label | require ... ).query | +| TaintedPath.js:79:60:79:66 | req.url | semmle.label | req.url | +| TaintedPath.js:87:48:87:60 | req.params[0] | semmle.label | req.params[0] | +| TaintedPath.js:95:30:95:31 | ev | semmle.label | ev | +| TaintedPath.js:96:24:96:25 | ev | semmle.label | ev | +| TaintedPath.js:96:24:96:30 | ev.data | semmle.label | ev.data | +| TaintedPath.js:100:6:100:47 | path | semmle.label | path | +| TaintedPath.js:100:13:100:36 | url.par ... , true) | semmle.label | url.par ... , true) | +| TaintedPath.js:100:13:100:42 | url.par ... ).query | semmle.label | url.par ... ).query | +| TaintedPath.js:100:13:100:47 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| TaintedPath.js:100:23:100:29 | req.url | semmle.label | req.url | +| TaintedPath.js:102:28:102:48 | fs.real ... c(path) | semmle.label | fs.real ... c(path) | +| TaintedPath.js:102:44:102:47 | path | semmle.label | path | +| TaintedPath.js:103:14:103:17 | path | semmle.label | path | +| TaintedPath.js:104:32:104:39 | realpath | semmle.label | realpath | +| TaintedPath.js:105:45:105:52 | realpath | semmle.label | realpath | +| TaintedPath.js:136:6:136:47 | path | semmle.label | path | +| TaintedPath.js:136:13:136:36 | url.par ... , true) | semmle.label | url.par ... , true) | +| TaintedPath.js:136:13:136:42 | url.par ... ).query | semmle.label | url.par ... ).query | +| TaintedPath.js:136:13:136:47 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| TaintedPath.js:136:23:136:29 | req.url | semmle.label | req.url | +| TaintedPath.js:138:23:138:26 | path | semmle.label | path | +| TaintedPath.js:142:7:142:48 | path | semmle.label | path | +| TaintedPath.js:142:14:142:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| TaintedPath.js:142:14:142:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| TaintedPath.js:142:14:142:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| TaintedPath.js:142:24:142:30 | req.url | semmle.label | req.url | +| TaintedPath.js:144:19:144:22 | path | semmle.label | path | +| TaintedPath.js:146:7:146:29 | split | semmle.label | split | +| TaintedPath.js:146:15:146:18 | path | semmle.label | path | +| TaintedPath.js:146:15:146:29 | path.split("/") | semmle.label | path.split("/") | +| TaintedPath.js:148:19:148:23 | split | semmle.label | split | +| TaintedPath.js:148:19:148:33 | split.join("/") | semmle.label | split.join("/") | +| TaintedPath.js:152:19:152:23 | split | semmle.label | split | +| TaintedPath.js:152:19:152:26 | split[x] | semmle.label | split[x] | +| TaintedPath.js:153:19:153:35 | prefix + split[x] | semmle.label | prefix + split[x] | +| TaintedPath.js:153:28:153:32 | split | semmle.label | split | +| TaintedPath.js:153:28:153:35 | split[x] | semmle.label | split[x] | +| TaintedPath.js:155:7:155:38 | concatted | semmle.label | concatted | +| TaintedPath.js:155:19:155:38 | prefix.concat(split) | semmle.label | prefix.concat(split) | +| TaintedPath.js:155:33:155:37 | split | semmle.label | split | +| TaintedPath.js:156:19:156:27 | concatted | semmle.label | concatted | +| TaintedPath.js:156:19:156:37 | concatted.join("/") | semmle.label | concatted.join("/") | +| TaintedPath.js:158:7:158:39 | concatted2 | semmle.label | concatted2 | +| TaintedPath.js:158:20:158:24 | split | semmle.label | split | +| TaintedPath.js:158:20:158:39 | split.concat(prefix) | semmle.label | split.concat(prefix) | +| TaintedPath.js:159:19:159:28 | concatted2 | semmle.label | concatted2 | +| TaintedPath.js:159:19:159:38 | concatted2.join("/") | semmle.label | concatted2.join("/") | +| TaintedPath.js:161:19:161:23 | split | semmle.label | split | +| TaintedPath.js:161:19:161:29 | split.pop() | semmle.label | split.pop() | +| TaintedPath.js:166:7:166:48 | path | semmle.label | path | +| TaintedPath.js:166:14:166:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| TaintedPath.js:166:14:166:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| TaintedPath.js:166:14:166:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| TaintedPath.js:166:24:166:30 | req.url | semmle.label | req.url | +| TaintedPath.js:170:29:170:32 | path | semmle.label | path | +| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | semmle.label | path.re ... /g, '') | +| TaintedPath.js:176:29:176:32 | path | semmle.label | path | +| TaintedPath.js:176:29:176:52 | path.re ... /g, '') | semmle.label | path.re ... /g, '') | +| TaintedPath.js:177:29:177:32 | path | semmle.label | path | +| TaintedPath.js:177:29:177:53 | path.re ... /g, '') | semmle.label | path.re ... /g, '') | +| TaintedPath.js:178:29:178:32 | path | semmle.label | path | +| TaintedPath.js:178:29:178:51 | path.re ... /g, '') | semmle.label | path.re ... /g, '') | +| TaintedPath.js:179:29:179:32 | path | semmle.label | path | +| TaintedPath.js:179:29:179:57 | path.re ... /g, '') | semmle.label | path.re ... /g, '') | +| TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | semmle.label | "prefix ... +/, '') | +| TaintedPath.js:194:40:194:43 | path | semmle.label | path | +| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | semmle.label | path.re ... +/, '') | +| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | semmle.label | pathMod ... e(path) | +| TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | semmle.label | pathMod ... +/, '') | +| TaintedPath.js:195:50:195:53 | path | semmle.label | path | +| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | semmle.label | qs.parse(req.url) | +| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | semmle.label | qs.pars ... rl).foo | +| TaintedPath.js:203:38:203:44 | req.url | semmle.label | req.url | +| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | semmle.label | qs.pars ... q.url)) | +| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | semmle.label | qs.pars ... l)).foo | +| TaintedPath.js:204:38:204:58 | normali ... eq.url) | semmle.label | normali ... eq.url) | +| TaintedPath.js:204:51:204:57 | req.url | semmle.label | req.url | +| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | semmle.label | parseqs ... eq.url) | +| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | semmle.label | parseqs ... rl).foo | +| TaintedPath.js:206:44:206:50 | req.url | semmle.label | req.url | +| TaintedPath.js:211:7:211:48 | path | semmle.label | path | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| TaintedPath.js:211:24:211:30 | req.url | semmle.label | req.url | +| TaintedPath.js:212:31:212:34 | path | semmle.label | path | +| TaintedPath.js:213:45:213:48 | path | semmle.label | path | +| TaintedPath.js:214:35:214:38 | path | semmle.label | path | +| express.js:8:20:8:32 | req.query.bar | semmle.label | req.query.bar | +| handlebars.js:10:51:10:58 | filePath | semmle.label | filePath | +| handlebars.js:11:32:11:39 | filePath | semmle.label | filePath | +| handlebars.js:13:73:13:80 | filePath | semmle.label | filePath | +| handlebars.js:15:25:15:32 | filePath | semmle.label | filePath | +| handlebars.js:29:46:29:60 | req.params.path | semmle.label | req.params.path | +| handlebars.js:43:15:43:29 | req.params.path | semmle.label | req.params.path | +| normalizedPaths.js:11:7:11:27 | path | semmle.label | path | +| normalizedPaths.js:11:14:11:27 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:13:19:13:22 | path | semmle.label | path | +| normalizedPaths.js:14:19:14:29 | './' + path | semmle.label | './' + path | +| normalizedPaths.js:14:26:14:29 | path | semmle.label | path | +| normalizedPaths.js:15:19:15:22 | path | semmle.label | path | +| normalizedPaths.js:15:19:15:38 | path + '/index.html' | semmle.label | path + '/index.html' | +| normalizedPaths.js:16:19:16:53 | pathMod ... .html') | semmle.label | pathMod ... .html') | +| normalizedPaths.js:16:35:16:38 | path | semmle.label | path | +| normalizedPaths.js:17:19:17:57 | pathMod ... , path) | semmle.label | pathMod ... , path) | +| normalizedPaths.js:17:53:17:56 | path | semmle.label | path | +| normalizedPaths.js:21:7:21:49 | path | semmle.label | path | +| normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | semmle.label | pathMod ... y.path) | +| normalizedPaths.js:21:35:21:48 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:23:19:23:22 | path | semmle.label | path | +| normalizedPaths.js:24:19:24:29 | './' + path | semmle.label | './' + path | +| normalizedPaths.js:24:26:24:29 | path | semmle.label | path | +| normalizedPaths.js:25:19:25:22 | path | semmle.label | path | +| normalizedPaths.js:25:19:25:38 | path + '/index.html' | semmle.label | path + '/index.html' | +| normalizedPaths.js:26:19:26:53 | pathMod ... .html') | semmle.label | pathMod ... .html') | +| normalizedPaths.js:26:35:26:38 | path | semmle.label | path | +| normalizedPaths.js:27:19:27:57 | pathMod ... , path) | semmle.label | pathMod ... , path) | +| normalizedPaths.js:27:53:27:56 | path | semmle.label | path | +| normalizedPaths.js:31:7:31:49 | path | semmle.label | path | +| normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | semmle.label | pathMod ... y.path) | +| normalizedPaths.js:31:35:31:48 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:36:19:36:22 | path | semmle.label | path | +| normalizedPaths.js:41:21:41:24 | path | semmle.label | path | +| normalizedPaths.js:54:7:54:49 | path | semmle.label | path | +| normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | semmle.label | pathMod ... y.path) | +| normalizedPaths.js:54:35:54:48 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:59:19:59:22 | path | semmle.label | path | +| normalizedPaths.js:63:19:63:22 | path | semmle.label | path | +| normalizedPaths.js:63:19:63:38 | path + "/index.html" | semmle.label | path + "/index.html" | +| normalizedPaths.js:68:21:68:24 | path | semmle.label | path | +| normalizedPaths.js:73:7:73:56 | path | semmle.label | path | +| normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | semmle.label | pathMod ... y.path) | +| normalizedPaths.js:73:35:73:55 | './' + ... ry.path | semmle.label | './' + ... ry.path | +| normalizedPaths.js:73:42:73:55 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:78:22:78:25 | path | semmle.label | path | +| normalizedPaths.js:82:7:82:27 | path | semmle.label | path | +| normalizedPaths.js:82:14:82:27 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:87:29:87:32 | path | semmle.label | path | +| normalizedPaths.js:90:31:90:34 | path | semmle.label | path | +| normalizedPaths.js:94:7:94:49 | path | semmle.label | path | +| normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | semmle.label | pathMod ... y.path) | +| normalizedPaths.js:94:35:94:48 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:99:29:99:32 | path | semmle.label | path | +| normalizedPaths.js:117:7:117:44 | path | semmle.label | path | +| normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | semmle.label | fs.real ... y.path) | +| normalizedPaths.js:117:30:117:43 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:119:19:119:22 | path | semmle.label | path | +| normalizedPaths.js:120:19:120:53 | pathMod ... .html') | semmle.label | pathMod ... .html') | +| normalizedPaths.js:120:35:120:38 | path | semmle.label | path | +| normalizedPaths.js:130:7:130:49 | path | semmle.label | path | +| normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | semmle.label | pathMod ... y.path) | +| normalizedPaths.js:130:35:130:48 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:135:21:135:24 | path | semmle.label | path | +| normalizedPaths.js:139:7:139:62 | path | semmle.label | path | +| normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | semmle.label | pathMod ... y.path) | +| normalizedPaths.js:139:48:139:61 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:144:21:144:24 | path | semmle.label | path | +| normalizedPaths.js:148:7:148:58 | path | semmle.label | path | +| normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | semmle.label | 'foo/' ... y.path) | +| normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | semmle.label | pathMod ... y.path) | +| normalizedPaths.js:148:44:148:57 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:151:21:151:24 | path | semmle.label | path | +| normalizedPaths.js:153:21:153:24 | path | semmle.label | path | +| normalizedPaths.js:160:7:160:49 | path | semmle.label | path | +| normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | semmle.label | pathMod ... y.path) | +| normalizedPaths.js:160:35:160:48 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:165:19:165:22 | path | semmle.label | path | +| normalizedPaths.js:170:21:170:24 | path | semmle.label | path | +| normalizedPaths.js:174:7:174:27 | path | semmle.label | path | +| normalizedPaths.js:174:14:174:27 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:184:19:184:22 | path | semmle.label | path | +| normalizedPaths.js:187:21:187:24 | path | semmle.label | path | +| normalizedPaths.js:189:21:189:24 | path | semmle.label | path | +| normalizedPaths.js:192:21:192:24 | path | semmle.label | path | +| normalizedPaths.js:194:21:194:24 | path | semmle.label | path | +| normalizedPaths.js:199:21:199:24 | path | semmle.label | path | +| normalizedPaths.js:201:7:201:49 | normalizedPath | semmle.label | normalizedPath | +| normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | semmle.label | pathMod ... e(path) | +| normalizedPaths.js:201:45:201:48 | path | semmle.label | path | +| normalizedPaths.js:205:21:205:34 | normalizedPath | semmle.label | normalizedPath | +| normalizedPaths.js:208:21:208:34 | normalizedPath | semmle.label | normalizedPath | +| normalizedPaths.js:210:21:210:34 | normalizedPath | semmle.label | normalizedPath | +| normalizedPaths.js:214:7:214:49 | path | semmle.label | path | +| normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | semmle.label | pathMod ... y.path) | +| normalizedPaths.js:214:35:214:48 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:219:3:219:33 | path | semmle.label | path | +| normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | semmle.label | decodeU ... t(path) | +| normalizedPaths.js:219:29:219:32 | path | semmle.label | path | +| normalizedPaths.js:222:21:222:24 | path | semmle.label | path | +| normalizedPaths.js:226:7:226:70 | path | semmle.label | path | +| normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | semmle.label | pathMod ... y.path) | +| normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | semmle.label | pathMod ... g, ' ') | +| normalizedPaths.js:226:35:226:48 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:228:21:228:24 | path | semmle.label | path | +| normalizedPaths.js:236:7:236:47 | path | semmle.label | path | +| normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | semmle.label | pathMod ... y.path) | +| normalizedPaths.js:236:33:236:46 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:238:19:238:22 | path | semmle.label | path | +| normalizedPaths.js:245:21:245:24 | path | semmle.label | path | +| normalizedPaths.js:250:21:250:24 | path | semmle.label | path | +| normalizedPaths.js:254:7:254:47 | path | semmle.label | path | +| normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | semmle.label | pathMod ... y.path) | +| normalizedPaths.js:254:33:254:46 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:256:19:256:22 | path | semmle.label | path | +| normalizedPaths.js:262:21:262:24 | path | semmle.label | path | +| normalizedPaths.js:267:7:267:42 | newpath | semmle.label | newpath | +| normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | semmle.label | pathMod ... e(path) | +| normalizedPaths.js:267:38:267:41 | path | semmle.label | path | +| normalizedPaths.js:270:21:270:27 | newpath | semmle.label | newpath | +| normalizedPaths.js:275:7:275:42 | newpath | semmle.label | newpath | +| normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | semmle.label | pathMod ... e(path) | +| normalizedPaths.js:275:38:275:41 | path | semmle.label | path | +| normalizedPaths.js:278:21:278:27 | newpath | semmle.label | newpath | +| normalizedPaths.js:283:7:283:42 | newpath | semmle.label | newpath | +| normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | semmle.label | pathMod ... e(path) | +| normalizedPaths.js:283:38:283:41 | path | semmle.label | path | +| normalizedPaths.js:286:21:286:27 | newpath | semmle.label | newpath | +| normalizedPaths.js:291:7:291:42 | newpath | semmle.label | newpath | +| normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | semmle.label | pathMod ... e(path) | +| normalizedPaths.js:291:38:291:41 | path | semmle.label | path | +| normalizedPaths.js:296:21:296:27 | newpath | semmle.label | newpath | +| normalizedPaths.js:303:6:303:26 | path | semmle.label | path | +| normalizedPaths.js:303:13:303:26 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:304:18:304:21 | path | semmle.label | path | +| normalizedPaths.js:309:19:309:22 | path | semmle.label | path | +| normalizedPaths.js:313:19:313:22 | path | semmle.label | path | +| normalizedPaths.js:316:19:316:22 | path | semmle.label | path | +| normalizedPaths.js:320:6:320:49 | normalizedPath | semmle.label | normalizedPath | +| normalizedPaths.js:320:23:320:49 | pathMod ... , path) | semmle.label | pathMod ... , path) | +| normalizedPaths.js:320:45:320:48 | path | semmle.label | path | +| normalizedPaths.js:325:19:325:32 | normalizedPath | semmle.label | normalizedPath | +| normalizedPaths.js:332:19:332:32 | normalizedPath | semmle.label | normalizedPath | +| normalizedPaths.js:339:6:339:46 | path | semmle.label | path | +| normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | semmle.label | pathMod ... y.path) | +| normalizedPaths.js:339:32:339:45 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:341:18:341:21 | path | semmle.label | path | +| normalizedPaths.js:346:19:346:22 | path | semmle.label | path | +| normalizedPaths.js:354:7:354:27 | path | semmle.label | path | +| normalizedPaths.js:354:14:354:27 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:356:19:356:22 | path | semmle.label | path | +| normalizedPaths.js:358:7:358:51 | requestPath | semmle.label | requestPath | +| normalizedPaths.js:358:21:358:51 | pathMod ... , path) | semmle.label | pathMod ... , path) | +| normalizedPaths.js:358:47:358:50 | path | semmle.label | path | +| normalizedPaths.js:363:21:363:31 | requestPath | semmle.label | requestPath | +| normalizedPaths.js:377:7:377:27 | path | semmle.label | path | +| normalizedPaths.js:377:14:377:27 | req.query.path | semmle.label | req.query.path | +| normalizedPaths.js:379:19:379:22 | path | semmle.label | path | +| normalizedPaths.js:381:19:381:29 | slash(path) | semmle.label | slash(path) | +| normalizedPaths.js:381:25:381:28 | path | semmle.label | path | +| normalizedPaths.js:385:7:385:46 | path | semmle.label | path | +| normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | semmle.label | pathMod ... uery.x) | +| normalizedPaths.js:385:35:385:45 | req.query.x | semmle.label | req.query.x | +| normalizedPaths.js:388:19:388:22 | path | semmle.label | path | +| normalizedPaths.js:399:21:399:24 | path | semmle.label | path | +| normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | semmle.label | pathMod ... t('/')) | +| normalizedPaths.js:407:45:407:55 | req.query.x | semmle.label | req.query.x | +| normalizedPaths.js:407:45:407:66 | req.que ... it('/') | semmle.label | req.que ... it('/') | +| normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | semmle.label | pathMod ... t('/')) | +| normalizedPaths.js:408:38:408:48 | req.query.x | semmle.label | req.query.x | +| normalizedPaths.js:408:38:408:59 | req.que ... it('/') | semmle.label | req.que ... it('/') | +| other-fs-libraries.js:9:7:9:48 | path | semmle.label | path | +| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| other-fs-libraries.js:9:24:9:30 | req.url | semmle.label | req.url | +| other-fs-libraries.js:11:19:11:22 | path | semmle.label | path | +| other-fs-libraries.js:12:27:12:30 | path | semmle.label | path | +| other-fs-libraries.js:13:24:13:27 | path | semmle.label | path | +| other-fs-libraries.js:14:27:14:30 | path | semmle.label | path | +| other-fs-libraries.js:16:34:16:37 | path | semmle.label | path | +| other-fs-libraries.js:17:35:17:38 | path | semmle.label | path | +| other-fs-libraries.js:19:56:19:59 | path | semmle.label | path | +| other-fs-libraries.js:24:35:24:38 | path | semmle.label | path | +| other-fs-libraries.js:38:7:38:48 | path | semmle.label | path | +| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| other-fs-libraries.js:38:24:38:30 | req.url | semmle.label | req.url | +| other-fs-libraries.js:40:35:40:38 | path | semmle.label | path | +| other-fs-libraries.js:41:50:41:53 | path | semmle.label | path | +| other-fs-libraries.js:42:53:42:56 | path | semmle.label | path | +| other-fs-libraries.js:49:7:49:48 | path | semmle.label | path | +| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| other-fs-libraries.js:49:24:49:30 | req.url | semmle.label | req.url | +| other-fs-libraries.js:51:19:51:22 | path | semmle.label | path | +| other-fs-libraries.js:52:24:52:27 | path | semmle.label | path | +| other-fs-libraries.js:54:36:54:39 | path | semmle.label | path | +| other-fs-libraries.js:55:36:55:39 | path | semmle.label | path | +| other-fs-libraries.js:57:46:57:49 | path | semmle.label | path | +| other-fs-libraries.js:59:39:59:42 | path | semmle.label | path | +| other-fs-libraries.js:62:43:62:46 | path | semmle.label | path | +| other-fs-libraries.js:63:51:63:54 | path | semmle.label | path | +| other-fs-libraries.js:68:7:68:48 | path | semmle.label | path | +| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| other-fs-libraries.js:68:24:68:30 | req.url | semmle.label | req.url | +| other-fs-libraries.js:70:19:70:22 | path | semmle.label | path | +| other-fs-libraries.js:71:10:71:13 | path | semmle.label | path | +| other-fs-libraries.js:72:15:72:18 | path | semmle.label | path | +| other-fs-libraries.js:73:8:73:11 | path | semmle.label | path | +| other-fs-libraries.js:75:15:75:15 | x | semmle.label | x | +| other-fs-libraries.js:76:19:76:19 | x | semmle.label | x | +| other-fs-libraries.js:81:7:81:48 | path | semmle.label | path | +| other-fs-libraries.js:81:14:81:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| other-fs-libraries.js:81:14:81:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| other-fs-libraries.js:81:14:81:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| other-fs-libraries.js:81:24:81:30 | req.url | semmle.label | req.url | +| other-fs-libraries.js:83:16:83:19 | path | semmle.label | path | +| prettier.js:6:11:6:28 | p | semmle.label | p | +| prettier.js:6:13:6:13 | p | semmle.label | p | +| prettier.js:7:28:7:28 | p | semmle.label | p | +| prettier.js:11:44:11:44 | p | semmle.label | p | +| pupeteer.js:5:9:5:71 | tainted | semmle.label | tainted | +| pupeteer.js:5:19:5:71 | "dir/" ... t.data" | semmle.label | "dir/" ... t.data" | +| pupeteer.js:5:28:5:53 | parseTo ... t).name | semmle.label | parseTo ... t).name | +| pupeteer.js:9:28:9:34 | tainted | semmle.label | tainted | +| pupeteer.js:13:37:13:43 | tainted | semmle.label | tainted | +| sharedlib-repro.js:13:22:13:43 | req.par ... spaceId | semmle.label | req.par ... spaceId | +| sharedlib-repro.js:21:27:21:34 | filepath | semmle.label | filepath | +| sharedlib-repro.js:22:18:22:25 | filepath | semmle.label | filepath | +| tainted-access-paths.js:6:7:6:48 | path | semmle.label | path | +| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| tainted-access-paths.js:6:24:6:30 | req.url | semmle.label | req.url | +| tainted-access-paths.js:8:19:8:22 | path | semmle.label | path | +| tainted-access-paths.js:10:7:10:36 | obj | semmle.label | obj | +| tainted-access-paths.js:10:33:10:36 | path | semmle.label | path | +| tainted-access-paths.js:12:19:12:21 | obj | semmle.label | obj | +| tainted-access-paths.js:12:19:12:25 | obj.sub | semmle.label | obj.sub | +| tainted-access-paths.js:26:19:26:21 | obj | semmle.label | obj | +| tainted-access-paths.js:26:19:26:26 | obj.sub3 | semmle.label | obj.sub3 | +| tainted-access-paths.js:29:21:29:23 | obj | semmle.label | obj | +| tainted-access-paths.js:29:21:29:28 | obj.sub4 | semmle.label | obj.sub4 | +| tainted-access-paths.js:30:23:30:25 | obj | semmle.label | obj | +| tainted-access-paths.js:30:23:30:30 | obj.sub4 | semmle.label | obj.sub4 | +| tainted-access-paths.js:31:23:31:25 | obj | semmle.label | obj | +| tainted-access-paths.js:31:23:31:30 | obj.sub4 | semmle.label | obj.sub4 | +| tainted-access-paths.js:39:7:39:48 | path | semmle.label | path | +| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| tainted-access-paths.js:39:24:39:30 | req.url | semmle.label | req.url | +| tainted-access-paths.js:40:23:40:26 | path | semmle.label | path | +| tainted-access-paths.js:48:7:48:48 | path | semmle.label | path | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| tainted-access-paths.js:48:24:48:30 | req.url | semmle.label | req.url | +| tainted-access-paths.js:49:10:49:13 | path | semmle.label | path | +| tainted-promise-steps.js:6:7:6:48 | path | semmle.label | path | +| tainted-promise-steps.js:6:14:6:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| tainted-promise-steps.js:6:14:6:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| tainted-promise-steps.js:6:14:6:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| tainted-promise-steps.js:6:24:6:30 | req.url | semmle.label | req.url | +| tainted-promise-steps.js:7:10:7:30 | Promise ... e(path) [PromiseValue] | semmle.label | Promise ... e(path) [PromiseValue] | +| tainted-promise-steps.js:7:26:7:29 | path | semmle.label | path | +| tainted-promise-steps.js:10:23:10:33 | pathPromise [PromiseValue] | semmle.label | pathPromise [PromiseValue] | +| tainted-promise-steps.js:11:19:11:35 | await pathPromise | semmle.label | await pathPromise | +| tainted-promise-steps.js:11:25:11:35 | pathPromise [PromiseValue] | semmle.label | pathPromise [PromiseValue] | +| tainted-promise-steps.js:12:3:12:13 | pathPromise [PromiseValue] | semmle.label | pathPromise [PromiseValue] | +| tainted-promise-steps.js:12:20:12:23 | path | semmle.label | path | +| tainted-promise-steps.js:12:44:12:47 | path | semmle.label | path | +| tainted-require.js:7:19:7:37 | req.param("module") | semmle.label | req.param("module") | +| tainted-require.js:12:29:12:47 | req.param("module") | semmle.label | req.param("module") | +| tainted-require.js:14:11:14:29 | req.param("module") | semmle.label | req.param("module") | +| tainted-sendFile.js:8:16:8:33 | req.param("gimme") | semmle.label | req.param("gimme") | +| tainted-sendFile.js:10:16:10:33 | req.param("gimme") | semmle.label | req.param("gimme") | +| tainted-sendFile.js:18:43:18:58 | req.param("dir") | semmle.label | req.param("dir") | +| tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | semmle.label | path.re ... rams.x) | +| tainted-sendFile.js:24:37:24:48 | req.params.x | semmle.label | req.params.x | +| tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | semmle.label | path.jo ... rams.x) | +| tainted-sendFile.js:25:34:25:45 | req.params.x | semmle.label | req.params.x | +| tainted-string-steps.js:6:7:6:48 | path | semmle.label | path | +| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| tainted-string-steps.js:6:24:6:30 | req.url | semmle.label | req.url | +| tainted-string-steps.js:8:18:8:21 | path | semmle.label | path | +| tainted-string-steps.js:8:18:8:34 | path.substring(4) | semmle.label | path.substring(4) | +| tainted-string-steps.js:9:18:9:21 | path | semmle.label | path | +| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | semmle.label | path.substring(0, i) | +| tainted-string-steps.js:10:18:10:21 | path | semmle.label | path | +| tainted-string-steps.js:10:18:10:31 | path.substr(4) | semmle.label | path.substr(4) | +| tainted-string-steps.js:11:18:11:21 | path | semmle.label | path | +| tainted-string-steps.js:11:18:11:30 | path.slice(4) | semmle.label | path.slice(4) | +| tainted-string-steps.js:13:18:13:21 | path | semmle.label | path | +| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | semmle.label | path.concat(unknown) | +| tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | semmle.label | unknown.concat(path) | +| tainted-string-steps.js:14:33:14:36 | path | semmle.label | path | +| tainted-string-steps.js:15:18:15:46 | unknown ... , path) | semmle.label | unknown ... , path) | +| tainted-string-steps.js:15:42:15:45 | path | semmle.label | path | +| tainted-string-steps.js:17:18:17:21 | path | semmle.label | path | +| tainted-string-steps.js:17:18:17:28 | path.trim() | semmle.label | path.trim() | +| tainted-string-steps.js:18:18:18:21 | path | semmle.label | path | +| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | semmle.label | path.toLowerCase() | +| tainted-string-steps.js:22:18:22:21 | path | semmle.label | path | +| tainted-string-steps.js:22:18:22:32 | path.split('/') | semmle.label | path.split('/') | +| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | semmle.label | path.split('/')[i] | +| tainted-string-steps.js:23:18:23:21 | path | semmle.label | path | +| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | semmle.label | path.split(/\\//) | +| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | semmle.label | path.split(/\\//)[i] | +| tainted-string-steps.js:24:18:24:21 | path | semmle.label | path | +| tainted-string-steps.js:24:18:24:32 | path.split("?") | semmle.label | path.split("?") | +| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | semmle.label | path.split("?")[0] | +| tainted-string-steps.js:26:18:26:21 | path | semmle.label | path | +| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | semmle.label | path.split(unknown) | +| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | semmle.label | path.sp ... hatever | +| tainted-string-steps.js:27:18:27:21 | path | semmle.label | path | +| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | semmle.label | path.split(unknown) | +| torrents.js:5:6:5:38 | name | semmle.label | name | +| torrents.js:5:13:5:38 | parseTo ... t).name | semmle.label | parseTo ... t).name | +| torrents.js:6:6:6:45 | loc | semmle.label | loc | +| torrents.js:6:12:6:45 | dir + " ... t.data" | semmle.label | dir + " ... t.data" | +| torrents.js:6:24:6:27 | name | semmle.label | name | +| torrents.js:7:25:7:27 | loc | semmle.label | loc | +| typescript.ts:9:7:9:48 | path | semmle.label | path | +| typescript.ts:9:14:9:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| typescript.ts:9:14:9:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| typescript.ts:9:14:9:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| typescript.ts:9:24:9:30 | req.url | semmle.label | req.url | +| typescript.ts:12:29:12:32 | path | semmle.label | path | +| typescript.ts:20:7:20:18 | path3 | semmle.label | path3 | +| typescript.ts:20:15:20:18 | path | semmle.label | path | +| typescript.ts:21:39:21:43 | path3 | semmle.label | path3 | +| typescript.ts:23:7:23:18 | path4 | semmle.label | path4 | +| typescript.ts:23:15:23:18 | path | semmle.label | path | +| typescript.ts:24:39:24:43 | path4 | semmle.label | path4 | +| typescript.ts:30:7:30:18 | path6 | semmle.label | path6 | +| typescript.ts:30:15:30:18 | path | semmle.label | path | +| typescript.ts:32:29:32:33 | path6 | semmle.label | path6 | +| views.js:1:43:1:55 | req.params[0] | semmle.label | req.params[0] | edges | TaintedPath-es6.js:7:7:7:44 | path | TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | | TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | TaintedPath-es6.js:7:7:7:44 | path | | TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | TaintedPath-es6.js:7:7:7:44 | path | | TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | | TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:15:45:15:48 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:15:45:15:48 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | | TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | | TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | | TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | | TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | | TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | | TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | | TaintedPath.js:38:3:38:44 | path | TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | | TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | | TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | | TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | | TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | | TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | | TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | | TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | | TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | | TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | | TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | | TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | | TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | | TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | | TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | | TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | | TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | | TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | | TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | | TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | | TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | | TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | | TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | | TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | | TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | | TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:87:48:87:60 | req.params[0] | TaintedPath.js:87:48:87:60 | req.params[0] | -| TaintedPath.js:95:30:95:31 | ev | TaintedPath.js:96:24:96:25 | ev | -| TaintedPath.js:95:30:95:31 | ev | TaintedPath.js:96:24:96:25 | ev | -| TaintedPath.js:95:30:95:31 | ev | TaintedPath.js:96:24:96:25 | ev | -| TaintedPath.js:95:30:95:31 | ev | TaintedPath.js:96:24:96:25 | ev | -| TaintedPath.js:95:30:95:31 | ev | TaintedPath.js:96:24:96:25 | ev | -| TaintedPath.js:95:30:95:31 | ev | TaintedPath.js:96:24:96:25 | ev | -| TaintedPath.js:95:30:95:31 | ev | TaintedPath.js:96:24:96:25 | ev | | TaintedPath.js:95:30:95:31 | ev | TaintedPath.js:96:24:96:25 | ev | | TaintedPath.js:96:24:96:25 | ev | TaintedPath.js:96:24:96:30 | ev.data | -| TaintedPath.js:96:24:96:25 | ev | TaintedPath.js:96:24:96:30 | ev.data | -| TaintedPath.js:96:24:96:25 | ev | TaintedPath.js:96:24:96:30 | ev.data | -| TaintedPath.js:96:24:96:25 | ev | TaintedPath.js:96:24:96:30 | ev.data | -| TaintedPath.js:96:24:96:30 | ev.data | TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:96:24:96:30 | ev.data | TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:96:24:96:30 | ev.data | TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:96:24:96:30 | ev.data | TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:96:24:96:30 | ev.data | TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:96:24:96:30 | ev.data | TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:96:24:96:30 | ev.data | TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | | TaintedPath.js:96:24:96:30 | ev.data | TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | | TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | | TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | | TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | | TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | | TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | | TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | | TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | | TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | | TaintedPath.js:104:32:104:39 | realpath | TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:104:32:104:39 | realpath | TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:104:32:104:39 | realpath | TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:104:32:104:39 | realpath | TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:104:32:104:39 | realpath | TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:104:32:104:39 | realpath | TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:104:32:104:39 | realpath | TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:104:32:104:39 | realpath | TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | | TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | | TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | | TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | | TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | | TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | | TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | | TaintedPath.js:142:7:142:48 | path | TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | | TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | | TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | | TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | | TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | | TaintedPath.js:146:7:146:29 | split | TaintedPath.js:148:19:148:23 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:148:19:148:23 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:148:19:148:23 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:148:19:148:23 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:152:19:152:23 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:152:19:152:23 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:152:19:152:23 | split | | TaintedPath.js:146:7:146:29 | split | TaintedPath.js:152:19:152:23 | split | | TaintedPath.js:146:7:146:29 | split | TaintedPath.js:153:28:153:32 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:153:28:153:32 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:153:28:153:32 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:153:28:153:32 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:155:33:155:37 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:155:33:155:37 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:155:33:155:37 | split | | TaintedPath.js:146:7:146:29 | split | TaintedPath.js:155:33:155:37 | split | | TaintedPath.js:146:7:146:29 | split | TaintedPath.js:158:20:158:24 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:158:20:158:24 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:158:20:158:24 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:158:20:158:24 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:161:19:161:23 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:161:19:161:23 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:161:19:161:23 | split | | TaintedPath.js:146:7:146:29 | split | TaintedPath.js:161:19:161:23 | split | | TaintedPath.js:146:15:146:18 | path | TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:18 | path | TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:18 | path | TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:18 | path | TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:18 | path | TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:18 | path | TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:18 | path | TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:18 | path | TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:18 | path | TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:18 | path | TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:18 | path | TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:18 | path | TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:29 | path.split("/") | TaintedPath.js:146:7:146:29 | split | -| TaintedPath.js:146:15:146:29 | path.split("/") | TaintedPath.js:146:7:146:29 | split | -| TaintedPath.js:146:15:146:29 | path.split("/") | TaintedPath.js:146:7:146:29 | split | | TaintedPath.js:146:15:146:29 | path.split("/") | TaintedPath.js:146:7:146:29 | split | | TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | | TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | | TaintedPath.js:153:28:153:32 | split | TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:32 | split | TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:32 | split | TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:32 | split | TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:32 | split | TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:32 | split | TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:32 | split | TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:32 | split | TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:32 | split | TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:32 | split | TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:32 | split | TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:32 | split | TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | | TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | | TaintedPath.js:155:7:155:38 | concatted | TaintedPath.js:156:19:156:27 | concatted | -| TaintedPath.js:155:7:155:38 | concatted | TaintedPath.js:156:19:156:27 | concatted | -| TaintedPath.js:155:7:155:38 | concatted | TaintedPath.js:156:19:156:27 | concatted | -| TaintedPath.js:155:7:155:38 | concatted | TaintedPath.js:156:19:156:27 | concatted | -| TaintedPath.js:155:19:155:38 | prefix.concat(split) | TaintedPath.js:155:7:155:38 | concatted | -| TaintedPath.js:155:19:155:38 | prefix.concat(split) | TaintedPath.js:155:7:155:38 | concatted | -| TaintedPath.js:155:19:155:38 | prefix.concat(split) | TaintedPath.js:155:7:155:38 | concatted | | TaintedPath.js:155:19:155:38 | prefix.concat(split) | TaintedPath.js:155:7:155:38 | concatted | | TaintedPath.js:155:33:155:37 | split | TaintedPath.js:155:19:155:38 | prefix.concat(split) | -| TaintedPath.js:155:33:155:37 | split | TaintedPath.js:155:19:155:38 | prefix.concat(split) | -| TaintedPath.js:155:33:155:37 | split | TaintedPath.js:155:19:155:38 | prefix.concat(split) | -| TaintedPath.js:155:33:155:37 | split | TaintedPath.js:155:19:155:38 | prefix.concat(split) | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | | TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | | TaintedPath.js:158:7:158:39 | concatted2 | TaintedPath.js:159:19:159:28 | concatted2 | -| TaintedPath.js:158:7:158:39 | concatted2 | TaintedPath.js:159:19:159:28 | concatted2 | -| TaintedPath.js:158:7:158:39 | concatted2 | TaintedPath.js:159:19:159:28 | concatted2 | -| TaintedPath.js:158:7:158:39 | concatted2 | TaintedPath.js:159:19:159:28 | concatted2 | -| TaintedPath.js:158:20:158:24 | split | TaintedPath.js:158:20:158:39 | split.concat(prefix) | -| TaintedPath.js:158:20:158:24 | split | TaintedPath.js:158:20:158:39 | split.concat(prefix) | -| TaintedPath.js:158:20:158:24 | split | TaintedPath.js:158:20:158:39 | split.concat(prefix) | | TaintedPath.js:158:20:158:24 | split | TaintedPath.js:158:20:158:39 | split.concat(prefix) | | TaintedPath.js:158:20:158:39 | split.concat(prefix) | TaintedPath.js:158:7:158:39 | concatted2 | -| TaintedPath.js:158:20:158:39 | split.concat(prefix) | TaintedPath.js:158:7:158:39 | concatted2 | -| TaintedPath.js:158:20:158:39 | split.concat(prefix) | TaintedPath.js:158:7:158:39 | concatted2 | -| TaintedPath.js:158:20:158:39 | split.concat(prefix) | TaintedPath.js:158:7:158:39 | concatted2 | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | | TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | | TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | | TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | | TaintedPath.js:166:7:166:48 | path | TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:177:29:177:32 | path | | TaintedPath.js:166:7:166:48 | path | TaintedPath.js:177:29:177:32 | path | | TaintedPath.js:166:7:166:48 | path | TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:179:29:179:32 | path | | TaintedPath.js:166:7:166:48 | path | TaintedPath.js:179:29:179:32 | path | | TaintedPath.js:166:7:166:48 | path | TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:195:50:195:53 | path | | TaintedPath.js:166:7:166:48 | path | TaintedPath.js:195:50:195:53 | path | | TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | | TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | | TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | | TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | | TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | | TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | | TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | | TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | | TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | | TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | | TaintedPath.js:195:29:195:54 | pathMod ... e(path) | TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:50:195:53 | path | TaintedPath.js:195:29:195:54 | pathMod ... e(path) | -| TaintedPath.js:195:50:195:53 | path | TaintedPath.js:195:29:195:54 | pathMod ... e(path) | -| TaintedPath.js:195:50:195:53 | path | TaintedPath.js:195:29:195:54 | pathMod ... e(path) | -| TaintedPath.js:195:50:195:53 | path | TaintedPath.js:195:29:195:54 | pathMod ... e(path) | -| TaintedPath.js:195:50:195:53 | path | TaintedPath.js:195:29:195:54 | pathMod ... e(path) | -| TaintedPath.js:195:50:195:53 | path | TaintedPath.js:195:29:195:54 | pathMod ... e(path) | -| TaintedPath.js:195:50:195:53 | path | TaintedPath.js:195:29:195:54 | pathMod ... e(path) | | TaintedPath.js:195:50:195:53 | path | TaintedPath.js:195:29:195:54 | pathMod ... e(path) | | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | | TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | | TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | | TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | | TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | | TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | | TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | | TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | | TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | | TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | | TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | | TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | -| handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | -| handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | -| handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | -| handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | -| handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | -| handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | -| handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | | handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | | handlebars.js:13:73:13:80 | filePath | handlebars.js:15:25:15:32 | filePath | -| handlebars.js:13:73:13:80 | filePath | handlebars.js:15:25:15:32 | filePath | -| handlebars.js:13:73:13:80 | filePath | handlebars.js:15:25:15:32 | filePath | -| handlebars.js:13:73:13:80 | filePath | handlebars.js:15:25:15:32 | filePath | -| handlebars.js:13:73:13:80 | filePath | handlebars.js:15:25:15:32 | filePath | -| handlebars.js:13:73:13:80 | filePath | handlebars.js:15:25:15:32 | filePath | -| handlebars.js:13:73:13:80 | filePath | handlebars.js:15:25:15:32 | filePath | -| handlebars.js:13:73:13:80 | filePath | handlebars.js:15:25:15:32 | filePath | -| handlebars.js:29:46:29:60 | req.params.path | handlebars.js:10:51:10:58 | filePath | -| handlebars.js:29:46:29:60 | req.params.path | handlebars.js:10:51:10:58 | filePath | -| handlebars.js:29:46:29:60 | req.params.path | handlebars.js:10:51:10:58 | filePath | -| handlebars.js:29:46:29:60 | req.params.path | handlebars.js:10:51:10:58 | filePath | -| handlebars.js:29:46:29:60 | req.params.path | handlebars.js:10:51:10:58 | filePath | -| handlebars.js:29:46:29:60 | req.params.path | handlebars.js:10:51:10:58 | filePath | -| handlebars.js:29:46:29:60 | req.params.path | handlebars.js:10:51:10:58 | filePath | | handlebars.js:29:46:29:60 | req.params.path | handlebars.js:10:51:10:58 | filePath | | handlebars.js:43:15:43:29 | req.params.path | handlebars.js:13:73:13:80 | filePath | -| handlebars.js:43:15:43:29 | req.params.path | handlebars.js:13:73:13:80 | filePath | -| handlebars.js:43:15:43:29 | req.params.path | handlebars.js:13:73:13:80 | filePath | -| handlebars.js:43:15:43:29 | req.params.path | handlebars.js:13:73:13:80 | filePath | -| handlebars.js:43:15:43:29 | req.params.path | handlebars.js:13:73:13:80 | filePath | -| handlebars.js:43:15:43:29 | req.params.path | handlebars.js:13:73:13:80 | filePath | -| handlebars.js:43:15:43:29 | req.params.path | handlebars.js:13:73:13:80 | filePath | -| handlebars.js:43:15:43:29 | req.params.path | handlebars.js:13:73:13:80 | filePath | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | | normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | | normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:14:26:14:29 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:14:26:14:29 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:14:26:14:29 | path | | normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:15:19:15:22 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:15:19:15:22 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:15:19:15:22 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:15:19:15:22 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:16:35:16:38 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:16:35:16:38 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:16:35:16:38 | path | | normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:16:35:16:38 | path | | normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:17:53:17:56 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:17:53:17:56 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:17:53:17:56 | path | -| normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | -| normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | -| normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | -| normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | -| normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | -| normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | -| normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | | normalizedPaths.js:14:26:14:29 | path | normalizedPaths.js:14:19:14:29 | './' + path | -| normalizedPaths.js:14:26:14:29 | path | normalizedPaths.js:14:19:14:29 | './' + path | -| normalizedPaths.js:14:26:14:29 | path | normalizedPaths.js:14:19:14:29 | './' + path | -| normalizedPaths.js:14:26:14:29 | path | normalizedPaths.js:14:19:14:29 | './' + path | -| normalizedPaths.js:14:26:14:29 | path | normalizedPaths.js:14:19:14:29 | './' + path | -| normalizedPaths.js:14:26:14:29 | path | normalizedPaths.js:14:19:14:29 | './' + path | | normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | | normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | | normalizedPaths.js:17:53:17:56 | path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | -| normalizedPaths.js:17:53:17:56 | path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | -| normalizedPaths.js:17:53:17:56 | path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | -| normalizedPaths.js:17:53:17:56 | path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | -| normalizedPaths.js:17:53:17:56 | path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | -| normalizedPaths.js:17:53:17:56 | path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | | normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | | normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:24:26:24:29 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:24:26:24:29 | path | | normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:25:19:25:22 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:25:19:25:22 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:25:19:25:22 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:25:19:25:22 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:26:35:26:38 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:26:35:26:38 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:26:35:26:38 | path | | normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:26:35:26:38 | path | | normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:27:53:27:56 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:27:53:27:56 | path | -| normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | normalizedPaths.js:21:7:21:49 | path | -| normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | normalizedPaths.js:21:7:21:49 | path | -| normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | normalizedPaths.js:21:7:21:49 | path | | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | normalizedPaths.js:21:7:21:49 | path | | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:24:26:24:29 | path | normalizedPaths.js:24:19:24:29 | './' + path | -| normalizedPaths.js:24:26:24:29 | path | normalizedPaths.js:24:19:24:29 | './' + path | -| normalizedPaths.js:24:26:24:29 | path | normalizedPaths.js:24:19:24:29 | './' + path | | normalizedPaths.js:24:26:24:29 | path | normalizedPaths.js:24:19:24:29 | './' + path | | normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | | normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | | normalizedPaths.js:27:53:27:56 | path | normalizedPaths.js:27:19:27:57 | pathMod ... , path) | -| normalizedPaths.js:27:53:27:56 | path | normalizedPaths.js:27:19:27:57 | pathMod ... , path) | -| normalizedPaths.js:27:53:27:56 | path | normalizedPaths.js:27:19:27:57 | pathMod ... , path) | -| normalizedPaths.js:27:53:27:56 | path | normalizedPaths.js:27:19:27:57 | pathMod ... , path) | | normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:36:19:36:22 | path | -| normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:36:19:36:22 | path | -| normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:36:19:36:22 | path | -| normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:36:19:36:22 | path | -| normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:41:21:41:24 | path | -| normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:41:21:41:24 | path | -| normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:41:21:41:24 | path | | normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:41:21:41:24 | path | | normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | normalizedPaths.js:31:7:31:49 | path | -| normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | normalizedPaths.js:31:7:31:49 | path | | normalizedPaths.js:31:35:31:48 | req.query.path | normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | -| normalizedPaths.js:31:35:31:48 | req.query.path | normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | -| normalizedPaths.js:31:35:31:48 | req.query.path | normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | -| normalizedPaths.js:31:35:31:48 | req.query.path | normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | -| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:59:19:59:22 | path | -| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:59:19:59:22 | path | -| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:59:19:59:22 | path | | normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:59:19:59:22 | path | | normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:63:19:63:22 | path | -| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:63:19:63:22 | path | -| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:68:21:68:24 | path | -| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:68:21:68:24 | path | -| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:68:21:68:24 | path | | normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:68:21:68:24 | path | | normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | normalizedPaths.js:54:7:54:49 | path | -| normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | normalizedPaths.js:54:7:54:49 | path | -| normalizedPaths.js:54:35:54:48 | req.query.path | normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | -| normalizedPaths.js:54:35:54:48 | req.query.path | normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | -| normalizedPaths.js:54:35:54:48 | req.query.path | normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | | normalizedPaths.js:54:35:54:48 | req.query.path | normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | | normalizedPaths.js:63:19:63:22 | path | normalizedPaths.js:63:19:63:38 | path + "/index.html" | -| normalizedPaths.js:63:19:63:22 | path | normalizedPaths.js:63:19:63:38 | path + "/index.html" | -| normalizedPaths.js:63:19:63:22 | path | normalizedPaths.js:63:19:63:38 | path + "/index.html" | -| normalizedPaths.js:63:19:63:22 | path | normalizedPaths.js:63:19:63:38 | path + "/index.html" | -| normalizedPaths.js:73:7:73:56 | path | normalizedPaths.js:78:22:78:25 | path | -| normalizedPaths.js:73:7:73:56 | path | normalizedPaths.js:78:22:78:25 | path | -| normalizedPaths.js:73:7:73:56 | path | normalizedPaths.js:78:22:78:25 | path | -| normalizedPaths.js:73:7:73:56 | path | normalizedPaths.js:78:22:78:25 | path | -| normalizedPaths.js:73:7:73:56 | path | normalizedPaths.js:78:22:78:25 | path | | normalizedPaths.js:73:7:73:56 | path | normalizedPaths.js:78:22:78:25 | path | | normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | normalizedPaths.js:73:7:73:56 | path | -| normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | normalizedPaths.js:73:7:73:56 | path | -| normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | normalizedPaths.js:73:7:73:56 | path | -| normalizedPaths.js:73:35:73:55 | './' + ... ry.path | normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | -| normalizedPaths.js:73:35:73:55 | './' + ... ry.path | normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | | normalizedPaths.js:73:35:73:55 | './' + ... ry.path | normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | | normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:73:35:73:55 | './' + ... ry.path | -| normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:73:35:73:55 | './' + ... ry.path | -| normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:73:35:73:55 | './' + ... ry.path | -| normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:73:35:73:55 | './' + ... ry.path | -| normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:73:35:73:55 | './' + ... ry.path | -| normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:73:35:73:55 | './' + ... ry.path | -| normalizedPaths.js:82:7:82:27 | path | normalizedPaths.js:87:29:87:32 | path | -| normalizedPaths.js:82:7:82:27 | path | normalizedPaths.js:87:29:87:32 | path | -| normalizedPaths.js:82:7:82:27 | path | normalizedPaths.js:87:29:87:32 | path | | normalizedPaths.js:82:7:82:27 | path | normalizedPaths.js:87:29:87:32 | path | | normalizedPaths.js:82:7:82:27 | path | normalizedPaths.js:90:31:90:34 | path | -| normalizedPaths.js:82:7:82:27 | path | normalizedPaths.js:90:31:90:34 | path | | normalizedPaths.js:82:14:82:27 | req.query.path | normalizedPaths.js:82:7:82:27 | path | -| normalizedPaths.js:82:14:82:27 | req.query.path | normalizedPaths.js:82:7:82:27 | path | -| normalizedPaths.js:82:14:82:27 | req.query.path | normalizedPaths.js:82:7:82:27 | path | -| normalizedPaths.js:82:14:82:27 | req.query.path | normalizedPaths.js:82:7:82:27 | path | -| normalizedPaths.js:94:7:94:49 | path | normalizedPaths.js:99:29:99:32 | path | -| normalizedPaths.js:94:7:94:49 | path | normalizedPaths.js:99:29:99:32 | path | -| normalizedPaths.js:94:7:94:49 | path | normalizedPaths.js:99:29:99:32 | path | | normalizedPaths.js:94:7:94:49 | path | normalizedPaths.js:99:29:99:32 | path | | normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | normalizedPaths.js:94:7:94:49 | path | -| normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | normalizedPaths.js:94:7:94:49 | path | -| normalizedPaths.js:94:35:94:48 | req.query.path | normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | -| normalizedPaths.js:94:35:94:48 | req.query.path | normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | -| normalizedPaths.js:94:35:94:48 | req.query.path | normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | | normalizedPaths.js:94:35:94:48 | req.query.path | normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | | normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:120:35:120:38 | path | -| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:120:35:120:38 | path | -| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:120:35:120:38 | path | | normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:120:35:120:38 | path | | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | normalizedPaths.js:117:7:117:44 | path | -| normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | normalizedPaths.js:117:7:117:44 | path | -| normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | normalizedPaths.js:117:7:117:44 | path | -| normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | normalizedPaths.js:117:7:117:44 | path | -| normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | -| normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | -| normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | -| normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | -| normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | -| normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | -| normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | | normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | | normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:130:7:130:49 | path | normalizedPaths.js:135:21:135:24 | path | -| normalizedPaths.js:130:7:130:49 | path | normalizedPaths.js:135:21:135:24 | path | -| normalizedPaths.js:130:7:130:49 | path | normalizedPaths.js:135:21:135:24 | path | -| normalizedPaths.js:130:7:130:49 | path | normalizedPaths.js:135:21:135:24 | path | -| normalizedPaths.js:130:7:130:49 | path | normalizedPaths.js:135:21:135:24 | path | | normalizedPaths.js:130:7:130:49 | path | normalizedPaths.js:135:21:135:24 | path | | normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | normalizedPaths.js:130:7:130:49 | path | -| normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | normalizedPaths.js:130:7:130:49 | path | -| normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | normalizedPaths.js:130:7:130:49 | path | | normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | -| normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | -| normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | -| normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | -| normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | -| normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | -| normalizedPaths.js:139:7:139:62 | path | normalizedPaths.js:144:21:144:24 | path | -| normalizedPaths.js:139:7:139:62 | path | normalizedPaths.js:144:21:144:24 | path | -| normalizedPaths.js:139:7:139:62 | path | normalizedPaths.js:144:21:144:24 | path | -| normalizedPaths.js:139:7:139:62 | path | normalizedPaths.js:144:21:144:24 | path | -| normalizedPaths.js:139:7:139:62 | path | normalizedPaths.js:144:21:144:24 | path | | normalizedPaths.js:139:7:139:62 | path | normalizedPaths.js:144:21:144:24 | path | | normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | normalizedPaths.js:139:7:139:62 | path | -| normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | normalizedPaths.js:139:7:139:62 | path | -| normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | normalizedPaths.js:139:7:139:62 | path | -| normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | -| normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | -| normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | -| normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | -| normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | | normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | | normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:151:21:151:24 | path | -| normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:151:21:151:24 | path | -| normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:151:21:151:24 | path | -| normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:151:21:151:24 | path | -| normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:153:21:153:24 | path | -| normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:153:21:153:24 | path | -| normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:153:21:153:24 | path | | normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:153:21:153:24 | path | | normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | normalizedPaths.js:148:7:148:58 | path | -| normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | normalizedPaths.js:148:7:148:58 | path | -| normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | | normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | | normalizedPaths.js:148:44:148:57 | req.query.path | normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | -| normalizedPaths.js:148:44:148:57 | req.query.path | normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | -| normalizedPaths.js:148:44:148:57 | req.query.path | normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | -| normalizedPaths.js:148:44:148:57 | req.query.path | normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | | normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:165:19:165:22 | path | -| normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:165:19:165:22 | path | -| normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:165:19:165:22 | path | -| normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:165:19:165:22 | path | -| normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:170:21:170:24 | path | -| normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:170:21:170:24 | path | -| normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:170:21:170:24 | path | | normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:170:21:170:24 | path | | normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | normalizedPaths.js:160:7:160:49 | path | -| normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | normalizedPaths.js:160:7:160:49 | path | -| normalizedPaths.js:160:35:160:48 | req.query.path | normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | -| normalizedPaths.js:160:35:160:48 | req.query.path | normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | -| normalizedPaths.js:160:35:160:48 | req.query.path | normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | | normalizedPaths.js:160:35:160:48 | req.query.path | normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:187:21:187:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:187:21:187:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:187:21:187:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:187:21:187:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:189:21:189:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:189:21:189:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:189:21:189:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:189:21:189:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:194:21:194:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:194:21:194:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:201:45:201:48 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:201:45:201:48 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:201:45:201:48 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:201:45:201:48 | path | -| normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | -| normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | -| normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | -| normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | -| normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | -| normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | -| normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | | normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | | normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | | normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | | normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | normalizedPaths.js:201:7:201:49 | normalizedPath | -| normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | normalizedPaths.js:201:7:201:49 | normalizedPath | -| normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | normalizedPaths.js:201:7:201:49 | normalizedPath | -| normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | normalizedPaths.js:201:7:201:49 | normalizedPath | -| normalizedPaths.js:201:45:201:48 | path | normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | -| normalizedPaths.js:201:45:201:48 | path | normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | -| normalizedPaths.js:201:45:201:48 | path | normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | | normalizedPaths.js:201:45:201:48 | path | normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | | normalizedPaths.js:214:7:214:49 | path | normalizedPaths.js:219:29:219:32 | path | -| normalizedPaths.js:214:7:214:49 | path | normalizedPaths.js:219:29:219:32 | path | -| normalizedPaths.js:214:7:214:49 | path | normalizedPaths.js:219:29:219:32 | path | -| normalizedPaths.js:214:7:214:49 | path | normalizedPaths.js:219:29:219:32 | path | -| normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | normalizedPaths.js:214:7:214:49 | path | -| normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | normalizedPaths.js:214:7:214:49 | path | -| normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | normalizedPaths.js:214:7:214:49 | path | | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | normalizedPaths.js:214:7:214:49 | path | | normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | | normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | | normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | normalizedPaths.js:219:3:219:33 | path | -| normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | normalizedPaths.js:219:3:219:33 | path | -| normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | normalizedPaths.js:219:3:219:33 | path | -| normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | normalizedPaths.js:219:3:219:33 | path | | normalizedPaths.js:219:29:219:32 | path | normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | -| normalizedPaths.js:219:29:219:32 | path | normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | -| normalizedPaths.js:219:29:219:32 | path | normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | -| normalizedPaths.js:219:29:219:32 | path | normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | -| normalizedPaths.js:226:7:226:70 | path | normalizedPaths.js:228:21:228:24 | path | -| normalizedPaths.js:226:7:226:70 | path | normalizedPaths.js:228:21:228:24 | path | -| normalizedPaths.js:226:7:226:70 | path | normalizedPaths.js:228:21:228:24 | path | | normalizedPaths.js:226:7:226:70 | path | normalizedPaths.js:228:21:228:24 | path | | normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | -| normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | -| normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | normalizedPaths.js:226:7:226:70 | path | | normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | normalizedPaths.js:226:7:226:70 | path | | normalizedPaths.js:226:35:226:48 | req.query.path | normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | -| normalizedPaths.js:226:35:226:48 | req.query.path | normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | -| normalizedPaths.js:226:35:226:48 | req.query.path | normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | -| normalizedPaths.js:226:35:226:48 | req.query.path | normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:238:19:238:22 | path | | normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:238:19:238:22 | path | | normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:250:21:250:24 | path | | normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:250:21:250:24 | path | | normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | normalizedPaths.js:236:7:236:47 | path | -| normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | normalizedPaths.js:236:7:236:47 | path | -| normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | normalizedPaths.js:236:7:236:47 | path | -| normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | normalizedPaths.js:236:7:236:47 | path | -| normalizedPaths.js:236:33:236:46 | req.query.path | normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | -| normalizedPaths.js:236:33:236:46 | req.query.path | normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | -| normalizedPaths.js:236:33:236:46 | req.query.path | normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | -| normalizedPaths.js:236:33:236:46 | req.query.path | normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | -| normalizedPaths.js:236:33:236:46 | req.query.path | normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | -| normalizedPaths.js:236:33:236:46 | req.query.path | normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | -| normalizedPaths.js:236:33:236:46 | req.query.path | normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | | normalizedPaths.js:236:33:236:46 | req.query.path | normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | | normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:262:21:262:24 | path | | normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:262:21:262:24 | path | | normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:267:38:267:41 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:267:38:267:41 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:267:38:267:41 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:267:38:267:41 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:275:38:275:41 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:275:38:275:41 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:275:38:275:41 | path | | normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:275:38:275:41 | path | | normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:283:38:283:41 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:283:38:283:41 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:283:38:283:41 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:283:38:283:41 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:291:38:291:41 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:291:38:291:41 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:291:38:291:41 | path | | normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:291:38:291:41 | path | | normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | normalizedPaths.js:254:7:254:47 | path | -| normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | normalizedPaths.js:254:7:254:47 | path | -| normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | normalizedPaths.js:254:7:254:47 | path | -| normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | normalizedPaths.js:254:7:254:47 | path | | normalizedPaths.js:254:33:254:46 | req.query.path | normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:254:33:254:46 | req.query.path | normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:254:33:254:46 | req.query.path | normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:254:33:254:46 | req.query.path | normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:254:33:254:46 | req.query.path | normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:254:33:254:46 | req.query.path | normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:254:33:254:46 | req.query.path | normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:254:33:254:46 | req.query.path | normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:267:7:267:42 | newpath | normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:267:7:267:42 | newpath | normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:267:7:267:42 | newpath | normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:267:7:267:42 | newpath | normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:267:7:267:42 | newpath | normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:267:7:267:42 | newpath | normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:267:7:267:42 | newpath | normalizedPaths.js:270:21:270:27 | newpath | | normalizedPaths.js:267:7:267:42 | newpath | normalizedPaths.js:270:21:270:27 | newpath | | normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | normalizedPaths.js:267:7:267:42 | newpath | -| normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | normalizedPaths.js:267:7:267:42 | newpath | -| normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | normalizedPaths.js:267:7:267:42 | newpath | -| normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | normalizedPaths.js:267:7:267:42 | newpath | -| normalizedPaths.js:267:38:267:41 | path | normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | -| normalizedPaths.js:267:38:267:41 | path | normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | -| normalizedPaths.js:267:38:267:41 | path | normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | | normalizedPaths.js:267:38:267:41 | path | normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | | normalizedPaths.js:275:7:275:42 | newpath | normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:275:7:275:42 | newpath | normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:275:7:275:42 | newpath | normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:275:7:275:42 | newpath | normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:275:7:275:42 | newpath | normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:275:7:275:42 | newpath | normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:275:7:275:42 | newpath | normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:275:7:275:42 | newpath | normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | normalizedPaths.js:275:7:275:42 | newpath | -| normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | normalizedPaths.js:275:7:275:42 | newpath | -| normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | normalizedPaths.js:275:7:275:42 | newpath | | normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | normalizedPaths.js:275:7:275:42 | newpath | | normalizedPaths.js:275:38:275:41 | path | normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | -| normalizedPaths.js:275:38:275:41 | path | normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | -| normalizedPaths.js:275:38:275:41 | path | normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | -| normalizedPaths.js:275:38:275:41 | path | normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | -| normalizedPaths.js:283:7:283:42 | newpath | normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:283:7:283:42 | newpath | normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:283:7:283:42 | newpath | normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:283:7:283:42 | newpath | normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:283:7:283:42 | newpath | normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:283:7:283:42 | newpath | normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:283:7:283:42 | newpath | normalizedPaths.js:286:21:286:27 | newpath | | normalizedPaths.js:283:7:283:42 | newpath | normalizedPaths.js:286:21:286:27 | newpath | | normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | normalizedPaths.js:283:7:283:42 | newpath | -| normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | normalizedPaths.js:283:7:283:42 | newpath | -| normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | normalizedPaths.js:283:7:283:42 | newpath | -| normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | normalizedPaths.js:283:7:283:42 | newpath | -| normalizedPaths.js:283:38:283:41 | path | normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | -| normalizedPaths.js:283:38:283:41 | path | normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | -| normalizedPaths.js:283:38:283:41 | path | normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | | normalizedPaths.js:283:38:283:41 | path | normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | | normalizedPaths.js:291:7:291:42 | newpath | normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:291:7:291:42 | newpath | normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:291:7:291:42 | newpath | normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:291:7:291:42 | newpath | normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:291:7:291:42 | newpath | normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:291:7:291:42 | newpath | normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:291:7:291:42 | newpath | normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:291:7:291:42 | newpath | normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | normalizedPaths.js:291:7:291:42 | newpath | -| normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | normalizedPaths.js:291:7:291:42 | newpath | -| normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | normalizedPaths.js:291:7:291:42 | newpath | | normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | normalizedPaths.js:291:7:291:42 | newpath | | normalizedPaths.js:291:38:291:41 | path | normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | -| normalizedPaths.js:291:38:291:41 | path | normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | -| normalizedPaths.js:291:38:291:41 | path | normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | -| normalizedPaths.js:291:38:291:41 | path | normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | | normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:309:19:309:22 | path | | normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:309:19:309:22 | path | | normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:313:19:313:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:313:19:313:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:313:19:313:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:313:19:313:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:313:19:313:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:313:19:313:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:316:19:316:22 | path | | normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:316:19:316:22 | path | | normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:320:45:320:48 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:320:45:320:48 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:320:45:320:48 | path | -| normalizedPaths.js:303:13:303:26 | req.query.path | normalizedPaths.js:303:6:303:26 | path | -| normalizedPaths.js:303:13:303:26 | req.query.path | normalizedPaths.js:303:6:303:26 | path | -| normalizedPaths.js:303:13:303:26 | req.query.path | normalizedPaths.js:303:6:303:26 | path | -| normalizedPaths.js:303:13:303:26 | req.query.path | normalizedPaths.js:303:6:303:26 | path | -| normalizedPaths.js:303:13:303:26 | req.query.path | normalizedPaths.js:303:6:303:26 | path | -| normalizedPaths.js:303:13:303:26 | req.query.path | normalizedPaths.js:303:6:303:26 | path | -| normalizedPaths.js:303:13:303:26 | req.query.path | normalizedPaths.js:303:6:303:26 | path | | normalizedPaths.js:303:13:303:26 | req.query.path | normalizedPaths.js:303:6:303:26 | path | | normalizedPaths.js:320:6:320:49 | normalizedPath | normalizedPaths.js:325:19:325:32 | normalizedPath | -| normalizedPaths.js:320:6:320:49 | normalizedPath | normalizedPaths.js:325:19:325:32 | normalizedPath | -| normalizedPaths.js:320:6:320:49 | normalizedPath | normalizedPaths.js:325:19:325:32 | normalizedPath | -| normalizedPaths.js:320:6:320:49 | normalizedPath | normalizedPaths.js:325:19:325:32 | normalizedPath | -| normalizedPaths.js:320:6:320:49 | normalizedPath | normalizedPaths.js:325:19:325:32 | normalizedPath | -| normalizedPaths.js:320:6:320:49 | normalizedPath | normalizedPaths.js:325:19:325:32 | normalizedPath | -| normalizedPaths.js:320:6:320:49 | normalizedPath | normalizedPaths.js:332:19:332:32 | normalizedPath | -| normalizedPaths.js:320:6:320:49 | normalizedPath | normalizedPaths.js:332:19:332:32 | normalizedPath | -| normalizedPaths.js:320:6:320:49 | normalizedPath | normalizedPaths.js:332:19:332:32 | normalizedPath | -| normalizedPaths.js:320:6:320:49 | normalizedPath | normalizedPaths.js:332:19:332:32 | normalizedPath | -| normalizedPaths.js:320:6:320:49 | normalizedPath | normalizedPaths.js:332:19:332:32 | normalizedPath | | normalizedPaths.js:320:6:320:49 | normalizedPath | normalizedPaths.js:332:19:332:32 | normalizedPath | | normalizedPaths.js:320:23:320:49 | pathMod ... , path) | normalizedPaths.js:320:6:320:49 | normalizedPath | -| normalizedPaths.js:320:23:320:49 | pathMod ... , path) | normalizedPaths.js:320:6:320:49 | normalizedPath | -| normalizedPaths.js:320:23:320:49 | pathMod ... , path) | normalizedPaths.js:320:6:320:49 | normalizedPath | -| normalizedPaths.js:320:45:320:48 | path | normalizedPaths.js:320:23:320:49 | pathMod ... , path) | -| normalizedPaths.js:320:45:320:48 | path | normalizedPaths.js:320:23:320:49 | pathMod ... , path) | | normalizedPaths.js:320:45:320:48 | path | normalizedPaths.js:320:23:320:49 | pathMod ... , path) | | normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:346:19:346:22 | path | | normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:346:19:346:22 | path | | normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | normalizedPaths.js:339:6:339:46 | path | -| normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | normalizedPaths.js:339:6:339:46 | path | -| normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | normalizedPaths.js:339:6:339:46 | path | -| normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | normalizedPaths.js:339:6:339:46 | path | | normalizedPaths.js:339:32:339:45 | req.query.path | normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:339:32:339:45 | req.query.path | normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:339:32:339:45 | req.query.path | normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:339:32:339:45 | req.query.path | normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:339:32:339:45 | req.query.path | normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:339:32:339:45 | req.query.path | normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:339:32:339:45 | req.query.path | normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:339:32:339:45 | req.query.path | normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path | | normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path | | normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:358:47:358:50 | path | -| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:358:47:358:50 | path | -| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:358:47:358:50 | path | | normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:358:7:358:51 | requestPath | normalizedPaths.js:363:21:363:31 | requestPath | -| normalizedPaths.js:358:7:358:51 | requestPath | normalizedPaths.js:363:21:363:31 | requestPath | -| normalizedPaths.js:358:7:358:51 | requestPath | normalizedPaths.js:363:21:363:31 | requestPath | -| normalizedPaths.js:358:7:358:51 | requestPath | normalizedPaths.js:363:21:363:31 | requestPath | -| normalizedPaths.js:358:7:358:51 | requestPath | normalizedPaths.js:363:21:363:31 | requestPath | | normalizedPaths.js:358:7:358:51 | requestPath | normalizedPaths.js:363:21:363:31 | requestPath | | normalizedPaths.js:358:21:358:51 | pathMod ... , path) | normalizedPaths.js:358:7:358:51 | requestPath | -| normalizedPaths.js:358:21:358:51 | pathMod ... , path) | normalizedPaths.js:358:7:358:51 | requestPath | -| normalizedPaths.js:358:21:358:51 | pathMod ... , path) | normalizedPaths.js:358:7:358:51 | requestPath | -| normalizedPaths.js:358:47:358:50 | path | normalizedPaths.js:358:21:358:51 | pathMod ... , path) | -| normalizedPaths.js:358:47:358:50 | path | normalizedPaths.js:358:21:358:51 | pathMod ... , path) | | normalizedPaths.js:358:47:358:50 | path | normalizedPaths.js:358:21:358:51 | pathMod ... , path) | | normalizedPaths.js:377:7:377:27 | path | normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:377:7:377:27 | path | normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:377:7:377:27 | path | normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:377:7:377:27 | path | normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:377:7:377:27 | path | normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:377:7:377:27 | path | normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:377:7:377:27 | path | normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:377:7:377:27 | path | normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:377:7:377:27 | path | normalizedPaths.js:381:25:381:28 | path | -| normalizedPaths.js:377:7:377:27 | path | normalizedPaths.js:381:25:381:28 | path | -| normalizedPaths.js:377:7:377:27 | path | normalizedPaths.js:381:25:381:28 | path | | normalizedPaths.js:377:7:377:27 | path | normalizedPaths.js:381:25:381:28 | path | | normalizedPaths.js:377:14:377:27 | req.query.path | normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:377:14:377:27 | req.query.path | normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:377:14:377:27 | req.query.path | normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:377:14:377:27 | req.query.path | normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:377:14:377:27 | req.query.path | normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:377:14:377:27 | req.query.path | normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:377:14:377:27 | req.query.path | normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:377:14:377:27 | req.query.path | normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:381:25:381:28 | path | normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:381:25:381:28 | path | normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:381:25:381:28 | path | normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:381:25:381:28 | path | normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:381:25:381:28 | path | normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:381:25:381:28 | path | normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:381:25:381:28 | path | normalizedPaths.js:381:19:381:29 | slash(path) | | normalizedPaths.js:381:25:381:28 | path | normalizedPaths.js:381:19:381:29 | slash(path) | | normalizedPaths.js:385:7:385:46 | path | normalizedPaths.js:388:19:388:22 | path | -| normalizedPaths.js:385:7:385:46 | path | normalizedPaths.js:388:19:388:22 | path | -| normalizedPaths.js:385:7:385:46 | path | normalizedPaths.js:388:19:388:22 | path | -| normalizedPaths.js:385:7:385:46 | path | normalizedPaths.js:388:19:388:22 | path | -| normalizedPaths.js:385:7:385:46 | path | normalizedPaths.js:399:21:399:24 | path | -| normalizedPaths.js:385:7:385:46 | path | normalizedPaths.js:399:21:399:24 | path | -| normalizedPaths.js:385:7:385:46 | path | normalizedPaths.js:399:21:399:24 | path | | normalizedPaths.js:385:7:385:46 | path | normalizedPaths.js:399:21:399:24 | path | | normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | normalizedPaths.js:385:7:385:46 | path | -| normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | normalizedPaths.js:385:7:385:46 | path | -| normalizedPaths.js:385:35:385:45 | req.query.x | normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | -| normalizedPaths.js:385:35:385:45 | req.query.x | normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | -| normalizedPaths.js:385:35:385:45 | req.query.x | normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | | normalizedPaths.js:385:35:385:45 | req.query.x | normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | | normalizedPaths.js:407:45:407:55 | req.query.x | normalizedPaths.js:407:45:407:66 | req.que ... it('/') | -| normalizedPaths.js:407:45:407:55 | req.query.x | normalizedPaths.js:407:45:407:66 | req.que ... it('/') | -| normalizedPaths.js:407:45:407:55 | req.query.x | normalizedPaths.js:407:45:407:66 | req.que ... it('/') | -| normalizedPaths.js:407:45:407:55 | req.query.x | normalizedPaths.js:407:45:407:66 | req.que ... it('/') | -| normalizedPaths.js:407:45:407:55 | req.query.x | normalizedPaths.js:407:45:407:66 | req.que ... it('/') | -| normalizedPaths.js:407:45:407:55 | req.query.x | normalizedPaths.js:407:45:407:66 | req.que ... it('/') | -| normalizedPaths.js:407:45:407:66 | req.que ... it('/') | normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | -| normalizedPaths.js:407:45:407:66 | req.que ... it('/') | normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | -| normalizedPaths.js:407:45:407:66 | req.que ... it('/') | normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | -| normalizedPaths.js:407:45:407:66 | req.que ... it('/') | normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | -| normalizedPaths.js:407:45:407:66 | req.que ... it('/') | normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | | normalizedPaths.js:407:45:407:66 | req.que ... it('/') | normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | | normalizedPaths.js:408:38:408:48 | req.query.x | normalizedPaths.js:408:38:408:59 | req.que ... it('/') | -| normalizedPaths.js:408:38:408:48 | req.query.x | normalizedPaths.js:408:38:408:59 | req.que ... it('/') | -| normalizedPaths.js:408:38:408:48 | req.query.x | normalizedPaths.js:408:38:408:59 | req.que ... it('/') | -| normalizedPaths.js:408:38:408:48 | req.query.x | normalizedPaths.js:408:38:408:59 | req.que ... it('/') | -| normalizedPaths.js:408:38:408:48 | req.query.x | normalizedPaths.js:408:38:408:59 | req.que ... it('/') | -| normalizedPaths.js:408:38:408:48 | req.query.x | normalizedPaths.js:408:38:408:59 | req.que ... it('/') | -| normalizedPaths.js:408:38:408:59 | req.que ... it('/') | normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | -| normalizedPaths.js:408:38:408:59 | req.que ... it('/') | normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | -| normalizedPaths.js:408:38:408:59 | req.que ... it('/') | normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | -| normalizedPaths.js:408:38:408:59 | req.que ... it('/') | normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | -| normalizedPaths.js:408:38:408:59 | req.que ... it('/') | normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | | normalizedPaths.js:408:38:408:59 | req.que ... it('/') | normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | | other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | | other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | | other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | | other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | | other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | | other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | | other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | | other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | | other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | | other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | | other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | | other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | | other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | | other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | | other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | | other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | | other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | | other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | | other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | | other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | | other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | | other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | | other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | | other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | | other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | +| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:73:8:73:11 | path | | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | | other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:7:77:48 | path | other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | -| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | -| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | -| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | -| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | -| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | -| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | +| other-fs-libraries.js:73:8:73:11 | path | other-fs-libraries.js:75:15:75:15 | x | +| other-fs-libraries.js:75:15:75:15 | x | other-fs-libraries.js:76:19:76:19 | x | +| other-fs-libraries.js:81:7:81:48 | path | other-fs-libraries.js:83:16:83:19 | path | +| other-fs-libraries.js:81:14:81:37 | url.par ... , true) | other-fs-libraries.js:81:14:81:43 | url.par ... ).query | +| other-fs-libraries.js:81:14:81:43 | url.par ... ).query | other-fs-libraries.js:81:14:81:48 | url.par ... ry.path | +| other-fs-libraries.js:81:14:81:48 | url.par ... ry.path | other-fs-libraries.js:81:7:81:48 | path | +| other-fs-libraries.js:81:24:81:30 | req.url | other-fs-libraries.js:81:14:81:37 | url.par ... , true) | | prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | | prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | -| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | -| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | -| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | -| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | -| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | -| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | -| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | -| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | -| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | -| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | -| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | -| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | -| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | -| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | | prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | | pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted | -| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted | -| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted | -| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted | -| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted | -| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted | -| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:13:37:13:43 | tainted | -| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:13:37:13:43 | tainted | -| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:13:37:13:43 | tainted | -| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:13:37:13:43 | tainted | -| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:13:37:13:43 | tainted | | pupeteer.js:5:9:5:71 | tainted | pupeteer.js:13:37:13:43 | tainted | | pupeteer.js:5:19:5:71 | "dir/" ... t.data" | pupeteer.js:5:9:5:71 | tainted | -| pupeteer.js:5:19:5:71 | "dir/" ... t.data" | pupeteer.js:5:9:5:71 | tainted | -| pupeteer.js:5:19:5:71 | "dir/" ... t.data" | pupeteer.js:5:9:5:71 | tainted | | pupeteer.js:5:28:5:53 | parseTo ... t).name | pupeteer.js:5:19:5:71 | "dir/" ... t.data" | -| pupeteer.js:5:28:5:53 | parseTo ... t).name | pupeteer.js:5:19:5:71 | "dir/" ... t.data" | -| pupeteer.js:5:28:5:53 | parseTo ... t).name | pupeteer.js:5:19:5:71 | "dir/" ... t.data" | -| pupeteer.js:5:28:5:53 | parseTo ... t).name | pupeteer.js:5:19:5:71 | "dir/" ... t.data" | -| pupeteer.js:5:28:5:53 | parseTo ... t).name | pupeteer.js:5:19:5:71 | "dir/" ... t.data" | -| pupeteer.js:5:28:5:53 | parseTo ... t).name | pupeteer.js:5:19:5:71 | "dir/" ... t.data" | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | +| sharedlib-repro.js:13:22:13:43 | req.par ... spaceId | sharedlib-repro.js:21:27:21:34 | filepath | +| sharedlib-repro.js:21:27:21:34 | filepath | sharedlib-repro.js:22:18:22:25 | filepath | | tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | | tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | | tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | | tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | | tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | | tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | | tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | | tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | +| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:7:10:36 | obj | | tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | | tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | | tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | | tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | | tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | | tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | | tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | | tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | | tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | -| tainted-require.js:12:29:12:47 | req.param("module") | tainted-require.js:12:29:12:47 | req.param("module") | -| tainted-require.js:14:11:14:29 | req.param("module") | tainted-require.js:14:11:14:29 | req.param("module") | -| tainted-sendFile.js:8:16:8:33 | req.param("gimme") | tainted-sendFile.js:8:16:8:33 | req.param("gimme") | -| tainted-sendFile.js:10:16:10:33 | req.param("gimme") | tainted-sendFile.js:10:16:10:33 | req.param("gimme") | -| tainted-sendFile.js:18:43:18:58 | req.param("dir") | tainted-sendFile.js:18:43:18:58 | req.param("dir") | -| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | +| tainted-promise-steps.js:6:7:6:48 | path | tainted-promise-steps.js:7:26:7:29 | path | +| tainted-promise-steps.js:6:14:6:37 | url.par ... , true) | tainted-promise-steps.js:6:14:6:43 | url.par ... ).query | +| tainted-promise-steps.js:6:14:6:43 | url.par ... ).query | tainted-promise-steps.js:6:14:6:48 | url.par ... ry.path | +| tainted-promise-steps.js:6:14:6:48 | url.par ... ry.path | tainted-promise-steps.js:6:7:6:48 | path | +| tainted-promise-steps.js:6:24:6:30 | req.url | tainted-promise-steps.js:6:14:6:37 | url.par ... , true) | +| tainted-promise-steps.js:7:10:7:30 | Promise ... e(path) [PromiseValue] | tainted-promise-steps.js:10:23:10:33 | pathPromise [PromiseValue] | +| tainted-promise-steps.js:7:26:7:29 | path | tainted-promise-steps.js:7:10:7:30 | Promise ... e(path) [PromiseValue] | +| tainted-promise-steps.js:10:23:10:33 | pathPromise [PromiseValue] | tainted-promise-steps.js:11:25:11:35 | pathPromise [PromiseValue] | +| tainted-promise-steps.js:10:23:10:33 | pathPromise [PromiseValue] | tainted-promise-steps.js:12:3:12:13 | pathPromise [PromiseValue] | +| tainted-promise-steps.js:11:25:11:35 | pathPromise [PromiseValue] | tainted-promise-steps.js:11:19:11:35 | await pathPromise | +| tainted-promise-steps.js:12:3:12:13 | pathPromise [PromiseValue] | tainted-promise-steps.js:12:20:12:23 | path | +| tainted-promise-steps.js:12:20:12:23 | path | tainted-promise-steps.js:12:44:12:47 | path | | tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | | tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | | tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | | tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | | tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | | tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | | tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | | tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:15:42:15:45 | path | | tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:15:42:15:45 | path | | tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | | tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | | tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:23:18:23:21 | path | | tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:23:18:23:21 | path | | tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | | tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | | tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | | tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | | tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | | tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | | tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | | tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | | tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | | tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | | tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | | tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | | tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | | tainted-string-steps.js:22:18:22:21 | path | tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:21 | path | tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:21 | path | tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:21 | path | tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:21 | path | tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:21 | path | tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:21 | path | tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:21 | path | tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:21 | path | tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:21 | path | tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:21 | path | tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:21 | path | tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | | tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | | tainted-string-steps.js:23:18:23:21 | path | tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:21 | path | tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:21 | path | tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:21 | path | tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:21 | path | tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:21 | path | tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:21 | path | tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:21 | path | tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:21 | path | tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:21 | path | tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:21 | path | tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:21 | path | tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | | tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | | tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | | tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | | tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | | tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | | torrents.js:5:6:5:38 | name | torrents.js:6:24:6:27 | name | -| torrents.js:5:6:5:38 | name | torrents.js:6:24:6:27 | name | -| torrents.js:5:6:5:38 | name | torrents.js:6:24:6:27 | name | | torrents.js:5:13:5:38 | parseTo ... t).name | torrents.js:5:6:5:38 | name | -| torrents.js:5:13:5:38 | parseTo ... t).name | torrents.js:5:6:5:38 | name | -| torrents.js:5:13:5:38 | parseTo ... t).name | torrents.js:5:6:5:38 | name | -| torrents.js:5:13:5:38 | parseTo ... t).name | torrents.js:5:6:5:38 | name | -| torrents.js:5:13:5:38 | parseTo ... t).name | torrents.js:5:6:5:38 | name | -| torrents.js:5:13:5:38 | parseTo ... t).name | torrents.js:5:6:5:38 | name | -| torrents.js:6:6:6:45 | loc | torrents.js:7:25:7:27 | loc | -| torrents.js:6:6:6:45 | loc | torrents.js:7:25:7:27 | loc | -| torrents.js:6:6:6:45 | loc | torrents.js:7:25:7:27 | loc | -| torrents.js:6:6:6:45 | loc | torrents.js:7:25:7:27 | loc | -| torrents.js:6:6:6:45 | loc | torrents.js:7:25:7:27 | loc | | torrents.js:6:6:6:45 | loc | torrents.js:7:25:7:27 | loc | | torrents.js:6:12:6:45 | dir + " ... t.data" | torrents.js:6:6:6:45 | loc | -| torrents.js:6:12:6:45 | dir + " ... t.data" | torrents.js:6:6:6:45 | loc | -| torrents.js:6:12:6:45 | dir + " ... t.data" | torrents.js:6:6:6:45 | loc | -| torrents.js:6:24:6:27 | name | torrents.js:6:12:6:45 | dir + " ... t.data" | -| torrents.js:6:24:6:27 | name | torrents.js:6:12:6:45 | dir + " ... t.data" | | torrents.js:6:24:6:27 | name | torrents.js:6:12:6:45 | dir + " ... t.data" | | typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | | typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | | typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | | typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | | typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | | typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | | typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | | typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | | typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | | typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | | typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | | typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | | typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | | typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | -| views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] | +subpaths #select | TaintedPath-es6.js:10:26:10:45 | join("public", path) | TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:10:26:10:45 | join("public", path) | This path depends on a $@. | TaintedPath-es6.js:7:20:7:26 | req.url | user-provided value | | TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on a $@. | TaintedPath.js:9:24:9:30 | req.url | user-provided value | @@ -10433,11 +1039,13 @@ edges | other-fs-libraries.js:70:19:70:22 | path | other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:70:19:70:22 | path | This path depends on a $@. | other-fs-libraries.js:68:24:68:30 | req.url | user-provided value | | other-fs-libraries.js:71:10:71:13 | path | other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:71:10:71:13 | path | This path depends on a $@. | other-fs-libraries.js:68:24:68:30 | req.url | user-provided value | | other-fs-libraries.js:72:15:72:18 | path | other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:72:15:72:18 | path | This path depends on a $@. | other-fs-libraries.js:68:24:68:30 | req.url | user-provided value | -| other-fs-libraries.js:79:16:79:19 | path | other-fs-libraries.js:77:24:77:30 | req.url | other-fs-libraries.js:79:16:79:19 | path | This path depends on a $@. | other-fs-libraries.js:77:24:77:30 | req.url | user-provided value | +| other-fs-libraries.js:76:19:76:19 | x | other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:76:19:76:19 | x | This path depends on a $@. | other-fs-libraries.js:68:24:68:30 | req.url | user-provided value | +| other-fs-libraries.js:83:16:83:19 | path | other-fs-libraries.js:81:24:81:30 | req.url | other-fs-libraries.js:83:16:83:19 | path | This path depends on a $@. | other-fs-libraries.js:81:24:81:30 | req.url | user-provided value | | prettier.js:7:28:7:28 | p | prettier.js:6:13:6:13 | p | prettier.js:7:28:7:28 | p | This path depends on a $@. | prettier.js:6:13:6:13 | p | user-provided value | | prettier.js:11:44:11:44 | p | prettier.js:6:13:6:13 | p | prettier.js:11:44:11:44 | p | This path depends on a $@. | prettier.js:6:13:6:13 | p | user-provided value | | pupeteer.js:9:28:9:34 | tainted | pupeteer.js:5:28:5:53 | parseTo ... t).name | pupeteer.js:9:28:9:34 | tainted | This path depends on a $@. | pupeteer.js:5:28:5:53 | parseTo ... t).name | user-provided value | | pupeteer.js:13:37:13:43 | tainted | pupeteer.js:5:28:5:53 | parseTo ... t).name | pupeteer.js:13:37:13:43 | tainted | This path depends on a $@. | pupeteer.js:5:28:5:53 | parseTo ... t).name | user-provided value | +| sharedlib-repro.js:22:18:22:25 | filepath | sharedlib-repro.js:13:22:13:43 | req.par ... spaceId | sharedlib-repro.js:22:18:22:25 | filepath | This path depends on a $@. | sharedlib-repro.js:13:22:13:43 | req.par ... spaceId | user-provided value | | tainted-access-paths.js:8:19:8:22 | path | tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:8:19:8:22 | path | This path depends on a $@. | tainted-access-paths.js:6:24:6:30 | req.url | user-provided value | | tainted-access-paths.js:12:19:12:25 | obj.sub | tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:12:19:12:25 | obj.sub | This path depends on a $@. | tainted-access-paths.js:6:24:6:30 | req.url | user-provided value | | tainted-access-paths.js:26:19:26:26 | obj.sub3 | tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:26:19:26:26 | obj.sub3 | This path depends on a $@. | tainted-access-paths.js:6:24:6:30 | req.url | user-provided value | @@ -10446,6 +1054,8 @@ edges | tainted-access-paths.js:31:23:31:30 | obj.sub4 | tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:31:23:31:30 | obj.sub4 | This path depends on a $@. | tainted-access-paths.js:6:24:6:30 | req.url | user-provided value | | tainted-access-paths.js:40:23:40:26 | path | tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:40:23:40:26 | path | This path depends on a $@. | tainted-access-paths.js:39:24:39:30 | req.url | user-provided value | | tainted-access-paths.js:49:10:49:13 | path | tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:49:10:49:13 | path | This path depends on a $@. | tainted-access-paths.js:48:24:48:30 | req.url | user-provided value | +| tainted-promise-steps.js:11:19:11:35 | await pathPromise | tainted-promise-steps.js:6:24:6:30 | req.url | tainted-promise-steps.js:11:19:11:35 | await pathPromise | This path depends on a $@. | tainted-promise-steps.js:6:24:6:30 | req.url | user-provided value | +| tainted-promise-steps.js:12:44:12:47 | path | tainted-promise-steps.js:6:24:6:30 | req.url | tainted-promise-steps.js:12:44:12:47 | path | This path depends on a $@. | tainted-promise-steps.js:6:24:6:30 | req.url | user-provided value | | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | This path depends on a $@. | tainted-require.js:7:19:7:37 | req.param("module") | user-provided value | | tainted-require.js:12:29:12:47 | req.param("module") | tainted-require.js:12:29:12:47 | req.param("module") | tainted-require.js:12:29:12:47 | req.param("module") | This path depends on a $@. | tainted-require.js:12:29:12:47 | req.param("module") | user-provided value | | tainted-require.js:14:11:14:29 | req.param("module") | tainted-require.js:14:11:14:29 | req.param("module") | tainted-require.js:14:11:14:29 | req.param("module") | This path depends on a $@. | tainted-require.js:14:11:14:29 | req.param("module") | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/other-fs-libraries.js b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/other-fs-libraries.js index 1a618105226..1dac13246c6 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/other-fs-libraries.js +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/other-fs-libraries.js @@ -70,7 +70,11 @@ http.createServer(function(req, res) { fs.readFileSync(path); // NOT OK mkdirp(path); // NOT OK mkdirp.sync(path); // NOT OK + func(path); }); +function func(x) { + fs.readFileSync(x); // NOT OK +} const fsp = require("fs/promises"); http.createServer(function(req, res) { diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/sharedlib-repro.js b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/sharedlib-repro.js new file mode 100644 index 00000000000..eebc95348ba --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/sharedlib-repro.js @@ -0,0 +1,35 @@ +const fs = require('fs'); +const express = require('express'); +const app = express(); + +app.get('/', function (req, res) { + getTree(req, res, { workspaceDir: '/tmp' }); +}); + +function getTree(req, res, options) { + var workspaceId = req.params.workspaceId; + var realfileRootPath = workspaceId; // getfileRoot(workspaceId); + var filePath = workspaceId; // path.join(options.workspaceDir,realfileRootPath, req.params["0"]); + withStatsAndETag(req.params.workspaceId, function (err, stats, etag) {}); +} + +function getfileRoot(workspaceId) { + var userId = decodeUserIdFromWorkspaceId(workspaceId); + return path.join(userId.substring(0,2), userId, decodeWorkspaceNameFromWorkspaceId(workspaceId)); +} + +function withStatsAndETag(filepath, callback) { + fs.readFileSync(filepath); // NOT OK +}; + +function decodeUserIdFromWorkspaceId(workspaceId) { + var index = workspaceId.lastIndexOf(SEPARATOR); + if (index === -1) return null; + return workspaceId.substring(0, index); +} + +function decodeWorkspaceNameFromWorkspaceId(workspaceId) { + var index = workspaceId.lastIndexOf(SEPARATOR); + if (index === -1) return null; + return workspaceId.substring(index + 1); +} diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/tainted-promise-steps.js b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/tainted-promise-steps.js new file mode 100644 index 00000000000..49c5fa78fe8 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/tainted-promise-steps.js @@ -0,0 +1,15 @@ +var fs = require('fs'), + http = require('http'), + url = require('url'); + +var server = http.createServer(function(req, res) { + let path = url.parse(req.url, true).query.path; + doRead(Promise.resolve(path)); +}); + +async function doRead(pathPromise) { + fs.readFileSync(await pathPromise); // NOT OK + pathPromise.then(path => fs.readFileSync(path)); // NO TOK +} + +server.listen(); From 547a8a958aec31beb9ebb8b392f1865e335f4dfc Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:24:57 +0200 Subject: [PATCH 046/514] JS: Port SqlInjection --- .../security/dataflow/NosqlInjectionQuery.qll | 66 +- .../security/dataflow/SqlInjectionQuery.qll | 40 +- .../ql/src/Security/CWE-089/SqlInjection.ql | 26 +- .../CWE-089/typed/SqlInjection.expected | 39 +- .../CWE-089/untyped/SqlInjection.expected | 1062 ++++++----------- 5 files changed, 497 insertions(+), 736 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/NosqlInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/NosqlInjectionQuery.qll index be9b3bdee0a..a213fa5aa4a 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/NosqlInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/NosqlInjectionQuery.qll @@ -14,7 +14,57 @@ import NosqlInjectionCustomizations::NosqlInjection /** * A taint-tracking configuration for reasoning about SQL-injection vulnerabilities. */ -class Configuration extends TaintTracking::Configuration { +module NosqlInjectionConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; + + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel state) { + source instanceof Source and state.isTaint() + or + TaintedObject::isSource(source, state) + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel state) { + sink.(Sink).getAFlowLabel() = state + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel state) { + node instanceof Sanitizer and state.isTaint() + or + TaintTracking::defaultSanitizer(node) and state.isTaint() + or + node = TaintedObject::SanitizerGuard::getABarrierNode(state) + } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowLabel state1, DataFlow::Node node2, + DataFlow::FlowLabel state2 + ) { + TaintedObject::step(node1, node2, state1, state2) + or + // additional flow step to track taint through NoSQL query objects + state1 = TaintedObject::label() and + state2 = TaintedObject::label() and + exists(NoSql::Query query, DataFlow::SourceNode queryObj | + queryObj.flowsTo(query) and + queryObj.flowsTo(node2) and + node1 = queryObj.getAPropertyWrite().getRhs() + ) + or + TaintTracking::defaultTaintStep(node1, node2) and + state1.isTaint() and + state2 = state1 + } +} + +/** + * Taint-tracking for reasoning about SQL-injection vulnerabilities. + */ +module NosqlInjectionFlow = DataFlow::GlobalWithState; + +/** + * DEPRECATED. Use the `NosqlInjectionFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "NosqlInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -37,17 +87,9 @@ class Configuration extends TaintTracking::Configuration { } override predicate isAdditionalFlowStep( - DataFlow::Node src, DataFlow::Node trg, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl + DataFlow::Node node1, DataFlow::Node node2, DataFlow::FlowLabel state1, + DataFlow::FlowLabel state2 ) { - TaintedObject::step(src, trg, inlbl, outlbl) - or - // additional flow step to track taint through NoSQL query objects - inlbl = TaintedObject::label() and - outlbl = TaintedObject::label() and - exists(NoSql::Query query, DataFlow::SourceNode queryObj | - queryObj.flowsTo(query) and - queryObj.flowsTo(trg) and - src = queryObj.getAPropertyWrite().getRhs() - ) + NosqlInjectionConfig::isAdditionalFlowStep(node1, state1, node2, state2) } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/SqlInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/SqlInjectionQuery.qll index 43f50e77c77..3a5f0e41bfa 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/SqlInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/SqlInjectionQuery.qll @@ -13,7 +13,35 @@ import SqlInjectionCustomizations::SqlInjection /** * A taint-tracking configuration for reasoning about string based query injection vulnerabilities. */ -class Configuration extends TaintTracking::Configuration { +module SqlInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { + exists(LdapJS::TaintPreservingLdapFilterStep filter | + pred = filter.getInput() and + succ = filter.getOutput() + ) + or + exists(HtmlSanitizerCall call | + pred = call.getInput() and + succ = call + ) + } +} + +/** + * Taint-tracking for reasoning about string based query injection vulnerabilities. + */ +module SqlInjectionFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `SqlInjectionFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "SqlInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -26,14 +54,6 @@ class Configuration extends TaintTracking::Configuration { } override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(LdapJS::TaintPreservingLdapFilterStep filter | - pred = filter.getInput() and - succ = filter.getOutput() - ) - or - exists(HtmlSanitizerCall call | - pred = call.getInput() and - succ = call - ) + SqlInjectionConfig::isAdditionalFlowStep(pred, succ) } } diff --git a/javascript/ql/src/Security/CWE-089/SqlInjection.ql b/javascript/ql/src/Security/CWE-089/SqlInjection.ql index f7a40bb91f9..7d64fb222ca 100644 --- a/javascript/ql/src/Security/CWE-089/SqlInjection.ql +++ b/javascript/ql/src/Security/CWE-089/SqlInjection.ql @@ -14,17 +14,23 @@ */ import javascript -import semmle.javascript.security.dataflow.SqlInjectionQuery as SqlInjection -import semmle.javascript.security.dataflow.NosqlInjectionQuery as NosqlInjection -import DataFlow::PathGraph +import semmle.javascript.security.dataflow.SqlInjectionQuery as Sql +import semmle.javascript.security.dataflow.NosqlInjectionQuery as Nosql -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, string type +module Merged = + DataFlow::MergePathGraph; + +import DataFlow::DeduplicatePathGraph + +from PathNode source, PathNode sink, string type where - ( - cfg instanceof SqlInjection::Configuration and type = "string" - or - cfg instanceof NosqlInjection::Configuration and type = "object" - ) and - cfg.hasFlowPath(source, sink) + Sql::SqlInjectionFlow::flowPath(source.getAnOriginalPathNode().asPathNode1(), + sink.getAnOriginalPathNode().asPathNode1()) and + type = "string" + or + Nosql::NosqlInjectionFlow::flowPath(source.getAnOriginalPathNode().asPathNode2(), + sink.getAnOriginalPathNode().asPathNode2()) and + type = "object" select sink.getNode(), source, sink, "This query " + type + " depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected index acf7e712ee2..174dcaf344a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected @@ -1,41 +1,32 @@ nodes -| typedClient.ts:13:7:13:32 | v | -| typedClient.ts:13:11:13:32 | JSON.pa ... body.x) | -| typedClient.ts:13:22:13:29 | req.body | -| typedClient.ts:13:22:13:29 | req.body | -| typedClient.ts:13:22:13:31 | req.body.x | -| typedClient.ts:14:24:14:32 | { id: v } | -| typedClient.ts:14:24:14:32 | { id: v } | -| typedClient.ts:14:30:14:30 | v | -| typedClient.ts:21:7:21:32 | v | -| typedClient.ts:21:11:21:32 | JSON.pa ... body.x) | -| typedClient.ts:21:22:21:29 | req.body | -| typedClient.ts:21:22:21:29 | req.body | -| typedClient.ts:21:22:21:31 | req.body.x | -| typedClient.ts:22:27:22:35 | { id: v } | -| typedClient.ts:22:27:22:35 | { id: v } | -| typedClient.ts:22:33:22:33 | v | -| typedClient.ts:23:27:23:35 | { id: v } | -| typedClient.ts:23:27:23:35 | { id: v } | -| typedClient.ts:23:33:23:33 | v | +| typedClient.ts:13:7:13:32 | v | semmle.label | v | +| typedClient.ts:13:11:13:32 | JSON.pa ... body.x) | semmle.label | JSON.pa ... body.x) | +| typedClient.ts:13:22:13:29 | req.body | semmle.label | req.body | +| typedClient.ts:13:22:13:31 | req.body.x | semmle.label | req.body.x | +| typedClient.ts:14:24:14:32 | { id: v } | semmle.label | { id: v } | +| typedClient.ts:14:30:14:30 | v | semmle.label | v | +| typedClient.ts:21:7:21:32 | v | semmle.label | v | +| typedClient.ts:21:11:21:32 | JSON.pa ... body.x) | semmle.label | JSON.pa ... body.x) | +| typedClient.ts:21:22:21:29 | req.body | semmle.label | req.body | +| typedClient.ts:21:22:21:31 | req.body.x | semmle.label | req.body.x | +| typedClient.ts:22:27:22:35 | { id: v } | semmle.label | { id: v } | +| typedClient.ts:22:33:22:33 | v | semmle.label | v | +| typedClient.ts:23:27:23:35 | { id: v } | semmle.label | { id: v } | +| typedClient.ts:23:33:23:33 | v | semmle.label | v | edges | typedClient.ts:13:7:13:32 | v | typedClient.ts:14:30:14:30 | v | | typedClient.ts:13:11:13:32 | JSON.pa ... body.x) | typedClient.ts:13:7:13:32 | v | | typedClient.ts:13:22:13:29 | req.body | typedClient.ts:13:22:13:31 | req.body.x | -| typedClient.ts:13:22:13:29 | req.body | typedClient.ts:13:22:13:31 | req.body.x | | typedClient.ts:13:22:13:31 | req.body.x | typedClient.ts:13:11:13:32 | JSON.pa ... body.x) | | typedClient.ts:14:30:14:30 | v | typedClient.ts:14:24:14:32 | { id: v } | -| typedClient.ts:14:30:14:30 | v | typedClient.ts:14:24:14:32 | { id: v } | | typedClient.ts:21:7:21:32 | v | typedClient.ts:22:33:22:33 | v | | typedClient.ts:21:7:21:32 | v | typedClient.ts:23:33:23:33 | v | | typedClient.ts:21:11:21:32 | JSON.pa ... body.x) | typedClient.ts:21:7:21:32 | v | | typedClient.ts:21:22:21:29 | req.body | typedClient.ts:21:22:21:31 | req.body.x | -| typedClient.ts:21:22:21:29 | req.body | typedClient.ts:21:22:21:31 | req.body.x | | typedClient.ts:21:22:21:31 | req.body.x | typedClient.ts:21:11:21:32 | JSON.pa ... body.x) | | typedClient.ts:22:33:22:33 | v | typedClient.ts:22:27:22:35 | { id: v } | -| typedClient.ts:22:33:22:33 | v | typedClient.ts:22:27:22:35 | { id: v } | -| typedClient.ts:23:33:23:33 | v | typedClient.ts:23:27:23:35 | { id: v } | | typedClient.ts:23:33:23:33 | v | typedClient.ts:23:27:23:35 | { id: v } | +subpaths #select | typedClient.ts:14:24:14:32 | { id: v } | typedClient.ts:13:22:13:29 | req.body | typedClient.ts:14:24:14:32 | { id: v } | This query object depends on a $@. | typedClient.ts:13:22:13:29 | req.body | user-provided value | | typedClient.ts:22:27:22:35 | { id: v } | typedClient.ts:21:22:21:29 | req.body | typedClient.ts:22:27:22:35 | { id: v } | This query object depends on a $@. | typedClient.ts:21:22:21:29 | req.body | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected index c241751da3e..f0b53a2bcc7 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected @@ -1,508 +1,338 @@ nodes -| graphql.js:8:11:8:28 | id | -| graphql.js:8:16:8:28 | req.params.id | -| graphql.js:8:16:8:28 | req.params.id | -| graphql.js:10:34:20:5 | `\\n ... }\\n ` | -| graphql.js:10:34:20:5 | `\\n ... }\\n ` | -| graphql.js:12:46:12:47 | id | -| graphql.js:26:11:26:28 | id | -| graphql.js:26:16:26:28 | req.params.id | -| graphql.js:26:16:26:28 | req.params.id | -| graphql.js:27:30:27:40 | `foo ${id}` | -| graphql.js:27:30:27:40 | `foo ${id}` | -| graphql.js:27:37:27:38 | id | -| graphql.js:30:32:30:42 | `foo ${id}` | -| graphql.js:30:32:30:42 | `foo ${id}` | -| graphql.js:30:39:30:40 | id | -| graphql.js:33:18:33:28 | `foo ${id}` | -| graphql.js:33:18:33:28 | `foo ${id}` | -| graphql.js:33:25:33:26 | id | -| graphql.js:39:11:39:28 | id | -| graphql.js:39:16:39:28 | req.params.id | -| graphql.js:39:16:39:28 | req.params.id | -| graphql.js:44:14:44:24 | `foo ${id}` | -| graphql.js:44:14:44:24 | `foo ${id}` | -| graphql.js:44:21:44:22 | id | -| graphql.js:48:44:48:54 | `foo ${id}` | -| graphql.js:48:44:48:54 | `foo ${id}` | -| graphql.js:48:51:48:52 | id | -| graphql.js:55:11:55:28 | id | -| graphql.js:55:16:55:28 | req.params.id | -| graphql.js:55:16:55:28 | req.params.id | -| graphql.js:56:39:56:49 | `foo ${id}` | -| graphql.js:56:39:56:49 | `foo ${id}` | -| graphql.js:56:46:56:47 | id | -| graphql.js:58:66:58:76 | `foo ${id}` | -| graphql.js:58:66:58:76 | `foo ${id}` | -| graphql.js:58:73:58:74 | id | -| graphql.js:74:9:74:25 | id | -| graphql.js:74:14:74:25 | req.query.id | -| graphql.js:74:14:74:25 | req.query.id | -| graphql.js:75:46:75:64 | "{ foo" + id + " }" | -| graphql.js:75:46:75:64 | "{ foo" + id + " }" | -| graphql.js:75:56:75:57 | id | -| graphql.js:84:14:90:8 | `{\\n ... }` | -| graphql.js:84:14:90:8 | `{\\n ... }` | -| graphql.js:88:13:88:14 | id | -| graphql.js:119:11:119:28 | id | -| graphql.js:119:16:119:28 | req.params.id | -| graphql.js:119:16:119:28 | req.params.id | -| graphql.js:120:38:120:48 | `foo ${id}` | -| graphql.js:120:38:120:48 | `foo ${id}` | -| graphql.js:120:45:120:46 | id | -| html-sanitizer.js:13:39:13:44 | param1 | -| html-sanitizer.js:13:39:13:44 | param1 | -| html-sanitizer.js:14:5:14:24 | param1 | -| html-sanitizer.js:14:14:14:24 | xss(param1) | -| html-sanitizer.js:14:18:14:23 | param1 | -| html-sanitizer.js:16:9:16:59 | `SELECT ... param1 | -| html-sanitizer.js:16:9:16:59 | `SELECT ... param1 | -| html-sanitizer.js:16:54:16:59 | param1 | -| json-schema-validator.js:25:15:25:48 | query | -| json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | -| json-schema-validator.js:25:34:25:47 | req.query.data | -| json-schema-validator.js:25:34:25:47 | req.query.data | -| json-schema-validator.js:33:22:33:26 | query | -| json-schema-validator.js:33:22:33:26 | query | -| json-schema-validator.js:35:18:35:22 | query | -| json-schema-validator.js:35:18:35:22 | query | -| json-schema-validator.js:50:15:50:48 | query | -| json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) | -| json-schema-validator.js:50:34:50:47 | req.query.data | -| json-schema-validator.js:50:34:50:47 | req.query.data | -| json-schema-validator.js:55:22:55:26 | query | -| json-schema-validator.js:55:22:55:26 | query | -| json-schema-validator.js:59:22:59:26 | query | -| json-schema-validator.js:59:22:59:26 | query | -| json-schema-validator.js:61:22:61:26 | query | -| json-schema-validator.js:61:22:61:26 | query | -| ldap.js:20:7:20:34 | q | -| ldap.js:20:11:20:34 | url.par ... , true) | -| ldap.js:20:21:20:27 | req.url | -| ldap.js:20:21:20:27 | req.url | -| ldap.js:22:7:22:33 | username | -| ldap.js:22:18:22:18 | q | -| ldap.js:22:18:22:24 | q.query | -| ldap.js:22:18:22:33 | q.query.username | -| ldap.js:25:13:25:57 | `(\|(nam ... ame}))` | -| ldap.js:25:24:25:31 | username | -| ldap.js:25:46:25:53 | username | -| ldap.js:28:30:28:34 | opts1 | -| ldap.js:28:30:28:34 | opts1 | -| ldap.js:32:5:32:61 | { filte ... e}))` } | -| ldap.js:32:5:32:61 | { filte ... e}))` } | -| ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | -| ldap.js:32:26:32:33 | username | -| ldap.js:32:48:32:55 | username | -| ldap.js:63:9:65:3 | parsedFilter | -| ldap.js:63:24:65:3 | ldap.pa ... ))`\\n ) | -| ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | -| ldap.js:64:16:64:23 | username | -| ldap.js:64:38:64:45 | username | -| ldap.js:66:30:66:53 | { filte ... ilter } | -| ldap.js:66:30:66:53 | { filte ... ilter } | -| ldap.js:66:40:66:51 | parsedFilter | -| ldap.js:68:27:68:42 | `cn=${username}` | -| ldap.js:68:27:68:42 | `cn=${username}` | -| ldap.js:68:33:68:40 | username | -| marsdb-flow-to.js:10:9:10:18 | query | -| marsdb-flow-to.js:10:17:10:18 | {} | -| marsdb-flow-to.js:11:17:11:24 | req.body | -| marsdb-flow-to.js:11:17:11:24 | req.body | -| marsdb-flow-to.js:11:17:11:30 | req.body.title | -| marsdb-flow-to.js:14:17:14:21 | query | -| marsdb-flow-to.js:14:17:14:21 | query | -| marsdb.js:12:9:12:18 | query | -| marsdb.js:12:17:12:18 | {} | -| marsdb.js:13:17:13:24 | req.body | -| marsdb.js:13:17:13:24 | req.body | -| marsdb.js:13:17:13:30 | req.body.title | -| marsdb.js:16:12:16:16 | query | -| marsdb.js:16:12:16:16 | query | -| minimongo.js:14:9:14:18 | query | -| minimongo.js:14:17:14:18 | {} | -| minimongo.js:15:17:15:24 | req.body | -| minimongo.js:15:17:15:24 | req.body | -| minimongo.js:15:17:15:30 | req.body.title | -| minimongo.js:18:12:18:16 | query | -| minimongo.js:18:12:18:16 | query | -| mongodb.js:12:11:12:20 | query | -| mongodb.js:12:19:12:20 | {} | -| mongodb.js:13:19:13:26 | req.body | -| mongodb.js:13:19:13:26 | req.body | -| mongodb.js:13:19:13:32 | req.body.title | -| mongodb.js:18:16:18:20 | query | -| mongodb.js:18:16:18:20 | query | -| mongodb.js:26:11:26:32 | title | -| mongodb.js:26:19:26:26 | req.body | -| mongodb.js:26:19:26:26 | req.body | -| mongodb.js:26:19:26:32 | req.body.title | -| mongodb.js:32:18:32:45 | { title ... itle) } | -| mongodb.js:32:18:32:45 | { title ... itle) } | -| mongodb.js:32:27:32:43 | JSON.parse(title) | -| mongodb.js:32:38:32:42 | title | -| mongodb.js:48:11:48:20 | query | -| mongodb.js:48:19:48:20 | {} | -| mongodb.js:49:19:49:33 | req.query.title | -| mongodb.js:49:19:49:33 | req.query.title | -| mongodb.js:54:16:54:20 | query | -| mongodb.js:54:16:54:20 | query | -| mongodb.js:59:8:59:17 | query | -| mongodb.js:59:16:59:17 | {} | -| mongodb.js:60:16:60:30 | req.query.title | -| mongodb.js:60:16:60:30 | req.query.title | -| mongodb.js:65:12:65:16 | query | -| mongodb.js:65:12:65:16 | query | -| mongodb.js:70:7:70:25 | tag | -| mongodb.js:70:13:70:25 | req.query.tag | -| mongodb.js:70:13:70:25 | req.query.tag | -| mongodb.js:77:14:77:26 | { tags: tag } | -| mongodb.js:77:14:77:26 | { tags: tag } | -| mongodb.js:77:22:77:24 | tag | -| mongodb.js:85:12:85:24 | { tags: tag } | -| mongodb.js:85:12:85:24 | { tags: tag } | -| mongodb.js:85:20:85:22 | tag | -| mongodb.js:106:9:106:18 | query | -| mongodb.js:106:17:106:18 | {} | -| mongodb.js:107:17:107:29 | queries.title | -| mongodb.js:107:17:107:29 | queries.title | -| mongodb.js:112:14:112:18 | query | -| mongodb.js:112:14:112:18 | query | -| mongodb_bodySafe.js:23:11:23:20 | query | -| mongodb_bodySafe.js:23:19:23:20 | {} | -| mongodb_bodySafe.js:24:19:24:33 | req.query.title | -| mongodb_bodySafe.js:24:19:24:33 | req.query.title | -| mongodb_bodySafe.js:29:16:29:20 | query | -| mongodb_bodySafe.js:29:16:29:20 | query | -| mongoose.js:20:8:20:17 | query | -| mongoose.js:20:16:20:17 | {} | -| mongoose.js:21:16:21:23 | req.body | -| mongoose.js:21:16:21:23 | req.body | -| mongoose.js:21:16:21:29 | req.body.title | -| mongoose.js:24:21:24:27 | [query] | -| mongoose.js:24:21:24:27 | [query] | -| mongoose.js:24:22:24:26 | query | -| mongoose.js:27:17:27:21 | query | -| mongoose.js:27:17:27:21 | query | -| mongoose.js:30:22:30:26 | query | -| mongoose.js:30:22:30:26 | query | -| mongoose.js:33:21:33:25 | query | -| mongoose.js:33:21:33:25 | query | -| mongoose.js:36:28:36:32 | query | -| mongoose.js:36:28:36:32 | query | -| mongoose.js:39:16:39:20 | query | -| mongoose.js:39:16:39:20 | query | -| mongoose.js:42:19:42:23 | query | -| mongoose.js:42:19:42:23 | query | -| mongoose.js:45:28:45:32 | query | -| mongoose.js:45:28:45:32 | query | -| mongoose.js:48:28:48:32 | query | -| mongoose.js:48:28:48:32 | query | -| mongoose.js:51:28:51:32 | query | -| mongoose.js:51:28:51:32 | query | -| mongoose.js:54:22:54:26 | query | -| mongoose.js:54:22:54:26 | query | -| mongoose.js:57:18:57:22 | query | -| mongoose.js:57:18:57:22 | query | -| mongoose.js:60:22:60:26 | query | -| mongoose.js:60:22:60:26 | query | -| mongoose.js:63:21:63:25 | query | -| mongoose.js:63:21:63:25 | query | -| mongoose.js:65:32:65:36 | query | -| mongoose.js:65:32:65:36 | query | -| mongoose.js:67:27:67:31 | query | -| mongoose.js:67:27:67:31 | query | -| mongoose.js:68:8:68:12 | query | -| mongoose.js:68:8:68:12 | query | -| mongoose.js:71:17:71:21 | query | -| mongoose.js:71:17:71:21 | query | -| mongoose.js:72:10:72:14 | query | -| mongoose.js:72:10:72:14 | query | -| mongoose.js:73:8:73:12 | query | -| mongoose.js:73:8:73:12 | query | -| mongoose.js:74:7:74:11 | query | -| mongoose.js:74:7:74:11 | query | -| mongoose.js:75:16:75:20 | query | -| mongoose.js:75:16:75:20 | query | -| mongoose.js:77:10:77:14 | query | -| mongoose.js:77:10:77:14 | query | -| mongoose.js:82:46:82:50 | query | -| mongoose.js:82:46:82:50 | query | -| mongoose.js:83:47:83:51 | query | -| mongoose.js:83:47:83:51 | query | -| mongoose.js:85:46:85:50 | query | -| mongoose.js:85:46:85:50 | query | -| mongoose.js:87:51:87:55 | query | -| mongoose.js:87:51:87:55 | query | -| mongoose.js:89:46:89:50 | query | -| mongoose.js:89:46:89:50 | query | -| mongoose.js:92:46:92:50 | query | -| mongoose.js:92:46:92:50 | query | -| mongoose.js:94:51:94:55 | query | -| mongoose.js:94:51:94:55 | query | -| mongoose.js:96:46:96:50 | query | -| mongoose.js:96:46:96:50 | query | -| mongoose.js:111:14:111:18 | query | -| mongoose.js:111:14:111:18 | query | -| mongoose.js:113:31:113:35 | query | -| mongoose.js:113:31:113:35 | query | -| mongoose.js:115:6:115:22 | id | -| mongoose.js:115:11:115:22 | req.query.id | -| mongoose.js:115:11:115:22 | req.query.id | -| mongoose.js:115:25:115:45 | cond | -| mongoose.js:115:32:115:45 | req.query.cond | -| mongoose.js:115:32:115:45 | req.query.cond | -| mongoose.js:116:22:116:25 | cond | -| mongoose.js:116:22:116:25 | cond | -| mongoose.js:117:21:117:24 | cond | -| mongoose.js:117:21:117:24 | cond | -| mongoose.js:118:21:118:24 | cond | -| mongoose.js:118:21:118:24 | cond | -| mongoose.js:119:18:119:21 | cond | -| mongoose.js:119:18:119:21 | cond | -| mongoose.js:120:22:120:25 | cond | -| mongoose.js:120:22:120:25 | cond | -| mongoose.js:121:16:121:19 | cond | -| mongoose.js:121:16:121:19 | cond | -| mongoose.js:122:19:122:22 | cond | -| mongoose.js:122:19:122:22 | cond | -| mongoose.js:123:20:123:21 | id | -| mongoose.js:123:20:123:21 | id | -| mongoose.js:124:28:124:31 | cond | -| mongoose.js:124:28:124:31 | cond | -| mongoose.js:125:28:125:31 | cond | -| mongoose.js:125:28:125:31 | cond | -| mongoose.js:126:28:126:31 | cond | -| mongoose.js:126:28:126:31 | cond | -| mongoose.js:127:18:127:21 | cond | -| mongoose.js:127:18:127:21 | cond | -| mongoose.js:128:22:128:25 | cond | -| mongoose.js:128:22:128:25 | cond | -| mongoose.js:129:21:129:24 | cond | -| mongoose.js:129:21:129:24 | cond | -| mongoose.js:130:16:130:26 | { _id: id } | -| mongoose.js:130:16:130:26 | { _id: id } | -| mongoose.js:130:23:130:24 | id | -| mongoose.js:136:30:136:34 | query | -| mongoose.js:136:30:136:34 | query | -| mongooseJsonParse.js:19:11:19:20 | query | -| mongooseJsonParse.js:19:19:19:20 | {} | -| mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) | -| mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | -| mongooseJsonParse.js:20:30:20:43 | req.query.data | -| mongooseJsonParse.js:20:30:20:43 | req.query.data | -| mongooseJsonParse.js:23:19:23:23 | query | -| mongooseJsonParse.js:23:19:23:23 | query | -| mongooseModelClient.js:10:7:10:32 | v | -| mongooseModelClient.js:10:11:10:32 | JSON.pa ... body.x) | -| mongooseModelClient.js:10:22:10:29 | req.body | -| mongooseModelClient.js:10:22:10:29 | req.body | -| mongooseModelClient.js:10:22:10:31 | req.body.x | -| mongooseModelClient.js:11:16:11:24 | { id: v } | -| mongooseModelClient.js:11:16:11:24 | { id: v } | -| mongooseModelClient.js:11:22:11:22 | v | -| mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | -| mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | -| mongooseModelClient.js:12:22:12:29 | req.body | -| mongooseModelClient.js:12:22:12:29 | req.body | -| mongooseModelClient.js:12:22:12:32 | req.body.id | -| mysql.js:6:9:6:31 | temp | -| mysql.js:6:16:6:31 | req.params.value | -| mysql.js:6:16:6:31 | req.params.value | -| mysql.js:15:18:15:65 | 'SELECT ... + temp | -| mysql.js:15:18:15:65 | 'SELECT ... + temp | -| mysql.js:15:62:15:65 | temp | -| mysql.js:19:26:19:73 | 'SELECT ... + temp | -| mysql.js:19:26:19:73 | 'SELECT ... + temp | -| mysql.js:19:70:19:73 | temp | -| pg-promise-types.ts:7:9:7:28 | taint | -| pg-promise-types.ts:7:17:7:28 | req.params.x | -| pg-promise-types.ts:7:17:7:28 | req.params.x | -| pg-promise-types.ts:8:17:8:21 | taint | -| pg-promise-types.ts:8:17:8:21 | taint | -| pg-promise.js:6:7:7:55 | query | -| pg-promise.js:6:15:7:55 | "SELECT ... PRICE" | -| pg-promise.js:7:16:7:34 | req.params.category | -| pg-promise.js:7:16:7:34 | req.params.category | -| pg-promise.js:9:10:9:14 | query | -| pg-promise.js:9:10:9:14 | query | -| pg-promise.js:10:11:10:15 | query | -| pg-promise.js:10:11:10:15 | query | -| pg-promise.js:11:17:11:21 | query | -| pg-promise.js:11:17:11:21 | query | -| pg-promise.js:12:10:12:14 | query | -| pg-promise.js:12:10:12:14 | query | -| pg-promise.js:13:12:13:16 | query | -| pg-promise.js:13:12:13:16 | query | -| pg-promise.js:14:18:14:22 | query | -| pg-promise.js:14:18:14:22 | query | -| pg-promise.js:15:11:15:15 | query | -| pg-promise.js:15:11:15:15 | query | -| pg-promise.js:16:10:16:14 | query | -| pg-promise.js:16:10:16:14 | query | -| pg-promise.js:17:16:17:20 | query | -| pg-promise.js:17:16:17:20 | query | -| pg-promise.js:18:12:18:16 | query | -| pg-promise.js:18:12:18:16 | query | -| pg-promise.js:19:13:19:17 | query | -| pg-promise.js:19:13:19:17 | query | -| pg-promise.js:22:11:22:15 | query | -| pg-promise.js:22:11:22:15 | query | -| pg-promise.js:30:13:30:25 | req.params.id | -| pg-promise.js:30:13:30:25 | req.params.id | -| pg-promise.js:30:13:30:25 | req.params.id | -| pg-promise.js:34:13:34:25 | req.params.id | -| pg-promise.js:34:13:34:25 | req.params.id | -| pg-promise.js:34:13:34:25 | req.params.id | -| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| pg-promise.js:39:7:39:19 | req.params.id | -| pg-promise.js:39:7:39:19 | req.params.id | -| pg-promise.js:39:7:39:19 | req.params.id | -| pg-promise.js:40:7:40:21 | req.params.name | -| pg-promise.js:40:7:40:21 | req.params.name | -| pg-promise.js:40:7:40:21 | req.params.name | -| pg-promise.js:41:7:41:20 | req.params.foo | -| pg-promise.js:41:7:41:20 | req.params.foo | -| pg-promise.js:47:11:47:23 | req.params.id | -| pg-promise.js:47:11:47:23 | req.params.id | -| pg-promise.js:47:11:47:23 | req.params.id | -| pg-promise.js:54:11:54:23 | req.params.id | -| pg-promise.js:54:11:54:23 | req.params.id | -| pg-promise.js:54:11:54:23 | req.params.id | -| pg-promise.js:56:14:56:29 | req.params.title | -| pg-promise.js:56:14:56:29 | req.params.title | -| pg-promise.js:56:14:56:29 | req.params.title | -| pg-promise.js:60:20:60:24 | query | -| pg-promise.js:60:20:60:24 | query | -| pg-promise.js:63:23:63:27 | query | -| pg-promise.js:63:23:63:27 | query | -| pg-promise.js:64:16:64:20 | query | -| pg-promise.js:64:16:64:20 | query | -| redis.js:10:16:10:23 | req.body | -| redis.js:10:16:10:23 | req.body | -| redis.js:10:16:10:27 | req.body.key | -| redis.js:10:16:10:27 | req.body.key | -| redis.js:12:9:12:26 | key | -| redis.js:12:15:12:22 | req.body | -| redis.js:12:15:12:22 | req.body | -| redis.js:12:15:12:26 | req.body.key | -| redis.js:18:16:18:18 | key | -| redis.js:18:16:18:18 | key | -| redis.js:19:43:19:45 | key | -| redis.js:19:43:19:45 | key | -| redis.js:25:14:25:16 | key | -| redis.js:25:14:25:16 | key | -| redis.js:30:23:30:25 | key | -| redis.js:30:23:30:25 | key | -| redis.js:32:28:32:30 | key | -| redis.js:32:28:32:30 | key | -| redis.js:38:11:38:28 | key | -| redis.js:38:17:38:24 | req.body | -| redis.js:38:17:38:24 | req.body | -| redis.js:38:17:38:28 | req.body.key | -| redis.js:39:16:39:18 | key | -| redis.js:39:16:39:18 | key | -| redis.js:43:27:43:29 | key | -| redis.js:43:27:43:29 | key | -| redis.js:46:34:46:36 | key | -| redis.js:46:34:46:36 | key | -| socketio.js:10:25:10:30 | handle | -| socketio.js:10:25:10:30 | handle | -| socketio.js:11:12:11:53 | `INSERT ... andle}` | -| socketio.js:11:12:11:53 | `INSERT ... andle}` | -| socketio.js:11:46:11:51 | handle | -| tst2.js:9:27:9:84 | "select ... d + "'" | -| tst2.js:9:27:9:84 | "select ... d + "'" | -| tst2.js:9:66:9:78 | req.params.id | -| tst2.js:9:66:9:78 | req.params.id | -| tst3.js:7:7:8:55 | query1 | -| tst3.js:7:16:8:55 | "SELECT ... PRICE" | -| tst3.js:8:16:8:34 | req.params.category | -| tst3.js:8:16:8:34 | req.params.category | -| tst3.js:9:14:9:19 | query1 | -| tst3.js:9:14:9:19 | query1 | -| tst4.js:8:10:8:66 | 'SELECT ... d + '"' | -| tst4.js:8:10:8:66 | 'SELECT ... d + '"' | -| tst4.js:8:46:8:60 | $routeParams.id | -| tst4.js:8:46:8:60 | $routeParams.id | -| tst.js:10:10:10:64 | 'SELECT ... d + '"' | -| tst.js:10:10:10:64 | 'SELECT ... d + '"' | -| tst.js:10:46:10:58 | req.params.id | -| tst.js:10:46:10:58 | req.params.id | +| graphql.js:8:11:8:28 | id | semmle.label | id | +| graphql.js:8:16:8:28 | req.params.id | semmle.label | req.params.id | +| graphql.js:10:34:20:5 | `\\n ... }\\n ` | semmle.label | `\\n ... }\\n ` | +| graphql.js:12:46:12:47 | id | semmle.label | id | +| graphql.js:26:11:26:28 | id | semmle.label | id | +| graphql.js:26:16:26:28 | req.params.id | semmle.label | req.params.id | +| graphql.js:27:30:27:40 | `foo ${id}` | semmle.label | `foo ${id}` | +| graphql.js:27:37:27:38 | id | semmle.label | id | +| graphql.js:30:32:30:42 | `foo ${id}` | semmle.label | `foo ${id}` | +| graphql.js:30:39:30:40 | id | semmle.label | id | +| graphql.js:33:18:33:28 | `foo ${id}` | semmle.label | `foo ${id}` | +| graphql.js:33:25:33:26 | id | semmle.label | id | +| graphql.js:39:11:39:28 | id | semmle.label | id | +| graphql.js:39:16:39:28 | req.params.id | semmle.label | req.params.id | +| graphql.js:44:14:44:24 | `foo ${id}` | semmle.label | `foo ${id}` | +| graphql.js:44:21:44:22 | id | semmle.label | id | +| graphql.js:48:44:48:54 | `foo ${id}` | semmle.label | `foo ${id}` | +| graphql.js:48:51:48:52 | id | semmle.label | id | +| graphql.js:55:11:55:28 | id | semmle.label | id | +| graphql.js:55:16:55:28 | req.params.id | semmle.label | req.params.id | +| graphql.js:56:39:56:49 | `foo ${id}` | semmle.label | `foo ${id}` | +| graphql.js:56:46:56:47 | id | semmle.label | id | +| graphql.js:58:66:58:76 | `foo ${id}` | semmle.label | `foo ${id}` | +| graphql.js:58:73:58:74 | id | semmle.label | id | +| graphql.js:74:9:74:25 | id | semmle.label | id | +| graphql.js:74:14:74:25 | req.query.id | semmle.label | req.query.id | +| graphql.js:75:46:75:64 | "{ foo" + id + " }" | semmle.label | "{ foo" + id + " }" | +| graphql.js:75:56:75:57 | id | semmle.label | id | +| graphql.js:84:14:90:8 | `{\\n ... }` | semmle.label | `{\\n ... }` | +| graphql.js:88:13:88:14 | id | semmle.label | id | +| graphql.js:119:11:119:28 | id | semmle.label | id | +| graphql.js:119:16:119:28 | req.params.id | semmle.label | req.params.id | +| graphql.js:120:38:120:48 | `foo ${id}` | semmle.label | `foo ${id}` | +| graphql.js:120:45:120:46 | id | semmle.label | id | +| html-sanitizer.js:13:39:13:44 | param1 | semmle.label | param1 | +| html-sanitizer.js:14:5:14:24 | param1 | semmle.label | param1 | +| html-sanitizer.js:14:14:14:24 | xss(param1) | semmle.label | xss(param1) | +| html-sanitizer.js:14:18:14:23 | param1 | semmle.label | param1 | +| html-sanitizer.js:16:9:16:59 | `SELECT ... param1 | semmle.label | `SELECT ... param1 | +| html-sanitizer.js:16:54:16:59 | param1 | semmle.label | param1 | +| json-schema-validator.js:25:15:25:48 | query | semmle.label | query | +| json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | semmle.label | JSON.pa ... y.data) | +| json-schema-validator.js:25:34:25:47 | req.query.data | semmle.label | req.query.data | +| json-schema-validator.js:33:22:33:26 | query | semmle.label | query | +| json-schema-validator.js:35:18:35:22 | query | semmle.label | query | +| json-schema-validator.js:50:15:50:48 | query | semmle.label | query | +| json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) | semmle.label | JSON.pa ... y.data) | +| json-schema-validator.js:50:34:50:47 | req.query.data | semmle.label | req.query.data | +| json-schema-validator.js:55:22:55:26 | query | semmle.label | query | +| json-schema-validator.js:59:22:59:26 | query | semmle.label | query | +| json-schema-validator.js:61:22:61:26 | query | semmle.label | query | +| koarouter.js:5:11:5:33 | version | semmle.label | version | +| koarouter.js:5:13:5:19 | version | semmle.label | version | +| koarouter.js:11:11:11:28 | conditions | semmle.label | conditions | +| koarouter.js:14:9:14:18 | [post update] conditions | semmle.label | [post update] conditions | +| koarouter.js:14:25:14:46 | `versio ... rsion}` | semmle.label | `versio ... rsion}` | +| koarouter.js:14:38:14:44 | version | semmle.label | version | +| koarouter.js:17:27:17:77 | `SELECT ... nd ')}` | semmle.label | `SELECT ... nd ')}` | +| koarouter.js:17:52:17:61 | conditions | semmle.label | conditions | +| koarouter.js:17:52:17:75 | conditi ... and ') | semmle.label | conditi ... and ') | +| ldap.js:20:7:20:34 | q | semmle.label | q | +| ldap.js:20:11:20:34 | url.par ... , true) | semmle.label | url.par ... , true) | +| ldap.js:20:21:20:27 | req.url | semmle.label | req.url | +| ldap.js:22:7:22:33 | username | semmle.label | username | +| ldap.js:22:18:22:18 | q | semmle.label | q | +| ldap.js:25:13:25:57 | `(\|(nam ... ame}))` | semmle.label | `(\|(nam ... ame}))` | +| ldap.js:25:24:25:31 | username | semmle.label | username | +| ldap.js:25:46:25:53 | username | semmle.label | username | +| ldap.js:28:30:28:34 | opts1 | semmle.label | opts1 | +| ldap.js:32:5:32:61 | { filte ... e}))` } | semmle.label | { filte ... e}))` } | +| ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | semmle.label | `(\|(nam ... ame}))` | +| ldap.js:32:26:32:33 | username | semmle.label | username | +| ldap.js:32:48:32:55 | username | semmle.label | username | +| ldap.js:63:9:65:3 | parsedFilter | semmle.label | parsedFilter | +| ldap.js:63:24:65:3 | ldap.pa ... ))`\\n ) | semmle.label | ldap.pa ... ))`\\n ) | +| ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | semmle.label | `(\|(nam ... ame}))` | +| ldap.js:64:16:64:23 | username | semmle.label | username | +| ldap.js:64:38:64:45 | username | semmle.label | username | +| ldap.js:66:30:66:53 | { filte ... ilter } | semmle.label | { filte ... ilter } | +| ldap.js:66:40:66:51 | parsedFilter | semmle.label | parsedFilter | +| ldap.js:68:27:68:42 | `cn=${username}` | semmle.label | `cn=${username}` | +| ldap.js:68:33:68:40 | username | semmle.label | username | +| marsdb-flow-to.js:10:9:10:18 | query | semmle.label | query | +| marsdb-flow-to.js:10:17:10:18 | {} | semmle.label | {} | +| marsdb-flow-to.js:11:17:11:24 | req.body | semmle.label | req.body | +| marsdb-flow-to.js:11:17:11:30 | req.body.title | semmle.label | req.body.title | +| marsdb-flow-to.js:14:17:14:21 | query | semmle.label | query | +| marsdb.js:12:9:12:18 | query | semmle.label | query | +| marsdb.js:12:17:12:18 | {} | semmle.label | {} | +| marsdb.js:13:17:13:24 | req.body | semmle.label | req.body | +| marsdb.js:13:17:13:30 | req.body.title | semmle.label | req.body.title | +| marsdb.js:16:12:16:16 | query | semmle.label | query | +| minimongo.js:14:9:14:18 | query | semmle.label | query | +| minimongo.js:14:17:14:18 | {} | semmle.label | {} | +| minimongo.js:15:17:15:24 | req.body | semmle.label | req.body | +| minimongo.js:15:17:15:30 | req.body.title | semmle.label | req.body.title | +| minimongo.js:18:12:18:16 | query | semmle.label | query | +| mongodb.js:12:11:12:20 | query | semmle.label | query | +| mongodb.js:12:19:12:20 | {} | semmle.label | {} | +| mongodb.js:13:5:13:9 | query | semmle.label | query | +| mongodb.js:13:19:13:26 | req.body | semmle.label | req.body | +| mongodb.js:13:19:13:32 | req.body.title | semmle.label | req.body.title | +| mongodb.js:18:16:18:20 | query | semmle.label | query | +| mongodb.js:26:11:26:32 | title | semmle.label | title | +| mongodb.js:26:19:26:26 | req.body | semmle.label | req.body | +| mongodb.js:26:19:26:32 | req.body.title | semmle.label | req.body.title | +| mongodb.js:32:18:32:45 | { title ... itle) } | semmle.label | { title ... itle) } | +| mongodb.js:32:27:32:43 | JSON.parse(title) | semmle.label | JSON.parse(title) | +| mongodb.js:32:38:32:42 | title | semmle.label | title | +| mongodb.js:48:11:48:20 | query | semmle.label | query | +| mongodb.js:48:19:48:20 | {} | semmle.label | {} | +| mongodb.js:49:5:49:9 | query | semmle.label | query | +| mongodb.js:49:19:49:33 | req.query.title | semmle.label | req.query.title | +| mongodb.js:54:16:54:20 | query | semmle.label | query | +| mongodb.js:59:8:59:17 | query | semmle.label | query | +| mongodb.js:59:16:59:17 | {} | semmle.label | {} | +| mongodb.js:60:2:60:6 | query | semmle.label | query | +| mongodb.js:60:16:60:30 | req.query.title | semmle.label | req.query.title | +| mongodb.js:65:12:65:16 | query | semmle.label | query | +| mongodb.js:70:7:70:25 | tag | semmle.label | tag | +| mongodb.js:70:13:70:25 | req.query.tag | semmle.label | req.query.tag | +| mongodb.js:77:14:77:26 | { tags: tag } | semmle.label | { tags: tag } | +| mongodb.js:77:22:77:24 | tag | semmle.label | tag | +| mongodb.js:85:12:85:24 | { tags: tag } | semmle.label | { tags: tag } | +| mongodb.js:85:20:85:22 | tag | semmle.label | tag | +| mongodb.js:106:9:106:18 | query | semmle.label | query | +| mongodb.js:106:17:106:18 | {} | semmle.label | {} | +| mongodb.js:107:3:107:7 | query | semmle.label | query | +| mongodb.js:107:17:107:29 | queries.title | semmle.label | queries.title | +| mongodb.js:112:14:112:18 | query | semmle.label | query | +| mongodb_bodySafe.js:23:11:23:20 | query | semmle.label | query | +| mongodb_bodySafe.js:23:19:23:20 | {} | semmle.label | {} | +| mongodb_bodySafe.js:24:5:24:9 | query | semmle.label | query | +| mongodb_bodySafe.js:24:19:24:33 | req.query.title | semmle.label | req.query.title | +| mongodb_bodySafe.js:29:16:29:20 | query | semmle.label | query | +| mongoose.js:20:8:20:17 | query | semmle.label | query | +| mongoose.js:20:16:20:17 | {} | semmle.label | {} | +| mongoose.js:21:2:21:6 | query | semmle.label | query | +| mongoose.js:21:16:21:23 | req.body | semmle.label | req.body | +| mongoose.js:21:16:21:29 | req.body.title | semmle.label | req.body.title | +| mongoose.js:24:21:24:27 | [query] | semmle.label | [query] | +| mongoose.js:24:22:24:26 | query | semmle.label | query | +| mongoose.js:27:17:27:21 | query | semmle.label | query | +| mongoose.js:30:22:30:26 | query | semmle.label | query | +| mongoose.js:33:21:33:25 | query | semmle.label | query | +| mongoose.js:36:28:36:32 | query | semmle.label | query | +| mongoose.js:39:16:39:20 | query | semmle.label | query | +| mongoose.js:42:19:42:23 | query | semmle.label | query | +| mongoose.js:45:28:45:32 | query | semmle.label | query | +| mongoose.js:48:28:48:32 | query | semmle.label | query | +| mongoose.js:51:28:51:32 | query | semmle.label | query | +| mongoose.js:54:22:54:26 | query | semmle.label | query | +| mongoose.js:57:18:57:22 | query | semmle.label | query | +| mongoose.js:60:22:60:26 | query | semmle.label | query | +| mongoose.js:63:21:63:25 | query | semmle.label | query | +| mongoose.js:65:32:65:36 | query | semmle.label | query | +| mongoose.js:67:27:67:31 | query | semmle.label | query | +| mongoose.js:68:8:68:12 | query | semmle.label | query | +| mongoose.js:71:17:71:21 | query | semmle.label | query | +| mongoose.js:72:10:72:14 | query | semmle.label | query | +| mongoose.js:73:8:73:12 | query | semmle.label | query | +| mongoose.js:74:7:74:11 | query | semmle.label | query | +| mongoose.js:75:16:75:20 | query | semmle.label | query | +| mongoose.js:76:12:76:16 | query | semmle.label | query | +| mongoose.js:77:10:77:14 | query | semmle.label | query | +| mongoose.js:81:37:81:41 | query | semmle.label | query | +| mongoose.js:82:46:82:50 | query | semmle.label | query | +| mongoose.js:83:47:83:51 | query | semmle.label | query | +| mongoose.js:85:46:85:50 | query | semmle.label | query | +| mongoose.js:87:51:87:55 | query | semmle.label | query | +| mongoose.js:89:46:89:50 | query | semmle.label | query | +| mongoose.js:92:46:92:50 | query | semmle.label | query | +| mongoose.js:94:51:94:55 | query | semmle.label | query | +| mongoose.js:96:46:96:50 | query | semmle.label | query | +| mongoose.js:104:21:104:25 | query | semmle.label | query | +| mongoose.js:111:14:111:18 | query | semmle.label | query | +| mongoose.js:113:31:113:35 | query | semmle.label | query | +| mongoose.js:115:6:115:22 | id | semmle.label | id | +| mongoose.js:115:11:115:22 | req.query.id | semmle.label | req.query.id | +| mongoose.js:115:25:115:45 | cond | semmle.label | cond | +| mongoose.js:115:32:115:45 | req.query.cond | semmle.label | req.query.cond | +| mongoose.js:116:22:116:25 | cond | semmle.label | cond | +| mongoose.js:117:21:117:24 | cond | semmle.label | cond | +| mongoose.js:118:21:118:24 | cond | semmle.label | cond | +| mongoose.js:119:18:119:21 | cond | semmle.label | cond | +| mongoose.js:120:22:120:25 | cond | semmle.label | cond | +| mongoose.js:121:16:121:19 | cond | semmle.label | cond | +| mongoose.js:122:19:122:22 | cond | semmle.label | cond | +| mongoose.js:123:20:123:21 | id | semmle.label | id | +| mongoose.js:124:28:124:31 | cond | semmle.label | cond | +| mongoose.js:125:28:125:31 | cond | semmle.label | cond | +| mongoose.js:126:28:126:31 | cond | semmle.label | cond | +| mongoose.js:127:18:127:21 | cond | semmle.label | cond | +| mongoose.js:128:22:128:25 | cond | semmle.label | cond | +| mongoose.js:129:21:129:24 | cond | semmle.label | cond | +| mongoose.js:130:16:130:26 | { _id: id } | semmle.label | { _id: id } | +| mongoose.js:130:23:130:24 | id | semmle.label | id | +| mongoose.js:133:38:133:42 | query | semmle.label | query | +| mongoose.js:134:30:134:34 | query | semmle.label | query | +| mongoose.js:136:30:136:34 | query | semmle.label | query | +| mongooseJsonParse.js:19:11:19:20 | query | semmle.label | query | +| mongooseJsonParse.js:19:19:19:20 | {} | semmle.label | {} | +| mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) | semmle.label | JSON.pa ... y.data) | +| mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | semmle.label | JSON.pa ... ).title | +| mongooseJsonParse.js:20:30:20:43 | req.query.data | semmle.label | req.query.data | +| mongooseJsonParse.js:23:19:23:23 | query | semmle.label | query | +| mongooseModelClient.js:10:7:10:32 | v | semmle.label | v | +| mongooseModelClient.js:10:11:10:32 | JSON.pa ... body.x) | semmle.label | JSON.pa ... body.x) | +| mongooseModelClient.js:10:22:10:29 | req.body | semmle.label | req.body | +| mongooseModelClient.js:10:22:10:31 | req.body.x | semmle.label | req.body.x | +| mongooseModelClient.js:11:16:11:24 | { id: v } | semmle.label | { id: v } | +| mongooseModelClient.js:11:22:11:22 | v | semmle.label | v | +| mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | semmle.label | { id: req.body.id } | +| mongooseModelClient.js:12:22:12:29 | req.body | semmle.label | req.body | +| mongooseModelClient.js:12:22:12:32 | req.body.id | semmle.label | req.body.id | +| mysql.js:6:9:6:31 | temp | semmle.label | temp | +| mysql.js:6:16:6:31 | req.params.value | semmle.label | req.params.value | +| mysql.js:15:18:15:65 | 'SELECT ... + temp | semmle.label | 'SELECT ... + temp | +| mysql.js:15:62:15:65 | temp | semmle.label | temp | +| mysql.js:19:26:19:73 | 'SELECT ... + temp | semmle.label | 'SELECT ... + temp | +| mysql.js:19:70:19:73 | temp | semmle.label | temp | +| pg-promise-types.ts:7:9:7:28 | taint | semmle.label | taint | +| pg-promise-types.ts:7:17:7:28 | req.params.x | semmle.label | req.params.x | +| pg-promise-types.ts:8:17:8:21 | taint | semmle.label | taint | +| pg-promise.js:6:7:7:55 | query | semmle.label | query | +| pg-promise.js:7:16:7:34 | req.params.category | semmle.label | req.params.category | +| pg-promise.js:9:10:9:14 | query | semmle.label | query | +| pg-promise.js:10:11:10:15 | query | semmle.label | query | +| pg-promise.js:11:17:11:21 | query | semmle.label | query | +| pg-promise.js:12:10:12:14 | query | semmle.label | query | +| pg-promise.js:13:12:13:16 | query | semmle.label | query | +| pg-promise.js:14:18:14:22 | query | semmle.label | query | +| pg-promise.js:15:11:15:15 | query | semmle.label | query | +| pg-promise.js:16:10:16:14 | query | semmle.label | query | +| pg-promise.js:17:16:17:20 | query | semmle.label | query | +| pg-promise.js:18:12:18:16 | query | semmle.label | query | +| pg-promise.js:19:13:19:17 | query | semmle.label | query | +| pg-promise.js:22:11:22:15 | query | semmle.label | query | +| pg-promise.js:30:13:30:25 | req.params.id | semmle.label | req.params.id | +| pg-promise.js:34:13:34:25 | req.params.id | semmle.label | req.params.id | +| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | semmle.label | [\\n ... n\\n ] | +| pg-promise.js:39:7:39:19 | req.params.id | semmle.label | req.params.id | +| pg-promise.js:40:7:40:21 | req.params.name | semmle.label | req.params.name | +| pg-promise.js:41:7:41:20 | req.params.foo | semmle.label | req.params.foo | +| pg-promise.js:47:11:47:23 | req.params.id | semmle.label | req.params.id | +| pg-promise.js:54:11:54:23 | req.params.id | semmle.label | req.params.id | +| pg-promise.js:56:14:56:29 | req.params.title | semmle.label | req.params.title | +| pg-promise.js:60:20:60:24 | query | semmle.label | query | +| pg-promise.js:63:23:63:27 | query | semmle.label | query | +| pg-promise.js:64:16:64:20 | query | semmle.label | query | +| redis.js:10:16:10:23 | req.body | semmle.label | req.body | +| redis.js:10:16:10:27 | req.body.key | semmle.label | req.body.key | +| redis.js:12:9:12:26 | key | semmle.label | key | +| redis.js:12:15:12:22 | req.body | semmle.label | req.body | +| redis.js:12:15:12:26 | req.body.key | semmle.label | req.body.key | +| redis.js:13:16:13:18 | key | semmle.label | key | +| redis.js:18:16:18:18 | key | semmle.label | key | +| redis.js:19:43:19:45 | key | semmle.label | key | +| redis.js:25:14:25:16 | key | semmle.label | key | +| redis.js:26:14:26:16 | key | semmle.label | key | +| redis.js:30:23:30:25 | key | semmle.label | key | +| redis.js:32:28:32:30 | key | semmle.label | key | +| redis.js:38:11:38:28 | key | semmle.label | key | +| redis.js:38:17:38:24 | req.body | semmle.label | req.body | +| redis.js:38:17:38:28 | req.body.key | semmle.label | req.body.key | +| redis.js:39:16:39:18 | key | semmle.label | key | +| redis.js:43:27:43:29 | key | semmle.label | key | +| redis.js:46:34:46:36 | key | semmle.label | key | +| socketio.js:10:25:10:30 | handle | semmle.label | handle | +| socketio.js:11:12:11:53 | `INSERT ... andle}` | semmle.label | `INSERT ... andle}` | +| socketio.js:11:46:11:51 | handle | semmle.label | handle | +| tst2.js:9:27:9:84 | "select ... d + "'" | semmle.label | "select ... d + "'" | +| tst2.js:9:66:9:78 | req.params.id | semmle.label | req.params.id | +| tst3.js:7:7:8:55 | query1 | semmle.label | query1 | +| tst3.js:8:16:8:34 | req.params.category | semmle.label | req.params.category | +| tst3.js:9:14:9:19 | query1 | semmle.label | query1 | +| tst4.js:8:10:8:66 | 'SELECT ... d + '"' | semmle.label | 'SELECT ... d + '"' | +| tst4.js:8:46:8:60 | $routeParams.id | semmle.label | $routeParams.id | +| tst.js:10:10:10:64 | 'SELECT ... d + '"' | semmle.label | 'SELECT ... d + '"' | +| tst.js:10:46:10:58 | req.params.id | semmle.label | req.params.id | edges | graphql.js:8:11:8:28 | id | graphql.js:12:46:12:47 | id | | graphql.js:8:16:8:28 | req.params.id | graphql.js:8:11:8:28 | id | -| graphql.js:8:16:8:28 | req.params.id | graphql.js:8:11:8:28 | id | -| graphql.js:12:46:12:47 | id | graphql.js:10:34:20:5 | `\\n ... }\\n ` | | graphql.js:12:46:12:47 | id | graphql.js:10:34:20:5 | `\\n ... }\\n ` | | graphql.js:26:11:26:28 | id | graphql.js:27:37:27:38 | id | | graphql.js:26:11:26:28 | id | graphql.js:30:39:30:40 | id | | graphql.js:26:11:26:28 | id | graphql.js:33:25:33:26 | id | | graphql.js:26:16:26:28 | req.params.id | graphql.js:26:11:26:28 | id | -| graphql.js:26:16:26:28 | req.params.id | graphql.js:26:11:26:28 | id | -| graphql.js:27:37:27:38 | id | graphql.js:27:30:27:40 | `foo ${id}` | | graphql.js:27:37:27:38 | id | graphql.js:27:30:27:40 | `foo ${id}` | | graphql.js:30:39:30:40 | id | graphql.js:30:32:30:42 | `foo ${id}` | -| graphql.js:30:39:30:40 | id | graphql.js:30:32:30:42 | `foo ${id}` | -| graphql.js:33:25:33:26 | id | graphql.js:33:18:33:28 | `foo ${id}` | | graphql.js:33:25:33:26 | id | graphql.js:33:18:33:28 | `foo ${id}` | | graphql.js:39:11:39:28 | id | graphql.js:44:21:44:22 | id | | graphql.js:39:11:39:28 | id | graphql.js:48:51:48:52 | id | | graphql.js:39:16:39:28 | req.params.id | graphql.js:39:11:39:28 | id | -| graphql.js:39:16:39:28 | req.params.id | graphql.js:39:11:39:28 | id | | graphql.js:44:21:44:22 | id | graphql.js:44:14:44:24 | `foo ${id}` | -| graphql.js:44:21:44:22 | id | graphql.js:44:14:44:24 | `foo ${id}` | -| graphql.js:48:51:48:52 | id | graphql.js:48:44:48:54 | `foo ${id}` | | graphql.js:48:51:48:52 | id | graphql.js:48:44:48:54 | `foo ${id}` | | graphql.js:55:11:55:28 | id | graphql.js:56:46:56:47 | id | | graphql.js:55:11:55:28 | id | graphql.js:58:73:58:74 | id | | graphql.js:55:16:55:28 | req.params.id | graphql.js:55:11:55:28 | id | -| graphql.js:55:16:55:28 | req.params.id | graphql.js:55:11:55:28 | id | | graphql.js:56:46:56:47 | id | graphql.js:56:39:56:49 | `foo ${id}` | -| graphql.js:56:46:56:47 | id | graphql.js:56:39:56:49 | `foo ${id}` | -| graphql.js:58:73:58:74 | id | graphql.js:58:66:58:76 | `foo ${id}` | | graphql.js:58:73:58:74 | id | graphql.js:58:66:58:76 | `foo ${id}` | | graphql.js:74:9:74:25 | id | graphql.js:75:56:75:57 | id | | graphql.js:74:9:74:25 | id | graphql.js:88:13:88:14 | id | | graphql.js:74:14:74:25 | req.query.id | graphql.js:74:9:74:25 | id | -| graphql.js:74:14:74:25 | req.query.id | graphql.js:74:9:74:25 | id | | graphql.js:75:56:75:57 | id | graphql.js:75:46:75:64 | "{ foo" + id + " }" | -| graphql.js:75:56:75:57 | id | graphql.js:75:46:75:64 | "{ foo" + id + " }" | -| graphql.js:88:13:88:14 | id | graphql.js:84:14:90:8 | `{\\n ... }` | | graphql.js:88:13:88:14 | id | graphql.js:84:14:90:8 | `{\\n ... }` | | graphql.js:119:11:119:28 | id | graphql.js:120:45:120:46 | id | | graphql.js:119:16:119:28 | req.params.id | graphql.js:119:11:119:28 | id | -| graphql.js:119:16:119:28 | req.params.id | graphql.js:119:11:119:28 | id | | graphql.js:120:45:120:46 | id | graphql.js:120:38:120:48 | `foo ${id}` | -| graphql.js:120:45:120:46 | id | graphql.js:120:38:120:48 | `foo ${id}` | -| html-sanitizer.js:13:39:13:44 | param1 | html-sanitizer.js:14:18:14:23 | param1 | | html-sanitizer.js:13:39:13:44 | param1 | html-sanitizer.js:14:18:14:23 | param1 | | html-sanitizer.js:14:5:14:24 | param1 | html-sanitizer.js:16:54:16:59 | param1 | | html-sanitizer.js:14:14:14:24 | xss(param1) | html-sanitizer.js:14:5:14:24 | param1 | | html-sanitizer.js:14:18:14:23 | param1 | html-sanitizer.js:14:14:14:24 | xss(param1) | | html-sanitizer.js:16:54:16:59 | param1 | html-sanitizer.js:16:9:16:59 | `SELECT ... param1 | -| html-sanitizer.js:16:54:16:59 | param1 | html-sanitizer.js:16:9:16:59 | `SELECT ... param1 | | json-schema-validator.js:25:15:25:48 | query | json-schema-validator.js:33:22:33:26 | query | -| json-schema-validator.js:25:15:25:48 | query | json-schema-validator.js:33:22:33:26 | query | -| json-schema-validator.js:25:15:25:48 | query | json-schema-validator.js:35:18:35:22 | query | | json-schema-validator.js:25:15:25:48 | query | json-schema-validator.js:35:18:35:22 | query | | json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | json-schema-validator.js:25:15:25:48 | query | | json-schema-validator.js:25:34:25:47 | req.query.data | json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | -| json-schema-validator.js:25:34:25:47 | req.query.data | json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | -| json-schema-validator.js:50:15:50:48 | query | json-schema-validator.js:55:22:55:26 | query | | json-schema-validator.js:50:15:50:48 | query | json-schema-validator.js:55:22:55:26 | query | | json-schema-validator.js:50:15:50:48 | query | json-schema-validator.js:59:22:59:26 | query | -| json-schema-validator.js:50:15:50:48 | query | json-schema-validator.js:59:22:59:26 | query | -| json-schema-validator.js:50:15:50:48 | query | json-schema-validator.js:61:22:61:26 | query | | json-schema-validator.js:50:15:50:48 | query | json-schema-validator.js:61:22:61:26 | query | | json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) | json-schema-validator.js:50:15:50:48 | query | | json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) | -| json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) | +| koarouter.js:5:11:5:33 | version | koarouter.js:14:38:14:44 | version | +| koarouter.js:5:13:5:19 | version | koarouter.js:5:11:5:33 | version | +| koarouter.js:11:11:11:28 | conditions | koarouter.js:17:52:17:61 | conditions | +| koarouter.js:14:9:14:18 | [post update] conditions | koarouter.js:11:11:11:28 | conditions | +| koarouter.js:14:25:14:46 | `versio ... rsion}` | koarouter.js:14:9:14:18 | [post update] conditions | +| koarouter.js:14:38:14:44 | version | koarouter.js:14:25:14:46 | `versio ... rsion}` | +| koarouter.js:17:52:17:61 | conditions | koarouter.js:17:52:17:75 | conditi ... and ') | +| koarouter.js:17:52:17:75 | conditi ... and ') | koarouter.js:17:27:17:77 | `SELECT ... nd ')}` | | ldap.js:20:7:20:34 | q | ldap.js:22:18:22:18 | q | | ldap.js:20:11:20:34 | url.par ... , true) | ldap.js:20:7:20:34 | q | | ldap.js:20:21:20:27 | req.url | ldap.js:20:11:20:34 | url.par ... , true) | -| ldap.js:20:21:20:27 | req.url | ldap.js:20:11:20:34 | url.par ... , true) | | ldap.js:22:7:22:33 | username | ldap.js:25:24:25:31 | username | | ldap.js:22:7:22:33 | username | ldap.js:25:46:25:53 | username | | ldap.js:22:7:22:33 | username | ldap.js:32:26:32:33 | username | @@ -510,15 +340,11 @@ edges | ldap.js:22:7:22:33 | username | ldap.js:64:16:64:23 | username | | ldap.js:22:7:22:33 | username | ldap.js:64:38:64:45 | username | | ldap.js:22:7:22:33 | username | ldap.js:68:33:68:40 | username | -| ldap.js:22:18:22:18 | q | ldap.js:22:18:22:24 | q.query | -| ldap.js:22:18:22:24 | q.query | ldap.js:22:18:22:33 | q.query.username | -| ldap.js:22:18:22:33 | q.query.username | ldap.js:22:7:22:33 | username | -| ldap.js:25:13:25:57 | `(\|(nam ... ame}))` | ldap.js:28:30:28:34 | opts1 | +| ldap.js:22:18:22:18 | q | ldap.js:22:7:22:33 | username | | ldap.js:25:13:25:57 | `(\|(nam ... ame}))` | ldap.js:28:30:28:34 | opts1 | | ldap.js:25:24:25:31 | username | ldap.js:25:13:25:57 | `(\|(nam ... ame}))` | | ldap.js:25:46:25:53 | username | ldap.js:25:13:25:57 | `(\|(nam ... ame}))` | | ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | ldap.js:32:5:32:61 | { filte ... e}))` } | -| ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | ldap.js:32:5:32:61 | { filte ... e}))` } | | ldap.js:32:26:32:33 | username | ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | | ldap.js:32:48:32:55 | username | ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | | ldap.js:63:9:65:3 | parsedFilter | ldap.js:66:40:66:51 | parsedFilter | @@ -527,412 +353,286 @@ edges | ldap.js:64:16:64:23 | username | ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | | ldap.js:64:38:64:45 | username | ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | | ldap.js:66:40:66:51 | parsedFilter | ldap.js:66:30:66:53 | { filte ... ilter } | -| ldap.js:66:40:66:51 | parsedFilter | ldap.js:66:30:66:53 | { filte ... ilter } | | ldap.js:68:33:68:40 | username | ldap.js:68:27:68:42 | `cn=${username}` | -| ldap.js:68:33:68:40 | username | ldap.js:68:27:68:42 | `cn=${username}` | -| marsdb-flow-to.js:10:9:10:18 | query | marsdb-flow-to.js:14:17:14:21 | query | | marsdb-flow-to.js:10:9:10:18 | query | marsdb-flow-to.js:14:17:14:21 | query | | marsdb-flow-to.js:10:17:10:18 | {} | marsdb-flow-to.js:10:9:10:18 | query | | marsdb-flow-to.js:11:17:11:24 | req.body | marsdb-flow-to.js:11:17:11:30 | req.body.title | -| marsdb-flow-to.js:11:17:11:24 | req.body | marsdb-flow-to.js:11:17:11:30 | req.body.title | | marsdb-flow-to.js:11:17:11:30 | req.body.title | marsdb-flow-to.js:10:9:10:18 | query | | marsdb-flow-to.js:11:17:11:30 | req.body.title | marsdb-flow-to.js:10:17:10:18 | {} | | marsdb-flow-to.js:11:17:11:30 | req.body.title | marsdb-flow-to.js:14:17:14:21 | query | -| marsdb-flow-to.js:11:17:11:30 | req.body.title | marsdb-flow-to.js:14:17:14:21 | query | -| marsdb.js:12:9:12:18 | query | marsdb.js:16:12:16:16 | query | | marsdb.js:12:9:12:18 | query | marsdb.js:16:12:16:16 | query | | marsdb.js:12:17:12:18 | {} | marsdb.js:12:9:12:18 | query | | marsdb.js:13:17:13:24 | req.body | marsdb.js:13:17:13:30 | req.body.title | -| marsdb.js:13:17:13:24 | req.body | marsdb.js:13:17:13:30 | req.body.title | | marsdb.js:13:17:13:30 | req.body.title | marsdb.js:12:9:12:18 | query | | marsdb.js:13:17:13:30 | req.body.title | marsdb.js:12:17:12:18 | {} | | marsdb.js:13:17:13:30 | req.body.title | marsdb.js:16:12:16:16 | query | -| marsdb.js:13:17:13:30 | req.body.title | marsdb.js:16:12:16:16 | query | -| minimongo.js:14:9:14:18 | query | minimongo.js:18:12:18:16 | query | | minimongo.js:14:9:14:18 | query | minimongo.js:18:12:18:16 | query | | minimongo.js:14:17:14:18 | {} | minimongo.js:14:9:14:18 | query | | minimongo.js:15:17:15:24 | req.body | minimongo.js:15:17:15:30 | req.body.title | -| minimongo.js:15:17:15:24 | req.body | minimongo.js:15:17:15:30 | req.body.title | | minimongo.js:15:17:15:30 | req.body.title | minimongo.js:14:9:14:18 | query | | minimongo.js:15:17:15:30 | req.body.title | minimongo.js:14:17:14:18 | {} | | minimongo.js:15:17:15:30 | req.body.title | minimongo.js:18:12:18:16 | query | -| minimongo.js:15:17:15:30 | req.body.title | minimongo.js:18:12:18:16 | query | -| mongodb.js:12:11:12:20 | query | mongodb.js:18:16:18:20 | query | -| mongodb.js:12:11:12:20 | query | mongodb.js:18:16:18:20 | query | +| mongodb.js:12:11:12:20 | query | mongodb.js:13:5:13:9 | query | | mongodb.js:12:19:12:20 | {} | mongodb.js:12:11:12:20 | query | -| mongodb.js:13:19:13:26 | req.body | mongodb.js:13:19:13:32 | req.body.title | +| mongodb.js:13:5:13:9 | query | mongodb.js:18:16:18:20 | query | | mongodb.js:13:19:13:26 | req.body | mongodb.js:13:19:13:32 | req.body.title | | mongodb.js:13:19:13:32 | req.body.title | mongodb.js:12:11:12:20 | query | | mongodb.js:13:19:13:32 | req.body.title | mongodb.js:12:19:12:20 | {} | -| mongodb.js:13:19:13:32 | req.body.title | mongodb.js:18:16:18:20 | query | +| mongodb.js:13:19:13:32 | req.body.title | mongodb.js:13:5:13:9 | query | | mongodb.js:13:19:13:32 | req.body.title | mongodb.js:18:16:18:20 | query | | mongodb.js:26:11:26:32 | title | mongodb.js:32:38:32:42 | title | | mongodb.js:26:19:26:26 | req.body | mongodb.js:26:19:26:32 | req.body.title | -| mongodb.js:26:19:26:26 | req.body | mongodb.js:26:19:26:32 | req.body.title | | mongodb.js:26:19:26:32 | req.body.title | mongodb.js:26:11:26:32 | title | | mongodb.js:32:27:32:43 | JSON.parse(title) | mongodb.js:32:18:32:45 | { title ... itle) } | -| mongodb.js:32:27:32:43 | JSON.parse(title) | mongodb.js:32:18:32:45 | { title ... itle) } | | mongodb.js:32:38:32:42 | title | mongodb.js:32:27:32:43 | JSON.parse(title) | -| mongodb.js:48:11:48:20 | query | mongodb.js:54:16:54:20 | query | -| mongodb.js:48:11:48:20 | query | mongodb.js:54:16:54:20 | query | +| mongodb.js:48:11:48:20 | query | mongodb.js:49:5:49:9 | query | | mongodb.js:48:19:48:20 | {} | mongodb.js:48:11:48:20 | query | -| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:48:11:48:20 | query | +| mongodb.js:49:5:49:9 | query | mongodb.js:54:16:54:20 | query | | mongodb.js:49:19:49:33 | req.query.title | mongodb.js:48:11:48:20 | query | | mongodb.js:49:19:49:33 | req.query.title | mongodb.js:48:19:48:20 | {} | -| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:48:19:48:20 | {} | +| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:49:5:49:9 | query | | mongodb.js:49:19:49:33 | req.query.title | mongodb.js:54:16:54:20 | query | -| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:54:16:54:20 | query | -| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:54:16:54:20 | query | -| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:54:16:54:20 | query | -| mongodb.js:59:8:59:17 | query | mongodb.js:65:12:65:16 | query | -| mongodb.js:59:8:59:17 | query | mongodb.js:65:12:65:16 | query | +| mongodb.js:59:8:59:17 | query | mongodb.js:60:2:60:6 | query | | mongodb.js:59:16:59:17 | {} | mongodb.js:59:8:59:17 | query | -| mongodb.js:60:16:60:30 | req.query.title | mongodb.js:59:8:59:17 | query | +| mongodb.js:60:2:60:6 | query | mongodb.js:65:12:65:16 | query | | mongodb.js:60:16:60:30 | req.query.title | mongodb.js:59:8:59:17 | query | | mongodb.js:60:16:60:30 | req.query.title | mongodb.js:59:16:59:17 | {} | -| mongodb.js:60:16:60:30 | req.query.title | mongodb.js:59:16:59:17 | {} | -| mongodb.js:60:16:60:30 | req.query.title | mongodb.js:65:12:65:16 | query | -| mongodb.js:60:16:60:30 | req.query.title | mongodb.js:65:12:65:16 | query | -| mongodb.js:60:16:60:30 | req.query.title | mongodb.js:65:12:65:16 | query | +| mongodb.js:60:16:60:30 | req.query.title | mongodb.js:60:2:60:6 | query | | mongodb.js:60:16:60:30 | req.query.title | mongodb.js:65:12:65:16 | query | | mongodb.js:70:7:70:25 | tag | mongodb.js:77:22:77:24 | tag | | mongodb.js:70:7:70:25 | tag | mongodb.js:85:20:85:22 | tag | | mongodb.js:70:13:70:25 | req.query.tag | mongodb.js:70:7:70:25 | tag | -| mongodb.js:70:13:70:25 | req.query.tag | mongodb.js:70:7:70:25 | tag | -| mongodb.js:77:22:77:24 | tag | mongodb.js:77:14:77:26 | { tags: tag } | | mongodb.js:77:22:77:24 | tag | mongodb.js:77:14:77:26 | { tags: tag } | | mongodb.js:85:20:85:22 | tag | mongodb.js:85:12:85:24 | { tags: tag } | -| mongodb.js:85:20:85:22 | tag | mongodb.js:85:12:85:24 | { tags: tag } | -| mongodb.js:106:9:106:18 | query | mongodb.js:112:14:112:18 | query | -| mongodb.js:106:9:106:18 | query | mongodb.js:112:14:112:18 | query | +| mongodb.js:106:9:106:18 | query | mongodb.js:107:3:107:7 | query | | mongodb.js:106:17:106:18 | {} | mongodb.js:106:9:106:18 | query | -| mongodb.js:107:17:107:29 | queries.title | mongodb.js:106:9:106:18 | query | +| mongodb.js:107:3:107:7 | query | mongodb.js:112:14:112:18 | query | | mongodb.js:107:17:107:29 | queries.title | mongodb.js:106:9:106:18 | query | | mongodb.js:107:17:107:29 | queries.title | mongodb.js:106:17:106:18 | {} | -| mongodb.js:107:17:107:29 | queries.title | mongodb.js:106:17:106:18 | {} | +| mongodb.js:107:17:107:29 | queries.title | mongodb.js:107:3:107:7 | query | | mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query | -| mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query | -| mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query | -| mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query | -| mongodb_bodySafe.js:23:11:23:20 | query | mongodb_bodySafe.js:29:16:29:20 | query | -| mongodb_bodySafe.js:23:11:23:20 | query | mongodb_bodySafe.js:29:16:29:20 | query | +| mongodb_bodySafe.js:23:11:23:20 | query | mongodb_bodySafe.js:24:5:24:9 | query | | mongodb_bodySafe.js:23:19:23:20 | {} | mongodb_bodySafe.js:23:11:23:20 | query | -| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:23:11:23:20 | query | +| mongodb_bodySafe.js:24:5:24:9 | query | mongodb_bodySafe.js:29:16:29:20 | query | | mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:23:11:23:20 | query | | mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:23:19:23:20 | {} | -| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:23:19:23:20 | {} | -| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | -| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | -| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | +| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:24:5:24:9 | query | | mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:21:2:21:6 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:24:22:24:26 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:27:17:27:21 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:27:17:27:21 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:30:22:30:26 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:30:22:30:26 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:33:21:33:25 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:33:21:33:25 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:36:28:36:32 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:36:28:36:32 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:39:16:39:20 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:39:16:39:20 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:42:19:42:23 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:42:19:42:23 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:45:28:45:32 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:45:28:45:32 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:48:28:48:32 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:48:28:48:32 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:51:28:51:32 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:51:28:51:32 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:54:22:54:26 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:54:22:54:26 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:57:18:57:22 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:57:18:57:22 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:60:22:60:26 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:60:22:60:26 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:63:21:63:25 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:63:21:63:25 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:65:32:65:36 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:65:32:65:36 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:67:27:67:31 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:67:27:67:31 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:68:8:68:12 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:68:8:68:12 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:71:17:71:21 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:71:17:71:21 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:72:10:72:14 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:72:10:72:14 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:73:8:73:12 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:73:8:73:12 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:74:7:74:11 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:74:7:74:11 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:75:16:75:20 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:75:16:75:20 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:76:12:76:16 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:77:10:77:14 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:77:10:77:14 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:82:46:82:50 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:81:37:81:41 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:82:46:82:50 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:83:47:83:51 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:83:47:83:51 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:85:46:85:50 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:85:46:85:50 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:87:51:87:55 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:87:51:87:55 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:89:46:89:50 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:89:46:89:50 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:92:46:92:50 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:92:46:92:50 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:94:51:94:55 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:94:51:94:55 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:96:46:96:50 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:96:46:96:50 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:111:14:111:18 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:104:21:104:25 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:111:14:111:18 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:113:31:113:35 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:113:31:113:35 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:136:30:136:34 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:133:38:133:42 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:134:30:134:34 | query | | mongoose.js:20:8:20:17 | query | mongoose.js:136:30:136:34 | query | | mongoose.js:20:16:20:17 | {} | mongoose.js:20:8:20:17 | query | -| mongoose.js:21:16:21:23 | req.body | mongoose.js:21:16:21:29 | req.body.title | +| mongoose.js:21:2:21:6 | query | mongoose.js:24:22:24:26 | query | | mongoose.js:21:16:21:23 | req.body | mongoose.js:21:16:21:29 | req.body.title | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:20:8:20:17 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:20:16:20:17 | {} | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:21:2:21:6 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:24:22:24:26 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:27:17:27:21 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:27:17:27:21 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:30:22:30:26 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:30:22:30:26 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:33:21:33:25 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:33:21:33:25 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:36:28:36:32 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:36:28:36:32 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:39:16:39:20 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:39:16:39:20 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:42:19:42:23 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:42:19:42:23 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:45:28:45:32 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:45:28:45:32 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:48:28:48:32 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:48:28:48:32 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:51:28:51:32 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:51:28:51:32 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:54:22:54:26 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:54:22:54:26 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:57:18:57:22 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:57:18:57:22 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:60:22:60:26 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:60:22:60:26 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:63:21:63:25 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:63:21:63:25 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:65:32:65:36 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:65:32:65:36 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:67:27:67:31 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:67:27:67:31 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:68:8:68:12 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:68:8:68:12 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:71:17:71:21 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:71:17:71:21 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:72:10:72:14 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:72:10:72:14 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:73:8:73:12 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:73:8:73:12 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:74:7:74:11 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:74:7:74:11 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:75:16:75:20 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:75:16:75:20 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:76:12:76:16 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:77:10:77:14 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:77:10:77:14 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:82:46:82:50 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:81:37:81:41 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:82:46:82:50 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:83:47:83:51 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:83:47:83:51 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:85:46:85:50 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:85:46:85:50 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:87:51:87:55 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:87:51:87:55 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:89:46:89:50 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:89:46:89:50 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:92:46:92:50 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:92:46:92:50 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:94:51:94:55 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:94:51:94:55 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:96:46:96:50 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:96:46:96:50 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:111:14:111:18 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:104:21:104:25 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:111:14:111:18 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:113:31:113:35 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:113:31:113:35 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:136:30:136:34 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:133:38:133:42 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:134:30:134:34 | query | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:136:30:136:34 | query | | mongoose.js:24:22:24:26 | query | mongoose.js:24:21:24:27 | [query] | -| mongoose.js:24:22:24:26 | query | mongoose.js:24:21:24:27 | [query] | -| mongoose.js:115:6:115:22 | id | mongoose.js:123:20:123:21 | id | +| mongoose.js:24:22:24:26 | query | mongoose.js:27:17:27:21 | query | +| mongoose.js:27:17:27:21 | query | mongoose.js:30:22:30:26 | query | +| mongoose.js:30:22:30:26 | query | mongoose.js:33:21:33:25 | query | +| mongoose.js:33:21:33:25 | query | mongoose.js:36:28:36:32 | query | +| mongoose.js:36:28:36:32 | query | mongoose.js:39:16:39:20 | query | +| mongoose.js:39:16:39:20 | query | mongoose.js:42:19:42:23 | query | +| mongoose.js:42:19:42:23 | query | mongoose.js:45:28:45:32 | query | +| mongoose.js:45:28:45:32 | query | mongoose.js:48:28:48:32 | query | +| mongoose.js:48:28:48:32 | query | mongoose.js:51:28:51:32 | query | +| mongoose.js:51:28:51:32 | query | mongoose.js:54:22:54:26 | query | +| mongoose.js:54:22:54:26 | query | mongoose.js:57:18:57:22 | query | +| mongoose.js:57:18:57:22 | query | mongoose.js:60:22:60:26 | query | +| mongoose.js:60:22:60:26 | query | mongoose.js:63:21:63:25 | query | +| mongoose.js:63:21:63:25 | query | mongoose.js:65:32:65:36 | query | +| mongoose.js:65:32:65:36 | query | mongoose.js:67:27:67:31 | query | +| mongoose.js:67:27:67:31 | query | mongoose.js:68:8:68:12 | query | +| mongoose.js:68:8:68:12 | query | mongoose.js:71:17:71:21 | query | +| mongoose.js:71:17:71:21 | query | mongoose.js:72:10:72:14 | query | +| mongoose.js:72:10:72:14 | query | mongoose.js:73:8:73:12 | query | +| mongoose.js:73:8:73:12 | query | mongoose.js:74:7:74:11 | query | +| mongoose.js:74:7:74:11 | query | mongoose.js:75:16:75:20 | query | +| mongoose.js:75:16:75:20 | query | mongoose.js:76:12:76:16 | query | +| mongoose.js:76:12:76:16 | query | mongoose.js:77:10:77:14 | query | +| mongoose.js:77:10:77:14 | query | mongoose.js:81:37:81:41 | query | +| mongoose.js:81:37:81:41 | query | mongoose.js:82:46:82:50 | query | +| mongoose.js:82:46:82:50 | query | mongoose.js:83:47:83:51 | query | +| mongoose.js:83:47:83:51 | query | mongoose.js:85:46:85:50 | query | +| mongoose.js:83:47:83:51 | query | mongoose.js:87:51:87:55 | query | +| mongoose.js:83:47:83:51 | query | mongoose.js:89:46:89:50 | query | +| mongoose.js:83:47:83:51 | query | mongoose.js:92:46:92:50 | query | +| mongoose.js:83:47:83:51 | query | mongoose.js:94:51:94:55 | query | +| mongoose.js:83:47:83:51 | query | mongoose.js:96:46:96:50 | query | +| mongoose.js:83:47:83:51 | query | mongoose.js:104:21:104:25 | query | +| mongoose.js:104:21:104:25 | query | mongoose.js:111:14:111:18 | query | +| mongoose.js:111:14:111:18 | query | mongoose.js:113:31:113:35 | query | +| mongoose.js:113:31:113:35 | query | mongoose.js:133:38:133:42 | query | | mongoose.js:115:6:115:22 | id | mongoose.js:123:20:123:21 | id | | mongoose.js:115:6:115:22 | id | mongoose.js:130:23:130:24 | id | | mongoose.js:115:11:115:22 | req.query.id | mongoose.js:115:6:115:22 | id | -| mongoose.js:115:11:115:22 | req.query.id | mongoose.js:115:6:115:22 | id | -| mongoose.js:115:25:115:45 | cond | mongoose.js:116:22:116:25 | cond | | mongoose.js:115:25:115:45 | cond | mongoose.js:116:22:116:25 | cond | | mongoose.js:115:25:115:45 | cond | mongoose.js:117:21:117:24 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:117:21:117:24 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:118:21:118:24 | cond | | mongoose.js:115:25:115:45 | cond | mongoose.js:118:21:118:24 | cond | | mongoose.js:115:25:115:45 | cond | mongoose.js:119:18:119:21 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:119:18:119:21 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:120:22:120:25 | cond | | mongoose.js:115:25:115:45 | cond | mongoose.js:120:22:120:25 | cond | | mongoose.js:115:25:115:45 | cond | mongoose.js:121:16:121:19 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:121:16:121:19 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:122:19:122:22 | cond | | mongoose.js:115:25:115:45 | cond | mongoose.js:122:19:122:22 | cond | | mongoose.js:115:25:115:45 | cond | mongoose.js:124:28:124:31 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:124:28:124:31 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:125:28:125:31 | cond | | mongoose.js:115:25:115:45 | cond | mongoose.js:125:28:125:31 | cond | | mongoose.js:115:25:115:45 | cond | mongoose.js:126:28:126:31 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:126:28:126:31 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:127:18:127:21 | cond | | mongoose.js:115:25:115:45 | cond | mongoose.js:127:18:127:21 | cond | | mongoose.js:115:25:115:45 | cond | mongoose.js:128:22:128:25 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:128:22:128:25 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:129:21:129:24 | cond | | mongoose.js:115:25:115:45 | cond | mongoose.js:129:21:129:24 | cond | | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:115:25:115:45 | cond | -| mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:115:25:115:45 | cond | | mongoose.js:130:23:130:24 | id | mongoose.js:130:16:130:26 | { _id: id } | -| mongoose.js:130:23:130:24 | id | mongoose.js:130:16:130:26 | { _id: id } | -| mongooseJsonParse.js:19:11:19:20 | query | mongooseJsonParse.js:23:19:23:23 | query | +| mongoose.js:133:38:133:42 | query | mongoose.js:134:30:134:34 | query | +| mongoose.js:133:38:133:42 | query | mongoose.js:136:30:136:34 | query | | mongooseJsonParse.js:19:11:19:20 | query | mongooseJsonParse.js:23:19:23:23 | query | | mongooseJsonParse.js:19:19:19:20 | {} | mongooseJsonParse.js:19:11:19:20 | query | | mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) | mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | | mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | mongooseJsonParse.js:19:11:19:20 | query | | mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | mongooseJsonParse.js:19:19:19:20 | {} | | mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | mongooseJsonParse.js:23:19:23:23 | query | -| mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | mongooseJsonParse.js:23:19:23:23 | query | -| mongooseJsonParse.js:20:30:20:43 | req.query.data | mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) | | mongooseJsonParse.js:20:30:20:43 | req.query.data | mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) | | mongooseModelClient.js:10:7:10:32 | v | mongooseModelClient.js:11:22:11:22 | v | | mongooseModelClient.js:10:11:10:32 | JSON.pa ... body.x) | mongooseModelClient.js:10:7:10:32 | v | | mongooseModelClient.js:10:22:10:29 | req.body | mongooseModelClient.js:10:22:10:31 | req.body.x | -| mongooseModelClient.js:10:22:10:29 | req.body | mongooseModelClient.js:10:22:10:31 | req.body.x | | mongooseModelClient.js:10:22:10:31 | req.body.x | mongooseModelClient.js:10:11:10:32 | JSON.pa ... body.x) | | mongooseModelClient.js:11:22:11:22 | v | mongooseModelClient.js:11:16:11:24 | { id: v } | -| mongooseModelClient.js:11:22:11:22 | v | mongooseModelClient.js:11:16:11:24 | { id: v } | | mongooseModelClient.js:12:22:12:29 | req.body | mongooseModelClient.js:12:22:12:32 | req.body.id | -| mongooseModelClient.js:12:22:12:29 | req.body | mongooseModelClient.js:12:22:12:32 | req.body.id | -| mongooseModelClient.js:12:22:12:32 | req.body.id | mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | | mongooseModelClient.js:12:22:12:32 | req.body.id | mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | | mysql.js:6:9:6:31 | temp | mysql.js:15:62:15:65 | temp | | mysql.js:6:9:6:31 | temp | mysql.js:19:70:19:73 | temp | | mysql.js:6:16:6:31 | req.params.value | mysql.js:6:9:6:31 | temp | -| mysql.js:6:16:6:31 | req.params.value | mysql.js:6:9:6:31 | temp | -| mysql.js:15:62:15:65 | temp | mysql.js:15:18:15:65 | 'SELECT ... + temp | | mysql.js:15:62:15:65 | temp | mysql.js:15:18:15:65 | 'SELECT ... + temp | | mysql.js:19:70:19:73 | temp | mysql.js:19:26:19:73 | 'SELECT ... + temp | -| mysql.js:19:70:19:73 | temp | mysql.js:19:26:19:73 | 'SELECT ... + temp | -| pg-promise-types.ts:7:9:7:28 | taint | pg-promise-types.ts:8:17:8:21 | taint | | pg-promise-types.ts:7:9:7:28 | taint | pg-promise-types.ts:8:17:8:21 | taint | | pg-promise-types.ts:7:17:7:28 | req.params.x | pg-promise-types.ts:7:9:7:28 | taint | -| pg-promise-types.ts:7:17:7:28 | req.params.x | pg-promise-types.ts:7:9:7:28 | taint | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:9:10:9:14 | query | | pg-promise.js:6:7:7:55 | query | pg-promise.js:9:10:9:14 | query | | pg-promise.js:6:7:7:55 | query | pg-promise.js:10:11:10:15 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:10:11:10:15 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:11:17:11:21 | query | | pg-promise.js:6:7:7:55 | query | pg-promise.js:11:17:11:21 | query | | pg-promise.js:6:7:7:55 | query | pg-promise.js:12:10:12:14 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:12:10:12:14 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:13:12:13:16 | query | | pg-promise.js:6:7:7:55 | query | pg-promise.js:13:12:13:16 | query | | pg-promise.js:6:7:7:55 | query | pg-promise.js:14:18:14:22 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:14:18:14:22 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:15:11:15:15 | query | | pg-promise.js:6:7:7:55 | query | pg-promise.js:15:11:15:15 | query | | pg-promise.js:6:7:7:55 | query | pg-promise.js:16:10:16:14 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:16:10:16:14 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:17:16:17:20 | query | | pg-promise.js:6:7:7:55 | query | pg-promise.js:17:16:17:20 | query | | pg-promise.js:6:7:7:55 | query | pg-promise.js:18:12:18:16 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:18:12:18:16 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:19:13:19:17 | query | | pg-promise.js:6:7:7:55 | query | pg-promise.js:19:13:19:17 | query | | pg-promise.js:6:7:7:55 | query | pg-promise.js:22:11:22:15 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:22:11:22:15 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:60:20:60:24 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:60:20:60:24 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:63:23:63:27 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:63:23:63:27 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:64:16:64:20 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:64:16:64:20 | query | -| pg-promise.js:6:15:7:55 | "SELECT ... PRICE" | pg-promise.js:6:7:7:55 | query | -| pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:6:15:7:55 | "SELECT ... PRICE" | -| pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:6:15:7:55 | "SELECT ... PRICE" | -| pg-promise.js:30:13:30:25 | req.params.id | pg-promise.js:30:13:30:25 | req.params.id | -| pg-promise.js:34:13:34:25 | req.params.id | pg-promise.js:34:13:34:25 | req.params.id | +| pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:6:7:7:55 | query | +| pg-promise.js:9:10:9:14 | query | pg-promise.js:10:11:10:15 | query | +| pg-promise.js:10:11:10:15 | query | pg-promise.js:11:17:11:21 | query | +| pg-promise.js:11:17:11:21 | query | pg-promise.js:12:10:12:14 | query | +| pg-promise.js:12:10:12:14 | query | pg-promise.js:13:12:13:16 | query | +| pg-promise.js:13:12:13:16 | query | pg-promise.js:14:18:14:22 | query | +| pg-promise.js:14:18:14:22 | query | pg-promise.js:15:11:15:15 | query | +| pg-promise.js:15:11:15:15 | query | pg-promise.js:16:10:16:14 | query | +| pg-promise.js:16:10:16:14 | query | pg-promise.js:17:16:17:20 | query | +| pg-promise.js:17:16:17:20 | query | pg-promise.js:18:12:18:16 | query | +| pg-promise.js:18:12:18:16 | query | pg-promise.js:19:13:19:17 | query | +| pg-promise.js:19:13:19:17 | query | pg-promise.js:22:11:22:15 | query | +| pg-promise.js:22:11:22:15 | query | pg-promise.js:60:20:60:24 | query | +| pg-promise.js:22:11:22:15 | query | pg-promise.js:63:23:63:27 | query | +| pg-promise.js:22:11:22:15 | query | pg-promise.js:64:16:64:20 | query | | pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:39:7:39:19 | req.params.id | | pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:40:7:40:21 | req.params.name | | pg-promise.js:41:7:41:20 | req.params.foo | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| pg-promise.js:41:7:41:20 | req.params.foo | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| pg-promise.js:41:7:41:20 | req.params.foo | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| pg-promise.js:41:7:41:20 | req.params.foo | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| pg-promise.js:47:11:47:23 | req.params.id | pg-promise.js:47:11:47:23 | req.params.id | -| pg-promise.js:54:11:54:23 | req.params.id | pg-promise.js:54:11:54:23 | req.params.id | -| pg-promise.js:56:14:56:29 | req.params.title | pg-promise.js:56:14:56:29 | req.params.title | | redis.js:10:16:10:23 | req.body | redis.js:10:16:10:27 | req.body.key | -| redis.js:10:16:10:23 | req.body | redis.js:10:16:10:27 | req.body.key | -| redis.js:10:16:10:23 | req.body | redis.js:10:16:10:27 | req.body.key | -| redis.js:10:16:10:23 | req.body | redis.js:10:16:10:27 | req.body.key | -| redis.js:12:9:12:26 | key | redis.js:18:16:18:18 | key | +| redis.js:12:9:12:26 | key | redis.js:13:16:13:18 | key | | redis.js:12:9:12:26 | key | redis.js:18:16:18:18 | key | | redis.js:12:9:12:26 | key | redis.js:19:43:19:45 | key | -| redis.js:12:9:12:26 | key | redis.js:19:43:19:45 | key | | redis.js:12:9:12:26 | key | redis.js:25:14:25:16 | key | -| redis.js:12:9:12:26 | key | redis.js:25:14:25:16 | key | -| redis.js:12:9:12:26 | key | redis.js:30:23:30:25 | key | -| redis.js:12:9:12:26 | key | redis.js:30:23:30:25 | key | +| redis.js:12:9:12:26 | key | redis.js:26:14:26:16 | key | | redis.js:12:9:12:26 | key | redis.js:32:28:32:30 | key | -| redis.js:12:9:12:26 | key | redis.js:32:28:32:30 | key | -| redis.js:12:15:12:22 | req.body | redis.js:12:15:12:26 | req.body.key | | redis.js:12:15:12:22 | req.body | redis.js:12:15:12:26 | req.body.key | | redis.js:12:15:12:26 | req.body.key | redis.js:12:9:12:26 | key | -| redis.js:38:11:38:28 | key | redis.js:39:16:39:18 | key | +| redis.js:13:16:13:18 | key | redis.js:18:16:18:18 | key | +| redis.js:18:16:18:18 | key | redis.js:19:43:19:45 | key | +| redis.js:19:43:19:45 | key | redis.js:25:14:25:16 | key | +| redis.js:25:14:25:16 | key | redis.js:26:14:26:16 | key | +| redis.js:26:14:26:16 | key | redis.js:30:23:30:25 | key | +| redis.js:26:14:26:16 | key | redis.js:32:28:32:30 | key | | redis.js:38:11:38:28 | key | redis.js:39:16:39:18 | key | | redis.js:38:11:38:28 | key | redis.js:43:27:43:29 | key | -| redis.js:38:11:38:28 | key | redis.js:43:27:43:29 | key | | redis.js:38:11:38:28 | key | redis.js:46:34:46:36 | key | -| redis.js:38:11:38:28 | key | redis.js:46:34:46:36 | key | -| redis.js:38:17:38:24 | req.body | redis.js:38:17:38:28 | req.body.key | | redis.js:38:17:38:24 | req.body | redis.js:38:17:38:28 | req.body.key | | redis.js:38:17:38:28 | req.body.key | redis.js:38:11:38:28 | key | | socketio.js:10:25:10:30 | handle | socketio.js:11:46:11:51 | handle | -| socketio.js:10:25:10:30 | handle | socketio.js:11:46:11:51 | handle | -| socketio.js:11:46:11:51 | handle | socketio.js:11:12:11:53 | `INSERT ... andle}` | | socketio.js:11:46:11:51 | handle | socketio.js:11:12:11:53 | `INSERT ... andle}` | | tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" | -| tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" | -| tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" | -| tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" | | tst3.js:7:7:8:55 | query1 | tst3.js:9:14:9:19 | query1 | -| tst3.js:7:7:8:55 | query1 | tst3.js:9:14:9:19 | query1 | -| tst3.js:7:16:8:55 | "SELECT ... PRICE" | tst3.js:7:7:8:55 | query1 | -| tst3.js:8:16:8:34 | req.params.category | tst3.js:7:16:8:55 | "SELECT ... PRICE" | -| tst3.js:8:16:8:34 | req.params.category | tst3.js:7:16:8:55 | "SELECT ... PRICE" | -| tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | -| tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | -| tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | +| tst3.js:8:16:8:34 | req.params.category | tst3.js:7:7:8:55 | query1 | | tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | | tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | -| tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | -| tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | -| tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | +subpaths #select | graphql.js:10:34:20:5 | `\\n ... }\\n ` | graphql.js:8:16:8:28 | req.params.id | graphql.js:10:34:20:5 | `\\n ... }\\n ` | This query string depends on a $@. | graphql.js:8:16:8:28 | req.params.id | user-provided value | | graphql.js:27:30:27:40 | `foo ${id}` | graphql.js:26:16:26:28 | req.params.id | graphql.js:27:30:27:40 | `foo ${id}` | This query string depends on a $@. | graphql.js:26:16:26:28 | req.params.id | user-provided value | @@ -951,6 +651,7 @@ edges | json-schema-validator.js:55:22:55:26 | query | json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:55:22:55:26 | query | This query object depends on a $@. | json-schema-validator.js:50:34:50:47 | req.query.data | user-provided value | | json-schema-validator.js:59:22:59:26 | query | json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:59:22:59:26 | query | This query object depends on a $@. | json-schema-validator.js:50:34:50:47 | req.query.data | user-provided value | | json-schema-validator.js:61:22:61:26 | query | json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:61:22:61:26 | query | This query object depends on a $@. | json-schema-validator.js:50:34:50:47 | req.query.data | user-provided value | +| koarouter.js:17:27:17:77 | `SELECT ... nd ')}` | koarouter.js:5:13:5:19 | version | koarouter.js:17:27:17:77 | `SELECT ... nd ')}` | This query string depends on a $@. | koarouter.js:5:13:5:19 | version | user-provided value | | ldap.js:28:30:28:34 | opts1 | ldap.js:20:21:20:27 | req.url | ldap.js:28:30:28:34 | opts1 | This query string depends on a $@. | ldap.js:20:21:20:27 | req.url | user-provided value | | ldap.js:32:5:32:61 | { filte ... e}))` } | ldap.js:20:21:20:27 | req.url | ldap.js:32:5:32:61 | { filte ... e}))` } | This query string depends on a $@. | ldap.js:20:21:20:27 | req.url | user-provided value | | ldap.js:66:30:66:53 | { filte ... ilter } | ldap.js:20:21:20:27 | req.url | ldap.js:66:30:66:53 | { filte ... ilter } | This query string depends on a $@. | ldap.js:20:21:20:27 | req.url | user-provided value | @@ -1014,6 +715,7 @@ edges | mongoose.js:128:22:128:25 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:128:22:128:25 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | | mongoose.js:129:21:129:24 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:129:21:129:24 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | | mongoose.js:130:16:130:26 | { _id: id } | mongoose.js:115:11:115:22 | req.query.id | mongoose.js:130:16:130:26 | { _id: id } | This query object depends on a $@. | mongoose.js:115:11:115:22 | req.query.id | user-provided value | +| mongoose.js:134:30:134:34 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:134:30:134:34 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | | mongoose.js:136:30:136:34 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:136:30:136:34 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | | mongooseJsonParse.js:23:19:23:23 | query | mongooseJsonParse.js:20:30:20:43 | req.query.data | mongooseJsonParse.js:23:19:23:23 | query | This query object depends on a $@. | mongooseJsonParse.js:20:30:20:43 | req.query.data | user-provided value | | mongooseModelClient.js:11:16:11:24 | { id: v } | mongooseModelClient.js:10:22:10:29 | req.body | mongooseModelClient.js:11:16:11:24 | { id: v } | This query object depends on a $@. | mongooseModelClient.js:10:22:10:29 | req.body | user-provided value | From 2818fa62d609225a1009fff34be42e89ae8a240f Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:28:27 +0200 Subject: [PATCH 047/514] JS: Updates to shared Xss.qll --- .../javascript/security/dataflow/Xss.qll | 54 +++++++++++++------ 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/Xss.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/Xss.qll index fc2db8e9f87..93a9fa7fc40 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/Xss.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/Xss.qll @@ -72,36 +72,60 @@ module Shared { private import semmle.javascript.security.dataflow.IncompleteHtmlAttributeSanitizationCustomizations::IncompleteHtmlAttributeSanitization as IncompleteHtml /** - * A guard that checks if a string can contain quotes, which is a guard for strings that are inside an HTML attribute. + * A barrier guard that applies to multiple XSS queries. */ - abstract class QuoteGuard extends TaintTracking::SanitizerGuardNode, StringOps::Includes { - QuoteGuard() { + 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() } + } + + /** + * A barrier guard that applies to multiple XSS queries. + */ + module BarrierGuard = DataFlow::MakeBarrierGuard; + + private class QuoteGuard2 extends BarrierGuard, StringOps::Includes { + QuoteGuard2() { this.getSubstring().mayHaveStringValue("\"") and this.getBaseString() .getALocalSource() .flowsTo(any(IncompleteHtml::HtmlAttributeConcatenation attributeConcat)) } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { e = this.getBaseString().getEnclosingExpr() and outcome = this.getPolarity().booleanNot() } } + /** + * A guard that checks if a string can contain quotes, which is a guard for strings that are inside an HTML attribute. + */ + abstract class QuoteGuard extends TaintTracking::SanitizerGuardNode instanceof QuoteGuard2 { + override predicate sanitizes(boolean outcome, Expr e) { super.blocksExpr(outcome, e) } + } + + private class ContainsHtmlGuard2 extends BarrierGuard, StringOps::RegExpTest { + ContainsHtmlGuard2() { + exists(RegExpCharacterClass regExp | + regExp = this.getRegExp() and + forall(string s | s = ["\"", "&", "<", ">"] | regExp.getAMatchedString() = s) + ) + } + + override predicate blocksExpr(boolean outcome, Expr e) { + outcome = this.getPolarity().booleanNot() and e = this.getStringOperand().asExpr() + } + } + /** * A sanitizer guard that checks for the existence of HTML chars in a string. * E.g. `/["'&<>]/.exec(str)`. */ - abstract class ContainsHtmlGuard extends TaintTracking::SanitizerGuardNode, StringOps::RegExpTest { - ContainsHtmlGuard() { - exists(RegExpCharacterClass regExp | - regExp = this.getRegExp() and - forall(string s | s = ["\"", "&", "<", ">"] | regExp.getAMatchedString() = s) - ) - } - - override predicate sanitizes(boolean outcome, Expr e) { - outcome = this.getPolarity().booleanNot() and e = this.getStringOperand().asExpr() - } + abstract class ContainsHtmlGuard extends TaintTracking::SanitizerGuardNode instanceof ContainsHtmlGuard2 + { + override predicate sanitizes(boolean outcome, Expr e) { super.blocksExpr(outcome, e) } } /** From e091fdefa4e40827ac4afc9be9a3b66e21da77c6 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:29:11 +0200 Subject: [PATCH 048/514] JS: Port DomBasedXss --- .../dataflow/DomBasedXssCustomizations.qll | 29 +- .../security/dataflow/DomBasedXssQuery.qll | 113 +- javascript/ql/src/Security/CWE-079/Xss.ql | 6 +- .../ConsistencyDomBasedXss.expected | 3 + .../DomBasedXss/ConsistencyDomBasedXss.ql | 8 +- .../Security/CWE-079/DomBasedXss/Xss.expected | 2642 +++++----------- .../XssWithAdditionalSources.expected | 2742 +++++------------ .../DomBasedXss/XssWithAdditionalSources.ql | 8 +- 8 files changed, 1534 insertions(+), 4017 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssCustomizations.qll index b3ab20583ef..190181fdebd 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssCustomizations.qll @@ -18,6 +18,30 @@ module DomBasedXss { /** A sanitizer for DOM-based XSS vulnerabilities. */ abstract class Sanitizer extends Shared::Sanitizer { } + /** + * A barrier guard for any tainted value. + */ + 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) + } + } + /** * An expression whose value is interpreted as HTML * and may be inserted into the DOM through a library. @@ -347,9 +371,8 @@ module DomBasedXss { /** * A sanitizer that blocks the `PrefixString` label when the start of the string is being tested as being of a particular prefix. */ - abstract class PrefixStringSanitizer extends TaintTracking::LabeledSanitizerGuardNode instanceof StringOps::StartsWith - { - override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { + abstract class PrefixStringSanitizer extends BarrierGuardLegacy instanceof StringOps::StartsWith { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { e = super.getBaseString().asExpr() and label = prefixLabel() and outcome = super.getPolarity() diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll index cc4fc0c47ea..67993ddfa01 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll @@ -23,7 +23,8 @@ class HtmlSink extends DataFlow::Node instanceof Sink { deprecated class HTMLSink = HtmlSink; /** - * A taint-tracking configuration for reasoning about XSS. + * A taint-tracking configuration for reasoning about XSS by DOM manipulation. + * * Both ordinary HTML sinks, URL sinks, and JQuery selector based sinks. * - HTML sinks are sinks for any tainted value * - URL sinks are only sinks when the scheme is user controlled @@ -34,10 +35,10 @@ deprecated class HTMLSink = HtmlSink; * - Taint: a tainted value where the attacker controls part of the value. * - PrefixLabel: a tainted value where the attacker controls the prefix */ -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "HtmlInjection" } +module DomBasedXssConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; - override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { source instanceof Source and (label.isTaint() or label = prefixLabel()) and not source = TaintedUrlSuffix::source() @@ -46,7 +47,7 @@ class Configuration extends TaintTracking::Configuration { label = TaintedUrlSuffix::label() } - override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { + predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { sink instanceof HtmlSink and label = [TaintedUrlSuffix::label(), prefixLabel(), DataFlow::FlowLabel::taint()] or @@ -57,23 +58,11 @@ class Configuration extends TaintTracking::Configuration { label = prefixLabel() } - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) - or - node instanceof Sanitizer - } + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } - override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) { - guard instanceof PrefixStringSanitizerActivated or - guard instanceof QuoteGuard or - guard instanceof ContainsHtmlGuard - } - - override predicate isLabeledBarrier(DataFlow::Node node, DataFlow::FlowLabel lbl) { - super.isLabeledBarrier(node, lbl) - or - // copy all taint barriers to the TaintedUrlSuffix/PrefixLabel label. This copies both the ordinary sanitizers and the sanitizer-guards. - super.isLabeledBarrier(node, DataFlow::FlowLabel::taint()) and + predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel lbl) { + // copy all taint barrier guards to the TaintedUrlSuffix/PrefixLabel label + TaintTracking::defaultSanitizer(node) and lbl = [TaintedUrlSuffix::label(), prefixLabel()] or // any non-first string-concatenation leaf is a barrier for the prefix label. @@ -89,43 +78,78 @@ class Configuration extends TaintTracking::Configuration { or isOptionallySanitizedNode(node) and lbl = [DataFlow::FlowLabel::taint(), prefixLabel(), TaintedUrlSuffix::label()] + or + node = DataFlow::MakeLabeledBarrierGuard::getABarrierNode(lbl) } - override predicate isAdditionalFlowStep( - DataFlow::Node src, DataFlow::Node trg, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowLabel state1, DataFlow::Node node2, + DataFlow::FlowLabel state2 ) { - TaintedUrlSuffix::step(src, trg, inlbl, outlbl) + TaintedUrlSuffix::step(node1, node2, state1, state2) or exists(DataFlow::Node operator | - StringConcatenation::taintStep(src, trg, operator, _) and + StringConcatenation::taintStep(node1, node2, operator, _) and StringConcatenation::getOperand(operator, 0).getStringValue() = "<" + any(string s) and - inlbl = TaintedUrlSuffix::label() and - outlbl.isTaint() + state1 = TaintedUrlSuffix::label() and + state2.isTaint() ) or - // inherit all ordinary taint steps for prefixLabel - inlbl = prefixLabel() and - outlbl = prefixLabel() and - TaintTracking::sharedTaintStep(src, trg) - or - // steps out of taintedSuffixlabel to taint-label are also a steps to prefixLabel. - TaintedUrlSuffix::step(src, trg, TaintedUrlSuffix::label(), DataFlow::FlowLabel::taint()) and - inlbl = TaintedUrlSuffix::label() and - outlbl = prefixLabel() + // steps out of taintedSuffixlabel to taint-label are also steps to prefixLabel. + TaintedUrlSuffix::step(node1, node2, TaintedUrlSuffix::label(), DataFlow::FlowLabel::taint()) and + state1 = TaintedUrlSuffix::label() and + state2 = prefixLabel() or + // FIXME: this fails to work in the test case at jquery.js:37 exists(DataFlow::FunctionNode callback, DataFlow::Node arg | any(JQuery::MethodCall c).interpretsArgumentAsHtml(arg) and callback = arg.getABoundFunctionValue(_) and - src = callback.getReturnNode() and - trg = callback and - inlbl = outlbl + node1 = callback.getReturnNode() and + node2 = callback and + state1 = state2 ) } } -private class PrefixStringSanitizerActivated extends TaintTracking::SanitizerGuardNode, - PrefixStringSanitizer -{ +/** + * Taint-tracking for reasoning about XSS by DOM manipulation. + */ +module DomBasedXssFlow = TaintTracking::GlobalWithState; + +/** + * DEPRECATED. Use the `DomBasedXssFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { + Configuration() { this = "HtmlInjection" } + + override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { + DomBasedXssConfig::isSource(source, label) + } + + override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { + DomBasedXssConfig::isSink(sink, label) + } + + override predicate isSanitizer(DataFlow::Node node) { DomBasedXssConfig::isBarrier(node) } + + override predicate isLabeledBarrier(DataFlow::Node node, DataFlow::FlowLabel lbl) { + DomBasedXssConfig::isBarrier(node, lbl) + } + + override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::Node node2, DataFlow::FlowLabel state1, + DataFlow::FlowLabel state2 + ) { + DomBasedXssConfig::isAdditionalFlowStep(node1, state1, node2, state2) + or + // inherit all ordinary taint steps for the prefix label + state1 = prefixLabel() and + state2 = prefixLabel() and + TaintTracking::sharedTaintStep(node1, node2) + } +} + +private class PrefixStringSanitizerActivated extends PrefixStringSanitizer { PrefixStringSanitizerActivated() { this = this } } @@ -133,11 +157,10 @@ private class PrefixStringActivated extends DataFlow::FlowLabel, PrefixString { PrefixStringActivated() { this = this } } -private class QuoteGuard extends TaintTracking::SanitizerGuardNode, Shared::QuoteGuard { +private class QuoteGuard extends Shared::QuoteGuard { QuoteGuard() { this = this } } -private class ContainsHtmlGuard extends TaintTracking::SanitizerGuardNode, Shared::ContainsHtmlGuard -{ +private class ContainsHtmlGuard extends Shared::ContainsHtmlGuard { ContainsHtmlGuard() { this = this } } diff --git a/javascript/ql/src/Security/CWE-079/Xss.ql b/javascript/ql/src/Security/CWE-079/Xss.ql index 63a56b2a3b3..a94710cc49a 100644 --- a/javascript/ql/src/Security/CWE-079/Xss.ql +++ b/javascript/ql/src/Security/CWE-079/Xss.ql @@ -14,10 +14,10 @@ import javascript import semmle.javascript.security.dataflow.DomBasedXssQuery -import DataFlow::PathGraph +import DataFlow::DeduplicatePathGraph -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from PathNode source, PathNode sink +where DomBasedXssFlow::flowPath(source.getAnOriginalPathNode(), sink.getAnOriginalPathNode()) select sink.getNode(), source, sink, sink.getNode().(Sink).getVulnerabilityKind() + " vulnerability due to $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected index e69de29bb2d..3ea47160e92 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected @@ -0,0 +1,3 @@ +| query-tests/Security/CWE-079/DomBasedXss/sanitiser.js:25 | did not expect an alert, but found an alert for HtmlInjection | OK | ConsistencyConfig | +| query-tests/Security/CWE-079/DomBasedXss/sanitiser.js:28 | did not expect an alert, but found an alert for HtmlInjection | OK | ConsistencyConfig | +| query-tests/Security/CWE-079/DomBasedXss/sanitiser.js:35 | did not expect an alert, but found an alert for HtmlInjection | OK | ConsistencyConfig | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.ql b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.ql index 639a895263a..cb88a7a2a26 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.ql @@ -1,3 +1,9 @@ import javascript import testUtilities.ConsistencyChecking -import semmle.javascript.security.dataflow.DomBasedXssQuery as DomXss +import semmle.javascript.security.dataflow.DomBasedXssQuery + +class ConsistencyConfig extends ConsistencyConfiguration { + ConsistencyConfig() { this = "ConsistencyConfig" } + + override DataFlow::Node getAnAlert() { DomBasedXssFlow::flow(_, result) } +} diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index f0ac4a5ec87..8617a3ee7df 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -1,1580 +1,742 @@ nodes -| addEventListener.js:1:43:1:47 | event | -| addEventListener.js:1:43:1:47 | event | -| addEventListener.js:1:43:1:47 | event | -| addEventListener.js:2:20:2:24 | event | -| addEventListener.js:2:20:2:24 | event | -| addEventListener.js:2:20:2:29 | event.data | -| addEventListener.js:2:20:2:29 | event.data | -| addEventListener.js:2:20:2:29 | event.data | -| addEventListener.js:5:43:5:48 | data | -| addEventListener.js:5:43:5:48 | data | -| addEventListener.js:5:43:5:48 | {data} | -| addEventListener.js:5:43:5:48 | {data} | -| addEventListener.js:5:43:5:48 | {data} | -| addEventListener.js:5:44:5:47 | data | -| addEventListener.js:5:44:5:47 | data | -| addEventListener.js:6:20:6:23 | data | -| addEventListener.js:6:20:6:23 | data | -| addEventListener.js:6:20:6:23 | data | -| addEventListener.js:10:21:10:25 | event | -| addEventListener.js:10:21:10:25 | event | -| addEventListener.js:10:21:10:25 | event | -| addEventListener.js:12:24:12:28 | event | -| addEventListener.js:12:24:12:28 | event | -| addEventListener.js:12:24:12:33 | event.data | -| addEventListener.js:12:24:12:33 | event.data | -| addEventListener.js:12:24:12:33 | event.data | -| angular2-client.ts:22:44:22:71 | \\u0275getDOM ... ().href | -| angular2-client.ts:22:44:22:71 | \\u0275getDOM ... ().href | -| angular2-client.ts:22:44:22:71 | \\u0275getDOM ... ().href | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | -| angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | -| angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:26:44:26:71 | this.ro ... ragment | -| angular2-client.ts:26:44:26:71 | this.ro ... ragment | -| angular2-client.ts:26:44:26:71 | this.ro ... ragment | -| angular2-client.ts:26:44:26:71 | this.ro ... ragment | -| angular2-client.ts:27:44:27:82 | this.ro ... ('foo') | -| angular2-client.ts:27:44:27:82 | this.ro ... ('foo') | -| angular2-client.ts:27:44:27:82 | this.ro ... ('foo') | -| angular2-client.ts:27:44:27:82 | this.ro ... ('foo') | -| angular2-client.ts:28:44:28:87 | this.ro ... ('foo') | -| angular2-client.ts:28:44:28:87 | this.ro ... ('foo') | -| angular2-client.ts:28:44:28:87 | this.ro ... ('foo') | -| angular2-client.ts:28:44:28:87 | this.ro ... ('foo') | -| angular2-client.ts:30:46:30:59 | map.get('foo') | -| angular2-client.ts:30:46:30:59 | map.get('foo') | -| angular2-client.ts:30:46:30:59 | map.get('foo') | -| angular2-client.ts:30:46:30:59 | map.get('foo') | -| angular2-client.ts:33:44:33:74 | this.ro ... 1].path | -| angular2-client.ts:33:44:33:74 | this.ro ... 1].path | -| angular2-client.ts:33:44:33:74 | this.ro ... 1].path | -| angular2-client.ts:33:44:33:74 | this.ro ... 1].path | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | -| angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:35:44:35:91 | this.ro ... et('x') | -| angular2-client.ts:35:44:35:91 | this.ro ... et('x') | -| angular2-client.ts:35:44:35:91 | this.ro ... et('x') | -| angular2-client.ts:35:44:35:91 | this.ro ... et('x') | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | -| angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:38:44:38:58 | this.router.url | -| angular2-client.ts:38:44:38:58 | this.router.url | -| angular2-client.ts:38:44:38:58 | this.router.url | -| angular2-client.ts:40:45:40:59 | this.router.url | -| angular2-client.ts:40:45:40:59 | this.router.url | -| angular2-client.ts:40:45:40:59 | this.router.url | -| angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | -| angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | -| angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | -| angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | -| classnames.js:7:31:7:84 | `` | -| classnames.js:7:31:7:84 | `` | -| classnames.js:7:47:7:69 | classNa ... w.name) | -| classnames.js:7:58:7:68 | window.name | -| classnames.js:7:58:7:68 | window.name | -| classnames.js:8:31:8:85 | `` | -| classnames.js:8:31:8:85 | `` | -| classnames.js:8:47:8:70 | classNa ... w.name) | -| classnames.js:8:59:8:69 | window.name | -| classnames.js:8:59:8:69 | window.name | -| classnames.js:9:31:9:85 | `` | -| classnames.js:9:31:9:85 | `` | -| classnames.js:9:47:9:70 | classNa ... w.name) | -| classnames.js:9:59:9:69 | window.name | -| classnames.js:9:59:9:69 | window.name | -| classnames.js:10:45:10:55 | window.name | -| classnames.js:10:45:10:55 | window.name | -| classnames.js:11:31:11:79 | `` | -| classnames.js:11:31:11:79 | `` | -| classnames.js:11:47:11:64 | unsafeStyle('foo') | -| classnames.js:13:31:13:83 | `` | -| classnames.js:13:31:13:83 | `` | -| classnames.js:13:47:13:68 | safeSty ... w.name) | -| classnames.js:13:57:13:67 | window.name | -| classnames.js:13:57:13:67 | window.name | -| classnames.js:15:31:15:78 | `` | -| classnames.js:15:31:15:78 | `` | -| classnames.js:15:47:15:63 | clsx(window.name) | -| classnames.js:15:52:15:62 | window.name | -| classnames.js:15:52:15:62 | window.name | -| classnames.js:17:32:17:79 | `` | -| classnames.js:17:32:17:79 | `` | -| classnames.js:17:48:17:64 | clsx(window.name) | -| classnames.js:17:53:17:63 | window.name | -| classnames.js:17:53:17:63 | window.name | -| clipboard.ts:8:11:8:51 | html | -| clipboard.ts:8:11:8:51 | html | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | -| clipboard.ts:15:25:15:28 | html | -| clipboard.ts:15:25:15:28 | html | -| clipboard.ts:15:25:15:28 | html | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:43:15:43:55 | html | -| clipboard.ts:43:15:43:55 | html | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | -| clipboard.ts:50:29:50:32 | html | -| clipboard.ts:50:29:50:32 | html | -| clipboard.ts:50:29:50:32 | html | -| clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | -| clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:98:15:98:54 | html | -| clipboard.ts:98:15:98:54 | html | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | -| clipboard.ts:99:23:99:26 | html | -| clipboard.ts:99:23:99:26 | html | -| clipboard.ts:99:23:99:26 | html | -| custom-element.js:5:26:5:36 | window.name | -| custom-element.js:5:26:5:36 | window.name | -| custom-element.js:5:26:5:36 | window.name | -| custom-element.js:5:26:5:36 | window.name | -| d3.js:4:12:4:22 | window.name | -| d3.js:4:12:4:22 | window.name | -| d3.js:4:12:4:22 | window.name | -| d3.js:11:15:11:24 | getTaint() | -| d3.js:11:15:11:24 | getTaint() | -| d3.js:11:15:11:24 | getTaint() | -| d3.js:12:20:12:29 | getTaint() | -| d3.js:12:20:12:29 | getTaint() | -| d3.js:12:20:12:29 | getTaint() | -| d3.js:14:20:14:29 | getTaint() | -| d3.js:14:20:14:29 | getTaint() | -| d3.js:14:20:14:29 | getTaint() | -| d3.js:21:15:21:24 | getTaint() | -| d3.js:21:15:21:24 | getTaint() | -| d3.js:21:15:21:24 | getTaint() | -| dates.js:9:9:9:69 | taint | -| dates.js:9:9:9:69 | taint | -| dates.js:9:17:9:69 | decodeU ... ing(1)) | -| dates.js:9:17:9:69 | decodeU ... ing(1)) | -| dates.js:9:36:9:55 | window.location.hash | -| dates.js:9:36:9:55 | window.location.hash | -| dates.js:9:36:9:68 | window. ... ring(1) | -| dates.js:9:36:9:68 | window. ... ring(1) | -| dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:42:11:68 | dateFns ... taint) | -| dates.js:11:42:11:68 | dateFns ... taint) | -| dates.js:11:63:11:67 | taint | -| dates.js:11:63:11:67 | taint | -| dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:42:12:71 | dateFns ... taint) | -| dates.js:12:42:12:71 | dateFns ... taint) | -| dates.js:12:66:12:70 | taint | -| dates.js:12:66:12:70 | taint | -| dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:42:13:70 | dateFns ... )(time) | -| dates.js:13:42:13:70 | dateFns ... )(time) | -| dates.js:13:59:13:63 | taint | -| dates.js:13:59:13:63 | taint | -| dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:42:16:67 | moment( ... (taint) | -| dates.js:16:42:16:67 | moment( ... (taint) | -| dates.js:16:62:16:66 | taint | -| dates.js:16:62:16:66 | taint | -| dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:42:18:64 | datefor ... taint) | -| dates.js:18:42:18:64 | datefor ... taint) | -| dates.js:18:59:18:63 | taint | -| dates.js:18:59:18:63 | taint | -| dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | -| dates.js:21:61:21:65 | taint | -| dates.js:21:61:21:65 | taint | -| dates.js:30:9:30:69 | taint | -| dates.js:30:9:30:69 | taint | -| dates.js:30:17:30:69 | decodeU ... ing(1)) | -| dates.js:30:17:30:69 | decodeU ... ing(1)) | -| dates.js:30:36:30:55 | window.location.hash | -| dates.js:30:36:30:55 | window.location.hash | -| dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:42:37:82 | dateFns ... taint) | -| dates.js:37:42:37:82 | dateFns ... taint) | -| dates.js:37:77:37:81 | taint | -| dates.js:37:77:37:81 | taint | -| dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:42:38:82 | luxon.f ... taint) | -| dates.js:38:42:38:82 | luxon.f ... taint) | -| dates.js:38:77:38:81 | taint | -| dates.js:38:77:38:81 | taint | -| dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:42:39:84 | moment. ... taint) | -| dates.js:39:42:39:84 | moment. ... taint) | -| dates.js:39:79:39:83 | taint | -| dates.js:39:79:39:83 | taint | -| dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:42:40:82 | dayjs.f ... taint) | -| dates.js:40:42:40:82 | dayjs.f ... taint) | -| dates.js:40:77:40:81 | taint | -| dates.js:40:77:40:81 | taint | -| dates.js:46:9:46:69 | taint | -| dates.js:46:9:46:69 | taint | -| dates.js:46:17:46:69 | decodeU ... ing(1)) | -| dates.js:46:17:46:69 | decodeU ... ing(1)) | -| dates.js:46:36:46:55 | window.location.hash | -| dates.js:46:36:46:55 | window.location.hash | -| dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:42:48:88 | DateTim ... (taint) | -| dates.js:48:42:48:88 | DateTim ... (taint) | -| dates.js:48:83:48:87 | taint | -| dates.js:48:83:48:87 | taint | -| dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:42:49:87 | new Dat ... (taint) | -| dates.js:49:42:49:87 | new Dat ... (taint) | -| dates.js:49:82:49:86 | taint | -| dates.js:49:82:49:86 | taint | -| dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:42:50:102 | DateTim ... (taint) | -| dates.js:50:42:50:102 | DateTim ... (taint) | -| dates.js:50:97:50:101 | taint | -| dates.js:50:97:50:101 | taint | -| dates.js:54:9:54:69 | taint | -| dates.js:54:9:54:69 | taint | -| dates.js:54:17:54:69 | decodeU ... ing(1)) | -| dates.js:54:17:54:69 | decodeU ... ing(1)) | -| dates.js:54:36:54:55 | window.location.hash | -| dates.js:54:36:54:55 | window.location.hash | -| dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:42:57:99 | moment. ... (taint) | -| dates.js:57:42:57:99 | moment. ... (taint) | -| dates.js:57:94:57:98 | taint | -| dates.js:57:94:57:98 | taint | -| dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:42:59:85 | luxon.e ... (taint) | -| dates.js:59:42:59:85 | luxon.e ... (taint) | -| dates.js:59:80:59:84 | taint | -| dates.js:59:80:59:84 | taint | -| dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | -| dates.js:61:81:61:85 | taint | -| dates.js:61:81:61:85 | taint | -| dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | -| dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | -| dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:71:13:71:61 | droppedHtml | -| dragAndDrop.ts:71:13:71:61 | droppedHtml | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | -| dragAndDrop.ts:73:29:73:39 | droppedHtml | -| dragAndDrop.ts:73:29:73:39 | droppedHtml | -| dragAndDrop.ts:73:29:73:39 | droppedHtml | -| event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:49:2:61 | location.href | -| event-handler-receiver.js:2:49:2:61 | location.href | -| express.js:7:15:7:33 | req.param("wobble") | -| express.js:7:15:7:33 | req.param("wobble") | -| express.js:7:15:7:33 | req.param("wobble") | -| express.js:7:15:7:33 | req.param("wobble") | -| jquery.js:2:7:2:40 | tainted | -| jquery.js:2:17:2:40 | documen ... .search | -| jquery.js:2:17:2:40 | documen ... .search | -| jquery.js:7:5:7:34 | "
" | -| jquery.js:7:5:7:34 | "
" | -| jquery.js:7:20:7:26 | tainted | -| jquery.js:8:18:8:34 | "XSS: " + tainted | -| jquery.js:8:18:8:34 | "XSS: " + tainted | -| jquery.js:8:28:8:34 | tainted | -| jquery.js:10:5:10:40 | "" + ... "" | -| jquery.js:10:5:10:40 | "" + ... "" | -| jquery.js:10:13:10:20 | location | -| jquery.js:10:13:10:20 | location | -| jquery.js:10:13:10:31 | location.toString() | -| jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:14:38:14:57 | window.location.hash | -| jquery.js:14:38:14:57 | window.location.hash | -| jquery.js:15:19:15:60 | decodeU ... search) | -| jquery.js:15:19:15:60 | decodeU ... search) | -| jquery.js:15:38:15:59 | window. ... .search | -| jquery.js:15:38:15:59 | window. ... .search | -| jquery.js:16:19:16:64 | decodeU ... ring()) | -| jquery.js:16:19:16:64 | decodeU ... ring()) | -| jquery.js:16:38:16:52 | window.location | -| jquery.js:16:38:16:52 | window.location | -| jquery.js:16:38:16:63 | window. ... tring() | -| jquery.js:18:7:18:33 | hash | -| jquery.js:18:14:18:33 | window.location.hash | -| jquery.js:18:14:18:33 | window.location.hash | -| jquery.js:21:5:21:8 | hash | -| jquery.js:21:5:21:21 | hash.substring(1) | -| jquery.js:21:5:21:21 | hash.substring(1) | -| jquery.js:21:5:21:21 | hash.substring(1) | -| jquery.js:22:5:22:8 | hash | -| jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:23:5:23:8 | hash | -| jquery.js:23:5:23:18 | hash.substr(1) | -| jquery.js:23:5:23:18 | hash.substr(1) | -| jquery.js:23:5:23:18 | hash.substr(1) | -| jquery.js:24:5:24:8 | hash | -| jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:27:5:27:8 | hash | -| jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:28:5:28:26 | window. ... .search | -| jquery.js:28:5:28:26 | window. ... .search | -| jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:34:5:34:25 | '' + ... '' | -| jquery.js:34:5:34:25 | '' + ... '' | -| jquery.js:34:13:34:16 | hash | -| jquery.js:36:25:36:31 | tainted | -| jquery.js:36:25:36:31 | tainted | -| jquery.js:37:25:37:37 | () => tainted | -| jquery.js:37:25:37:37 | () => tainted | -| jquery.js:37:31:37:37 | tainted | -| json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | -| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | -| json-stringify.jsx:11:51:11:56 | locale | -| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | -| json-stringify.jsx:19:56:19:61 | locale | -| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:55:31:60 | locale | -| json-stringify.jsx:31:55:31:60 | locale | -| json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | -| json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | -| jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:7:17:7:35 | req.param("wobble") | -| jwt-server.js:7:17:7:35 | req.param("wobble") | -| jwt-server.js:7:17:7:35 | req.param("wobble") | -| jwt-server.js:9:16:9:20 | taint | -| jwt-server.js:9:16:9:20 | taint | -| jwt-server.js:9:55:9:61 | decoded | -| jwt-server.js:9:55:9:61 | decoded | -| jwt-server.js:11:19:11:25 | decoded | -| jwt-server.js:11:19:11:25 | decoded | -| jwt-server.js:11:19:11:29 | decoded.foo | -| jwt-server.js:11:19:11:29 | decoded.foo | -| jwt-server.js:11:19:11:29 | decoded.foo | -| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| nodemailer.js:13:50:13:66 | req.query.message | -| nodemailer.js:13:50:13:66 | req.query.message | -| optionalSanitizer.js:2:7:2:39 | target | -| optionalSanitizer.js:2:16:2:39 | documen ... .search | -| optionalSanitizer.js:2:16:2:39 | documen ... .search | -| optionalSanitizer.js:6:18:6:23 | target | -| optionalSanitizer.js:6:18:6:23 | target | -| optionalSanitizer.js:8:7:8:22 | tainted | -| optionalSanitizer.js:8:17:8:22 | target | -| optionalSanitizer.js:9:18:9:24 | tainted | -| optionalSanitizer.js:9:18:9:24 | tainted | -| optionalSanitizer.js:15:9:15:14 | target | -| optionalSanitizer.js:16:18:16:18 | x | -| optionalSanitizer.js:17:20:17:20 | x | -| optionalSanitizer.js:17:20:17:20 | x | -| optionalSanitizer.js:26:7:26:39 | target | -| optionalSanitizer.js:26:16:26:39 | documen ... .search | -| optionalSanitizer.js:26:16:26:39 | documen ... .search | -| optionalSanitizer.js:31:7:31:23 | tainted2 | -| optionalSanitizer.js:31:18:31:23 | target | -| optionalSanitizer.js:32:18:32:25 | tainted2 | -| optionalSanitizer.js:32:18:32:25 | tainted2 | -| optionalSanitizer.js:34:5:34:36 | tainted2 | -| optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | -| optionalSanitizer.js:34:28:34:35 | tainted2 | -| optionalSanitizer.js:36:18:36:25 | tainted2 | -| optionalSanitizer.js:36:18:36:25 | tainted2 | -| optionalSanitizer.js:38:7:38:23 | tainted3 | -| optionalSanitizer.js:38:18:38:23 | target | -| optionalSanitizer.js:39:18:39:25 | tainted3 | -| optionalSanitizer.js:39:18:39:25 | tainted3 | -| optionalSanitizer.js:41:5:41:36 | tainted3 | -| optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | -| optionalSanitizer.js:41:28:41:35 | tainted3 | -| optionalSanitizer.js:43:18:43:25 | tainted3 | -| optionalSanitizer.js:43:18:43:25 | tainted3 | -| optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | -| optionalSanitizer.js:45:41:45:46 | target | -| optionalSanitizer.js:45:51:45:56 | target | -| pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:5:9:5:29 | id | -| pages/[id].jsx:5:9:5:29 | id | -| pages/[id].jsx:5:11:5:12 | id | -| pages/[id].jsx:5:11:5:12 | id | -| pages/[id].jsx:5:18:5:29 | router.query | -| pages/[id].jsx:5:18:5:29 | router.query | -| pages/[id].jsx:5:18:5:29 | router.query | -| pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:25:11:25:24 | context.params | -| pages/[id].jsx:25:11:25:24 | context.params | -| pages/[id].jsx:25:11:25:24 | context.params | -| pages/[id].jsx:25:11:25:27 | context.params.id | -| pages/[id].jsx:25:11:25:27 | context.params.id | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | -| pages/[id].jsx:26:10:26:22 | context.query | -| pages/[id].jsx:26:10:26:22 | context.query | -| pages/[id].jsx:26:10:26:22 | context.query | -| pages/[id].jsx:26:10:26:30 | context ... .foobar | -| pages/[id].jsx:26:10:26:30 | context ... .foobar | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | -| react-native.js:7:7:7:33 | tainted | -| react-native.js:7:7:7:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:8:18:8:24 | tainted | -| react-native.js:8:18:8:24 | tainted | -| react-native.js:8:18:8:24 | tainted | -| react-native.js:9:27:9:33 | tainted | -| react-native.js:9:27:9:33 | tainted | -| react-native.js:9:27:9:33 | tainted | -| react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:16:26:16:36 | window.name | -| react-use-context.js:16:26:16:36 | window.name | -| react-use-context.js:16:26:16:36 | window.name | -| react-use-context.js:16:26:16:36 | window.name | -| react-use-router.js:4:9:4:28 | router | -| react-use-router.js:4:18:4:28 | useRouter() | -| react-use-router.js:8:21:8:26 | router | -| react-use-router.js:8:21:8:32 | router.query | -| react-use-router.js:8:21:8:32 | router.query | -| react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:11:24:11:29 | router | -| react-use-router.js:11:24:11:35 | router.query | -| react-use-router.js:11:24:11:35 | router.query | -| react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:22:15:22:24 | router | -| react-use-router.js:22:17:22:22 | router | -| react-use-router.js:23:43:23:48 | router | -| react-use-router.js:23:43:23:54 | router.query | -| react-use-router.js:23:43:23:54 | router.query | -| react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:29:9:29:30 | router | -| react-use-router.js:29:18:29:30 | myUseRouter() | -| react-use-router.js:33:21:33:26 | router | -| react-use-router.js:33:21:33:32 | router.query | -| react-use-router.js:33:21:33:32 | router.query | -| react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-state.js:4:9:4:49 | state | -| react-use-state.js:4:9:4:49 | state | -| react-use-state.js:4:10:4:14 | state | -| react-use-state.js:4:10:4:14 | state | -| react-use-state.js:4:38:4:48 | window.name | -| react-use-state.js:4:38:4:48 | window.name | -| react-use-state.js:4:38:4:48 | window.name | -| react-use-state.js:5:51:5:55 | state | -| react-use-state.js:5:51:5:55 | state | -| react-use-state.js:5:51:5:55 | state | -| react-use-state.js:9:9:9:43 | state | -| react-use-state.js:9:9:9:43 | state | -| react-use-state.js:9:10:9:14 | state | -| react-use-state.js:9:10:9:14 | state | -| react-use-state.js:10:14:10:24 | window.name | -| react-use-state.js:10:14:10:24 | window.name | -| react-use-state.js:10:14:10:24 | window.name | -| react-use-state.js:11:51:11:55 | state | -| react-use-state.js:11:51:11:55 | state | -| react-use-state.js:11:51:11:55 | state | -| react-use-state.js:15:9:15:43 | state | -| react-use-state.js:15:9:15:43 | state | -| react-use-state.js:15:10:15:14 | state | -| react-use-state.js:15:10:15:14 | state | -| react-use-state.js:16:20:16:30 | window.name | -| react-use-state.js:16:20:16:30 | window.name | -| react-use-state.js:16:20:16:30 | window.name | -| react-use-state.js:17:51:17:55 | state | -| react-use-state.js:17:51:17:55 | state | -| react-use-state.js:17:51:17:55 | state | -| react-use-state.js:21:10:21:14 | state | -| react-use-state.js:21:10:21:14 | state | -| react-use-state.js:22:14:22:17 | prev | -| react-use-state.js:22:14:22:17 | prev | -| react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:25:20:25:30 | window.name | -| react-use-state.js:25:20:25:30 | window.name | -| react-use-state.js:25:20:25:30 | window.name | -| sanitiser.js:16:7:16:27 | tainted | -| sanitiser.js:16:7:16:27 | tainted | -| sanitiser.js:16:17:16:27 | window.name | -| sanitiser.js:16:17:16:27 | window.name | -| sanitiser.js:16:17:16:27 | window.name | -| sanitiser.js:23:21:23:44 | '' + ... '' | -| sanitiser.js:23:21:23:44 | '' + ... '' | -| sanitiser.js:23:29:23:35 | tainted | -| sanitiser.js:30:21:30:44 | '' + ... '' | -| sanitiser.js:30:21:30:44 | '' + ... '' | -| sanitiser.js:30:29:30:35 | tainted | -| sanitiser.js:33:21:33:44 | '' + ... '' | -| sanitiser.js:33:21:33:44 | '' + ... '' | -| sanitiser.js:33:29:33:35 | tainted | -| sanitiser.js:38:21:38:44 | '' + ... '' | -| sanitiser.js:38:21:38:44 | '' + ... '' | -| sanitiser.js:38:29:38:35 | tainted | -| sanitiser.js:45:21:45:44 | '' + ... '' | -| sanitiser.js:45:21:45:44 | '' + ... '' | -| sanitiser.js:45:29:45:35 | tainted | -| sanitiser.js:48:19:48:25 | tainted | -| sanitiser.js:48:19:48:25 | tainted | -| sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| stored-xss.js:2:39:2:62 | documen ... .search | -| stored-xss.js:2:39:2:62 | documen ... .search | -| stored-xss.js:3:35:3:58 | documen ... .search | -| stored-xss.js:3:35:3:58 | documen ... .search | -| stored-xss.js:5:20:5:52 | session ... ssion') | -| stored-xss.js:5:20:5:52 | session ... ssion') | -| stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:10:9:10:44 | href | -| stored-xss.js:10:16:10:44 | localSt ... local') | -| stored-xss.js:12:20:12:54 | "" | -| stored-xss.js:12:20:12:54 | "" | -| stored-xss.js:12:20:12:54 | "" | -| stored-xss.js:12:35:12:38 | href | -| string-manipulations.js:3:16:3:32 | document.location | -| string-manipulations.js:3:16:3:32 | document.location | -| string-manipulations.js:3:16:3:32 | document.location | -| string-manipulations.js:4:16:4:37 | documen ... on.href | -| string-manipulations.js:4:16:4:37 | documen ... on.href | -| string-manipulations.js:4:16:4:37 | documen ... on.href | -| string-manipulations.js:5:16:5:37 | documen ... on.href | -| string-manipulations.js:5:16:5:37 | documen ... on.href | -| string-manipulations.js:5:16:5:47 | documen ... lueOf() | -| string-manipulations.js:5:16:5:47 | documen ... lueOf() | -| string-manipulations.js:6:16:6:37 | documen ... on.href | -| string-manipulations.js:6:16:6:37 | documen ... on.href | -| string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:7:16:7:37 | documen ... on.href | -| string-manipulations.js:7:16:7:37 | documen ... on.href | -| string-manipulations.js:7:16:7:51 | documen ... rCase() | -| string-manipulations.js:7:16:7:51 | documen ... rCase() | -| string-manipulations.js:8:16:8:37 | documen ... on.href | -| string-manipulations.js:8:16:8:37 | documen ... on.href | -| string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:9:16:9:58 | String. ... n.href) | -| string-manipulations.js:9:16:9:58 | String. ... n.href) | -| string-manipulations.js:9:36:9:57 | documen ... on.href | -| string-manipulations.js:9:36:9:57 | documen ... on.href | -| string-manipulations.js:10:16:10:45 | String( ... n.href) | -| string-manipulations.js:10:16:10:45 | String( ... n.href) | -| string-manipulations.js:10:23:10:44 | documen ... on.href | -| string-manipulations.js:10:23:10:44 | documen ... on.href | -| tooltip.jsx:6:11:6:30 | source | -| tooltip.jsx:6:11:6:30 | source | -| tooltip.jsx:6:20:6:30 | window.name | -| tooltip.jsx:6:20:6:30 | window.name | -| tooltip.jsx:6:20:6:30 | window.name | -| tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:11:25:11:30 | source | -| translate.js:6:7:6:39 | target | -| translate.js:6:16:6:39 | documen ... .search | -| translate.js:6:16:6:39 | documen ... .search | -| translate.js:7:7:7:61 | searchParams | -| translate.js:7:22:7:61 | new URL ... ing(1)) | -| translate.js:7:42:7:47 | target | -| translate.js:7:42:7:60 | target.substring(1) | -| translate.js:7:42:7:60 | target.substring(1) | -| translate.js:7:42:7:60 | target.substring(1) | -| translate.js:9:27:9:38 | searchParams | -| translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:9:27:9:50 | searchP ... 'term') | -| trusted-types-lib.js:1:28:1:28 | x | -| trusted-types-lib.js:1:28:1:28 | x | -| trusted-types-lib.js:2:12:2:12 | x | -| trusted-types-lib.js:2:12:2:12 | x | -| trusted-types-lib.js:2:12:2:12 | x | -| trusted-types.js:3:62:3:62 | x | -| trusted-types.js:3:62:3:62 | x | -| trusted-types.js:3:67:3:67 | x | -| trusted-types.js:3:67:3:67 | x | -| trusted-types.js:3:67:3:67 | x | -| trusted-types.js:4:20:4:30 | window.name | -| trusted-types.js:4:20:4:30 | window.name | -| trusted-types.js:4:20:4:30 | window.name | -| trusted-types.js:13:20:13:30 | window.name | -| trusted-types.js:13:20:13:30 | window.name | -| trusted-types.js:13:20:13:30 | window.name | -| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | -| tst3.js:2:23:2:74 | decodeU ... str(1)) | -| tst3.js:2:42:2:63 | window. ... .search | -| tst3.js:2:42:2:63 | window. ... .search | -| tst3.js:2:42:2:73 | window. ... bstr(1) | -| tst3.js:4:25:4:28 | data | -| tst3.js:4:25:4:32 | data.src | -| tst3.js:4:25:4:32 | data.src | -| tst3.js:5:26:5:29 | data | -| tst3.js:5:26:5:31 | data.p | -| tst3.js:5:26:5:31 | data.p | -| tst3.js:7:32:7:35 | data | -| tst3.js:7:32:7:37 | data.p | -| tst3.js:7:32:7:37 | data.p | -| tst3.js:9:37:9:40 | data | -| tst3.js:9:37:9:42 | data.p | -| tst3.js:9:37:9:42 | data.p | -| tst3.js:10:38:10:41 | data | -| tst3.js:10:38:10:43 | data.p | -| tst3.js:10:38:10:43 | data.p | -| tst.js:2:7:2:39 | target | -| tst.js:2:16:2:39 | documen ... .search | -| tst.js:2:16:2:39 | documen ... .search | -| tst.js:5:18:5:23 | target | -| tst.js:5:18:5:23 | target | -| tst.js:8:18:8:126 | "" | -| tst.js:8:18:8:126 | "" | -| tst.js:8:18:8:126 | "" | -| tst.js:8:37:8:58 | documen ... on.href | -| tst.js:8:37:8:58 | documen ... on.href | -| tst.js:8:37:8:114 | documen ... t=")+8) | -| tst.js:8:37:8:114 | documen ... t=")+8) | -| tst.js:12:5:12:42 | '
' | -| tst.js:12:5:12:42 | '
' | -| tst.js:12:28:12:33 | target | -| tst.js:17:7:17:56 | params | -| tst.js:17:16:17:56 | (new UR ... hParams | -| tst.js:17:25:17:41 | document.location | -| tst.js:17:25:17:41 | document.location | -| tst.js:18:18:18:23 | params | -| tst.js:18:18:18:35 | params.get('name') | -| tst.js:18:18:18:35 | params.get('name') | -| tst.js:18:18:18:35 | params.get('name') | -| tst.js:18:18:18:35 | params.get('name') | -| tst.js:20:7:20:61 | searchParams | -| tst.js:20:22:20:61 | new URL ... ing(1)) | -| tst.js:20:42:20:47 | target | -| tst.js:20:42:20:60 | target.substring(1) | -| tst.js:20:42:20:60 | target.substring(1) | -| tst.js:20:42:20:60 | target.substring(1) | -| tst.js:21:18:21:29 | searchParams | -| tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:24:14:24:19 | target | -| tst.js:26:18:26:23 | target | -| tst.js:26:18:26:23 | target | -| tst.js:28:5:28:28 | documen ... .search | -| tst.js:28:5:28:28 | documen ... .search | -| tst.js:31:10:31:33 | documen ... .search | -| tst.js:31:10:31:33 | documen ... .search | -| tst.js:34:16:34:20 | bar() | -| tst.js:34:16:34:20 | bar() | -| tst.js:40:16:40:44 | baz(doc ... search) | -| tst.js:40:16:40:44 | baz(doc ... search) | -| tst.js:40:20:40:43 | documen ... .search | -| tst.js:40:20:40:43 | documen ... .search | -| tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:21:46:44 | documen ... .search | -| tst.js:46:21:46:44 | documen ... .search | -| tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | -| tst.js:54:21:54:44 | documen ... .search | -| tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | -| tst.js:56:21:56:44 | documen ... .search | -| tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:21:58:31 | chop(bar()) | -| tst.js:58:21:58:31 | chop(bar()) | -| tst.js:58:26:58:30 | bar() | -| tst.js:60:34:60:34 | s | -| tst.js:62:18:62:18 | s | -| tst.js:62:18:62:18 | s | -| tst.js:64:25:64:48 | documen ... .search | -| tst.js:64:25:64:48 | documen ... .search | -| tst.js:65:25:65:48 | documen ... .search | -| tst.js:65:25:65:48 | documen ... .search | -| tst.js:68:16:68:20 | bar() | -| tst.js:68:16:68:20 | bar() | -| tst.js:70:1:70:27 | [,docum ... search] | -| tst.js:70:3:70:26 | documen ... .search | -| tst.js:70:3:70:26 | documen ... .search | -| tst.js:70:46:70:46 | x | -| tst.js:73:20:73:20 | x | -| tst.js:73:20:73:20 | x | -| tst.js:77:49:77:72 | documen ... .search | -| tst.js:77:49:77:72 | documen ... .search | -| tst.js:77:49:77:72 | documen ... .search | -| tst.js:81:26:81:49 | documen ... .search | -| tst.js:81:26:81:49 | documen ... .search | -| tst.js:81:26:81:49 | documen ... .search | -| tst.js:82:25:82:48 | documen ... .search | -| tst.js:82:25:82:48 | documen ... .search | -| tst.js:82:25:82:48 | documen ... .search | -| tst.js:84:33:84:56 | documen ... .search | -| tst.js:84:33:84:56 | documen ... .search | -| tst.js:84:33:84:56 | documen ... .search | -| tst.js:85:32:85:55 | documen ... .search | -| tst.js:85:32:85:55 | documen ... .search | -| tst.js:85:32:85:55 | documen ... .search | -| tst.js:90:39:90:62 | documen ... .search | -| tst.js:90:39:90:62 | documen ... .search | -| tst.js:90:39:90:62 | documen ... .search | -| tst.js:96:30:96:53 | documen ... .search | -| tst.js:96:30:96:53 | documen ... .search | -| tst.js:96:30:96:53 | documen ... .search | -| tst.js:102:25:102:48 | documen ... .search | -| tst.js:102:25:102:48 | documen ... .search | -| tst.js:102:25:102:48 | documen ... .search | -| tst.js:107:7:107:44 | v | -| tst.js:107:7:107:44 | v | -| tst.js:107:7:107:44 | v | -| tst.js:107:11:107:34 | documen ... .search | -| tst.js:107:11:107:34 | documen ... .search | -| tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:110:18:110:18 | v | -| tst.js:110:18:110:18 | v | -| tst.js:110:18:110:18 | v | -| tst.js:110:18:110:18 | v | -| tst.js:136:18:136:18 | v | -| tst.js:136:18:136:18 | v | -| tst.js:136:18:136:18 | v | -| tst.js:136:18:136:18 | v | -| tst.js:148:29:148:50 | window. ... .search | -| tst.js:148:29:148:50 | window. ... .search | -| tst.js:151:29:151:29 | v | -| tst.js:151:49:151:49 | v | -| tst.js:151:49:151:49 | v | -| tst.js:155:29:155:46 | xssSourceService() | -| tst.js:155:29:155:46 | xssSourceService() | -| tst.js:158:40:158:61 | window. ... .search | -| tst.js:158:40:158:61 | window. ... .search | -| tst.js:177:9:177:41 | target | -| tst.js:177:18:177:41 | documen ... .search | -| tst.js:177:18:177:41 | documen ... .search | -| tst.js:180:28:180:33 | target | -| tst.js:180:28:180:33 | target | -| tst.js:184:9:184:42 | tainted | -| tst.js:184:19:184:42 | documen ... .search | -| tst.js:184:19:184:42 | documen ... .search | -| tst.js:186:31:186:37 | tainted | -| tst.js:186:31:186:37 | tainted | -| tst.js:188:42:188:48 | tainted | -| tst.js:188:42:188:48 | tainted | -| tst.js:189:33:189:39 | tainted | -| tst.js:189:33:189:39 | tainted | -| tst.js:191:54:191:60 | tainted | -| tst.js:191:54:191:60 | tainted | -| tst.js:192:45:192:51 | tainted | -| tst.js:192:45:192:51 | tainted | -| tst.js:193:49:193:55 | tainted | -| tst.js:193:49:193:55 | tainted | -| tst.js:197:9:197:42 | tainted | -| tst.js:197:19:197:42 | documen ... .search | -| tst.js:197:19:197:42 | documen ... .search | -| tst.js:199:67:199:73 | tainted | -| tst.js:199:67:199:73 | tainted | -| tst.js:200:67:200:73 | tainted | -| tst.js:200:67:200:73 | tainted | -| tst.js:204:35:204:41 | tainted | -| tst.js:206:46:206:52 | tainted | -| tst.js:207:38:207:44 | tainted | -| tst.js:208:35:208:41 | tainted | -| tst.js:212:28:212:46 | this.state.tainted1 | -| tst.js:212:28:212:46 | this.state.tainted1 | -| tst.js:213:28:213:46 | this.state.tainted2 | -| tst.js:213:28:213:46 | this.state.tainted2 | -| tst.js:214:28:214:46 | this.state.tainted3 | -| tst.js:214:28:214:46 | this.state.tainted3 | -| tst.js:218:32:218:49 | prevState.tainted4 | -| tst.js:218:32:218:49 | prevState.tainted4 | -| tst.js:225:28:225:46 | this.props.tainted1 | -| tst.js:225:28:225:46 | this.props.tainted1 | -| tst.js:226:28:226:46 | this.props.tainted2 | -| tst.js:226:28:226:46 | this.props.tainted2 | -| tst.js:227:28:227:46 | this.props.tainted3 | -| tst.js:227:28:227:46 | this.props.tainted3 | -| tst.js:231:32:231:49 | prevProps.tainted4 | -| tst.js:231:32:231:49 | prevProps.tainted4 | -| tst.js:236:35:236:41 | tainted | -| tst.js:238:20:238:26 | tainted | -| tst.js:240:23:240:29 | tainted | -| tst.js:241:23:241:29 | tainted | -| tst.js:247:39:247:55 | props.propTainted | -| tst.js:251:60:251:82 | this.st ... Tainted | -| tst.js:251:60:251:82 | this.st ... Tainted | -| tst.js:255:23:255:29 | tainted | -| tst.js:259:7:259:17 | window.name | -| tst.js:259:7:259:17 | window.name | -| tst.js:259:7:259:17 | window.name | -| tst.js:259:7:259:17 | window.name | -| tst.js:260:7:260:10 | name | -| tst.js:260:7:260:10 | name | -| tst.js:260:7:260:10 | name | -| tst.js:260:7:260:10 | name | -| tst.js:264:11:264:21 | window.name | -| tst.js:264:11:264:21 | window.name | -| tst.js:264:11:264:21 | window.name | -| tst.js:264:11:264:21 | window.name | -| tst.js:280:22:280:29 | location | -| tst.js:280:22:280:29 | location | -| tst.js:280:22:280:29 | location | -| tst.js:285:9:285:29 | tainted | -| tst.js:285:9:285:29 | tainted | -| tst.js:285:19:285:29 | window.name | -| tst.js:285:19:285:29 | window.name | -| tst.js:285:19:285:29 | window.name | -| tst.js:288:59:288:65 | tainted | -| tst.js:288:59:288:65 | tainted | -| tst.js:288:59:288:65 | tainted | -| tst.js:301:9:301:16 | location | -| tst.js:301:9:301:16 | location | -| tst.js:302:10:302:10 | e | -| tst.js:303:20:303:20 | e | -| tst.js:303:20:303:20 | e | -| tst.js:308:10:308:17 | location | -| tst.js:308:10:308:17 | location | -| tst.js:310:10:310:10 | e | -| tst.js:311:20:311:20 | e | -| tst.js:311:20:311:20 | e | -| tst.js:316:35:316:42 | location | -| tst.js:316:35:316:42 | location | -| tst.js:316:35:316:42 | location | -| tst.js:327:18:327:34 | document.location | -| tst.js:327:18:327:34 | document.location | -| tst.js:331:7:331:43 | params | -| tst.js:331:16:331:43 | getTain ... hParams | -| tst.js:332:18:332:23 | params | -| tst.js:332:18:332:35 | params.get('name') | -| tst.js:332:18:332:35 | params.get('name') | -| tst.js:332:18:332:35 | params.get('name') | -| tst.js:332:18:332:35 | params.get('name') | -| tst.js:341:20:341:36 | document.location | -| tst.js:341:20:341:36 | document.location | -| tst.js:343:5:343:17 | getUrl().hash | -| tst.js:343:5:343:30 | getUrl( ... ring(1) | -| tst.js:343:5:343:30 | getUrl( ... ring(1) | -| tst.js:343:5:343:30 | getUrl( ... ring(1) | -| tst.js:348:7:348:39 | target | -| tst.js:348:16:348:39 | documen ... .search | -| tst.js:348:16:348:39 | documen ... .search | -| tst.js:349:12:349:17 | target | -| tst.js:349:12:349:17 | target | -| tst.js:355:10:355:42 | target | -| tst.js:355:19:355:42 | documen ... .search | -| tst.js:355:19:355:42 | documen ... .search | -| tst.js:356:16:356:21 | target | -| tst.js:356:16:356:21 | target | -| tst.js:360:21:360:26 | target | -| tst.js:360:21:360:26 | target | -| tst.js:363:18:363:23 | target | -| tst.js:363:18:363:23 | target | -| tst.js:371:7:371:39 | target | -| tst.js:371:16:371:39 | documen ... .search | -| tst.js:371:16:371:39 | documen ... .search | -| tst.js:374:18:374:23 | target | -| tst.js:374:18:374:23 | target | -| tst.js:381:7:381:39 | target | -| tst.js:381:16:381:39 | documen ... .search | -| tst.js:381:16:381:39 | documen ... .search | -| tst.js:384:18:384:23 | target | -| tst.js:384:18:384:23 | target | -| tst.js:386:18:386:23 | target | -| tst.js:386:18:386:29 | target.taint | -| tst.js:386:18:386:29 | target.taint | -| tst.js:391:19:391:42 | documen ... .search | -| tst.js:391:19:391:42 | documen ... .search | -| tst.js:392:18:392:30 | target.taint3 | -| tst.js:392:18:392:30 | target.taint3 | -| tst.js:397:18:397:23 | target | -| tst.js:397:18:397:30 | target.taint5 | -| tst.js:397:18:397:30 | target.taint5 | -| tst.js:406:18:406:23 | target | -| tst.js:406:18:406:30 | target.taint7 | -| tst.js:406:18:406:30 | target.taint7 | -| tst.js:408:19:408:24 | target | -| tst.js:408:19:408:31 | target.taint8 | -| tst.js:409:18:409:30 | target.taint8 | -| tst.js:409:18:409:30 | target.taint8 | -| tst.js:416:7:416:46 | payload | -| tst.js:416:7:416:46 | payload | -| tst.js:416:7:416:46 | payload | -| tst.js:416:17:416:36 | window.location.hash | -| tst.js:416:17:416:36 | window.location.hash | -| tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:417:18:417:24 | payload | -| tst.js:417:18:417:24 | payload | -| tst.js:417:18:417:24 | payload | -| tst.js:417:18:417:24 | payload | -| tst.js:419:7:419:55 | match | -| tst.js:419:15:419:34 | window.location.hash | -| tst.js:419:15:419:34 | window.location.hash | -| tst.js:419:15:419:55 | window. ... (\\w+)/) | -| tst.js:421:20:421:24 | match | -| tst.js:421:20:421:27 | match[1] | -| tst.js:421:20:421:27 | match[1] | -| tst.js:424:18:424:37 | window.location.hash | -| tst.js:424:18:424:37 | window.location.hash | -| tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:428:7:428:39 | target | -| tst.js:428:16:428:39 | documen ... .search | -| tst.js:428:16:428:39 | documen ... .search | -| tst.js:430:18:430:23 | target | -| tst.js:430:18:430:89 | target. ... data>') | -| tst.js:430:18:430:89 | target. ... data>') | -| tst.js:436:6:436:38 | source | -| tst.js:436:15:436:38 | documen ... .search | -| tst.js:436:15:436:38 | documen ... .search | -| tst.js:440:28:440:33 | source | -| tst.js:440:28:440:33 | source | -| tst.js:441:33:441:38 | source | -| tst.js:441:33:441:38 | source | -| tst.js:442:34:442:39 | source | -| tst.js:442:34:442:39 | source | -| tst.js:443:41:443:46 | source | -| tst.js:443:41:443:46 | source | -| tst.js:444:44:444:49 | source | -| tst.js:444:44:444:49 | source | -| tst.js:445:32:445:37 | source | -| tst.js:445:32:445:37 | source | -| tst.js:453:7:453:39 | source | -| tst.js:453:16:453:39 | documen ... .search | -| tst.js:453:16:453:39 | documen ... .search | -| tst.js:455:18:455:23 | source | -| tst.js:455:18:455:23 | source | -| tst.js:456:18:456:42 | ansiToH ... source) | -| tst.js:456:18:456:42 | ansiToH ... source) | -| tst.js:456:36:456:41 | source | -| tst.js:460:6:460:38 | source | -| tst.js:460:15:460:38 | documen ... .search | -| tst.js:460:15:460:38 | documen ... .search | -| tst.js:463:21:463:26 | source | -| tst.js:463:21:463:26 | source | -| tst.js:465:19:465:24 | source | -| tst.js:465:19:465:24 | source | -| tst.js:467:20:467:25 | source | -| tst.js:467:20:467:25 | source | -| tst.js:471:7:471:46 | url | -| tst.js:471:13:471:36 | documen ... .search | -| tst.js:471:13:471:36 | documen ... .search | -| tst.js:471:13:471:46 | documen ... bstr(1) | -| tst.js:473:19:473:21 | url | -| tst.js:473:19:473:21 | url | -| tst.js:474:26:474:28 | url | -| tst.js:474:26:474:28 | url | -| tst.js:475:25:475:27 | url | -| tst.js:475:25:475:27 | url | -| tst.js:476:20:476:22 | url | -| tst.js:476:20:476:22 | url | -| tst.js:486:22:486:24 | url | -| tst.js:486:22:486:24 | url | -| tst.js:491:23:491:35 | location.hash | -| tst.js:491:23:491:35 | location.hash | -| tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:494:18:494:30 | location.hash | -| tst.js:494:18:494:30 | location.hash | -| tst.js:494:18:494:40 | locatio ... bstr(1) | -| tst.js:494:18:494:40 | locatio ... bstr(1) | -| tst.js:501:33:501:63 | decodeU ... n.hash) | -| tst.js:501:33:501:63 | decodeU ... n.hash) | -| tst.js:501:43:501:62 | window.location.hash | -| tst.js:501:43:501:62 | window.location.hash | -| typeahead.js:20:13:20:45 | target | -| typeahead.js:20:22:20:45 | documen ... .search | -| typeahead.js:20:22:20:45 | documen ... .search | -| typeahead.js:21:12:21:17 | target | -| typeahead.js:24:30:24:32 | val | -| typeahead.js:25:18:25:20 | val | -| typeahead.js:25:18:25:20 | val | -| v-html.vue:2:8:2:23 | v-html=tainted | -| v-html.vue:2:8:2:23 | v-html=tainted | -| v-html.vue:6:42:6:58 | document.location | -| v-html.vue:6:42:6:58 | document.location | -| various-concat-obfuscations.js:2:6:2:39 | tainted | -| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | -| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | -| various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | -| various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | -| various-concat-obfuscations.js:4:14:4:20 | tainted | -| various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | -| various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | -| various-concat-obfuscations.js:5:12:5:18 | tainted | -| various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | -| various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | -| various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | -| various-concat-obfuscations.js:6:19:6:25 | tainted | -| various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | -| various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | -| various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | -| various-concat-obfuscations.js:7:14:7:20 | tainted | -| various-concat-obfuscations.js:9:4:9:34 | "
" | -| various-concat-obfuscations.js:9:4:9:34 | "
" | -| various-concat-obfuscations.js:9:19:9:25 | tainted | -| various-concat-obfuscations.js:10:4:10:27 | `
` | -| various-concat-obfuscations.js:10:4:10:27 | `
` | -| various-concat-obfuscations.js:10:16:10:22 | tainted | -| various-concat-obfuscations.js:11:4:11:31 | "
") | -| various-concat-obfuscations.js:11:4:11:44 | "
") | -| various-concat-obfuscations.js:11:24:11:30 | tainted | -| various-concat-obfuscations.js:12:4:12:34 | ["
"] | -| various-concat-obfuscations.js:12:4:12:41 | ["
` | semmle.label | `` | +| classnames.js:7:47:7:69 | classNa ... w.name) | semmle.label | classNa ... w.name) | +| classnames.js:7:58:7:68 | window.name | semmle.label | window.name | +| classnames.js:8:31:8:85 | `` | semmle.label | `` | +| classnames.js:8:47:8:70 | classNa ... w.name) | semmle.label | classNa ... w.name) | +| classnames.js:8:59:8:69 | window.name | semmle.label | window.name | +| classnames.js:9:31:9:85 | `` | semmle.label | `` | +| classnames.js:9:47:9:70 | classNa ... w.name) | semmle.label | classNa ... w.name) | +| classnames.js:9:59:9:69 | window.name | semmle.label | window.name | +| classnames.js:10:45:10:55 | window.name | semmle.label | window.name | +| classnames.js:11:31:11:79 | `` | semmle.label | `` | +| classnames.js:11:47:11:64 | unsafeStyle('foo') | semmle.label | unsafeStyle('foo') | +| classnames.js:13:31:13:83 | `` | semmle.label | `` | +| classnames.js:13:47:13:68 | safeSty ... w.name) | semmle.label | safeSty ... w.name) | +| classnames.js:13:57:13:67 | window.name | semmle.label | window.name | +| classnames.js:15:31:15:78 | `` | semmle.label | `` | +| classnames.js:15:47:15:63 | clsx(window.name) | semmle.label | clsx(window.name) | +| classnames.js:15:52:15:62 | window.name | semmle.label | window.name | +| classnames.js:17:32:17:79 | `` | semmle.label | `` | +| classnames.js:17:48:17:64 | clsx(window.name) | semmle.label | clsx(window.name) | +| classnames.js:17:53:17:63 | window.name | semmle.label | window.name | +| clipboard.ts:8:11:8:51 | html | semmle.label | html | +| clipboard.ts:8:18:8:51 | clipboa ... /html') | semmle.label | clipboa ... /html') | +| clipboard.ts:15:25:15:28 | html | semmle.label | html | +| clipboard.ts:24:23:24:58 | e.clipb ... /html') | semmle.label | e.clipb ... /html') | +| clipboard.ts:29:19:29:54 | e.clipb ... /html') | semmle.label | e.clipb ... /html') | +| clipboard.ts:33:19:33:68 | e.origi ... /html') | semmle.label | e.origi ... /html') | +| clipboard.ts:43:15:43:55 | html | semmle.label | html | +| clipboard.ts:43:22:43:55 | clipboa ... /html') | semmle.label | clipboa ... /html') | +| clipboard.ts:50:29:50:32 | html | semmle.label | html | +| clipboard.ts:71:13:71:62 | droppedHtml | semmle.label | droppedHtml | +| clipboard.ts:71:27:71:62 | e.clipb ... /html') | semmle.label | e.clipb ... /html') | +| clipboard.ts:73:29:73:39 | droppedHtml | semmle.label | droppedHtml | +| clipboard.ts:98:15:98:54 | html | semmle.label | html | +| clipboard.ts:98:22:98:54 | dataTra ... /html') | semmle.label | dataTra ... /html') | +| clipboard.ts:99:23:99:26 | html | semmle.label | html | +| custom-element.js:5:26:5:36 | window.name | semmle.label | window.name | +| d3.js:4:12:4:22 | window.name | semmle.label | window.name | +| d3.js:11:15:11:24 | getTaint() | semmle.label | getTaint() | +| d3.js:12:20:12:29 | getTaint() | semmle.label | getTaint() | +| d3.js:14:20:14:29 | getTaint() | semmle.label | getTaint() | +| d3.js:21:15:21:24 | getTaint() | semmle.label | getTaint() | +| dates.js:9:9:9:69 | taint | semmle.label | taint | +| dates.js:9:17:9:69 | decodeU ... ing(1)) | semmle.label | decodeU ... ing(1)) | +| dates.js:9:36:9:55 | window.location.hash | semmle.label | window.location.hash | +| dates.js:9:36:9:68 | window. ... ring(1) | semmle.label | window. ... ring(1) | +| dates.js:11:31:11:70 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:11:42:11:68 | dateFns ... taint) | semmle.label | dateFns ... taint) | +| dates.js:11:63:11:67 | taint | semmle.label | taint | +| dates.js:12:31:12:73 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:12:42:12:71 | dateFns ... taint) | semmle.label | dateFns ... taint) | +| dates.js:12:66:12:70 | taint | semmle.label | taint | +| dates.js:13:31:13:72 | `Time i ... time)}` | semmle.label | `Time i ... time)}` | +| dates.js:13:42:13:70 | dateFns ... )(time) | semmle.label | dateFns ... )(time) | +| dates.js:13:59:13:63 | taint | semmle.label | taint | +| dates.js:16:31:16:69 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:16:42:16:67 | moment( ... (taint) | semmle.label | moment( ... (taint) | +| dates.js:16:62:16:66 | taint | semmle.label | taint | +| dates.js:18:31:18:66 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:18:42:18:64 | datefor ... taint) | semmle.label | datefor ... taint) | +| dates.js:18:59:18:63 | taint | semmle.label | taint | +| dates.js:21:31:21:68 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:21:42:21:66 | dayjs(t ... (taint) | semmle.label | dayjs(t ... (taint) | +| dates.js:21:61:21:65 | taint | semmle.label | taint | +| dates.js:30:9:30:69 | taint | semmle.label | taint | +| dates.js:30:17:30:69 | decodeU ... ing(1)) | semmle.label | decodeU ... ing(1)) | +| dates.js:30:36:30:55 | window.location.hash | semmle.label | window.location.hash | +| dates.js:30:36:30:68 | window. ... ring(1) | semmle.label | window. ... ring(1) | +| dates.js:37:31:37:84 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:37:42:37:82 | dateFns ... taint) | semmle.label | dateFns ... taint) | +| dates.js:37:77:37:81 | taint | semmle.label | taint | +| dates.js:38:31:38:84 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:38:42:38:82 | luxon.f ... taint) | semmle.label | luxon.f ... taint) | +| dates.js:38:77:38:81 | taint | semmle.label | taint | +| dates.js:39:31:39:86 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:39:42:39:84 | moment. ... taint) | semmle.label | moment. ... taint) | +| dates.js:39:79:39:83 | taint | semmle.label | taint | +| dates.js:40:31:40:84 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:40:42:40:82 | dayjs.f ... taint) | semmle.label | dayjs.f ... taint) | +| dates.js:40:77:40:81 | taint | semmle.label | taint | +| dates.js:46:9:46:69 | taint | semmle.label | taint | +| dates.js:46:17:46:69 | decodeU ... ing(1)) | semmle.label | decodeU ... ing(1)) | +| dates.js:46:36:46:55 | window.location.hash | semmle.label | window.location.hash | +| dates.js:46:36:46:68 | window. ... ring(1) | semmle.label | window. ... ring(1) | +| dates.js:48:31:48:90 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:48:42:48:88 | DateTim ... (taint) | semmle.label | DateTim ... (taint) | +| dates.js:48:83:48:87 | taint | semmle.label | taint | +| dates.js:49:31:49:89 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:49:42:49:87 | new Dat ... (taint) | semmle.label | new Dat ... (taint) | +| dates.js:49:82:49:86 | taint | semmle.label | taint | +| dates.js:50:31:50:104 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:50:42:50:102 | DateTim ... (taint) | semmle.label | DateTim ... (taint) | +| dates.js:50:97:50:101 | taint | semmle.label | taint | +| dates.js:54:9:54:69 | taint | semmle.label | taint | +| dates.js:54:17:54:69 | decodeU ... ing(1)) | semmle.label | decodeU ... ing(1)) | +| dates.js:54:36:54:55 | window.location.hash | semmle.label | window.location.hash | +| dates.js:54:36:54:68 | window. ... ring(1) | semmle.label | window. ... ring(1) | +| dates.js:57:31:57:101 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:57:42:57:99 | moment. ... (taint) | semmle.label | moment. ... (taint) | +| dates.js:57:94:57:98 | taint | semmle.label | taint | +| dates.js:59:31:59:87 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:59:42:59:85 | luxon.e ... (taint) | semmle.label | luxon.e ... (taint) | +| dates.js:59:80:59:84 | taint | semmle.label | taint | +| dates.js:61:31:61:88 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:61:42:61:86 | dayjs.s ... (taint) | semmle.label | dayjs.s ... (taint) | +| dates.js:61:81:61:85 | taint | semmle.label | taint | +| dragAndDrop.ts:8:11:8:50 | html | semmle.label | html | +| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | semmle.label | dataTra ... /html') | +| dragAndDrop.ts:15:25:15:28 | html | semmle.label | html | +| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | semmle.label | e.dataT ... /html') | +| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | semmle.label | e.dataT ... /html') | +| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | semmle.label | e.origi ... /html') | +| dragAndDrop.ts:43:15:43:54 | html | semmle.label | html | +| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | semmle.label | dataTra ... /html') | +| dragAndDrop.ts:50:29:50:32 | html | semmle.label | html | +| dragAndDrop.ts:71:13:71:61 | droppedHtml | semmle.label | droppedHtml | +| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | semmle.label | e.dataT ... /html') | +| dragAndDrop.ts:73:29:73:39 | droppedHtml | semmle.label | droppedHtml | +| event-handler-receiver.js:2:31:2:83 | '

' | semmle.label | '

' | +| event-handler-receiver.js:2:49:2:61 | location.href | semmle.label | location.href | +| express.js:7:15:7:33 | req.param("wobble") | semmle.label | req.param("wobble") | +| jquery.js:2:7:2:40 | tainted | semmle.label | tainted | +| jquery.js:2:17:2:40 | documen ... .search | semmle.label | documen ... .search | +| jquery.js:7:5:7:34 | "
" | semmle.label | "
" | +| jquery.js:7:20:7:26 | tainted | semmle.label | tainted | +| jquery.js:8:18:8:34 | "XSS: " + tainted | semmle.label | "XSS: " + tainted | +| jquery.js:8:28:8:34 | tainted | semmle.label | tainted | +| jquery.js:10:5:10:40 | "" + ... "" | semmle.label | "" + ... "" | +| jquery.js:10:13:10:20 | location | semmle.label | location | +| jquery.js:10:13:10:31 | location.toString() | semmle.label | location.toString() | +| jquery.js:14:19:14:58 | decodeU ... n.hash) | semmle.label | decodeU ... n.hash) | +| jquery.js:14:38:14:57 | window.location.hash | semmle.label | window.location.hash | +| jquery.js:15:19:15:60 | decodeU ... search) | semmle.label | decodeU ... search) | +| jquery.js:15:38:15:59 | window. ... .search | semmle.label | window. ... .search | +| jquery.js:16:19:16:64 | decodeU ... ring()) | semmle.label | decodeU ... ring()) | +| jquery.js:16:38:16:52 | window.location | semmle.label | window.location | +| jquery.js:16:38:16:63 | window. ... tring() | semmle.label | window. ... tring() | +| jquery.js:18:7:18:33 | hash | semmle.label | hash | +| jquery.js:18:14:18:33 | window.location.hash | semmle.label | window.location.hash | +| jquery.js:21:5:21:8 | hash | semmle.label | hash | +| jquery.js:21:5:21:21 | hash.substring(1) | semmle.label | hash.substring(1) | +| jquery.js:22:5:22:8 | hash | semmle.label | hash | +| jquery.js:22:5:22:25 | hash.su ... (1, 10) | semmle.label | hash.su ... (1, 10) | +| jquery.js:23:5:23:8 | hash | semmle.label | hash | +| jquery.js:23:5:23:18 | hash.substr(1) | semmle.label | hash.substr(1) | +| jquery.js:24:5:24:8 | hash | semmle.label | hash | +| jquery.js:24:5:24:17 | hash.slice(1) | semmle.label | hash.slice(1) | +| jquery.js:27:5:27:8 | hash | semmle.label | hash | +| jquery.js:27:5:27:25 | hash.re ... #', '') | semmle.label | hash.re ... #', '') | +| jquery.js:28:5:28:26 | window. ... .search | semmle.label | window. ... .search | +| jquery.js:28:5:28:43 | window. ... ?', '') | semmle.label | window. ... ?', '') | +| jquery.js:34:5:34:25 | '' + ... '' | semmle.label | '' + ... '' | +| jquery.js:34:13:34:16 | hash | semmle.label | hash | +| jquery.js:36:25:36:31 | tainted | semmle.label | tainted | +| jquery.js:37:25:37:37 | () => tainted | semmle.label | () => tainted | +| jquery.js:37:31:37:37 | tainted | semmle.label | tainted | +| json-stringify.jsx:5:9:5:36 | locale | semmle.label | locale | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | semmle.label | req.param("locale") | +| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | semmle.label | `https: ... ocale}` | +| json-stringify.jsx:11:51:11:56 | locale | semmle.label | locale | +| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | semmle.label | `https: ... ocale}` | +| json-stringify.jsx:19:56:19:61 | locale | semmle.label | locale | +| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | semmle.label | JSON.st ... locale) | +| json-stringify.jsx:31:55:31:60 | locale | semmle.label | locale | +| json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | semmle.label | JSON.st ... jsonLD) | +| jwt-server.js:7:9:7:35 | taint | semmle.label | taint | +| jwt-server.js:7:17:7:35 | req.param("wobble") | semmle.label | req.param("wobble") | +| jwt-server.js:9:16:9:20 | taint | semmle.label | taint | +| jwt-server.js:9:55:9:61 | decoded | semmle.label | decoded | +| jwt-server.js:11:19:11:25 | decoded | semmle.label | decoded | +| jwt-server.js:11:19:11:29 | decoded.foo | semmle.label | decoded.foo | +| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | semmle.label | `Hi, yo ... sage}.` | +| nodemailer.js:13:50:13:66 | req.query.message | semmle.label | req.query.message | +| optionalSanitizer.js:2:7:2:39 | target | semmle.label | target | +| optionalSanitizer.js:2:16:2:39 | documen ... .search | semmle.label | documen ... .search | +| optionalSanitizer.js:6:18:6:23 | target | semmle.label | target | +| optionalSanitizer.js:8:7:8:22 | tainted | semmle.label | tainted | +| optionalSanitizer.js:8:17:8:22 | target | semmle.label | target | +| optionalSanitizer.js:9:18:9:24 | tainted | semmle.label | tainted | +| optionalSanitizer.js:15:9:15:14 | target | semmle.label | target | +| optionalSanitizer.js:16:18:16:18 | x | semmle.label | x | +| optionalSanitizer.js:17:20:17:20 | x | semmle.label | x | +| optionalSanitizer.js:26:7:26:39 | target | semmle.label | target | +| optionalSanitizer.js:26:16:26:39 | documen ... .search | semmle.label | documen ... .search | +| optionalSanitizer.js:28:24:28:24 | x | semmle.label | x | +| optionalSanitizer.js:29:12:29:12 | x | semmle.label | x | +| optionalSanitizer.js:31:7:31:23 | tainted2 | semmle.label | tainted2 | +| optionalSanitizer.js:31:18:31:23 | target | semmle.label | target | +| optionalSanitizer.js:32:18:32:25 | tainted2 | semmle.label | tainted2 | +| optionalSanitizer.js:34:5:34:36 | tainted2 | semmle.label | tainted2 | +| optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | semmle.label | sanitiz ... inted2) | +| optionalSanitizer.js:34:28:34:35 | tainted2 | semmle.label | tainted2 | +| optionalSanitizer.js:36:18:36:25 | tainted2 | semmle.label | tainted2 | +| optionalSanitizer.js:38:7:38:23 | tainted3 | semmle.label | tainted3 | +| optionalSanitizer.js:38:18:38:23 | target | semmle.label | target | +| optionalSanitizer.js:39:18:39:25 | tainted3 | semmle.label | tainted3 | +| optionalSanitizer.js:41:5:41:36 | tainted3 | semmle.label | tainted3 | +| optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | semmle.label | sanitiz ... inted3) | +| optionalSanitizer.js:41:28:41:35 | tainted3 | semmle.label | tainted3 | +| optionalSanitizer.js:43:18:43:25 | tainted3 | semmle.label | tainted3 | +| optionalSanitizer.js:45:18:45:56 | sanitiz ... target | semmle.label | sanitiz ... target | +| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | semmle.label | sanitizeBad(target) | +| optionalSanitizer.js:45:41:45:46 | target | semmle.label | target | +| optionalSanitizer.js:45:51:45:56 | target | semmle.label | target | +| pages/[id].jsx:3:30:3:35 | params [id] | semmle.label | params [id] | +| pages/[id].jsx:3:30:3:35 | params [q] | semmle.label | params [q] | +| pages/[id].jsx:5:9:5:14 | { id } | semmle.label | { id } | +| pages/[id].jsx:5:9:5:29 | id | semmle.label | id | +| pages/[id].jsx:5:11:5:12 | id | semmle.label | id | +| pages/[id].jsx:5:18:5:29 | router.query | semmle.label | router.query | +| pages/[id].jsx:10:44:10:45 | id | semmle.label | id | +| pages/[id].jsx:13:44:13:49 | params [id] | semmle.label | params [id] | +| pages/[id].jsx:13:44:13:52 | params.id | semmle.label | params.id | +| pages/[id].jsx:16:44:16:49 | params [q] | semmle.label | params [q] | +| pages/[id].jsx:16:44:16:51 | params.q | semmle.label | params.q | +| pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | semmle.label | {\\n ... ,\\n } [id] | +| pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | semmle.label | {\\n ... ,\\n } [q] | +| pages/[id].jsx:25:11:25:24 | context.params | semmle.label | context.params | +| pages/[id].jsx:25:11:25:27 | context.params.id | semmle.label | context.params.id | +| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | semmle.label | context ... d \|\| "" | +| pages/[id].jsx:26:10:26:22 | context.query | semmle.label | context.query | +| pages/[id].jsx:26:10:26:30 | context ... .foobar | semmle.label | context ... .foobar | +| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | semmle.label | context ... r \|\| "" | +| react-native.js:7:7:7:33 | tainted | semmle.label | tainted | +| react-native.js:7:17:7:33 | req.param("code") | semmle.label | req.param("code") | +| react-native.js:8:18:8:24 | tainted | semmle.label | tainted | +| react-native.js:9:27:9:33 | tainted | semmle.label | tainted | +| react-use-context.js:10:22:10:32 | window.name | semmle.label | window.name | +| react-use-context.js:16:26:16:36 | window.name | semmle.label | window.name | +| react-use-router.js:8:21:8:32 | router.query | semmle.label | router.query | +| react-use-router.js:8:21:8:39 | router.query.foobar | semmle.label | router.query.foobar | +| react-use-router.js:11:24:11:35 | router.query | semmle.label | router.query | +| react-use-router.js:11:24:11:42 | router.query.foobar | semmle.label | router.query.foobar | +| react-use-router.js:23:31:23:36 | [post update] router | semmle.label | [post update] router | +| react-use-router.js:23:43:23:48 | router | semmle.label | router | +| react-use-router.js:23:43:23:54 | router.query | semmle.label | router.query | +| react-use-router.js:23:43:23:61 | router.query.foobar | semmle.label | router.query.foobar | +| react-use-router.js:33:21:33:32 | router.query | semmle.label | router.query | +| react-use-router.js:33:21:33:39 | router.query.foobar | semmle.label | router.query.foobar | +| react-use-state.js:4:9:4:49 | state | semmle.label | state | +| react-use-state.js:4:10:4:14 | state | semmle.label | state | +| react-use-state.js:4:38:4:48 | window.name | semmle.label | window.name | +| react-use-state.js:5:51:5:55 | state | semmle.label | state | +| react-use-state.js:9:9:9:43 | state | semmle.label | state | +| react-use-state.js:9:10:9:14 | state | semmle.label | state | +| react-use-state.js:10:14:10:24 | window.name | semmle.label | window.name | +| react-use-state.js:11:51:11:55 | state | semmle.label | state | +| react-use-state.js:15:9:15:43 | state | semmle.label | state | +| react-use-state.js:15:10:15:14 | state | semmle.label | state | +| react-use-state.js:16:20:16:30 | window.name | semmle.label | window.name | +| react-use-state.js:17:51:17:55 | state | semmle.label | state | +| react-use-state.js:21:10:21:14 | state | semmle.label | state | +| react-use-state.js:22:14:22:17 | prev | semmle.label | prev | +| react-use-state.js:23:35:23:38 | prev | semmle.label | prev | +| react-use-state.js:25:20:25:30 | window.name | semmle.label | window.name | +| sanitiser.js:16:7:16:27 | tainted | semmle.label | tainted | +| sanitiser.js:16:17:16:27 | window.name | semmle.label | window.name | +| sanitiser.js:23:21:23:44 | '' + ... '' | semmle.label | '' + ... '' | +| sanitiser.js:23:29:23:35 | tainted | semmle.label | tainted | +| sanitiser.js:25:21:25:44 | '' + ... '' | semmle.label | '' + ... '' | +| sanitiser.js:25:29:25:35 | tainted | semmle.label | tainted | +| sanitiser.js:28:21:28:44 | '' + ... '' | semmle.label | '' + ... '' | +| sanitiser.js:28:29:28:35 | tainted | semmle.label | tainted | +| sanitiser.js:30:21:30:44 | '' + ... '' | semmle.label | '' + ... '' | +| sanitiser.js:30:29:30:35 | tainted | semmle.label | tainted | +| sanitiser.js:33:21:33:44 | '' + ... '' | semmle.label | '' + ... '' | +| sanitiser.js:33:29:33:35 | tainted | semmle.label | tainted | +| sanitiser.js:35:21:35:44 | '' + ... '' | semmle.label | '' + ... '' | +| sanitiser.js:35:29:35:35 | tainted | semmle.label | tainted | +| sanitiser.js:38:21:38:44 | '' + ... '' | semmle.label | '' + ... '' | +| sanitiser.js:38:29:38:35 | tainted | semmle.label | tainted | +| sanitiser.js:45:21:45:44 | '' + ... '' | semmle.label | '' + ... '' | +| sanitiser.js:45:29:45:35 | tainted | semmle.label | tainted | +| sanitiser.js:48:19:48:25 | tainted | semmle.label | tainted | +| sanitiser.js:48:19:48:46 | tainted ... /g, '') | semmle.label | tainted ... /g, '') | +| stored-xss.js:2:39:2:62 | documen ... .search | semmle.label | documen ... .search | +| stored-xss.js:3:35:3:58 | documen ... .search | semmle.label | documen ... .search | +| stored-xss.js:5:20:5:52 | session ... ssion') | semmle.label | session ... ssion') | +| stored-xss.js:8:20:8:48 | localSt ... local') | semmle.label | localSt ... local') | +| stored-xss.js:10:9:10:44 | href | semmle.label | href | +| stored-xss.js:10:16:10:44 | localSt ... local') | semmle.label | localSt ... local') | +| stored-xss.js:12:20:12:54 | "" | semmle.label | "" | +| stored-xss.js:12:35:12:38 | href | semmle.label | href | +| string-manipulations.js:3:16:3:32 | document.location | semmle.label | document.location | +| string-manipulations.js:4:16:4:37 | documen ... on.href | semmle.label | documen ... on.href | +| string-manipulations.js:5:16:5:37 | documen ... on.href | semmle.label | documen ... on.href | +| string-manipulations.js:5:16:5:47 | documen ... lueOf() | semmle.label | documen ... lueOf() | +| string-manipulations.js:6:16:6:37 | documen ... on.href | semmle.label | documen ... on.href | +| string-manipulations.js:6:16:6:43 | documen ... f.sup() | semmle.label | documen ... f.sup() | +| string-manipulations.js:7:16:7:37 | documen ... on.href | semmle.label | documen ... on.href | +| string-manipulations.js:7:16:7:51 | documen ... rCase() | semmle.label | documen ... rCase() | +| string-manipulations.js:8:16:8:37 | documen ... on.href | semmle.label | documen ... on.href | +| string-manipulations.js:8:16:8:48 | documen ... mLeft() | semmle.label | documen ... mLeft() | +| string-manipulations.js:9:16:9:58 | String. ... n.href) | semmle.label | String. ... n.href) | +| string-manipulations.js:9:36:9:57 | documen ... on.href | semmle.label | documen ... on.href | +| string-manipulations.js:10:16:10:45 | String( ... n.href) | semmle.label | String( ... n.href) | +| string-manipulations.js:10:23:10:44 | documen ... on.href | semmle.label | documen ... on.href | +| tooltip.jsx:6:11:6:30 | source | semmle.label | source | +| tooltip.jsx:6:20:6:30 | window.name | semmle.label | window.name | +| tooltip.jsx:10:25:10:30 | source | semmle.label | source | +| tooltip.jsx:11:25:11:30 | source | semmle.label | source | +| translate.js:6:7:6:39 | target | semmle.label | target | +| translate.js:6:16:6:39 | documen ... .search | semmle.label | documen ... .search | +| translate.js:7:7:7:61 | searchParams | semmle.label | searchParams | +| translate.js:7:22:7:61 | new URL ... ing(1)) | semmle.label | new URL ... ing(1)) | +| translate.js:7:42:7:47 | target | semmle.label | target | +| translate.js:7:42:7:60 | target.substring(1) | semmle.label | target.substring(1) | +| translate.js:9:27:9:38 | searchParams | semmle.label | searchParams | +| translate.js:9:27:9:50 | searchP ... 'term') | semmle.label | searchP ... 'term') | +| trusted-types-lib.js:1:28:1:28 | x | semmle.label | x | +| trusted-types-lib.js:2:12:2:12 | x | semmle.label | x | +| trusted-types.js:3:62:3:62 | x | semmle.label | x | +| trusted-types.js:3:67:3:67 | x | semmle.label | x | +| trusted-types.js:4:20:4:30 | window.name | semmle.label | window.name | +| trusted-types.js:13:20:13:30 | window.name | semmle.label | window.name | +| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | semmle.label | JSON.pa ... tr(1))) | +| tst3.js:2:23:2:74 | decodeU ... str(1)) | semmle.label | decodeU ... str(1)) | +| tst3.js:2:42:2:63 | window. ... .search | semmle.label | window. ... .search | +| tst3.js:2:42:2:73 | window. ... bstr(1) | semmle.label | window. ... bstr(1) | +| tst3.js:4:25:4:28 | data | semmle.label | data | +| tst3.js:4:25:4:32 | data.src | semmle.label | data.src | +| tst3.js:5:26:5:29 | data | semmle.label | data | +| tst3.js:5:26:5:31 | data.p | semmle.label | data.p | +| tst3.js:7:32:7:35 | data | semmle.label | data | +| tst3.js:7:32:7:37 | data.p | semmle.label | data.p | +| tst3.js:9:37:9:40 | data | semmle.label | data | +| tst3.js:9:37:9:42 | data.p | semmle.label | data.p | +| tst3.js:10:38:10:41 | data | semmle.label | data | +| tst3.js:10:38:10:43 | data.p | semmle.label | data.p | +| tst.js:2:7:2:39 | target | semmle.label | target | +| tst.js:2:16:2:39 | documen ... .search | semmle.label | documen ... .search | +| tst.js:5:18:5:23 | target | semmle.label | target | +| tst.js:8:18:8:126 | "" | semmle.label | "" | +| tst.js:8:37:8:58 | documen ... on.href | semmle.label | documen ... on.href | +| tst.js:8:37:8:114 | documen ... t=")+8) | semmle.label | documen ... t=")+8) | +| tst.js:12:5:12:42 | '
' | semmle.label | '
' | +| tst.js:12:28:12:33 | target | semmle.label | target | +| tst.js:17:7:17:56 | params | semmle.label | params | +| tst.js:17:16:17:43 | (new UR ... ation)) [searchParams] | semmle.label | (new UR ... ation)) [searchParams] | +| tst.js:17:16:17:56 | (new UR ... hParams | semmle.label | (new UR ... hParams | +| tst.js:17:17:17:42 | new URL ... cation) [searchParams] | semmle.label | new URL ... cation) [searchParams] | +| tst.js:17:25:17:41 | document.location | semmle.label | document.location | +| tst.js:18:18:18:23 | params | semmle.label | params | +| tst.js:18:18:18:35 | params.get('name') | semmle.label | params.get('name') | +| tst.js:20:7:20:61 | searchParams | semmle.label | searchParams | +| tst.js:20:22:20:61 | new URL ... ing(1)) | semmle.label | new URL ... ing(1)) | +| tst.js:20:42:20:47 | target | semmle.label | target | +| tst.js:20:42:20:60 | target.substring(1) | semmle.label | target.substring(1) | +| tst.js:21:18:21:29 | searchParams | semmle.label | searchParams | +| tst.js:21:18:21:41 | searchP ... 'name') | semmle.label | searchP ... 'name') | +| tst.js:24:14:24:19 | target | semmle.label | target | +| tst.js:26:18:26:23 | target | semmle.label | target | +| tst.js:28:5:28:28 | documen ... .search | semmle.label | documen ... .search | +| tst.js:31:10:31:33 | documen ... .search | semmle.label | documen ... .search | +| tst.js:34:16:34:20 | bar() | semmle.label | bar() | +| tst.js:36:14:36:14 | x | semmle.label | x | +| tst.js:37:10:37:10 | x | semmle.label | x | +| tst.js:40:16:40:44 | baz(doc ... search) | semmle.label | baz(doc ... search) | +| tst.js:40:20:40:43 | documen ... .search | semmle.label | documen ... .search | +| tst.js:42:15:42:15 | s | semmle.label | s | +| tst.js:43:10:43:31 | "
" ...
" | semmle.label | "
" ...
" | +| tst.js:43:20:43:20 | s | semmle.label | s | +| tst.js:46:16:46:45 | wrap(do ... search) | semmle.label | wrap(do ... search) | +| tst.js:46:21:46:44 | documen ... .search | semmle.label | documen ... .search | +| tst.js:48:15:48:15 | s | semmle.label | s | +| tst.js:50:12:50:12 | s | semmle.label | s | +| tst.js:50:12:50:22 | s.substr(1) | semmle.label | s.substr(1) | +| tst.js:54:16:54:45 | chop(do ... search) | semmle.label | chop(do ... search) | +| tst.js:54:21:54:44 | documen ... .search | semmle.label | documen ... .search | +| tst.js:56:16:56:45 | chop(do ... search) | semmle.label | chop(do ... search) | +| tst.js:56:21:56:44 | documen ... .search | semmle.label | documen ... .search | +| tst.js:58:16:58:32 | wrap(chop(bar())) | semmle.label | wrap(chop(bar())) | +| tst.js:58:21:58:31 | chop(bar()) | semmle.label | chop(bar()) | +| tst.js:58:26:58:30 | bar() | semmle.label | bar() | +| tst.js:60:34:60:34 | s | semmle.label | s | +| tst.js:62:18:62:18 | s | semmle.label | s | +| tst.js:64:25:64:48 | documen ... .search | semmle.label | documen ... .search | +| tst.js:65:25:65:48 | documen ... .search | semmle.label | documen ... .search | +| tst.js:68:16:68:20 | bar() | semmle.label | bar() | +| tst.js:70:1:70:27 | [,docum ... search] | semmle.label | [,docum ... search] | +| tst.js:70:1:70:27 | [,docum ... search] [1] | semmle.label | [,docum ... search] [1] | +| tst.js:70:3:70:26 | documen ... .search | semmle.label | documen ... .search | +| tst.js:70:46:70:46 | x | semmle.label | x | +| tst.js:73:20:73:20 | x | semmle.label | x | +| tst.js:77:49:77:72 | documen ... .search | semmle.label | documen ... .search | +| tst.js:81:26:81:49 | documen ... .search | semmle.label | documen ... .search | +| tst.js:82:25:82:48 | documen ... .search | semmle.label | documen ... .search | +| tst.js:84:33:84:56 | documen ... .search | semmle.label | documen ... .search | +| tst.js:85:32:85:55 | documen ... .search | semmle.label | documen ... .search | +| tst.js:90:39:90:62 | documen ... .search | semmle.label | documen ... .search | +| tst.js:96:30:96:53 | documen ... .search | semmle.label | documen ... .search | +| tst.js:102:25:102:48 | documen ... .search | semmle.label | documen ... .search | +| tst.js:107:7:107:44 | v | semmle.label | v | +| tst.js:107:11:107:34 | documen ... .search | semmle.label | documen ... .search | +| tst.js:107:11:107:44 | documen ... bstr(1) | semmle.label | documen ... bstr(1) | +| tst.js:110:18:110:18 | v | semmle.label | v | +| tst.js:136:18:136:18 | v | semmle.label | v | +| tst.js:148:29:148:50 | window. ... .search | semmle.label | window. ... .search | +| tst.js:151:29:151:29 | v | semmle.label | v | +| tst.js:151:49:151:49 | v | semmle.label | v | +| tst.js:155:29:155:46 | xssSourceService() | semmle.label | xssSourceService() | +| tst.js:158:40:158:61 | window. ... .search | semmle.label | window. ... .search | +| tst.js:177:9:177:41 | target | semmle.label | target | +| tst.js:177:18:177:41 | documen ... .search | semmle.label | documen ... .search | +| tst.js:180:28:180:33 | target | semmle.label | target | +| tst.js:184:9:184:42 | tainted | semmle.label | tainted | +| tst.js:184:19:184:42 | documen ... .search | semmle.label | documen ... .search | +| tst.js:186:31:186:37 | tainted | semmle.label | tainted | +| tst.js:188:42:188:48 | tainted | semmle.label | tainted | +| tst.js:189:33:189:39 | tainted | semmle.label | tainted | +| tst.js:191:54:191:60 | tainted | semmle.label | tainted | +| tst.js:192:45:192:51 | tainted | semmle.label | tainted | +| tst.js:193:49:193:55 | tainted | semmle.label | tainted | +| tst.js:197:9:197:42 | tainted | semmle.label | tainted | +| tst.js:197:19:197:42 | documen ... .search | semmle.label | documen ... .search | +| tst.js:199:67:199:73 | tainted | semmle.label | tainted | +| tst.js:200:67:200:73 | tainted | semmle.label | tainted | +| tst.js:204:35:204:41 | tainted | semmle.label | tainted | +| tst.js:206:46:206:52 | tainted | semmle.label | tainted | +| tst.js:207:38:207:44 | tainted | semmle.label | tainted | +| tst.js:208:35:208:41 | tainted | semmle.label | tainted | +| tst.js:212:28:212:46 | this.state.tainted1 | semmle.label | this.state.tainted1 | +| tst.js:213:28:213:46 | this.state.tainted2 | semmle.label | this.state.tainted2 | +| tst.js:214:28:214:46 | this.state.tainted3 | semmle.label | this.state.tainted3 | +| tst.js:218:32:218:49 | prevState.tainted4 | semmle.label | prevState.tainted4 | +| tst.js:225:28:225:46 | this.props.tainted1 | semmle.label | this.props.tainted1 | +| tst.js:226:28:226:46 | this.props.tainted2 | semmle.label | this.props.tainted2 | +| tst.js:227:28:227:46 | this.props.tainted3 | semmle.label | this.props.tainted3 | +| tst.js:231:32:231:49 | prevProps.tainted4 | semmle.label | prevProps.tainted4 | +| tst.js:236:35:236:41 | tainted | semmle.label | tainted | +| tst.js:238:20:238:26 | tainted | semmle.label | tainted | +| tst.js:240:23:240:29 | tainted | semmle.label | tainted | +| tst.js:241:23:241:29 | tainted | semmle.label | tainted | +| tst.js:247:39:247:55 | props.propTainted | semmle.label | props.propTainted | +| tst.js:251:60:251:82 | this.st ... Tainted | semmle.label | this.st ... Tainted | +| tst.js:255:23:255:29 | tainted | semmle.label | tainted | +| tst.js:259:7:259:17 | window.name | semmle.label | window.name | +| tst.js:260:7:260:10 | name | semmle.label | name | +| tst.js:264:11:264:21 | window.name | semmle.label | window.name | +| tst.js:280:22:280:29 | location | semmle.label | location | +| tst.js:285:9:285:29 | tainted | semmle.label | tainted | +| tst.js:285:19:285:29 | window.name | semmle.label | window.name | +| tst.js:288:59:288:65 | tainted | semmle.label | tainted | +| tst.js:301:9:301:16 | location | semmle.label | location | +| tst.js:302:10:302:10 | e | semmle.label | e | +| tst.js:303:20:303:20 | e | semmle.label | e | +| tst.js:308:10:308:17 | location | semmle.label | location | +| tst.js:310:10:310:10 | e | semmle.label | e | +| tst.js:311:20:311:20 | e | semmle.label | e | +| tst.js:316:35:316:42 | location | semmle.label | location | +| tst.js:327:10:327:35 | new URL ... cation) [searchParams] | semmle.label | new URL ... cation) [searchParams] | +| tst.js:327:18:327:34 | document.location | semmle.label | document.location | +| tst.js:331:7:331:43 | params | semmle.label | params | +| tst.js:331:16:331:30 | getTaintedUrl() [searchParams] | semmle.label | getTaintedUrl() [searchParams] | +| tst.js:331:16:331:43 | getTain ... hParams | semmle.label | getTain ... hParams | +| tst.js:332:18:332:23 | params | semmle.label | params | +| tst.js:332:18:332:35 | params.get('name') | semmle.label | params.get('name') | +| tst.js:341:12:341:37 | new URL ... cation) [hash] | semmle.label | new URL ... cation) [hash] | +| tst.js:341:20:341:36 | document.location | semmle.label | document.location | +| tst.js:343:5:343:12 | getUrl() [hash] | semmle.label | getUrl() [hash] | +| tst.js:343:5:343:17 | getUrl().hash | semmle.label | getUrl().hash | +| tst.js:343:5:343:30 | getUrl( ... ring(1) | semmle.label | getUrl( ... ring(1) | +| tst.js:348:7:348:39 | target | semmle.label | target | +| tst.js:348:16:348:39 | documen ... .search | semmle.label | documen ... .search | +| tst.js:349:12:349:17 | target | semmle.label | target | +| tst.js:355:10:355:42 | target | semmle.label | target | +| tst.js:355:19:355:42 | documen ... .search | semmle.label | documen ... .search | +| tst.js:356:16:356:21 | target | semmle.label | target | +| tst.js:360:21:360:26 | target | semmle.label | target | +| tst.js:363:18:363:23 | target | semmle.label | target | +| tst.js:371:7:371:39 | target | semmle.label | target | +| tst.js:371:16:371:39 | documen ... .search | semmle.label | documen ... .search | +| tst.js:374:18:374:23 | target | semmle.label | target | +| tst.js:381:7:381:39 | target | semmle.label | target | +| tst.js:381:7:381:39 | target [taint3] | semmle.label | target [taint3] | +| tst.js:381:7:381:39 | target [taint8] | semmle.label | target [taint8] | +| tst.js:381:16:381:39 | documen ... .search | semmle.label | documen ... .search | +| tst.js:384:18:384:23 | target | semmle.label | target | +| tst.js:386:18:386:23 | target | semmle.label | target | +| tst.js:386:18:386:29 | target.taint | semmle.label | target.taint | +| tst.js:391:3:391:8 | [post update] target [taint3] | semmle.label | [post update] target [taint3] | +| tst.js:391:19:391:42 | documen ... .search | semmle.label | documen ... .search | +| tst.js:392:18:392:23 | target [taint3] | semmle.label | target [taint3] | +| tst.js:392:18:392:30 | target.taint3 | semmle.label | target.taint3 | +| tst.js:397:18:397:23 | target | semmle.label | target | +| tst.js:397:18:397:30 | target.taint5 | semmle.label | target.taint5 | +| tst.js:406:18:406:23 | target | semmle.label | target | +| tst.js:406:18:406:30 | target.taint7 | semmle.label | target.taint7 | +| tst.js:408:3:408:8 | [post update] target [taint8] | semmle.label | [post update] target [taint8] | +| tst.js:408:19:408:24 | target | semmle.label | target | +| tst.js:408:19:408:24 | target [taint8] | semmle.label | target [taint8] | +| tst.js:408:19:408:31 | target.taint8 | semmle.label | target.taint8 | +| tst.js:409:18:409:23 | target [taint8] | semmle.label | target [taint8] | +| tst.js:409:18:409:30 | target.taint8 | semmle.label | target.taint8 | +| tst.js:416:7:416:46 | payload | semmle.label | payload | +| tst.js:416:17:416:36 | window.location.hash | semmle.label | window.location.hash | +| tst.js:416:17:416:46 | window. ... bstr(1) | semmle.label | window. ... bstr(1) | +| tst.js:417:18:417:24 | payload | semmle.label | payload | +| tst.js:419:7:419:55 | match | semmle.label | match | +| tst.js:419:15:419:34 | window.location.hash | semmle.label | window.location.hash | +| tst.js:419:15:419:55 | window. ... (\\w+)/) | semmle.label | window. ... (\\w+)/) | +| tst.js:421:20:421:24 | match | semmle.label | match | +| tst.js:421:20:421:27 | match[1] | semmle.label | match[1] | +| tst.js:424:18:424:37 | window.location.hash | semmle.label | window.location.hash | +| tst.js:424:18:424:48 | window. ... it('#') | semmle.label | window. ... it('#') | +| tst.js:424:18:424:51 | window. ... '#')[1] | semmle.label | window. ... '#')[1] | +| tst.js:428:7:428:39 | target | semmle.label | target | +| tst.js:428:16:428:39 | documen ... .search | semmle.label | documen ... .search | +| tst.js:430:18:430:23 | target | semmle.label | target | +| tst.js:430:18:430:89 | target. ... data>') | semmle.label | target. ... data>') | +| tst.js:436:6:436:38 | source | semmle.label | source | +| tst.js:436:15:436:38 | documen ... .search | semmle.label | documen ... .search | +| tst.js:440:28:440:33 | source | semmle.label | source | +| tst.js:441:33:441:38 | source | semmle.label | source | +| tst.js:442:34:442:39 | source | semmle.label | source | +| tst.js:443:41:443:46 | source | semmle.label | source | +| tst.js:444:44:444:49 | source | semmle.label | source | +| tst.js:445:32:445:37 | source | semmle.label | source | +| tst.js:453:7:453:39 | source | semmle.label | source | +| tst.js:453:16:453:39 | documen ... .search | semmle.label | documen ... .search | +| tst.js:455:18:455:23 | source | semmle.label | source | +| tst.js:456:18:456:42 | ansiToH ... source) | semmle.label | ansiToH ... source) | +| tst.js:456:36:456:41 | source | semmle.label | source | +| tst.js:460:6:460:38 | source | semmle.label | source | +| tst.js:460:15:460:38 | documen ... .search | semmle.label | documen ... .search | +| tst.js:463:21:463:26 | source | semmle.label | source | +| tst.js:465:19:465:24 | source | semmle.label | source | +| tst.js:467:20:467:25 | source | semmle.label | source | +| tst.js:471:7:471:46 | url | semmle.label | url | +| tst.js:471:13:471:36 | documen ... .search | semmle.label | documen ... .search | +| tst.js:471:13:471:46 | documen ... bstr(1) | semmle.label | documen ... bstr(1) | +| tst.js:473:19:473:21 | url | semmle.label | url | +| tst.js:474:26:474:28 | url | semmle.label | url | +| tst.js:475:25:475:27 | url | semmle.label | url | +| tst.js:476:20:476:22 | url | semmle.label | url | +| tst.js:486:22:486:24 | url | semmle.label | url | +| tst.js:491:23:491:35 | location.hash | semmle.label | location.hash | +| tst.js:491:23:491:45 | locatio ... bstr(1) | semmle.label | locatio ... bstr(1) | +| tst.js:494:18:494:30 | location.hash | semmle.label | location.hash | +| tst.js:494:18:494:40 | locatio ... bstr(1) | semmle.label | locatio ... bstr(1) | +| tst.js:501:33:501:63 | decodeU ... n.hash) | semmle.label | decodeU ... n.hash) | +| tst.js:501:43:501:62 | window.location.hash | semmle.label | window.location.hash | +| typeahead.js:20:13:20:45 | target | semmle.label | target | +| typeahead.js:20:22:20:45 | documen ... .search | semmle.label | documen ... .search | +| typeahead.js:21:12:21:17 | target | semmle.label | target | +| typeahead.js:24:30:24:32 | val | semmle.label | val | +| typeahead.js:25:18:25:20 | val | semmle.label | val | +| various-concat-obfuscations.js:2:6:2:39 | tainted | semmle.label | tainted | +| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | semmle.label | documen ... .search | +| various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | semmle.label | "
" ...
" | +| various-concat-obfuscations.js:4:14:4:20 | tainted | semmle.label | tainted | +| various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | semmle.label | `
$ ...
` | +| various-concat-obfuscations.js:5:12:5:18 | tainted | semmle.label | tainted | +| various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | semmle.label | "
" ... ainted) | +| various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | semmle.label | "
" ... /div>") | +| various-concat-obfuscations.js:6:19:6:25 | tainted | semmle.label | tainted | +| various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | semmle.label | ["
... /div>"] | +| various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | semmle.label | ["
... .join() | +| various-concat-obfuscations.js:7:14:7:20 | tainted | semmle.label | tainted | +| various-concat-obfuscations.js:9:4:9:34 | "
" | semmle.label | "
" | +| various-concat-obfuscations.js:9:19:9:25 | tainted | semmle.label | tainted | +| various-concat-obfuscations.js:10:4:10:27 | `
` | semmle.label | `
` | +| various-concat-obfuscations.js:10:16:10:22 | tainted | semmle.label | tainted | +| various-concat-obfuscations.js:11:4:11:31 | "
") | semmle.label | "
") | +| various-concat-obfuscations.js:11:24:11:30 | tainted | semmle.label | tainted | +| various-concat-obfuscations.js:12:4:12:34 | ["
"] | semmle.label | ["
"] | +| various-concat-obfuscations.js:12:4:12:41 | ["
' | semmle.label | '
' | +| various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | semmle.label | (attrs. ... 'left') | +| various-concat-obfuscations.js:15:28:15:32 | attrs | semmle.label | attrs | +| various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | semmle.label | attrs.defaultattr | +| various-concat-obfuscations.js:17:24:17:28 | attrs | semmle.label | attrs | +| various-concat-obfuscations.js:18:10:18:59 | '
') | semmle.label | '
') | +| various-concat-obfuscations.js:18:32:18:36 | attrs | semmle.label | attrs | +| various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | semmle.label | attrs.defaultattr | +| various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | semmle.label | attrs.d ... 'left' | +| various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) | semmle.label | indirec ... .attrs) | +| various-concat-obfuscations.js:20:17:20:40 | documen ... .search | semmle.label | documen ... .search | +| various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | semmle.label | documen ... h.attrs | +| various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | semmle.label | indirec ... .attrs) | +| various-concat-obfuscations.js:21:17:21:40 | documen ... .search | semmle.label | documen ... .search | +| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | semmle.label | documen ... h.attrs | +| winjs.js:2:7:2:53 | tainted | semmle.label | tainted | +| winjs.js:2:17:2:40 | documen ... .search | semmle.label | documen ... .search | +| winjs.js:2:17:2:53 | documen ... ring(1) | semmle.label | documen ... ring(1) | +| winjs.js:3:43:3:49 | tainted | semmle.label | tainted | +| winjs.js:4:43:4:49 | tainted | semmle.label | tainted | edges | addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | -| addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | -| addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | -| addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | -| addEventListener.js:2:20:2:24 | event | addEventListener.js:2:20:2:29 | event.data | -| addEventListener.js:2:20:2:24 | event | addEventListener.js:2:20:2:29 | event.data | -| addEventListener.js:2:20:2:24 | event | addEventListener.js:2:20:2:29 | event.data | | addEventListener.js:2:20:2:24 | event | addEventListener.js:2:20:2:29 | event.data | | addEventListener.js:5:43:5:48 | data | addEventListener.js:6:20:6:23 | data | -| addEventListener.js:5:43:5:48 | data | addEventListener.js:6:20:6:23 | data | -| addEventListener.js:5:43:5:48 | data | addEventListener.js:6:20:6:23 | data | -| addEventListener.js:5:43:5:48 | data | addEventListener.js:6:20:6:23 | data | -| addEventListener.js:5:43:5:48 | {data} | addEventListener.js:5:44:5:47 | data | -| addEventListener.js:5:43:5:48 | {data} | addEventListener.js:5:44:5:47 | data | -| addEventListener.js:5:43:5:48 | {data} | addEventListener.js:5:44:5:47 | data | | addEventListener.js:5:43:5:48 | {data} | addEventListener.js:5:44:5:47 | data | | addEventListener.js:5:44:5:47 | data | addEventListener.js:5:43:5:48 | data | -| addEventListener.js:5:44:5:47 | data | addEventListener.js:5:43:5:48 | data | -| addEventListener.js:10:21:10:25 | event | addEventListener.js:12:24:12:28 | event | -| addEventListener.js:10:21:10:25 | event | addEventListener.js:12:24:12:28 | event | -| addEventListener.js:10:21:10:25 | event | addEventListener.js:12:24:12:28 | event | | addEventListener.js:10:21:10:25 | event | addEventListener.js:12:24:12:28 | event | | addEventListener.js:12:24:12:28 | event | addEventListener.js:12:24:12:33 | event.data | -| addEventListener.js:12:24:12:28 | event | addEventListener.js:12:24:12:33 | event.data | -| addEventListener.js:12:24:12:28 | event | addEventListener.js:12:24:12:33 | event.data | -| addEventListener.js:12:24:12:28 | event | addEventListener.js:12:24:12:33 | event.data | -| angular2-client.ts:22:44:22:71 | \\u0275getDOM ... ().href | angular2-client.ts:22:44:22:71 | \\u0275getDOM ... ().href | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | | angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | | angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:26:44:26:71 | this.ro ... ragment | angular2-client.ts:26:44:26:71 | this.ro ... ragment | -| angular2-client.ts:27:44:27:82 | this.ro ... ('foo') | angular2-client.ts:27:44:27:82 | this.ro ... ('foo') | -| angular2-client.ts:28:44:28:87 | this.ro ... ('foo') | angular2-client.ts:28:44:28:87 | this.ro ... ('foo') | -| angular2-client.ts:30:46:30:59 | map.get('foo') | angular2-client.ts:30:46:30:59 | map.get('foo') | -| angular2-client.ts:33:44:33:74 | this.ro ... 1].path | angular2-client.ts:33:44:33:74 | this.ro ... 1].path | | angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:35:44:35:91 | this.ro ... et('x') | angular2-client.ts:35:44:35:91 | this.ro ... et('x') | | angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:38:44:38:58 | this.router.url | angular2-client.ts:38:44:38:58 | this.router.url | -| angular2-client.ts:40:45:40:59 | this.router.url | angular2-client.ts:40:45:40:59 | this.router.url | -| angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | -| classnames.js:7:47:7:69 | classNa ... w.name) | classnames.js:7:31:7:84 | `` | | classnames.js:7:47:7:69 | classNa ... w.name) | classnames.js:7:31:7:84 | `` | | classnames.js:7:58:7:68 | window.name | classnames.js:7:47:7:69 | classNa ... w.name) | -| classnames.js:7:58:7:68 | window.name | classnames.js:7:47:7:69 | classNa ... w.name) | -| classnames.js:8:47:8:70 | classNa ... w.name) | classnames.js:8:31:8:85 | `` | | classnames.js:8:47:8:70 | classNa ... w.name) | classnames.js:8:31:8:85 | `` | | classnames.js:8:59:8:69 | window.name | classnames.js:8:47:8:70 | classNa ... w.name) | -| classnames.js:8:59:8:69 | window.name | classnames.js:8:47:8:70 | classNa ... w.name) | -| classnames.js:9:47:9:70 | classNa ... w.name) | classnames.js:9:31:9:85 | `` | | classnames.js:9:47:9:70 | classNa ... w.name) | classnames.js:9:31:9:85 | `` | | classnames.js:9:59:9:69 | window.name | classnames.js:9:47:9:70 | classNa ... w.name) | -| classnames.js:9:59:9:69 | window.name | classnames.js:9:47:9:70 | classNa ... w.name) | -| classnames.js:10:45:10:55 | window.name | classnames.js:11:47:11:64 | unsafeStyle('foo') | | classnames.js:10:45:10:55 | window.name | classnames.js:11:47:11:64 | unsafeStyle('foo') | | classnames.js:11:47:11:64 | unsafeStyle('foo') | classnames.js:11:31:11:79 | `` | -| classnames.js:11:47:11:64 | unsafeStyle('foo') | classnames.js:11:31:11:79 | `` | -| classnames.js:13:47:13:68 | safeSty ... w.name) | classnames.js:13:31:13:83 | `` | | classnames.js:13:47:13:68 | safeSty ... w.name) | classnames.js:13:31:13:83 | `` | | classnames.js:13:57:13:67 | window.name | classnames.js:13:47:13:68 | safeSty ... w.name) | -| classnames.js:13:57:13:67 | window.name | classnames.js:13:47:13:68 | safeSty ... w.name) | -| classnames.js:15:47:15:63 | clsx(window.name) | classnames.js:15:31:15:78 | `` | | classnames.js:15:47:15:63 | clsx(window.name) | classnames.js:15:31:15:78 | `` | | classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) | -| classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) | -| classnames.js:17:48:17:64 | clsx(window.name) | classnames.js:17:32:17:79 | `` | | classnames.js:17:48:17:64 | clsx(window.name) | classnames.js:17:32:17:79 | `` | | classnames.js:17:53:17:63 | window.name | classnames.js:17:48:17:64 | clsx(window.name) | -| classnames.js:17:53:17:63 | window.name | classnames.js:17:48:17:64 | clsx(window.name) | -| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | -| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | -| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | | clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | | clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:43:15:43:55 | html | clipboard.ts:50:29:50:32 | html | -| clipboard.ts:43:15:43:55 | html | clipboard.ts:50:29:50:32 | html | -| clipboard.ts:43:15:43:55 | html | clipboard.ts:50:29:50:32 | html | | clipboard.ts:43:15:43:55 | html | clipboard.ts:50:29:50:32 | html | | clipboard.ts:43:22:43:55 | clipboa ... /html') | clipboard.ts:43:15:43:55 | html | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | clipboard.ts:43:15:43:55 | html | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | clipboard.ts:43:15:43:55 | html | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | clipboard.ts:43:15:43:55 | html | -| clipboard.ts:71:13:71:62 | droppedHtml | clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:71:13:71:62 | droppedHtml | clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:71:13:71:62 | droppedHtml | clipboard.ts:73:29:73:39 | droppedHtml | | clipboard.ts:71:13:71:62 | droppedHtml | clipboard.ts:73:29:73:39 | droppedHtml | | clipboard.ts:71:27:71:62 | e.clipb ... /html') | clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:98:15:98:54 | html | clipboard.ts:99:23:99:26 | html | -| clipboard.ts:98:15:98:54 | html | clipboard.ts:99:23:99:26 | html | -| clipboard.ts:98:15:98:54 | html | clipboard.ts:99:23:99:26 | html | | clipboard.ts:98:15:98:54 | html | clipboard.ts:99:23:99:26 | html | | clipboard.ts:98:22:98:54 | dataTra ... /html') | clipboard.ts:98:15:98:54 | html | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | clipboard.ts:98:15:98:54 | html | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | clipboard.ts:98:15:98:54 | html | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | clipboard.ts:98:15:98:54 | html | -| custom-element.js:5:26:5:36 | window.name | custom-element.js:5:26:5:36 | window.name | -| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | | d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | | d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | | d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | | d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | | dates.js:9:9:9:69 | taint | dates.js:11:63:11:67 | taint | -| dates.js:9:9:9:69 | taint | dates.js:11:63:11:67 | taint | -| dates.js:9:9:9:69 | taint | dates.js:12:66:12:70 | taint | | dates.js:9:9:9:69 | taint | dates.js:12:66:12:70 | taint | | dates.js:9:9:9:69 | taint | dates.js:13:59:13:63 | taint | -| dates.js:9:9:9:69 | taint | dates.js:13:59:13:63 | taint | -| dates.js:9:9:9:69 | taint | dates.js:16:62:16:66 | taint | | dates.js:9:9:9:69 | taint | dates.js:16:62:16:66 | taint | | dates.js:9:9:9:69 | taint | dates.js:18:59:18:63 | taint | -| dates.js:9:9:9:69 | taint | dates.js:18:59:18:63 | taint | -| dates.js:9:9:9:69 | taint | dates.js:21:61:21:65 | taint | | dates.js:9:9:9:69 | taint | dates.js:21:61:21:65 | taint | | dates.js:9:17:9:69 | decodeU ... ing(1)) | dates.js:9:9:9:69 | taint | -| dates.js:9:17:9:69 | decodeU ... ing(1)) | dates.js:9:9:9:69 | taint | -| dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | -| dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | -| dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | | dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | | dates.js:9:36:9:68 | window. ... ring(1) | dates.js:9:17:9:69 | decodeU ... ing(1)) | -| dates.js:9:36:9:68 | window. ... ring(1) | dates.js:9:17:9:69 | decodeU ... ing(1)) | -| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | | dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | | dates.js:11:63:11:67 | taint | dates.js:11:42:11:68 | dateFns ... taint) | -| dates.js:11:63:11:67 | taint | dates.js:11:42:11:68 | dateFns ... taint) | -| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | | dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | | dates.js:12:66:12:70 | taint | dates.js:12:42:12:71 | dateFns ... taint) | -| dates.js:12:66:12:70 | taint | dates.js:12:42:12:71 | dateFns ... taint) | -| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | | dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | | dates.js:13:59:13:63 | taint | dates.js:13:42:13:70 | dateFns ... )(time) | -| dates.js:13:59:13:63 | taint | dates.js:13:42:13:70 | dateFns ... )(time) | -| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | | dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | | dates.js:16:62:16:66 | taint | dates.js:16:42:16:67 | moment( ... (taint) | -| dates.js:16:62:16:66 | taint | dates.js:16:42:16:67 | moment( ... (taint) | -| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | | dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | | dates.js:18:59:18:63 | taint | dates.js:18:42:18:64 | datefor ... taint) | -| dates.js:18:59:18:63 | taint | dates.js:18:42:18:64 | datefor ... taint) | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | | dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | | dates.js:21:61:21:65 | taint | dates.js:21:42:21:66 | dayjs(t ... (taint) | -| dates.js:21:61:21:65 | taint | dates.js:21:42:21:66 | dayjs(t ... (taint) | -| dates.js:30:9:30:69 | taint | dates.js:37:77:37:81 | taint | | dates.js:30:9:30:69 | taint | dates.js:37:77:37:81 | taint | | dates.js:30:9:30:69 | taint | dates.js:38:77:38:81 | taint | -| dates.js:30:9:30:69 | taint | dates.js:38:77:38:81 | taint | -| dates.js:30:9:30:69 | taint | dates.js:39:79:39:83 | taint | | dates.js:30:9:30:69 | taint | dates.js:39:79:39:83 | taint | | dates.js:30:9:30:69 | taint | dates.js:40:77:40:81 | taint | -| dates.js:30:9:30:69 | taint | dates.js:40:77:40:81 | taint | -| dates.js:30:17:30:69 | decodeU ... ing(1)) | dates.js:30:9:30:69 | taint | | dates.js:30:17:30:69 | decodeU ... ing(1)) | dates.js:30:9:30:69 | taint | | dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:30:36:30:68 | window. ... ring(1) | dates.js:30:17:30:69 | decodeU ... ing(1)) | | dates.js:30:36:30:68 | window. ... ring(1) | dates.js:30:17:30:69 | decodeU ... ing(1)) | | dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:77:37:81 | taint | dates.js:37:42:37:82 | dateFns ... taint) | | dates.js:37:77:37:81 | taint | dates.js:37:42:37:82 | dateFns ... taint) | | dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:77:38:81 | taint | dates.js:38:42:38:82 | luxon.f ... taint) | | dates.js:38:77:38:81 | taint | dates.js:38:42:38:82 | luxon.f ... taint) | | dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:79:39:83 | taint | dates.js:39:42:39:84 | moment. ... taint) | | dates.js:39:79:39:83 | taint | dates.js:39:42:39:84 | moment. ... taint) | | dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:77:40:81 | taint | dates.js:40:42:40:82 | dayjs.f ... taint) | | dates.js:40:77:40:81 | taint | dates.js:40:42:40:82 | dayjs.f ... taint) | | dates.js:46:9:46:69 | taint | dates.js:48:83:48:87 | taint | -| dates.js:46:9:46:69 | taint | dates.js:48:83:48:87 | taint | -| dates.js:46:9:46:69 | taint | dates.js:49:82:49:86 | taint | | dates.js:46:9:46:69 | taint | dates.js:49:82:49:86 | taint | | dates.js:46:9:46:69 | taint | dates.js:50:97:50:101 | taint | -| dates.js:46:9:46:69 | taint | dates.js:50:97:50:101 | taint | -| dates.js:46:17:46:69 | decodeU ... ing(1)) | dates.js:46:9:46:69 | taint | | dates.js:46:17:46:69 | decodeU ... ing(1)) | dates.js:46:9:46:69 | taint | | dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:46:36:46:68 | window. ... ring(1) | dates.js:46:17:46:69 | decodeU ... ing(1)) | | dates.js:46:36:46:68 | window. ... ring(1) | dates.js:46:17:46:69 | decodeU ... ing(1)) | | dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:83:48:87 | taint | dates.js:48:42:48:88 | DateTim ... (taint) | | dates.js:48:83:48:87 | taint | dates.js:48:42:48:88 | DateTim ... (taint) | | dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:82:49:86 | taint | dates.js:49:42:49:87 | new Dat ... (taint) | | dates.js:49:82:49:86 | taint | dates.js:49:42:49:87 | new Dat ... (taint) | | dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:97:50:101 | taint | dates.js:50:42:50:102 | DateTim ... (taint) | | dates.js:50:97:50:101 | taint | dates.js:50:42:50:102 | DateTim ... (taint) | | dates.js:54:9:54:69 | taint | dates.js:57:94:57:98 | taint | -| dates.js:54:9:54:69 | taint | dates.js:57:94:57:98 | taint | -| dates.js:54:9:54:69 | taint | dates.js:59:80:59:84 | taint | | dates.js:54:9:54:69 | taint | dates.js:59:80:59:84 | taint | | dates.js:54:9:54:69 | taint | dates.js:61:81:61:85 | taint | -| dates.js:54:9:54:69 | taint | dates.js:61:81:61:85 | taint | -| dates.js:54:17:54:69 | decodeU ... ing(1)) | dates.js:54:9:54:69 | taint | | dates.js:54:17:54:69 | decodeU ... ing(1)) | dates.js:54:9:54:69 | taint | | dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:54:36:54:68 | window. ... ring(1) | dates.js:54:17:54:69 | decodeU ... ing(1)) | | dates.js:54:36:54:68 | window. ... ring(1) | dates.js:54:17:54:69 | decodeU ... ing(1)) | | dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:94:57:98 | taint | dates.js:57:42:57:99 | moment. ... (taint) | | dates.js:57:94:57:98 | taint | dates.js:57:42:57:99 | moment. ... (taint) | | dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:80:59:84 | taint | dates.js:59:42:59:85 | luxon.e ... (taint) | | dates.js:59:80:59:84 | taint | dates.js:59:42:59:85 | luxon.e ... (taint) | | dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:81:61:85 | taint | dates.js:61:42:61:86 | dayjs.s ... (taint) | | dates.js:61:81:61:85 | taint | dates.js:61:42:61:86 | dayjs.s ... (taint) | | dragAndDrop.ts:8:11:8:50 | html | dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:8:11:8:50 | html | dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:8:11:8:50 | html | dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:8:11:8:50 | html | dragAndDrop.ts:15:25:15:28 | html | | dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:43:15:43:54 | html | dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:43:15:43:54 | html | dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:43:15:43:54 | html | dragAndDrop.ts:50:29:50:32 | html | | dragAndDrop.ts:43:15:43:54 | html | dragAndDrop.ts:50:29:50:32 | html | | dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:71:13:71:61 | droppedHtml | dragAndDrop.ts:73:29:73:39 | droppedHtml | -| dragAndDrop.ts:71:13:71:61 | droppedHtml | dragAndDrop.ts:73:29:73:39 | droppedHtml | -| dragAndDrop.ts:71:13:71:61 | droppedHtml | dragAndDrop.ts:73:29:73:39 | droppedHtml | | dragAndDrop.ts:71:13:71:61 | droppedHtml | dragAndDrop.ts:73:29:73:39 | droppedHtml | | dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | | event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | -| express.js:7:15:7:33 | req.param("wobble") | express.js:7:15:7:33 | req.param("wobble") | | jquery.js:2:7:2:40 | tainted | jquery.js:7:20:7:26 | tainted | | jquery.js:2:7:2:40 | tainted | jquery.js:8:28:8:34 | tainted | | jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | -| jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | | jquery.js:2:7:2:40 | tainted | jquery.js:37:31:37:37 | tainted | | jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | -| jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | -| jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "
" | | jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "
" | | jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | -| jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | -| jquery.js:10:13:10:20 | location | jquery.js:10:13:10:31 | location.toString() | | jquery.js:10:13:10:20 | location | jquery.js:10:13:10:31 | location.toString() | | jquery.js:10:13:10:31 | location.toString() | jquery.js:10:5:10:40 | "" + ... "" | -| jquery.js:10:13:10:31 | location.toString() | jquery.js:10:5:10:40 | "" + ... "" | | jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | -| jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | -| jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | | jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | | jquery.js:16:38:16:52 | window.location | jquery.js:16:38:16:63 | window. ... tring() | -| jquery.js:16:38:16:52 | window.location | jquery.js:16:38:16:63 | window. ... tring() | -| jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) | | jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) | | jquery.js:18:7:18:33 | hash | jquery.js:21:5:21:8 | hash | | jquery.js:18:7:18:33 | hash | jquery.js:22:5:22:8 | hash | @@ -1583,338 +745,145 @@ edges | jquery.js:18:7:18:33 | hash | jquery.js:27:5:27:8 | hash | | jquery.js:18:7:18:33 | hash | jquery.js:34:13:34:16 | hash | | jquery.js:18:14:18:33 | window.location.hash | jquery.js:18:7:18:33 | hash | -| jquery.js:18:14:18:33 | window.location.hash | jquery.js:18:7:18:33 | hash | -| jquery.js:21:5:21:8 | hash | jquery.js:21:5:21:21 | hash.substring(1) | -| jquery.js:21:5:21:8 | hash | jquery.js:21:5:21:21 | hash.substring(1) | | jquery.js:21:5:21:8 | hash | jquery.js:21:5:21:21 | hash.substring(1) | | jquery.js:22:5:22:8 | hash | jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:22:5:22:8 | hash | jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:22:5:22:8 | hash | jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:23:5:23:8 | hash | jquery.js:23:5:23:18 | hash.substr(1) | -| jquery.js:23:5:23:8 | hash | jquery.js:23:5:23:18 | hash.substr(1) | | jquery.js:23:5:23:8 | hash | jquery.js:23:5:23:18 | hash.substr(1) | | jquery.js:24:5:24:8 | hash | jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:24:5:24:8 | hash | jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:24:5:24:8 | hash | jquery.js:24:5:24:17 | hash.slice(1) | | jquery.js:27:5:27:8 | hash | jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:27:5:27:8 | hash | jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:27:5:27:8 | hash | jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | | jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | | jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '' + ... '' | -| jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '' + ... '' | -| jquery.js:37:31:37:37 | tainted | jquery.js:37:25:37:37 | () => tainted | | jquery.js:37:31:37:37 | tainted | jquery.js:37:25:37:37 | () => tainted | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:11:51:11:56 | locale | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:19:56:19:61 | locale | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:31:55:31:60 | locale | -| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:31:55:31:60 | locale | | json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | | json-stringify.jsx:11:51:11:56 | locale | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | | json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | -| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | | json-stringify.jsx:19:56:19:61 | locale | json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | | json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| jwt-server.js:7:9:7:35 | taint | jwt-server.js:9:16:9:20 | taint | | jwt-server.js:7:9:7:35 | taint | jwt-server.js:9:16:9:20 | taint | | jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:9:16:9:20 | taint | jwt-server.js:9:55:9:61 | decoded | | jwt-server.js:9:16:9:20 | taint | jwt-server.js:9:55:9:61 | decoded | | jwt-server.js:9:55:9:61 | decoded | jwt-server.js:11:19:11:25 | decoded | -| jwt-server.js:9:55:9:61 | decoded | jwt-server.js:11:19:11:25 | decoded | -| jwt-server.js:11:19:11:25 | decoded | jwt-server.js:11:19:11:29 | decoded.foo | -| jwt-server.js:11:19:11:25 | decoded | jwt-server.js:11:19:11:29 | decoded.foo | -| jwt-server.js:11:19:11:25 | decoded | jwt-server.js:11:19:11:29 | decoded.foo | | jwt-server.js:11:19:11:25 | decoded | jwt-server.js:11:19:11:29 | decoded.foo | | nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:6:18:6:23 | target | | optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:6:18:6:23 | target | | optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:8:17:8:22 | target | | optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:15:9:15:14 | target | | optionalSanitizer.js:2:16:2:39 | documen ... .search | optionalSanitizer.js:2:7:2:39 | target | -| optionalSanitizer.js:2:16:2:39 | documen ... .search | optionalSanitizer.js:2:7:2:39 | target | -| optionalSanitizer.js:8:7:8:22 | tainted | optionalSanitizer.js:9:18:9:24 | tainted | | optionalSanitizer.js:8:7:8:22 | tainted | optionalSanitizer.js:9:18:9:24 | tainted | | optionalSanitizer.js:8:17:8:22 | target | optionalSanitizer.js:8:7:8:22 | tainted | | optionalSanitizer.js:15:9:15:14 | target | optionalSanitizer.js:16:18:16:18 | x | | optionalSanitizer.js:16:18:16:18 | x | optionalSanitizer.js:17:20:17:20 | x | -| optionalSanitizer.js:16:18:16:18 | x | optionalSanitizer.js:17:20:17:20 | x | | optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:31:18:31:23 | target | | optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:38:18:38:23 | target | | optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:45:41:45:46 | target | | optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:45:51:45:56 | target | | optionalSanitizer.js:26:16:26:39 | documen ... .search | optionalSanitizer.js:26:7:26:39 | target | -| optionalSanitizer.js:26:16:26:39 | documen ... .search | optionalSanitizer.js:26:7:26:39 | target | -| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:32:18:32:25 | tainted2 | +| optionalSanitizer.js:28:24:28:24 | x | optionalSanitizer.js:29:12:29:12 | x | | optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:32:18:32:25 | tainted2 | | optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:34:28:34:35 | tainted2 | | optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 | -| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 | | optionalSanitizer.js:31:18:31:23 | target | optionalSanitizer.js:31:7:31:23 | tainted2 | | optionalSanitizer.js:34:5:34:36 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 | -| optionalSanitizer.js:34:5:34:36 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 | | optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | optionalSanitizer.js:34:5:34:36 | tainted2 | +| optionalSanitizer.js:34:28:34:35 | tainted2 | optionalSanitizer.js:28:24:28:24 | x | | optionalSanitizer.js:34:28:34:35 | tainted2 | optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | | optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:39:18:39:25 | tainted3 | -| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:39:18:39:25 | tainted3 | | optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:41:28:41:35 | tainted3 | | optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 | -| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 | | optionalSanitizer.js:38:18:38:23 | target | optionalSanitizer.js:38:7:38:23 | tainted3 | | optionalSanitizer.js:41:5:41:36 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 | -| optionalSanitizer.js:41:5:41:36 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 | | optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | optionalSanitizer.js:41:5:41:36 | tainted3 | +| optionalSanitizer.js:41:28:41:35 | tainted3 | optionalSanitizer.js:28:24:28:24 | x | | optionalSanitizer.js:41:28:41:35 | tainted3 | optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | | optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | +| optionalSanitizer.js:45:41:45:46 | target | optionalSanitizer.js:28:24:28:24 | x | | optionalSanitizer.js:45:41:45:46 | target | optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | | optionalSanitizer.js:45:51:45:56 | target | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| optionalSanitizer.js:45:51:45:56 | target | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| pages/[id].jsx:5:9:5:14 | { id } | pages/[id].jsx:5:11:5:12 | id | +| pages/[id].jsx:3:30:3:35 | params [id] | pages/[id].jsx:13:44:13:49 | params [id] | +| pages/[id].jsx:3:30:3:35 | params [q] | pages/[id].jsx:16:44:16:49 | params [q] | | pages/[id].jsx:5:9:5:14 | { id } | pages/[id].jsx:5:11:5:12 | id | | pages/[id].jsx:5:9:5:29 | id | pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:5:9:5:29 | id | pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:5:9:5:29 | id | pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:5:9:5:29 | id | pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:5:11:5:12 | id | pages/[id].jsx:5:9:5:29 | id | | pages/[id].jsx:5:11:5:12 | id | pages/[id].jsx:5:9:5:29 | id | | pages/[id].jsx:5:18:5:29 | router.query | pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:5:18:5:29 | router.query | pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:5:18:5:29 | router.query | pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:5:18:5:29 | router.query | pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:25:11:25:24 | context.params | pages/[id].jsx:25:11:25:27 | context.params.id | -| pages/[id].jsx:25:11:25:24 | context.params | pages/[id].jsx:25:11:25:27 | context.params.id | -| pages/[id].jsx:25:11:25:24 | context.params | pages/[id].jsx:25:11:25:27 | context.params.id | +| pages/[id].jsx:13:44:13:49 | params [id] | pages/[id].jsx:13:44:13:52 | params.id | +| pages/[id].jsx:16:44:16:49 | params [q] | pages/[id].jsx:16:44:16:51 | params.q | +| pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | pages/[id].jsx:3:30:3:35 | params [id] | +| pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | pages/[id].jsx:3:30:3:35 | params [q] | | pages/[id].jsx:25:11:25:24 | context.params | pages/[id].jsx:25:11:25:27 | context.params.id | | pages/[id].jsx:25:11:25:27 | context.params.id | pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | -| pages/[id].jsx:25:11:25:27 | context.params.id | pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:26:10:26:22 | context.query | pages/[id].jsx:26:10:26:30 | context ... .foobar | -| pages/[id].jsx:26:10:26:22 | context.query | pages/[id].jsx:26:10:26:30 | context ... .foobar | -| pages/[id].jsx:26:10:26:22 | context.query | pages/[id].jsx:26:10:26:30 | context ... .foobar | +| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | | pages/[id].jsx:26:10:26:22 | context.query | pages/[id].jsx:26:10:26:30 | context ... .foobar | | pages/[id].jsx:26:10:26:30 | context ... .foobar | pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | -| pages/[id].jsx:26:10:26:30 | context ... .foobar | pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | pages/[id].jsx:16:44:16:51 | params.q | -| react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted | +| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | | react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted | | react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted | | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | -| react-use-context.js:10:22:10:32 | window.name | react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:16:26:16:36 | window.name | react-use-context.js:16:26:16:36 | window.name | -| react-use-router.js:4:9:4:28 | router | react-use-router.js:8:21:8:26 | router | -| react-use-router.js:4:9:4:28 | router | react-use-router.js:11:24:11:29 | router | -| react-use-router.js:4:18:4:28 | useRouter() | react-use-router.js:4:9:4:28 | router | -| react-use-router.js:8:21:8:26 | router | react-use-router.js:8:21:8:32 | router.query | | react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:8:21:8:39 | router.query.foobar | react-use-router.js:4:18:4:28 | useRouter() | -| react-use-router.js:11:24:11:29 | router | react-use-router.js:11:24:11:35 | router.query | | react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:22:15:22:24 | router | react-use-router.js:23:43:23:48 | router | -| react-use-router.js:22:17:22:22 | router | react-use-router.js:22:15:22:24 | router | +| react-use-router.js:23:31:23:36 | [post update] router | react-use-router.js:23:43:23:48 | router | | react-use-router.js:23:43:23:48 | router | react-use-router.js:23:43:23:54 | router.query | | react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:22:17:22:22 | router | -| react-use-router.js:29:9:29:30 | router | react-use-router.js:33:21:33:26 | router | -| react-use-router.js:29:18:29:30 | myUseRouter() | react-use-router.js:29:9:29:30 | router | -| react-use-router.js:33:21:33:26 | router | react-use-router.js:33:21:33:32 | router.query | +| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:31:23:36 | [post update] router | | react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-router.js:33:21:33:39 | router.query.foobar | react-use-router.js:29:18:29:30 | myUseRouter() | -| react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | -| react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | -| react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | | react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | | react-use-state.js:4:10:4:14 | state | react-use-state.js:4:9:4:49 | state | -| react-use-state.js:4:10:4:14 | state | react-use-state.js:4:9:4:49 | state | | react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:10:4:14 | state | -| react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:10:4:14 | state | -| react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:10:4:14 | state | -| react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:10:4:14 | state | -| react-use-state.js:9:9:9:43 | state | react-use-state.js:11:51:11:55 | state | -| react-use-state.js:9:9:9:43 | state | react-use-state.js:11:51:11:55 | state | -| react-use-state.js:9:9:9:43 | state | react-use-state.js:11:51:11:55 | state | | react-use-state.js:9:9:9:43 | state | react-use-state.js:11:51:11:55 | state | | react-use-state.js:9:10:9:14 | state | react-use-state.js:9:9:9:43 | state | -| react-use-state.js:9:10:9:14 | state | react-use-state.js:9:9:9:43 | state | | react-use-state.js:10:14:10:24 | window.name | react-use-state.js:9:10:9:14 | state | -| react-use-state.js:10:14:10:24 | window.name | react-use-state.js:9:10:9:14 | state | -| react-use-state.js:10:14:10:24 | window.name | react-use-state.js:9:10:9:14 | state | -| react-use-state.js:10:14:10:24 | window.name | react-use-state.js:9:10:9:14 | state | -| react-use-state.js:15:9:15:43 | state | react-use-state.js:17:51:17:55 | state | -| react-use-state.js:15:9:15:43 | state | react-use-state.js:17:51:17:55 | state | -| react-use-state.js:15:9:15:43 | state | react-use-state.js:17:51:17:55 | state | | react-use-state.js:15:9:15:43 | state | react-use-state.js:17:51:17:55 | state | | react-use-state.js:15:10:15:14 | state | react-use-state.js:15:9:15:43 | state | -| react-use-state.js:15:10:15:14 | state | react-use-state.js:15:9:15:43 | state | -| react-use-state.js:16:20:16:30 | window.name | react-use-state.js:15:10:15:14 | state | -| react-use-state.js:16:20:16:30 | window.name | react-use-state.js:15:10:15:14 | state | -| react-use-state.js:16:20:16:30 | window.name | react-use-state.js:15:10:15:14 | state | | react-use-state.js:16:20:16:30 | window.name | react-use-state.js:15:10:15:14 | state | | react-use-state.js:21:10:21:14 | state | react-use-state.js:22:14:22:17 | prev | -| react-use-state.js:21:10:21:14 | state | react-use-state.js:22:14:22:17 | prev | | react-use-state.js:22:14:22:17 | prev | react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:22:14:22:17 | prev | react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:22:14:22:17 | prev | react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:22:14:22:17 | prev | react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:25:20:25:30 | window.name | react-use-state.js:21:10:21:14 | state | -| react-use-state.js:25:20:25:30 | window.name | react-use-state.js:21:10:21:14 | state | -| react-use-state.js:25:20:25:30 | window.name | react-use-state.js:21:10:21:14 | state | | react-use-state.js:25:20:25:30 | window.name | react-use-state.js:21:10:21:14 | state | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:23:29:23:35 | tainted | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:25:29:25:35 | tainted | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:28:29:28:35 | tainted | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:30:29:30:35 | tainted | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:33:29:33:35 | tainted | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:35:29:35:35 | tainted | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:38:29:38:35 | tainted | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:45:29:45:35 | tainted | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:48:19:48:25 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:48:19:48:25 | tainted | -| sanitiser.js:16:17:16:27 | window.name | sanitiser.js:16:7:16:27 | tainted | -| sanitiser.js:16:17:16:27 | window.name | sanitiser.js:16:7:16:27 | tainted | -| sanitiser.js:16:17:16:27 | window.name | sanitiser.js:16:7:16:27 | tainted | | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:16:7:16:27 | tainted | | sanitiser.js:23:29:23:35 | tainted | sanitiser.js:23:21:23:44 | '' + ... '' | -| sanitiser.js:23:29:23:35 | tainted | sanitiser.js:23:21:23:44 | '' + ... '' | -| sanitiser.js:30:29:30:35 | tainted | sanitiser.js:30:21:30:44 | '' + ... '' | +| sanitiser.js:25:29:25:35 | tainted | sanitiser.js:25:21:25:44 | '' + ... '' | +| sanitiser.js:28:29:28:35 | tainted | sanitiser.js:28:21:28:44 | '' + ... '' | | sanitiser.js:30:29:30:35 | tainted | sanitiser.js:30:21:30:44 | '' + ... '' | | sanitiser.js:33:29:33:35 | tainted | sanitiser.js:33:21:33:44 | '' + ... '' | -| sanitiser.js:33:29:33:35 | tainted | sanitiser.js:33:21:33:44 | '' + ... '' | -| sanitiser.js:38:29:38:35 | tainted | sanitiser.js:38:21:38:44 | '' + ... '' | +| sanitiser.js:35:29:35:35 | tainted | sanitiser.js:35:21:35:44 | '' + ... '' | | sanitiser.js:38:29:38:35 | tainted | sanitiser.js:38:21:38:44 | '' + ... '' | | sanitiser.js:45:29:45:35 | tainted | sanitiser.js:45:21:45:44 | '' + ... '' | -| sanitiser.js:45:29:45:35 | tainted | sanitiser.js:45:21:45:44 | '' + ... '' | -| sanitiser.js:48:19:48:25 | tainted | sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| sanitiser.js:48:19:48:25 | tainted | sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| sanitiser.js:48:19:48:25 | tainted | sanitiser.js:48:19:48:46 | tainted ... /g, '') | | sanitiser.js:48:19:48:25 | tainted | sanitiser.js:48:19:48:46 | tainted ... /g, '') | | stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | -| stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | -| stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | -| stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | | stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:10:16:10:44 | localSt ... local') | | stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:10:16:10:44 | localSt ... local') | | stored-xss.js:10:9:10:44 | href | stored-xss.js:12:35:12:38 | href | | stored-xss.js:10:16:10:44 | localSt ... local') | stored-xss.js:10:9:10:44 | href | | stored-xss.js:12:35:12:38 | href | stored-xss.js:12:20:12:54 | "" | -| stored-xss.js:12:35:12:38 | href | stored-xss.js:12:20:12:54 | "" | -| stored-xss.js:12:35:12:38 | href | stored-xss.js:12:20:12:54 | "" | -| string-manipulations.js:3:16:3:32 | document.location | string-manipulations.js:3:16:3:32 | document.location | -| string-manipulations.js:4:16:4:37 | documen ... on.href | string-manipulations.js:4:16:4:37 | documen ... on.href | -| string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | -| string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | -| string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | | string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | | string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | -| string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | -| string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | | string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | | string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | -| string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | -| string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | | string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | | string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | -| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | -| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | -| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | -| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | | tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | | tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source | -| tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source | -| tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source | | tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source | | translate.js:6:7:6:39 | target | translate.js:7:42:7:47 | target | | translate.js:6:16:6:39 | documen ... .search | translate.js:6:7:6:39 | target | -| translate.js:6:16:6:39 | documen ... .search | translate.js:6:7:6:39 | target | | translate.js:7:7:7:61 | searchParams | translate.js:9:27:9:38 | searchParams | | translate.js:7:22:7:61 | new URL ... ing(1)) | translate.js:7:7:7:61 | searchParams | | translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | -| translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | -| translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | | translate.js:7:42:7:60 | target.substring(1) | translate.js:7:22:7:61 | new URL ... ing(1)) | -| translate.js:7:42:7:60 | target.substring(1) | translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:7:42:7:60 | target.substring(1) | translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:7:42:7:60 | target.substring(1) | translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:7:42:7:60 | target.substring(1) | translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:7:42:7:60 | target.substring(1) | translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:7:42:7:60 | target.substring(1) | translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:9:27:9:38 | searchParams | translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:9:27:9:38 | searchParams | translate.js:9:27:9:50 | searchP ... 'term') | | translate.js:9:27:9:38 | searchParams | translate.js:9:27:9:50 | searchP ... 'term') | | trusted-types-lib.js:1:28:1:28 | x | trusted-types-lib.js:2:12:2:12 | x | -| trusted-types-lib.js:1:28:1:28 | x | trusted-types-lib.js:2:12:2:12 | x | -| trusted-types-lib.js:1:28:1:28 | x | trusted-types-lib.js:2:12:2:12 | x | -| trusted-types-lib.js:1:28:1:28 | x | trusted-types-lib.js:2:12:2:12 | x | -| trusted-types.js:3:62:3:62 | x | trusted-types.js:3:67:3:67 | x | -| trusted-types.js:3:62:3:62 | x | trusted-types.js:3:67:3:67 | x | -| trusted-types.js:3:62:3:62 | x | trusted-types.js:3:67:3:67 | x | | trusted-types.js:3:62:3:62 | x | trusted-types.js:3:67:3:67 | x | | trusted-types.js:4:20:4:30 | window.name | trusted-types.js:3:62:3:62 | x | -| trusted-types.js:4:20:4:30 | window.name | trusted-types.js:3:62:3:62 | x | -| trusted-types.js:4:20:4:30 | window.name | trusted-types.js:3:62:3:62 | x | -| trusted-types.js:4:20:4:30 | window.name | trusted-types.js:3:62:3:62 | x | -| trusted-types.js:13:20:13:30 | window.name | trusted-types-lib.js:1:28:1:28 | x | -| trusted-types.js:13:20:13:30 | window.name | trusted-types-lib.js:1:28:1:28 | x | -| trusted-types.js:13:20:13:30 | window.name | trusted-types-lib.js:1:28:1:28 | x | | trusted-types.js:13:20:13:30 | window.name | trusted-types-lib.js:1:28:1:28 | x | | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:4:25:4:28 | data | | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:5:26:5:29 | data | @@ -1923,179 +892,77 @@ edges | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:10:38:10:41 | data | | tst3.js:2:23:2:74 | decodeU ... str(1)) | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | | tst3.js:2:42:2:63 | window. ... .search | tst3.js:2:42:2:73 | window. ... bstr(1) | -| tst3.js:2:42:2:63 | window. ... .search | tst3.js:2:42:2:73 | window. ... bstr(1) | | tst3.js:2:42:2:73 | window. ... bstr(1) | tst3.js:2:23:2:74 | decodeU ... str(1)) | | tst3.js:4:25:4:28 | data | tst3.js:4:25:4:32 | data.src | -| tst3.js:4:25:4:28 | data | tst3.js:4:25:4:32 | data.src | -| tst3.js:5:26:5:29 | data | tst3.js:5:26:5:31 | data.p | | tst3.js:5:26:5:29 | data | tst3.js:5:26:5:31 | data.p | | tst3.js:7:32:7:35 | data | tst3.js:7:32:7:37 | data.p | -| tst3.js:7:32:7:35 | data | tst3.js:7:32:7:37 | data.p | -| tst3.js:9:37:9:40 | data | tst3.js:9:37:9:42 | data.p | | tst3.js:9:37:9:40 | data | tst3.js:9:37:9:42 | data.p | | tst3.js:10:38:10:41 | data | tst3.js:10:38:10:43 | data.p | -| tst3.js:10:38:10:41 | data | tst3.js:10:38:10:43 | data.p | -| tst.js:2:7:2:39 | target | tst.js:5:18:5:23 | target | | tst.js:2:7:2:39 | target | tst.js:5:18:5:23 | target | | tst.js:2:7:2:39 | target | tst.js:12:28:12:33 | target | | tst.js:2:7:2:39 | target | tst.js:20:42:20:47 | target | | tst.js:2:16:2:39 | documen ... .search | tst.js:2:7:2:39 | target | -| tst.js:2:16:2:39 | documen ... .search | tst.js:2:7:2:39 | target | -| tst.js:8:37:8:58 | documen ... on.href | tst.js:8:37:8:114 | documen ... t=")+8) | -| tst.js:8:37:8:58 | documen ... on.href | tst.js:8:37:8:114 | documen ... t=")+8) | -| tst.js:8:37:8:58 | documen ... on.href | tst.js:8:37:8:114 | documen ... t=")+8) | | tst.js:8:37:8:58 | documen ... on.href | tst.js:8:37:8:114 | documen ... t=")+8) | | tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:126 | "" | -| tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:126 | "" | -| tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:126 | "" | -| tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:126 | "" | -| tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:126 | "" | -| tst.js:12:28:12:33 | target | tst.js:12:5:12:42 | '
' | | tst.js:12:28:12:33 | target | tst.js:12:5:12:42 | '
' | | tst.js:17:7:17:56 | params | tst.js:18:18:18:23 | params | +| tst.js:17:16:17:43 | (new UR ... ation)) [searchParams] | tst.js:17:16:17:56 | (new UR ... hParams | | tst.js:17:16:17:56 | (new UR ... hParams | tst.js:17:7:17:56 | params | -| tst.js:17:25:17:41 | document.location | tst.js:17:16:17:56 | (new UR ... hParams | -| tst.js:17:25:17:41 | document.location | tst.js:17:16:17:56 | (new UR ... hParams | -| tst.js:17:25:17:41 | document.location | tst.js:18:18:18:35 | params.get('name') | -| tst.js:17:25:17:41 | document.location | tst.js:18:18:18:35 | params.get('name') | -| tst.js:17:25:17:41 | document.location | tst.js:18:18:18:35 | params.get('name') | -| tst.js:17:25:17:41 | document.location | tst.js:18:18:18:35 | params.get('name') | -| tst.js:18:18:18:23 | params | tst.js:18:18:18:35 | params.get('name') | -| tst.js:18:18:18:23 | params | tst.js:18:18:18:35 | params.get('name') | +| tst.js:17:17:17:42 | new URL ... cation) [searchParams] | tst.js:17:16:17:43 | (new UR ... ation)) [searchParams] | +| tst.js:17:25:17:41 | document.location | tst.js:17:17:17:42 | new URL ... cation) [searchParams] | | tst.js:18:18:18:23 | params | tst.js:18:18:18:35 | params.get('name') | | tst.js:20:7:20:61 | searchParams | tst.js:21:18:21:29 | searchParams | | tst.js:20:22:20:61 | new URL ... ing(1)) | tst.js:20:7:20:61 | searchParams | | tst.js:20:42:20:47 | target | tst.js:20:42:20:60 | target.substring(1) | -| tst.js:20:42:20:47 | target | tst.js:20:42:20:60 | target.substring(1) | -| tst.js:20:42:20:47 | target | tst.js:20:42:20:60 | target.substring(1) | | tst.js:20:42:20:60 | target.substring(1) | tst.js:20:22:20:61 | new URL ... ing(1)) | -| tst.js:20:42:20:60 | target.substring(1) | tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:20:42:20:60 | target.substring(1) | tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:20:42:20:60 | target.substring(1) | tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:20:42:20:60 | target.substring(1) | tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:20:42:20:60 | target.substring(1) | tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:20:42:20:60 | target.substring(1) | tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:21:18:21:29 | searchParams | tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:21:18:21:29 | searchParams | tst.js:21:18:21:41 | searchP ... 'name') | | tst.js:21:18:21:29 | searchParams | tst.js:21:18:21:41 | searchP ... 'name') | | tst.js:24:14:24:19 | target | tst.js:26:18:26:23 | target | -| tst.js:24:14:24:19 | target | tst.js:26:18:26:23 | target | -| tst.js:28:5:28:28 | documen ... .search | tst.js:24:14:24:19 | target | | tst.js:28:5:28:28 | documen ... .search | tst.js:24:14:24:19 | target | | tst.js:31:10:31:33 | documen ... .search | tst.js:34:16:34:20 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:34:16:34:20 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:34:16:34:20 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:34:16:34:20 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:58:26:58:30 | bar() | | tst.js:31:10:31:33 | documen ... .search | tst.js:58:26:58:30 | bar() | | tst.js:31:10:31:33 | documen ... .search | tst.js:68:16:68:20 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:68:16:68:20 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:68:16:68:20 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:68:16:68:20 | bar() | -| tst.js:40:20:40:43 | documen ... .search | tst.js:40:16:40:44 | baz(doc ... search) | -| tst.js:40:20:40:43 | documen ... .search | tst.js:40:16:40:44 | baz(doc ... search) | -| tst.js:40:20:40:43 | documen ... .search | tst.js:40:16:40:44 | baz(doc ... search) | +| tst.js:36:14:36:14 | x | tst.js:37:10:37:10 | x | +| tst.js:40:20:40:43 | documen ... .search | tst.js:36:14:36:14 | x | | tst.js:40:20:40:43 | documen ... .search | tst.js:40:16:40:44 | baz(doc ... search) | +| tst.js:42:15:42:15 | s | tst.js:43:20:43:20 | s | +| tst.js:43:20:43:20 | s | tst.js:43:10:43:31 | "
" ...
" | +| tst.js:46:21:46:44 | documen ... .search | tst.js:42:15:42:15 | s | | tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | +| tst.js:48:15:48:15 | s | tst.js:50:12:50:12 | s | +| tst.js:50:12:50:12 | s | tst.js:50:12:50:22 | s.substr(1) | +| tst.js:54:21:54:44 | documen ... .search | tst.js:48:15:48:15 | s | | tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | +| tst.js:56:21:56:44 | documen ... .search | tst.js:48:15:48:15 | s | | tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | +| tst.js:58:21:58:31 | chop(bar()) | tst.js:42:15:42:15 | s | | tst.js:58:21:58:31 | chop(bar()) | tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:21:58:31 | chop(bar()) | tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:21:58:31 | chop(bar()) | tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:21:58:31 | chop(bar()) | tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:21:58:31 | chop(bar()) | tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:26:58:30 | bar() | tst.js:58:21:58:31 | chop(bar()) | +| tst.js:58:26:58:30 | bar() | tst.js:48:15:48:15 | s | | tst.js:58:26:58:30 | bar() | tst.js:58:21:58:31 | chop(bar()) | | tst.js:60:34:60:34 | s | tst.js:62:18:62:18 | s | -| tst.js:60:34:60:34 | s | tst.js:62:18:62:18 | s | | tst.js:64:25:64:48 | documen ... .search | tst.js:60:34:60:34 | s | -| tst.js:64:25:64:48 | documen ... .search | tst.js:60:34:60:34 | s | -| tst.js:65:25:65:48 | documen ... .search | tst.js:60:34:60:34 | s | | tst.js:65:25:65:48 | documen ... .search | tst.js:60:34:60:34 | s | | tst.js:70:1:70:27 | [,docum ... search] | tst.js:70:46:70:46 | x | +| tst.js:70:1:70:27 | [,docum ... search] [1] | tst.js:70:46:70:46 | x | | tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] | -| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] | -| tst.js:70:3:70:26 | documen ... .search | tst.js:70:46:70:46 | x | -| tst.js:70:3:70:26 | documen ... .search | tst.js:70:46:70:46 | x | +| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] [1] | | tst.js:70:46:70:46 | x | tst.js:73:20:73:20 | x | -| tst.js:70:46:70:46 | x | tst.js:73:20:73:20 | x | -| tst.js:77:49:77:72 | documen ... .search | tst.js:77:49:77:72 | documen ... .search | -| tst.js:81:26:81:49 | documen ... .search | tst.js:81:26:81:49 | documen ... .search | -| tst.js:82:25:82:48 | documen ... .search | tst.js:82:25:82:48 | documen ... .search | -| tst.js:84:33:84:56 | documen ... .search | tst.js:84:33:84:56 | documen ... .search | -| tst.js:85:32:85:55 | documen ... .search | tst.js:85:32:85:55 | documen ... .search | -| tst.js:90:39:90:62 | documen ... .search | tst.js:90:39:90:62 | documen ... .search | -| tst.js:96:30:96:53 | documen ... .search | tst.js:96:30:96:53 | documen ... .search | -| tst.js:102:25:102:48 | documen ... .search | tst.js:102:25:102:48 | documen ... .search | -| tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | -| tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | -| tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | -| tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | -| tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | | tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | | tst.js:107:7:107:44 | v | tst.js:136:18:136:18 | v | -| tst.js:107:7:107:44 | v | tst.js:136:18:136:18 | v | -| tst.js:107:7:107:44 | v | tst.js:136:18:136:18 | v | -| tst.js:107:7:107:44 | v | tst.js:136:18:136:18 | v | -| tst.js:107:7:107:44 | v | tst.js:136:18:136:18 | v | -| tst.js:107:7:107:44 | v | tst.js:136:18:136:18 | v | | tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:44 | documen ... bstr(1) | tst.js:107:7:107:44 | v | -| tst.js:107:11:107:44 | documen ... bstr(1) | tst.js:107:7:107:44 | v | | tst.js:107:11:107:44 | documen ... bstr(1) | tst.js:107:7:107:44 | v | | tst.js:148:29:148:50 | window. ... .search | tst.js:151:29:151:29 | v | -| tst.js:148:29:148:50 | window. ... .search | tst.js:151:29:151:29 | v | -| tst.js:151:29:151:29 | v | tst.js:151:49:151:49 | v | | tst.js:151:29:151:29 | v | tst.js:151:49:151:49 | v | | tst.js:158:40:158:61 | window. ... .search | tst.js:155:29:155:46 | xssSourceService() | -| tst.js:158:40:158:61 | window. ... .search | tst.js:155:29:155:46 | xssSourceService() | -| tst.js:158:40:158:61 | window. ... .search | tst.js:155:29:155:46 | xssSourceService() | -| tst.js:158:40:158:61 | window. ... .search | tst.js:155:29:155:46 | xssSourceService() | -| tst.js:177:9:177:41 | target | tst.js:180:28:180:33 | target | | tst.js:177:9:177:41 | target | tst.js:180:28:180:33 | target | | tst.js:177:18:177:41 | documen ... .search | tst.js:177:9:177:41 | target | -| tst.js:177:18:177:41 | documen ... .search | tst.js:177:9:177:41 | target | -| tst.js:184:9:184:42 | tainted | tst.js:186:31:186:37 | tainted | | tst.js:184:9:184:42 | tainted | tst.js:186:31:186:37 | tainted | | tst.js:184:9:184:42 | tainted | tst.js:188:42:188:48 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:188:42:188:48 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:189:33:189:39 | tainted | | tst.js:184:9:184:42 | tainted | tst.js:189:33:189:39 | tainted | | tst.js:184:9:184:42 | tainted | tst.js:191:54:191:60 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:191:54:191:60 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:192:45:192:51 | tainted | | tst.js:184:9:184:42 | tainted | tst.js:192:45:192:51 | tainted | | tst.js:184:9:184:42 | tainted | tst.js:193:49:193:55 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:193:49:193:55 | tainted | -| tst.js:184:19:184:42 | documen ... .search | tst.js:184:9:184:42 | tainted | | tst.js:184:19:184:42 | documen ... .search | tst.js:184:9:184:42 | tainted | | tst.js:197:9:197:42 | tainted | tst.js:199:67:199:73 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:199:67:199:73 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:200:67:200:73 | tainted | | tst.js:197:9:197:42 | tainted | tst.js:200:67:200:73 | tainted | | tst.js:197:9:197:42 | tainted | tst.js:204:35:204:41 | tainted | | tst.js:197:9:197:42 | tainted | tst.js:206:46:206:52 | tainted | @@ -2107,203 +974,101 @@ edges | tst.js:197:9:197:42 | tainted | tst.js:241:23:241:29 | tainted | | tst.js:197:9:197:42 | tainted | tst.js:255:23:255:29 | tainted | | tst.js:197:19:197:42 | documen ... .search | tst.js:197:9:197:42 | tainted | -| tst.js:197:19:197:42 | documen ... .search | tst.js:197:9:197:42 | tainted | -| tst.js:204:35:204:41 | tainted | tst.js:212:28:212:46 | this.state.tainted1 | | tst.js:204:35:204:41 | tainted | tst.js:212:28:212:46 | this.state.tainted1 | | tst.js:206:46:206:52 | tainted | tst.js:213:28:213:46 | this.state.tainted2 | -| tst.js:206:46:206:52 | tainted | tst.js:213:28:213:46 | this.state.tainted2 | -| tst.js:207:38:207:44 | tainted | tst.js:214:28:214:46 | this.state.tainted3 | | tst.js:207:38:207:44 | tainted | tst.js:214:28:214:46 | this.state.tainted3 | | tst.js:208:35:208:41 | tainted | tst.js:218:32:218:49 | prevState.tainted4 | -| tst.js:208:35:208:41 | tainted | tst.js:218:32:218:49 | prevState.tainted4 | -| tst.js:236:35:236:41 | tainted | tst.js:225:28:225:46 | this.props.tainted1 | | tst.js:236:35:236:41 | tainted | tst.js:225:28:225:46 | this.props.tainted1 | | tst.js:238:20:238:26 | tainted | tst.js:226:28:226:46 | this.props.tainted2 | -| tst.js:238:20:238:26 | tainted | tst.js:226:28:226:46 | this.props.tainted2 | -| tst.js:240:23:240:29 | tainted | tst.js:227:28:227:46 | this.props.tainted3 | | tst.js:240:23:240:29 | tainted | tst.js:227:28:227:46 | this.props.tainted3 | | tst.js:241:23:241:29 | tainted | tst.js:231:32:231:49 | prevProps.tainted4 | -| tst.js:241:23:241:29 | tainted | tst.js:231:32:231:49 | prevProps.tainted4 | -| tst.js:247:39:247:55 | props.propTainted | tst.js:251:60:251:82 | this.st ... Tainted | | tst.js:247:39:247:55 | props.propTainted | tst.js:251:60:251:82 | this.st ... Tainted | | tst.js:255:23:255:29 | tainted | tst.js:247:39:247:55 | props.propTainted | -| tst.js:259:7:259:17 | window.name | tst.js:259:7:259:17 | window.name | -| tst.js:260:7:260:10 | name | tst.js:260:7:260:10 | name | -| tst.js:264:11:264:21 | window.name | tst.js:264:11:264:21 | window.name | -| tst.js:280:22:280:29 | location | tst.js:280:22:280:29 | location | | tst.js:285:9:285:29 | tainted | tst.js:288:59:288:65 | tainted | -| tst.js:285:9:285:29 | tainted | tst.js:288:59:288:65 | tainted | -| tst.js:285:9:285:29 | tainted | tst.js:288:59:288:65 | tainted | -| tst.js:285:9:285:29 | tainted | tst.js:288:59:288:65 | tainted | -| tst.js:285:19:285:29 | window.name | tst.js:285:9:285:29 | tainted | -| tst.js:285:19:285:29 | window.name | tst.js:285:9:285:29 | tainted | -| tst.js:285:19:285:29 | window.name | tst.js:285:9:285:29 | tainted | | tst.js:285:19:285:29 | window.name | tst.js:285:9:285:29 | tainted | | tst.js:301:9:301:16 | location | tst.js:302:10:302:10 | e | -| tst.js:301:9:301:16 | location | tst.js:302:10:302:10 | e | -| tst.js:302:10:302:10 | e | tst.js:303:20:303:20 | e | | tst.js:302:10:302:10 | e | tst.js:303:20:303:20 | e | | tst.js:308:10:308:17 | location | tst.js:310:10:310:10 | e | -| tst.js:308:10:308:17 | location | tst.js:310:10:310:10 | e | | tst.js:310:10:310:10 | e | tst.js:311:20:311:20 | e | -| tst.js:310:10:310:10 | e | tst.js:311:20:311:20 | e | -| tst.js:316:35:316:42 | location | tst.js:316:35:316:42 | location | -| tst.js:327:18:327:34 | document.location | tst.js:331:16:331:43 | getTain ... hParams | -| tst.js:327:18:327:34 | document.location | tst.js:331:16:331:43 | getTain ... hParams | -| tst.js:327:18:327:34 | document.location | tst.js:332:18:332:35 | params.get('name') | -| tst.js:327:18:327:34 | document.location | tst.js:332:18:332:35 | params.get('name') | -| tst.js:327:18:327:34 | document.location | tst.js:332:18:332:35 | params.get('name') | -| tst.js:327:18:327:34 | document.location | tst.js:332:18:332:35 | params.get('name') | +| tst.js:327:10:327:35 | new URL ... cation) [searchParams] | tst.js:331:16:331:30 | getTaintedUrl() [searchParams] | +| tst.js:327:18:327:34 | document.location | tst.js:327:10:327:35 | new URL ... cation) [searchParams] | | tst.js:331:7:331:43 | params | tst.js:332:18:332:23 | params | +| tst.js:331:16:331:30 | getTaintedUrl() [searchParams] | tst.js:331:16:331:43 | getTain ... hParams | | tst.js:331:16:331:43 | getTain ... hParams | tst.js:331:7:331:43 | params | | tst.js:332:18:332:23 | params | tst.js:332:18:332:35 | params.get('name') | -| tst.js:332:18:332:23 | params | tst.js:332:18:332:35 | params.get('name') | -| tst.js:332:18:332:23 | params | tst.js:332:18:332:35 | params.get('name') | -| tst.js:341:20:341:36 | document.location | tst.js:343:5:343:17 | getUrl().hash | -| tst.js:341:20:341:36 | document.location | tst.js:343:5:343:17 | getUrl().hash | -| tst.js:343:5:343:17 | getUrl().hash | tst.js:343:5:343:30 | getUrl( ... ring(1) | -| tst.js:343:5:343:17 | getUrl().hash | tst.js:343:5:343:30 | getUrl( ... ring(1) | +| tst.js:341:12:341:37 | new URL ... cation) [hash] | tst.js:343:5:343:12 | getUrl() [hash] | +| tst.js:341:20:341:36 | document.location | tst.js:341:12:341:37 | new URL ... cation) [hash] | +| tst.js:343:5:343:12 | getUrl() [hash] | tst.js:343:5:343:17 | getUrl().hash | | tst.js:343:5:343:17 | getUrl().hash | tst.js:343:5:343:30 | getUrl( ... ring(1) | | tst.js:348:7:348:39 | target | tst.js:349:12:349:17 | target | -| tst.js:348:7:348:39 | target | tst.js:349:12:349:17 | target | -| tst.js:348:16:348:39 | documen ... .search | tst.js:348:7:348:39 | target | | tst.js:348:16:348:39 | documen ... .search | tst.js:348:7:348:39 | target | | tst.js:355:10:355:42 | target | tst.js:356:16:356:21 | target | -| tst.js:355:10:355:42 | target | tst.js:356:16:356:21 | target | -| tst.js:355:10:355:42 | target | tst.js:360:21:360:26 | target | | tst.js:355:10:355:42 | target | tst.js:360:21:360:26 | target | | tst.js:355:10:355:42 | target | tst.js:363:18:363:23 | target | -| tst.js:355:10:355:42 | target | tst.js:363:18:363:23 | target | -| tst.js:355:19:355:42 | documen ... .search | tst.js:355:10:355:42 | target | | tst.js:355:19:355:42 | documen ... .search | tst.js:355:10:355:42 | target | | tst.js:371:7:371:39 | target | tst.js:374:18:374:23 | target | -| tst.js:371:7:371:39 | target | tst.js:374:18:374:23 | target | | tst.js:371:16:371:39 | documen ... .search | tst.js:371:7:371:39 | target | -| tst.js:371:16:371:39 | documen ... .search | tst.js:371:7:371:39 | target | -| tst.js:381:7:381:39 | target | tst.js:384:18:384:23 | target | | tst.js:381:7:381:39 | target | tst.js:384:18:384:23 | target | | tst.js:381:7:381:39 | target | tst.js:386:18:386:23 | target | | tst.js:381:7:381:39 | target | tst.js:397:18:397:23 | target | | tst.js:381:7:381:39 | target | tst.js:406:18:406:23 | target | | tst.js:381:7:381:39 | target | tst.js:408:19:408:24 | target | -| tst.js:381:16:381:39 | documen ... .search | tst.js:381:7:381:39 | target | +| tst.js:381:7:381:39 | target [taint3] | tst.js:392:18:392:23 | target [taint3] | +| tst.js:381:7:381:39 | target [taint8] | tst.js:408:19:408:24 | target [taint8] | +| tst.js:381:7:381:39 | target [taint8] | tst.js:409:18:409:23 | target [taint8] | | tst.js:381:16:381:39 | documen ... .search | tst.js:381:7:381:39 | target | | tst.js:386:18:386:23 | target | tst.js:386:18:386:29 | target.taint | -| tst.js:386:18:386:23 | target | tst.js:386:18:386:29 | target.taint | -| tst.js:391:19:391:42 | documen ... .search | tst.js:392:18:392:30 | target.taint3 | -| tst.js:391:19:391:42 | documen ... .search | tst.js:392:18:392:30 | target.taint3 | -| tst.js:391:19:391:42 | documen ... .search | tst.js:392:18:392:30 | target.taint3 | -| tst.js:391:19:391:42 | documen ... .search | tst.js:392:18:392:30 | target.taint3 | -| tst.js:397:18:397:23 | target | tst.js:397:18:397:30 | target.taint5 | +| tst.js:391:3:391:8 | [post update] target [taint3] | tst.js:381:7:381:39 | target [taint3] | +| tst.js:391:19:391:42 | documen ... .search | tst.js:391:3:391:8 | [post update] target [taint3] | +| tst.js:392:18:392:23 | target [taint3] | tst.js:392:18:392:30 | target.taint3 | | tst.js:397:18:397:23 | target | tst.js:397:18:397:30 | target.taint5 | | tst.js:406:18:406:23 | target | tst.js:406:18:406:30 | target.taint7 | -| tst.js:406:18:406:23 | target | tst.js:406:18:406:30 | target.taint7 | +| tst.js:408:3:408:8 | [post update] target [taint8] | tst.js:381:7:381:39 | target [taint8] | | tst.js:408:19:408:24 | target | tst.js:408:19:408:31 | target.taint8 | -| tst.js:408:19:408:31 | target.taint8 | tst.js:408:19:408:31 | target.taint8 | -| tst.js:408:19:408:31 | target.taint8 | tst.js:409:18:409:30 | target.taint8 | -| tst.js:408:19:408:31 | target.taint8 | tst.js:409:18:409:30 | target.taint8 | -| tst.js:416:7:416:46 | payload | tst.js:417:18:417:24 | payload | -| tst.js:416:7:416:46 | payload | tst.js:417:18:417:24 | payload | -| tst.js:416:7:416:46 | payload | tst.js:417:18:417:24 | payload | -| tst.js:416:7:416:46 | payload | tst.js:417:18:417:24 | payload | -| tst.js:416:7:416:46 | payload | tst.js:417:18:417:24 | payload | +| tst.js:408:19:408:24 | target [taint8] | tst.js:408:19:408:31 | target.taint8 | +| tst.js:408:19:408:31 | target.taint8 | tst.js:408:3:408:8 | [post update] target [taint8] | +| tst.js:409:18:409:23 | target [taint8] | tst.js:409:18:409:30 | target.taint8 | | tst.js:416:7:416:46 | payload | tst.js:417:18:417:24 | payload | | tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:46 | window. ... bstr(1) | tst.js:416:7:416:46 | payload | -| tst.js:416:17:416:46 | window. ... bstr(1) | tst.js:416:7:416:46 | payload | | tst.js:416:17:416:46 | window. ... bstr(1) | tst.js:416:7:416:46 | payload | | tst.js:419:7:419:55 | match | tst.js:421:20:421:24 | match | | tst.js:419:15:419:34 | window.location.hash | tst.js:419:15:419:55 | window. ... (\\w+)/) | -| tst.js:419:15:419:34 | window.location.hash | tst.js:419:15:419:55 | window. ... (\\w+)/) | | tst.js:419:15:419:55 | window. ... (\\w+)/) | tst.js:419:7:419:55 | match | | tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | -| tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | | tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | | tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | | tst.js:428:7:428:39 | target | tst.js:430:18:430:23 | target | | tst.js:428:16:428:39 | documen ... .search | tst.js:428:7:428:39 | target | -| tst.js:428:16:428:39 | documen ... .search | tst.js:428:7:428:39 | target | -| tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | | tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | | tst.js:436:6:436:38 | source | tst.js:440:28:440:33 | source | -| tst.js:436:6:436:38 | source | tst.js:440:28:440:33 | source | -| tst.js:436:6:436:38 | source | tst.js:441:33:441:38 | source | | tst.js:436:6:436:38 | source | tst.js:441:33:441:38 | source | | tst.js:436:6:436:38 | source | tst.js:442:34:442:39 | source | -| tst.js:436:6:436:38 | source | tst.js:442:34:442:39 | source | -| tst.js:436:6:436:38 | source | tst.js:443:41:443:46 | source | | tst.js:436:6:436:38 | source | tst.js:443:41:443:46 | source | | tst.js:436:6:436:38 | source | tst.js:444:44:444:49 | source | -| tst.js:436:6:436:38 | source | tst.js:444:44:444:49 | source | -| tst.js:436:6:436:38 | source | tst.js:445:32:445:37 | source | | tst.js:436:6:436:38 | source | tst.js:445:32:445:37 | source | | tst.js:436:15:436:38 | documen ... .search | tst.js:436:6:436:38 | source | -| tst.js:436:15:436:38 | documen ... .search | tst.js:436:6:436:38 | source | -| tst.js:453:7:453:39 | source | tst.js:455:18:455:23 | source | | tst.js:453:7:453:39 | source | tst.js:455:18:455:23 | source | | tst.js:453:7:453:39 | source | tst.js:456:36:456:41 | source | | tst.js:453:16:453:39 | documen ... .search | tst.js:453:7:453:39 | source | -| tst.js:453:16:453:39 | documen ... .search | tst.js:453:7:453:39 | source | -| tst.js:456:36:456:41 | source | tst.js:456:18:456:42 | ansiToH ... source) | | tst.js:456:36:456:41 | source | tst.js:456:18:456:42 | ansiToH ... source) | | tst.js:460:6:460:38 | source | tst.js:463:21:463:26 | source | -| tst.js:460:6:460:38 | source | tst.js:463:21:463:26 | source | -| tst.js:460:6:460:38 | source | tst.js:465:19:465:24 | source | | tst.js:460:6:460:38 | source | tst.js:465:19:465:24 | source | | tst.js:460:6:460:38 | source | tst.js:467:20:467:25 | source | -| tst.js:460:6:460:38 | source | tst.js:467:20:467:25 | source | -| tst.js:460:15:460:38 | documen ... .search | tst.js:460:6:460:38 | source | | tst.js:460:15:460:38 | documen ... .search | tst.js:460:6:460:38 | source | | tst.js:471:7:471:46 | url | tst.js:473:19:473:21 | url | -| tst.js:471:7:471:46 | url | tst.js:473:19:473:21 | url | -| tst.js:471:7:471:46 | url | tst.js:474:26:474:28 | url | | tst.js:471:7:471:46 | url | tst.js:474:26:474:28 | url | | tst.js:471:7:471:46 | url | tst.js:475:25:475:27 | url | -| tst.js:471:7:471:46 | url | tst.js:475:25:475:27 | url | -| tst.js:471:7:471:46 | url | tst.js:476:20:476:22 | url | | tst.js:471:7:471:46 | url | tst.js:476:20:476:22 | url | | tst.js:471:7:471:46 | url | tst.js:486:22:486:24 | url | -| tst.js:471:7:471:46 | url | tst.js:486:22:486:24 | url | -| tst.js:471:13:471:36 | documen ... .search | tst.js:471:13:471:46 | documen ... bstr(1) | | tst.js:471:13:471:36 | documen ... .search | tst.js:471:13:471:46 | documen ... bstr(1) | | tst.js:471:13:471:46 | documen ... bstr(1) | tst.js:471:7:471:46 | url | | tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | | tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | -| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | -| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | -| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | -| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | -| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | -| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | | tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | | typeahead.js:20:13:20:45 | target | typeahead.js:21:12:21:17 | target | | typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target | -| typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target | | typeahead.js:21:12:21:17 | target | typeahead.js:24:30:24:32 | val | | typeahead.js:24:30:24:32 | val | typeahead.js:25:18:25:20 | val | -| typeahead.js:24:30:24:32 | val | typeahead.js:25:18:25:20 | val | -| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | -| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | -| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | -| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | | various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:4:14:4:20 | tainted | | various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:5:12:5:18 | tainted | | various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:6:19:6:25 | tainted | @@ -2313,56 +1078,52 @@ edges | various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:11:24:11:30 | tainted | | various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:12:19:12:25 | tainted | | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:2:6:2:39 | tainted | -| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:2:6:2:39 | tainted | -| various-concat-obfuscations.js:4:14:4:20 | tainted | various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | | various-concat-obfuscations.js:4:14:4:20 | tainted | various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | | various-concat-obfuscations.js:5:12:5:18 | tainted | various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | -| various-concat-obfuscations.js:5:12:5:18 | tainted | various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | -| various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | | various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | | various-concat-obfuscations.js:6:19:6:25 | tainted | various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | | various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | -| various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | | various-concat-obfuscations.js:7:14:7:20 | tainted | various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | | various-concat-obfuscations.js:9:19:9:25 | tainted | various-concat-obfuscations.js:9:4:9:34 | "
" | -| various-concat-obfuscations.js:9:19:9:25 | tainted | various-concat-obfuscations.js:9:4:9:34 | "
" | | various-concat-obfuscations.js:10:16:10:22 | tainted | various-concat-obfuscations.js:10:4:10:27 | `
` | -| various-concat-obfuscations.js:10:16:10:22 | tainted | various-concat-obfuscations.js:10:4:10:27 | `
` | -| various-concat-obfuscations.js:11:4:11:31 | "
") | | various-concat-obfuscations.js:11:4:11:31 | "
") | | various-concat-obfuscations.js:11:24:11:30 | tainted | various-concat-obfuscations.js:11:4:11:31 | "
"] | various-concat-obfuscations.js:12:4:12:41 | ["
"] | various-concat-obfuscations.js:12:4:12:41 | ["
"] | +| various-concat-obfuscations.js:14:24:14:28 | attrs | various-concat-obfuscations.js:15:28:15:32 | attrs | +| various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | various-concat-obfuscations.js:15:10:15:83 | '
' | +| various-concat-obfuscations.js:15:28:15:32 | attrs | various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | +| various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | +| various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:32:18:36 | attrs | +| various-concat-obfuscations.js:18:10:18:59 | '
') | +| various-concat-obfuscations.js:18:10:18:88 | '
') | +| various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | +| various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | +| various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | various-concat-obfuscations.js:18:10:18:59 | '
" ...
" | tst.js:46:16:46:45 | wrap(do ... search) | +| tst.js:54:21:54:44 | documen ... .search | tst.js:48:15:48:15 | s | tst.js:50:12:50:22 | s.substr(1) | tst.js:54:16:54:45 | chop(do ... search) | +| tst.js:56:21:56:44 | documen ... .search | tst.js:48:15:48:15 | s | tst.js:50:12:50:22 | s.substr(1) | tst.js:56:16:56:45 | chop(do ... search) | +| tst.js:58:21:58:31 | chop(bar()) | tst.js:42:15:42:15 | s | tst.js:43:10:43:31 | "
" ...
" | tst.js:58:16:58:32 | wrap(chop(bar())) | +| tst.js:58:26:58:30 | bar() | tst.js:48:15:48:15 | s | tst.js:50:12:50:22 | s.substr(1) | tst.js:58:21:58:31 | chop(bar()) | +| various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:14:24:14:28 | attrs | various-concat-obfuscations.js:15:10:15:83 | '
' | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) | +| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:10:18:105 | '
') | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | #select | addEventListener.js:2:20:2:29 | event.data | addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:29 | event.data | Cross-site scripting vulnerability due to $@. | addEventListener.js:1:43:1:47 | event | user-provided value | | addEventListener.js:6:20:6:23 | data | addEventListener.js:5:43:5:48 | {data} | addEventListener.js:6:20:6:23 | data | Cross-site scripting vulnerability due to $@. | addEventListener.js:5:43:5:48 | {data} | user-provided value | @@ -2459,7 +1220,6 @@ edges | react-use-context.js:10:22:10:32 | window.name | react-use-context.js:10:22:10:32 | window.name | react-use-context.js:10:22:10:32 | window.name | Cross-site scripting vulnerability due to $@. | react-use-context.js:10:22:10:32 | window.name | user-provided value | | react-use-context.js:16:26:16:36 | window.name | react-use-context.js:16:26:16:36 | window.name | react-use-context.js:16:26:16:36 | window.name | Cross-site scripting vulnerability due to $@. | react-use-context.js:16:26:16:36 | window.name | user-provided value | | react-use-router.js:8:21:8:39 | router.query.foobar | react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | Cross-site scripting vulnerability due to $@. | react-use-router.js:8:21:8:32 | router.query | user-provided value | -| react-use-router.js:11:24:11:42 | router.query.foobar | react-use-router.js:8:21:8:32 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | Cross-site scripting vulnerability due to $@. | react-use-router.js:8:21:8:32 | router.query | user-provided value | | react-use-router.js:11:24:11:42 | router.query.foobar | react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | Cross-site scripting vulnerability due to $@. | react-use-router.js:11:24:11:35 | router.query | user-provided value | | react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | Cross-site scripting vulnerability due to $@. | react-use-router.js:23:43:23:54 | router.query | user-provided value | | react-use-router.js:33:21:33:39 | router.query.foobar | react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | Cross-site scripting vulnerability due to $@. | react-use-router.js:33:21:33:32 | router.query | user-provided value | @@ -2468,8 +1228,11 @@ edges | react-use-state.js:17:51:17:55 | state | react-use-state.js:16:20:16:30 | window.name | react-use-state.js:17:51:17:55 | state | Cross-site scripting vulnerability due to $@. | react-use-state.js:16:20:16:30 | window.name | user-provided value | | react-use-state.js:23:35:23:38 | prev | react-use-state.js:25:20:25:30 | window.name | react-use-state.js:23:35:23:38 | prev | Cross-site scripting vulnerability due to $@. | react-use-state.js:25:20:25:30 | window.name | user-provided value | | sanitiser.js:23:21:23:44 | '' + ... '' | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:23:21:23:44 | '' + ... '' | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | +| sanitiser.js:25:21:25:44 | '' + ... '' | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:25:21:25:44 | '' + ... '' | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | +| sanitiser.js:28:21:28:44 | '' + ... '' | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:28:21:28:44 | '' + ... '' | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | | sanitiser.js:30:21:30:44 | '' + ... '' | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:30:21:30:44 | '' + ... '' | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | | sanitiser.js:33:21:33:44 | '' + ... '' | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:33:21:33:44 | '' + ... '' | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | +| sanitiser.js:35:21:35:44 | '' + ... '' | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:35:21:35:44 | '' + ... '' | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | | sanitiser.js:38:21:38:44 | '' + ... '' | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:38:21:38:44 | '' + ... '' | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | | sanitiser.js:45:21:45:44 | '' + ... '' | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:45:21:45:44 | '' + ... '' | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | | sanitiser.js:48:19:48:46 | tainted ... /g, '') | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:48:19:48:46 | tainted ... /g, '') | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | @@ -2585,7 +1348,6 @@ edges | tst.js:494:18:494:40 | locatio ... bstr(1) | tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | Cross-site scripting vulnerability due to $@. | tst.js:494:18:494:30 | location.hash | user-provided value | | tst.js:501:33:501:63 | decodeU ... n.hash) | tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | Cross-site scripting vulnerability due to $@. | tst.js:501:43:501:62 | window.location.hash | user-provided value | | typeahead.js:25:18:25:20 | val | typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:25:18:25:20 | val | Cross-site scripting vulnerability due to $@. | typeahead.js:20:22:20:45 | documen ... .search | user-provided value | -| v-html.vue:2:8:2:23 | v-html=tainted | v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | Cross-site scripting vulnerability due to $@. | v-html.vue:6:42:6:58 | document.location | user-provided value | | various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | user-provided value | | various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | user-provided value | | various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index 3edc5412c5b..f2ffc738451 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -1,1630 +1,763 @@ nodes -| addEventListener.js:1:43:1:47 | event | -| addEventListener.js:1:43:1:47 | event | -| addEventListener.js:1:43:1:47 | event | -| addEventListener.js:2:20:2:24 | event | -| addEventListener.js:2:20:2:24 | event | -| addEventListener.js:2:20:2:29 | event.data | -| addEventListener.js:2:20:2:29 | event.data | -| addEventListener.js:2:20:2:29 | event.data | -| addEventListener.js:5:43:5:48 | data | -| addEventListener.js:5:43:5:48 | data | -| addEventListener.js:5:43:5:48 | {data} | -| addEventListener.js:5:43:5:48 | {data} | -| addEventListener.js:5:43:5:48 | {data} | -| addEventListener.js:5:44:5:47 | data | -| addEventListener.js:5:44:5:47 | data | -| addEventListener.js:6:20:6:23 | data | -| addEventListener.js:6:20:6:23 | data | -| addEventListener.js:6:20:6:23 | data | -| addEventListener.js:10:21:10:25 | event | -| addEventListener.js:10:21:10:25 | event | -| addEventListener.js:10:21:10:25 | event | -| addEventListener.js:12:24:12:28 | event | -| addEventListener.js:12:24:12:28 | event | -| addEventListener.js:12:24:12:33 | event.data | -| addEventListener.js:12:24:12:33 | event.data | -| addEventListener.js:12:24:12:33 | event.data | -| angular2-client.ts:22:44:22:71 | \\u0275getDOM ... ().href | -| angular2-client.ts:22:44:22:71 | \\u0275getDOM ... ().href | -| angular2-client.ts:22:44:22:71 | \\u0275getDOM ... ().href | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | -| angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | -| angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:26:44:26:71 | this.ro ... ragment | -| angular2-client.ts:26:44:26:71 | this.ro ... ragment | -| angular2-client.ts:26:44:26:71 | this.ro ... ragment | -| angular2-client.ts:26:44:26:71 | this.ro ... ragment | -| angular2-client.ts:27:44:27:82 | this.ro ... ('foo') | -| angular2-client.ts:27:44:27:82 | this.ro ... ('foo') | -| angular2-client.ts:27:44:27:82 | this.ro ... ('foo') | -| angular2-client.ts:27:44:27:82 | this.ro ... ('foo') | -| angular2-client.ts:28:44:28:87 | this.ro ... ('foo') | -| angular2-client.ts:28:44:28:87 | this.ro ... ('foo') | -| angular2-client.ts:28:44:28:87 | this.ro ... ('foo') | -| angular2-client.ts:28:44:28:87 | this.ro ... ('foo') | -| angular2-client.ts:30:46:30:59 | map.get('foo') | -| angular2-client.ts:30:46:30:59 | map.get('foo') | -| angular2-client.ts:30:46:30:59 | map.get('foo') | -| angular2-client.ts:30:46:30:59 | map.get('foo') | -| angular2-client.ts:33:44:33:74 | this.ro ... 1].path | -| angular2-client.ts:33:44:33:74 | this.ro ... 1].path | -| angular2-client.ts:33:44:33:74 | this.ro ... 1].path | -| angular2-client.ts:33:44:33:74 | this.ro ... 1].path | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | -| angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:35:44:35:91 | this.ro ... et('x') | -| angular2-client.ts:35:44:35:91 | this.ro ... et('x') | -| angular2-client.ts:35:44:35:91 | this.ro ... et('x') | -| angular2-client.ts:35:44:35:91 | this.ro ... et('x') | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | -| angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:38:44:38:58 | this.router.url | -| angular2-client.ts:38:44:38:58 | this.router.url | -| angular2-client.ts:38:44:38:58 | this.router.url | -| angular2-client.ts:40:45:40:59 | this.router.url | -| angular2-client.ts:40:45:40:59 | this.router.url | -| angular2-client.ts:40:45:40:59 | this.router.url | -| angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | -| angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | -| angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | -| angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | -| classnames.js:7:31:7:84 | `` | -| classnames.js:7:31:7:84 | `` | -| classnames.js:7:47:7:69 | classNa ... w.name) | -| classnames.js:7:58:7:68 | window.name | -| classnames.js:7:58:7:68 | window.name | -| classnames.js:8:31:8:85 | `` | -| classnames.js:8:31:8:85 | `` | -| classnames.js:8:47:8:70 | classNa ... w.name) | -| classnames.js:8:59:8:69 | window.name | -| classnames.js:8:59:8:69 | window.name | -| classnames.js:9:31:9:85 | `` | -| classnames.js:9:31:9:85 | `` | -| classnames.js:9:47:9:70 | classNa ... w.name) | -| classnames.js:9:59:9:69 | window.name | -| classnames.js:9:59:9:69 | window.name | -| classnames.js:10:45:10:55 | window.name | -| classnames.js:10:45:10:55 | window.name | -| classnames.js:11:31:11:79 | `` | -| classnames.js:11:31:11:79 | `` | -| classnames.js:11:47:11:64 | unsafeStyle('foo') | -| classnames.js:13:31:13:83 | `` | -| classnames.js:13:31:13:83 | `` | -| classnames.js:13:47:13:68 | safeSty ... w.name) | -| classnames.js:13:57:13:67 | window.name | -| classnames.js:13:57:13:67 | window.name | -| classnames.js:15:31:15:78 | `` | -| classnames.js:15:31:15:78 | `` | -| classnames.js:15:47:15:63 | clsx(window.name) | -| classnames.js:15:52:15:62 | window.name | -| classnames.js:15:52:15:62 | window.name | -| classnames.js:17:32:17:79 | `` | -| classnames.js:17:32:17:79 | `` | -| classnames.js:17:48:17:64 | clsx(window.name) | -| classnames.js:17:53:17:63 | window.name | -| classnames.js:17:53:17:63 | window.name | -| clipboard.ts:8:11:8:51 | html | -| clipboard.ts:8:11:8:51 | html | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | -| clipboard.ts:15:25:15:28 | html | -| clipboard.ts:15:25:15:28 | html | -| clipboard.ts:15:25:15:28 | html | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:43:15:43:55 | html | -| clipboard.ts:43:15:43:55 | html | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | -| clipboard.ts:50:29:50:32 | html | -| clipboard.ts:50:29:50:32 | html | -| clipboard.ts:50:29:50:32 | html | -| clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | -| clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:98:15:98:54 | html | -| clipboard.ts:98:15:98:54 | html | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | -| clipboard.ts:99:23:99:26 | html | -| clipboard.ts:99:23:99:26 | html | -| clipboard.ts:99:23:99:26 | html | -| custom-element.js:5:26:5:36 | window.name | -| custom-element.js:5:26:5:36 | window.name | -| custom-element.js:5:26:5:36 | window.name | -| custom-element.js:5:26:5:36 | window.name | -| d3.js:4:12:4:22 | window.name | -| d3.js:4:12:4:22 | window.name | -| d3.js:4:12:4:22 | window.name | -| d3.js:11:15:11:24 | getTaint() | -| d3.js:11:15:11:24 | getTaint() | -| d3.js:11:15:11:24 | getTaint() | -| d3.js:12:20:12:29 | getTaint() | -| d3.js:12:20:12:29 | getTaint() | -| d3.js:12:20:12:29 | getTaint() | -| d3.js:14:20:14:29 | getTaint() | -| d3.js:14:20:14:29 | getTaint() | -| d3.js:14:20:14:29 | getTaint() | -| d3.js:21:15:21:24 | getTaint() | -| d3.js:21:15:21:24 | getTaint() | -| d3.js:21:15:21:24 | getTaint() | -| dates.js:9:9:9:69 | taint | -| dates.js:9:9:9:69 | taint | -| dates.js:9:17:9:69 | decodeU ... ing(1)) | -| dates.js:9:17:9:69 | decodeU ... ing(1)) | -| dates.js:9:36:9:55 | window.location.hash | -| dates.js:9:36:9:55 | window.location.hash | -| dates.js:9:36:9:68 | window. ... ring(1) | -| dates.js:9:36:9:68 | window. ... ring(1) | -| dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:42:11:68 | dateFns ... taint) | -| dates.js:11:42:11:68 | dateFns ... taint) | -| dates.js:11:63:11:67 | taint | -| dates.js:11:63:11:67 | taint | -| dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:42:12:71 | dateFns ... taint) | -| dates.js:12:42:12:71 | dateFns ... taint) | -| dates.js:12:66:12:70 | taint | -| dates.js:12:66:12:70 | taint | -| dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:42:13:70 | dateFns ... )(time) | -| dates.js:13:42:13:70 | dateFns ... )(time) | -| dates.js:13:59:13:63 | taint | -| dates.js:13:59:13:63 | taint | -| dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:42:16:67 | moment( ... (taint) | -| dates.js:16:42:16:67 | moment( ... (taint) | -| dates.js:16:62:16:66 | taint | -| dates.js:16:62:16:66 | taint | -| dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:42:18:64 | datefor ... taint) | -| dates.js:18:42:18:64 | datefor ... taint) | -| dates.js:18:59:18:63 | taint | -| dates.js:18:59:18:63 | taint | -| dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | -| dates.js:21:61:21:65 | taint | -| dates.js:21:61:21:65 | taint | -| dates.js:30:9:30:69 | taint | -| dates.js:30:9:30:69 | taint | -| dates.js:30:17:30:69 | decodeU ... ing(1)) | -| dates.js:30:17:30:69 | decodeU ... ing(1)) | -| dates.js:30:36:30:55 | window.location.hash | -| dates.js:30:36:30:55 | window.location.hash | -| dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:42:37:82 | dateFns ... taint) | -| dates.js:37:42:37:82 | dateFns ... taint) | -| dates.js:37:77:37:81 | taint | -| dates.js:37:77:37:81 | taint | -| dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:42:38:82 | luxon.f ... taint) | -| dates.js:38:42:38:82 | luxon.f ... taint) | -| dates.js:38:77:38:81 | taint | -| dates.js:38:77:38:81 | taint | -| dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:42:39:84 | moment. ... taint) | -| dates.js:39:42:39:84 | moment. ... taint) | -| dates.js:39:79:39:83 | taint | -| dates.js:39:79:39:83 | taint | -| dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:42:40:82 | dayjs.f ... taint) | -| dates.js:40:42:40:82 | dayjs.f ... taint) | -| dates.js:40:77:40:81 | taint | -| dates.js:40:77:40:81 | taint | -| dates.js:46:9:46:69 | taint | -| dates.js:46:9:46:69 | taint | -| dates.js:46:17:46:69 | decodeU ... ing(1)) | -| dates.js:46:17:46:69 | decodeU ... ing(1)) | -| dates.js:46:36:46:55 | window.location.hash | -| dates.js:46:36:46:55 | window.location.hash | -| dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:42:48:88 | DateTim ... (taint) | -| dates.js:48:42:48:88 | DateTim ... (taint) | -| dates.js:48:83:48:87 | taint | -| dates.js:48:83:48:87 | taint | -| dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:42:49:87 | new Dat ... (taint) | -| dates.js:49:42:49:87 | new Dat ... (taint) | -| dates.js:49:82:49:86 | taint | -| dates.js:49:82:49:86 | taint | -| dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:42:50:102 | DateTim ... (taint) | -| dates.js:50:42:50:102 | DateTim ... (taint) | -| dates.js:50:97:50:101 | taint | -| dates.js:50:97:50:101 | taint | -| dates.js:54:9:54:69 | taint | -| dates.js:54:9:54:69 | taint | -| dates.js:54:17:54:69 | decodeU ... ing(1)) | -| dates.js:54:17:54:69 | decodeU ... ing(1)) | -| dates.js:54:36:54:55 | window.location.hash | -| dates.js:54:36:54:55 | window.location.hash | -| dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:42:57:99 | moment. ... (taint) | -| dates.js:57:42:57:99 | moment. ... (taint) | -| dates.js:57:94:57:98 | taint | -| dates.js:57:94:57:98 | taint | -| dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:42:59:85 | luxon.e ... (taint) | -| dates.js:59:42:59:85 | luxon.e ... (taint) | -| dates.js:59:80:59:84 | taint | -| dates.js:59:80:59:84 | taint | -| dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | -| dates.js:61:81:61:85 | taint | -| dates.js:61:81:61:85 | taint | -| dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | -| dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | -| dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:71:13:71:61 | droppedHtml | -| dragAndDrop.ts:71:13:71:61 | droppedHtml | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | -| dragAndDrop.ts:73:29:73:39 | droppedHtml | -| dragAndDrop.ts:73:29:73:39 | droppedHtml | -| dragAndDrop.ts:73:29:73:39 | droppedHtml | -| event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:49:2:61 | location.href | -| event-handler-receiver.js:2:49:2:61 | location.href | -| express.js:7:15:7:33 | req.param("wobble") | -| express.js:7:15:7:33 | req.param("wobble") | -| express.js:7:15:7:33 | req.param("wobble") | -| express.js:7:15:7:33 | req.param("wobble") | -| jquery.js:2:7:2:40 | tainted | -| jquery.js:2:17:2:40 | documen ... .search | -| jquery.js:2:17:2:40 | documen ... .search | -| jquery.js:7:5:7:34 | "
" | -| jquery.js:7:5:7:34 | "
" | -| jquery.js:7:20:7:26 | tainted | -| jquery.js:8:18:8:34 | "XSS: " + tainted | -| jquery.js:8:18:8:34 | "XSS: " + tainted | -| jquery.js:8:28:8:34 | tainted | -| jquery.js:10:5:10:40 | "" + ... "" | -| jquery.js:10:5:10:40 | "" + ... "" | -| jquery.js:10:13:10:20 | location | -| jquery.js:10:13:10:20 | location | -| jquery.js:10:13:10:31 | location.toString() | -| jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:14:38:14:57 | window.location.hash | -| jquery.js:14:38:14:57 | window.location.hash | -| jquery.js:15:19:15:60 | decodeU ... search) | -| jquery.js:15:19:15:60 | decodeU ... search) | -| jquery.js:15:38:15:59 | window. ... .search | -| jquery.js:15:38:15:59 | window. ... .search | -| jquery.js:16:19:16:64 | decodeU ... ring()) | -| jquery.js:16:19:16:64 | decodeU ... ring()) | -| jquery.js:16:38:16:52 | window.location | -| jquery.js:16:38:16:52 | window.location | -| jquery.js:16:38:16:63 | window. ... tring() | -| jquery.js:18:7:18:33 | hash | -| jquery.js:18:14:18:33 | window.location.hash | -| jquery.js:18:14:18:33 | window.location.hash | -| jquery.js:21:5:21:8 | hash | -| jquery.js:21:5:21:21 | hash.substring(1) | -| jquery.js:21:5:21:21 | hash.substring(1) | -| jquery.js:21:5:21:21 | hash.substring(1) | -| jquery.js:22:5:22:8 | hash | -| jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:23:5:23:8 | hash | -| jquery.js:23:5:23:18 | hash.substr(1) | -| jquery.js:23:5:23:18 | hash.substr(1) | -| jquery.js:23:5:23:18 | hash.substr(1) | -| jquery.js:24:5:24:8 | hash | -| jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:27:5:27:8 | hash | -| jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:28:5:28:26 | window. ... .search | -| jquery.js:28:5:28:26 | window. ... .search | -| jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:34:5:34:25 | '' + ... '' | -| jquery.js:34:5:34:25 | '' + ... '' | -| jquery.js:34:13:34:16 | hash | -| jquery.js:36:25:36:31 | tainted | -| jquery.js:36:25:36:31 | tainted | -| jquery.js:37:25:37:37 | () => tainted | -| jquery.js:37:25:37:37 | () => tainted | -| jquery.js:37:31:37:37 | tainted | -| json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | -| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | -| json-stringify.jsx:11:51:11:56 | locale | -| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | -| json-stringify.jsx:19:56:19:61 | locale | -| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:55:31:60 | locale | -| json-stringify.jsx:31:55:31:60 | locale | -| json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | -| json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | -| jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:7:17:7:35 | req.param("wobble") | -| jwt-server.js:7:17:7:35 | req.param("wobble") | -| jwt-server.js:7:17:7:35 | req.param("wobble") | -| jwt-server.js:9:16:9:20 | taint | -| jwt-server.js:9:16:9:20 | taint | -| jwt-server.js:9:55:9:61 | decoded | -| jwt-server.js:9:55:9:61 | decoded | -| jwt-server.js:11:19:11:25 | decoded | -| jwt-server.js:11:19:11:25 | decoded | -| jwt-server.js:11:19:11:29 | decoded.foo | -| jwt-server.js:11:19:11:29 | decoded.foo | -| jwt-server.js:11:19:11:29 | decoded.foo | -| jwt.js:4:36:4:39 | data | -| jwt.js:4:36:4:39 | data | -| jwt.js:4:36:4:39 | data | -| jwt.js:5:9:5:34 | decoded | -| jwt.js:5:9:5:34 | decoded | -| jwt.js:5:19:5:34 | jwt_decode(data) | -| jwt.js:5:19:5:34 | jwt_decode(data) | -| jwt.js:5:30:5:33 | data | -| jwt.js:5:30:5:33 | data | -| jwt.js:6:14:6:20 | decoded | -| jwt.js:6:14:6:20 | decoded | -| jwt.js:6:14:6:20 | decoded | -| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| nodemailer.js:13:50:13:66 | req.query.message | -| nodemailer.js:13:50:13:66 | req.query.message | -| optionalSanitizer.js:2:7:2:39 | target | -| optionalSanitizer.js:2:16:2:39 | documen ... .search | -| optionalSanitizer.js:2:16:2:39 | documen ... .search | -| optionalSanitizer.js:6:18:6:23 | target | -| optionalSanitizer.js:6:18:6:23 | target | -| optionalSanitizer.js:8:7:8:22 | tainted | -| optionalSanitizer.js:8:17:8:22 | target | -| optionalSanitizer.js:9:18:9:24 | tainted | -| optionalSanitizer.js:9:18:9:24 | tainted | -| optionalSanitizer.js:15:9:15:14 | target | -| optionalSanitizer.js:16:18:16:18 | x | -| optionalSanitizer.js:17:20:17:20 | x | -| optionalSanitizer.js:17:20:17:20 | x | -| optionalSanitizer.js:26:7:26:39 | target | -| optionalSanitizer.js:26:16:26:39 | documen ... .search | -| optionalSanitizer.js:26:16:26:39 | documen ... .search | -| optionalSanitizer.js:31:7:31:23 | tainted2 | -| optionalSanitizer.js:31:18:31:23 | target | -| optionalSanitizer.js:32:18:32:25 | tainted2 | -| optionalSanitizer.js:32:18:32:25 | tainted2 | -| optionalSanitizer.js:34:5:34:36 | tainted2 | -| optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | -| optionalSanitizer.js:34:28:34:35 | tainted2 | -| optionalSanitizer.js:36:18:36:25 | tainted2 | -| optionalSanitizer.js:36:18:36:25 | tainted2 | -| optionalSanitizer.js:38:7:38:23 | tainted3 | -| optionalSanitizer.js:38:18:38:23 | target | -| optionalSanitizer.js:39:18:39:25 | tainted3 | -| optionalSanitizer.js:39:18:39:25 | tainted3 | -| optionalSanitizer.js:41:5:41:36 | tainted3 | -| optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | -| optionalSanitizer.js:41:28:41:35 | tainted3 | -| optionalSanitizer.js:43:18:43:25 | tainted3 | -| optionalSanitizer.js:43:18:43:25 | tainted3 | -| optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | -| optionalSanitizer.js:45:41:45:46 | target | -| optionalSanitizer.js:45:51:45:56 | target | -| pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:5:9:5:29 | id | -| pages/[id].jsx:5:9:5:29 | id | -| pages/[id].jsx:5:11:5:12 | id | -| pages/[id].jsx:5:11:5:12 | id | -| pages/[id].jsx:5:18:5:29 | router.query | -| pages/[id].jsx:5:18:5:29 | router.query | -| pages/[id].jsx:5:18:5:29 | router.query | -| pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:25:11:25:24 | context.params | -| pages/[id].jsx:25:11:25:24 | context.params | -| pages/[id].jsx:25:11:25:24 | context.params | -| pages/[id].jsx:25:11:25:27 | context.params.id | -| pages/[id].jsx:25:11:25:27 | context.params.id | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | -| pages/[id].jsx:26:10:26:22 | context.query | -| pages/[id].jsx:26:10:26:22 | context.query | -| pages/[id].jsx:26:10:26:22 | context.query | -| pages/[id].jsx:26:10:26:30 | context ... .foobar | -| pages/[id].jsx:26:10:26:30 | context ... .foobar | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | -| react-native.js:7:7:7:33 | tainted | -| react-native.js:7:7:7:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:8:18:8:24 | tainted | -| react-native.js:8:18:8:24 | tainted | -| react-native.js:8:18:8:24 | tainted | -| react-native.js:9:27:9:33 | tainted | -| react-native.js:9:27:9:33 | tainted | -| react-native.js:9:27:9:33 | tainted | -| react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:16:26:16:36 | window.name | -| react-use-context.js:16:26:16:36 | window.name | -| react-use-context.js:16:26:16:36 | window.name | -| react-use-context.js:16:26:16:36 | window.name | -| react-use-router.js:4:9:4:28 | router | -| react-use-router.js:4:18:4:28 | useRouter() | -| react-use-router.js:8:21:8:26 | router | -| react-use-router.js:8:21:8:32 | router.query | -| react-use-router.js:8:21:8:32 | router.query | -| react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:11:24:11:29 | router | -| react-use-router.js:11:24:11:35 | router.query | -| react-use-router.js:11:24:11:35 | router.query | -| react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:22:15:22:24 | router | -| react-use-router.js:22:17:22:22 | router | -| react-use-router.js:23:43:23:48 | router | -| react-use-router.js:23:43:23:54 | router.query | -| react-use-router.js:23:43:23:54 | router.query | -| react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:29:9:29:30 | router | -| react-use-router.js:29:18:29:30 | myUseRouter() | -| react-use-router.js:33:21:33:26 | router | -| react-use-router.js:33:21:33:32 | router.query | -| react-use-router.js:33:21:33:32 | router.query | -| react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-state.js:4:9:4:49 | state | -| react-use-state.js:4:9:4:49 | state | -| react-use-state.js:4:10:4:14 | state | -| react-use-state.js:4:10:4:14 | state | -| react-use-state.js:4:38:4:48 | window.name | -| react-use-state.js:4:38:4:48 | window.name | -| react-use-state.js:4:38:4:48 | window.name | -| react-use-state.js:5:51:5:55 | state | -| react-use-state.js:5:51:5:55 | state | -| react-use-state.js:5:51:5:55 | state | -| react-use-state.js:9:9:9:43 | state | -| react-use-state.js:9:9:9:43 | state | -| react-use-state.js:9:10:9:14 | state | -| react-use-state.js:9:10:9:14 | state | -| react-use-state.js:10:14:10:24 | window.name | -| react-use-state.js:10:14:10:24 | window.name | -| react-use-state.js:10:14:10:24 | window.name | -| react-use-state.js:11:51:11:55 | state | -| react-use-state.js:11:51:11:55 | state | -| react-use-state.js:11:51:11:55 | state | -| react-use-state.js:15:9:15:43 | state | -| react-use-state.js:15:9:15:43 | state | -| react-use-state.js:15:10:15:14 | state | -| react-use-state.js:15:10:15:14 | state | -| react-use-state.js:16:20:16:30 | window.name | -| react-use-state.js:16:20:16:30 | window.name | -| react-use-state.js:16:20:16:30 | window.name | -| react-use-state.js:17:51:17:55 | state | -| react-use-state.js:17:51:17:55 | state | -| react-use-state.js:17:51:17:55 | state | -| react-use-state.js:21:10:21:14 | state | -| react-use-state.js:21:10:21:14 | state | -| react-use-state.js:22:14:22:17 | prev | -| react-use-state.js:22:14:22:17 | prev | -| react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:25:20:25:30 | window.name | -| react-use-state.js:25:20:25:30 | window.name | -| react-use-state.js:25:20:25:30 | window.name | -| sanitiser.js:16:7:16:27 | tainted | -| sanitiser.js:16:7:16:27 | tainted | -| sanitiser.js:16:17:16:27 | window.name | -| sanitiser.js:16:17:16:27 | window.name | -| sanitiser.js:16:17:16:27 | window.name | -| sanitiser.js:23:21:23:44 | '' + ... '' | -| sanitiser.js:23:21:23:44 | '' + ... '' | -| sanitiser.js:23:29:23:35 | tainted | -| sanitiser.js:30:21:30:44 | '' + ... '' | -| sanitiser.js:30:21:30:44 | '' + ... '' | -| sanitiser.js:30:29:30:35 | tainted | -| sanitiser.js:33:21:33:44 | '' + ... '' | -| sanitiser.js:33:21:33:44 | '' + ... '' | -| sanitiser.js:33:29:33:35 | tainted | -| sanitiser.js:38:21:38:44 | '' + ... '' | -| sanitiser.js:38:21:38:44 | '' + ... '' | -| sanitiser.js:38:29:38:35 | tainted | -| sanitiser.js:45:21:45:44 | '' + ... '' | -| sanitiser.js:45:21:45:44 | '' + ... '' | -| sanitiser.js:45:29:45:35 | tainted | -| sanitiser.js:48:19:48:25 | tainted | -| sanitiser.js:48:19:48:25 | tainted | -| sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| stored-xss.js:2:39:2:62 | documen ... .search | -| stored-xss.js:2:39:2:62 | documen ... .search | -| stored-xss.js:3:35:3:58 | documen ... .search | -| stored-xss.js:3:35:3:58 | documen ... .search | -| stored-xss.js:5:20:5:52 | session ... ssion') | -| stored-xss.js:5:20:5:52 | session ... ssion') | -| stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:10:9:10:44 | href | -| stored-xss.js:10:16:10:44 | localSt ... local') | -| stored-xss.js:12:20:12:54 | "" | -| stored-xss.js:12:20:12:54 | "" | -| stored-xss.js:12:20:12:54 | "" | -| stored-xss.js:12:35:12:38 | href | -| string-manipulations.js:3:16:3:32 | document.location | -| string-manipulations.js:3:16:3:32 | document.location | -| string-manipulations.js:3:16:3:32 | document.location | -| string-manipulations.js:4:16:4:37 | documen ... on.href | -| string-manipulations.js:4:16:4:37 | documen ... on.href | -| string-manipulations.js:4:16:4:37 | documen ... on.href | -| string-manipulations.js:5:16:5:37 | documen ... on.href | -| string-manipulations.js:5:16:5:37 | documen ... on.href | -| string-manipulations.js:5:16:5:47 | documen ... lueOf() | -| string-manipulations.js:5:16:5:47 | documen ... lueOf() | -| string-manipulations.js:6:16:6:37 | documen ... on.href | -| string-manipulations.js:6:16:6:37 | documen ... on.href | -| string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:7:16:7:37 | documen ... on.href | -| string-manipulations.js:7:16:7:37 | documen ... on.href | -| string-manipulations.js:7:16:7:51 | documen ... rCase() | -| string-manipulations.js:7:16:7:51 | documen ... rCase() | -| string-manipulations.js:8:16:8:37 | documen ... on.href | -| string-manipulations.js:8:16:8:37 | documen ... on.href | -| string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:9:16:9:58 | String. ... n.href) | -| string-manipulations.js:9:16:9:58 | String. ... n.href) | -| string-manipulations.js:9:36:9:57 | documen ... on.href | -| string-manipulations.js:9:36:9:57 | documen ... on.href | -| string-manipulations.js:10:16:10:45 | String( ... n.href) | -| string-manipulations.js:10:16:10:45 | String( ... n.href) | -| string-manipulations.js:10:23:10:44 | documen ... on.href | -| string-manipulations.js:10:23:10:44 | documen ... on.href | -| tooltip.jsx:6:11:6:30 | source | -| tooltip.jsx:6:11:6:30 | source | -| tooltip.jsx:6:20:6:30 | window.name | -| tooltip.jsx:6:20:6:30 | window.name | -| tooltip.jsx:6:20:6:30 | window.name | -| tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:11:25:11:30 | source | -| translate.js:6:7:6:39 | target | -| translate.js:6:16:6:39 | documen ... .search | -| translate.js:6:16:6:39 | documen ... .search | -| translate.js:7:7:7:61 | searchParams | -| translate.js:7:22:7:61 | new URL ... ing(1)) | -| translate.js:7:42:7:47 | target | -| translate.js:7:42:7:60 | target.substring(1) | -| translate.js:7:42:7:60 | target.substring(1) | -| translate.js:7:42:7:60 | target.substring(1) | -| translate.js:9:27:9:38 | searchParams | -| translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:9:27:9:50 | searchP ... 'term') | -| trusted-types-lib.js:1:28:1:28 | x | -| trusted-types-lib.js:1:28:1:28 | x | -| trusted-types-lib.js:2:12:2:12 | x | -| trusted-types-lib.js:2:12:2:12 | x | -| trusted-types-lib.js:2:12:2:12 | x | -| trusted-types.js:3:62:3:62 | x | -| trusted-types.js:3:62:3:62 | x | -| trusted-types.js:3:67:3:67 | x | -| trusted-types.js:3:67:3:67 | x | -| trusted-types.js:3:67:3:67 | x | -| trusted-types.js:4:20:4:30 | window.name | -| trusted-types.js:4:20:4:30 | window.name | -| trusted-types.js:4:20:4:30 | window.name | -| trusted-types.js:13:20:13:30 | window.name | -| trusted-types.js:13:20:13:30 | window.name | -| trusted-types.js:13:20:13:30 | window.name | -| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | -| tst3.js:2:23:2:74 | decodeU ... str(1)) | -| tst3.js:2:42:2:63 | window. ... .search | -| tst3.js:2:42:2:63 | window. ... .search | -| tst3.js:2:42:2:73 | window. ... bstr(1) | -| tst3.js:4:25:4:28 | data | -| tst3.js:4:25:4:32 | data.src | -| tst3.js:4:25:4:32 | data.src | -| tst3.js:5:26:5:29 | data | -| tst3.js:5:26:5:31 | data.p | -| tst3.js:5:26:5:31 | data.p | -| tst3.js:7:32:7:35 | data | -| tst3.js:7:32:7:37 | data.p | -| tst3.js:7:32:7:37 | data.p | -| tst3.js:9:37:9:40 | data | -| tst3.js:9:37:9:42 | data.p | -| tst3.js:9:37:9:42 | data.p | -| tst3.js:10:38:10:41 | data | -| tst3.js:10:38:10:43 | data.p | -| tst3.js:10:38:10:43 | data.p | -| tst.js:2:7:2:39 | target | -| tst.js:2:16:2:39 | documen ... .search | -| tst.js:2:16:2:39 | documen ... .search | -| tst.js:5:18:5:23 | target | -| tst.js:5:18:5:23 | target | -| tst.js:8:18:8:126 | "" | -| tst.js:8:18:8:126 | "" | -| tst.js:8:18:8:126 | "" | -| tst.js:8:37:8:58 | documen ... on.href | -| tst.js:8:37:8:58 | documen ... on.href | -| tst.js:8:37:8:114 | documen ... t=")+8) | -| tst.js:8:37:8:114 | documen ... t=")+8) | -| tst.js:12:5:12:42 | '
' | -| tst.js:12:5:12:42 | '
' | -| tst.js:12:28:12:33 | target | -| tst.js:17:7:17:56 | params | -| tst.js:17:16:17:56 | (new UR ... hParams | -| tst.js:17:25:17:41 | document.location | -| tst.js:17:25:17:41 | document.location | -| tst.js:18:18:18:23 | params | -| tst.js:18:18:18:35 | params.get('name') | -| tst.js:18:18:18:35 | params.get('name') | -| tst.js:18:18:18:35 | params.get('name') | -| tst.js:18:18:18:35 | params.get('name') | -| tst.js:20:7:20:61 | searchParams | -| tst.js:20:22:20:61 | new URL ... ing(1)) | -| tst.js:20:42:20:47 | target | -| tst.js:20:42:20:60 | target.substring(1) | -| tst.js:20:42:20:60 | target.substring(1) | -| tst.js:20:42:20:60 | target.substring(1) | -| tst.js:21:18:21:29 | searchParams | -| tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:24:14:24:19 | target | -| tst.js:26:18:26:23 | target | -| tst.js:26:18:26:23 | target | -| tst.js:28:5:28:28 | documen ... .search | -| tst.js:28:5:28:28 | documen ... .search | -| tst.js:31:10:31:33 | documen ... .search | -| tst.js:31:10:31:33 | documen ... .search | -| tst.js:34:16:34:20 | bar() | -| tst.js:34:16:34:20 | bar() | -| tst.js:40:16:40:44 | baz(doc ... search) | -| tst.js:40:16:40:44 | baz(doc ... search) | -| tst.js:40:20:40:43 | documen ... .search | -| tst.js:40:20:40:43 | documen ... .search | -| tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:21:46:44 | documen ... .search | -| tst.js:46:21:46:44 | documen ... .search | -| tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | -| tst.js:54:21:54:44 | documen ... .search | -| tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | -| tst.js:56:21:56:44 | documen ... .search | -| tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:21:58:31 | chop(bar()) | -| tst.js:58:21:58:31 | chop(bar()) | -| tst.js:58:26:58:30 | bar() | -| tst.js:60:34:60:34 | s | -| tst.js:62:18:62:18 | s | -| tst.js:62:18:62:18 | s | -| tst.js:64:25:64:48 | documen ... .search | -| tst.js:64:25:64:48 | documen ... .search | -| tst.js:65:25:65:48 | documen ... .search | -| tst.js:65:25:65:48 | documen ... .search | -| tst.js:68:16:68:20 | bar() | -| tst.js:68:16:68:20 | bar() | -| tst.js:70:1:70:27 | [,docum ... search] | -| tst.js:70:3:70:26 | documen ... .search | -| tst.js:70:3:70:26 | documen ... .search | -| tst.js:70:46:70:46 | x | -| tst.js:73:20:73:20 | x | -| tst.js:73:20:73:20 | x | -| tst.js:77:49:77:72 | documen ... .search | -| tst.js:77:49:77:72 | documen ... .search | -| tst.js:77:49:77:72 | documen ... .search | -| tst.js:81:26:81:49 | documen ... .search | -| tst.js:81:26:81:49 | documen ... .search | -| tst.js:81:26:81:49 | documen ... .search | -| tst.js:82:25:82:48 | documen ... .search | -| tst.js:82:25:82:48 | documen ... .search | -| tst.js:82:25:82:48 | documen ... .search | -| tst.js:84:33:84:56 | documen ... .search | -| tst.js:84:33:84:56 | documen ... .search | -| tst.js:84:33:84:56 | documen ... .search | -| tst.js:85:32:85:55 | documen ... .search | -| tst.js:85:32:85:55 | documen ... .search | -| tst.js:85:32:85:55 | documen ... .search | -| tst.js:90:39:90:62 | documen ... .search | -| tst.js:90:39:90:62 | documen ... .search | -| tst.js:90:39:90:62 | documen ... .search | -| tst.js:96:30:96:53 | documen ... .search | -| tst.js:96:30:96:53 | documen ... .search | -| tst.js:96:30:96:53 | documen ... .search | -| tst.js:102:25:102:48 | documen ... .search | -| tst.js:102:25:102:48 | documen ... .search | -| tst.js:102:25:102:48 | documen ... .search | -| tst.js:107:7:107:44 | v | -| tst.js:107:7:107:44 | v | -| tst.js:107:7:107:44 | v | -| tst.js:107:11:107:34 | documen ... .search | -| tst.js:107:11:107:34 | documen ... .search | -| tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:110:18:110:18 | v | -| tst.js:110:18:110:18 | v | -| tst.js:110:18:110:18 | v | -| tst.js:110:18:110:18 | v | -| tst.js:136:18:136:18 | v | -| tst.js:136:18:136:18 | v | -| tst.js:136:18:136:18 | v | -| tst.js:136:18:136:18 | v | -| tst.js:148:29:148:50 | window. ... .search | -| tst.js:148:29:148:50 | window. ... .search | -| tst.js:151:29:151:29 | v | -| tst.js:151:49:151:49 | v | -| tst.js:151:49:151:49 | v | -| tst.js:155:29:155:46 | xssSourceService() | -| tst.js:155:29:155:46 | xssSourceService() | -| tst.js:158:40:158:61 | window. ... .search | -| tst.js:158:40:158:61 | window. ... .search | -| tst.js:177:9:177:41 | target | -| tst.js:177:18:177:41 | documen ... .search | -| tst.js:177:18:177:41 | documen ... .search | -| tst.js:180:28:180:33 | target | -| tst.js:180:28:180:33 | target | -| tst.js:184:9:184:42 | tainted | -| tst.js:184:19:184:42 | documen ... .search | -| tst.js:184:19:184:42 | documen ... .search | -| tst.js:186:31:186:37 | tainted | -| tst.js:186:31:186:37 | tainted | -| tst.js:188:42:188:48 | tainted | -| tst.js:188:42:188:48 | tainted | -| tst.js:189:33:189:39 | tainted | -| tst.js:189:33:189:39 | tainted | -| tst.js:191:54:191:60 | tainted | -| tst.js:191:54:191:60 | tainted | -| tst.js:192:45:192:51 | tainted | -| tst.js:192:45:192:51 | tainted | -| tst.js:193:49:193:55 | tainted | -| tst.js:193:49:193:55 | tainted | -| tst.js:197:9:197:42 | tainted | -| tst.js:197:19:197:42 | documen ... .search | -| tst.js:197:19:197:42 | documen ... .search | -| tst.js:199:67:199:73 | tainted | -| tst.js:199:67:199:73 | tainted | -| tst.js:200:67:200:73 | tainted | -| tst.js:200:67:200:73 | tainted | -| tst.js:204:35:204:41 | tainted | -| tst.js:206:46:206:52 | tainted | -| tst.js:207:38:207:44 | tainted | -| tst.js:208:35:208:41 | tainted | -| tst.js:212:28:212:46 | this.state.tainted1 | -| tst.js:212:28:212:46 | this.state.tainted1 | -| tst.js:213:28:213:46 | this.state.tainted2 | -| tst.js:213:28:213:46 | this.state.tainted2 | -| tst.js:214:28:214:46 | this.state.tainted3 | -| tst.js:214:28:214:46 | this.state.tainted3 | -| tst.js:218:32:218:49 | prevState.tainted4 | -| tst.js:218:32:218:49 | prevState.tainted4 | -| tst.js:225:28:225:46 | this.props.tainted1 | -| tst.js:225:28:225:46 | this.props.tainted1 | -| tst.js:226:28:226:46 | this.props.tainted2 | -| tst.js:226:28:226:46 | this.props.tainted2 | -| tst.js:227:28:227:46 | this.props.tainted3 | -| tst.js:227:28:227:46 | this.props.tainted3 | -| tst.js:231:32:231:49 | prevProps.tainted4 | -| tst.js:231:32:231:49 | prevProps.tainted4 | -| tst.js:236:35:236:41 | tainted | -| tst.js:238:20:238:26 | tainted | -| tst.js:240:23:240:29 | tainted | -| tst.js:241:23:241:29 | tainted | -| tst.js:247:39:247:55 | props.propTainted | -| tst.js:251:60:251:82 | this.st ... Tainted | -| tst.js:251:60:251:82 | this.st ... Tainted | -| tst.js:255:23:255:29 | tainted | -| tst.js:259:7:259:17 | window.name | -| tst.js:259:7:259:17 | window.name | -| tst.js:259:7:259:17 | window.name | -| tst.js:259:7:259:17 | window.name | -| tst.js:260:7:260:10 | name | -| tst.js:260:7:260:10 | name | -| tst.js:260:7:260:10 | name | -| tst.js:260:7:260:10 | name | -| tst.js:264:11:264:21 | window.name | -| tst.js:264:11:264:21 | window.name | -| tst.js:264:11:264:21 | window.name | -| tst.js:264:11:264:21 | window.name | -| tst.js:280:22:280:29 | location | -| tst.js:280:22:280:29 | location | -| tst.js:280:22:280:29 | location | -| tst.js:285:9:285:29 | tainted | -| tst.js:285:9:285:29 | tainted | -| tst.js:285:19:285:29 | window.name | -| tst.js:285:19:285:29 | window.name | -| tst.js:285:19:285:29 | window.name | -| tst.js:288:59:288:65 | tainted | -| tst.js:288:59:288:65 | tainted | -| tst.js:288:59:288:65 | tainted | -| tst.js:301:9:301:16 | location | -| tst.js:301:9:301:16 | location | -| tst.js:302:10:302:10 | e | -| tst.js:303:20:303:20 | e | -| tst.js:303:20:303:20 | e | -| tst.js:308:10:308:17 | location | -| tst.js:308:10:308:17 | location | -| tst.js:310:10:310:10 | e | -| tst.js:311:20:311:20 | e | -| tst.js:311:20:311:20 | e | -| tst.js:316:35:316:42 | location | -| tst.js:316:35:316:42 | location | -| tst.js:316:35:316:42 | location | -| tst.js:327:18:327:34 | document.location | -| tst.js:327:18:327:34 | document.location | -| tst.js:331:7:331:43 | params | -| tst.js:331:16:331:43 | getTain ... hParams | -| tst.js:332:18:332:23 | params | -| tst.js:332:18:332:35 | params.get('name') | -| tst.js:332:18:332:35 | params.get('name') | -| tst.js:332:18:332:35 | params.get('name') | -| tst.js:332:18:332:35 | params.get('name') | -| tst.js:341:20:341:36 | document.location | -| tst.js:341:20:341:36 | document.location | -| tst.js:343:5:343:17 | getUrl().hash | -| tst.js:343:5:343:30 | getUrl( ... ring(1) | -| tst.js:343:5:343:30 | getUrl( ... ring(1) | -| tst.js:343:5:343:30 | getUrl( ... ring(1) | -| tst.js:348:7:348:39 | target | -| tst.js:348:16:348:39 | documen ... .search | -| tst.js:348:16:348:39 | documen ... .search | -| tst.js:349:12:349:17 | target | -| tst.js:349:12:349:17 | target | -| tst.js:355:10:355:42 | target | -| tst.js:355:19:355:42 | documen ... .search | -| tst.js:355:19:355:42 | documen ... .search | -| tst.js:356:16:356:21 | target | -| tst.js:356:16:356:21 | target | -| tst.js:360:21:360:26 | target | -| tst.js:360:21:360:26 | target | -| tst.js:363:18:363:23 | target | -| tst.js:363:18:363:23 | target | -| tst.js:371:7:371:39 | target | -| tst.js:371:16:371:39 | documen ... .search | -| tst.js:371:16:371:39 | documen ... .search | -| tst.js:374:18:374:23 | target | -| tst.js:374:18:374:23 | target | -| tst.js:381:7:381:39 | target | -| tst.js:381:16:381:39 | documen ... .search | -| tst.js:381:16:381:39 | documen ... .search | -| tst.js:384:18:384:23 | target | -| tst.js:384:18:384:23 | target | -| tst.js:386:18:386:23 | target | -| tst.js:386:18:386:29 | target.taint | -| tst.js:386:18:386:29 | target.taint | -| tst.js:391:19:391:42 | documen ... .search | -| tst.js:391:19:391:42 | documen ... .search | -| tst.js:392:18:392:30 | target.taint3 | -| tst.js:392:18:392:30 | target.taint3 | -| tst.js:397:18:397:23 | target | -| tst.js:397:18:397:30 | target.taint5 | -| tst.js:397:18:397:30 | target.taint5 | -| tst.js:406:18:406:23 | target | -| tst.js:406:18:406:30 | target.taint7 | -| tst.js:406:18:406:30 | target.taint7 | -| tst.js:408:19:408:24 | target | -| tst.js:408:19:408:31 | target.taint8 | -| tst.js:409:18:409:30 | target.taint8 | -| tst.js:409:18:409:30 | target.taint8 | -| tst.js:416:7:416:46 | payload | -| tst.js:416:7:416:46 | payload | -| tst.js:416:7:416:46 | payload | -| tst.js:416:17:416:36 | window.location.hash | -| tst.js:416:17:416:36 | window.location.hash | -| tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:417:18:417:24 | payload | -| tst.js:417:18:417:24 | payload | -| tst.js:417:18:417:24 | payload | -| tst.js:417:18:417:24 | payload | -| tst.js:419:7:419:55 | match | -| tst.js:419:15:419:34 | window.location.hash | -| tst.js:419:15:419:34 | window.location.hash | -| tst.js:419:15:419:55 | window. ... (\\w+)/) | -| tst.js:421:20:421:24 | match | -| tst.js:421:20:421:27 | match[1] | -| tst.js:421:20:421:27 | match[1] | -| tst.js:424:18:424:37 | window.location.hash | -| tst.js:424:18:424:37 | window.location.hash | -| tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:428:7:428:39 | target | -| tst.js:428:16:428:39 | documen ... .search | -| tst.js:428:16:428:39 | documen ... .search | -| tst.js:430:18:430:23 | target | -| tst.js:430:18:430:89 | target. ... data>') | -| tst.js:430:18:430:89 | target. ... data>') | -| tst.js:436:6:436:38 | source | -| tst.js:436:15:436:38 | documen ... .search | -| tst.js:436:15:436:38 | documen ... .search | -| tst.js:440:28:440:33 | source | -| tst.js:440:28:440:33 | source | -| tst.js:441:33:441:38 | source | -| tst.js:441:33:441:38 | source | -| tst.js:442:34:442:39 | source | -| tst.js:442:34:442:39 | source | -| tst.js:443:41:443:46 | source | -| tst.js:443:41:443:46 | source | -| tst.js:444:44:444:49 | source | -| tst.js:444:44:444:49 | source | -| tst.js:445:32:445:37 | source | -| tst.js:445:32:445:37 | source | -| tst.js:453:7:453:39 | source | -| tst.js:453:16:453:39 | documen ... .search | -| tst.js:453:16:453:39 | documen ... .search | -| tst.js:455:18:455:23 | source | -| tst.js:455:18:455:23 | source | -| tst.js:456:18:456:42 | ansiToH ... source) | -| tst.js:456:18:456:42 | ansiToH ... source) | -| tst.js:456:36:456:41 | source | -| tst.js:460:6:460:38 | source | -| tst.js:460:15:460:38 | documen ... .search | -| tst.js:460:15:460:38 | documen ... .search | -| tst.js:463:21:463:26 | source | -| tst.js:463:21:463:26 | source | -| tst.js:465:19:465:24 | source | -| tst.js:465:19:465:24 | source | -| tst.js:467:20:467:25 | source | -| tst.js:467:20:467:25 | source | -| tst.js:471:7:471:46 | url | -| tst.js:471:13:471:36 | documen ... .search | -| tst.js:471:13:471:36 | documen ... .search | -| tst.js:471:13:471:46 | documen ... bstr(1) | -| tst.js:473:19:473:21 | url | -| tst.js:473:19:473:21 | url | -| tst.js:474:26:474:28 | url | -| tst.js:474:26:474:28 | url | -| tst.js:475:25:475:27 | url | -| tst.js:475:25:475:27 | url | -| tst.js:476:20:476:22 | url | -| tst.js:476:20:476:22 | url | -| tst.js:486:22:486:24 | url | -| tst.js:486:22:486:24 | url | -| tst.js:491:23:491:35 | location.hash | -| tst.js:491:23:491:35 | location.hash | -| tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:494:18:494:30 | location.hash | -| tst.js:494:18:494:30 | location.hash | -| tst.js:494:18:494:40 | locatio ... bstr(1) | -| tst.js:494:18:494:40 | locatio ... bstr(1) | -| tst.js:501:33:501:63 | decodeU ... n.hash) | -| tst.js:501:33:501:63 | decodeU ... n.hash) | -| tst.js:501:43:501:62 | window.location.hash | -| tst.js:501:43:501:62 | window.location.hash | -| typeahead.js:9:28:9:30 | loc | -| typeahead.js:9:28:9:30 | loc | -| typeahead.js:9:28:9:30 | loc | -| typeahead.js:10:16:10:18 | loc | -| typeahead.js:10:16:10:18 | loc | -| typeahead.js:10:16:10:18 | loc | -| typeahead.js:20:13:20:45 | target | -| typeahead.js:20:22:20:45 | documen ... .search | -| typeahead.js:20:22:20:45 | documen ... .search | -| typeahead.js:21:12:21:17 | target | -| typeahead.js:24:30:24:32 | val | -| typeahead.js:25:18:25:20 | val | -| typeahead.js:25:18:25:20 | val | -| v-html.vue:2:8:2:23 | v-html=tainted | -| v-html.vue:2:8:2:23 | v-html=tainted | -| v-html.vue:6:42:6:58 | document.location | -| v-html.vue:6:42:6:58 | document.location | -| various-concat-obfuscations.js:2:6:2:39 | tainted | -| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | -| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | -| various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | -| various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | -| various-concat-obfuscations.js:4:14:4:20 | tainted | -| various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | -| various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | -| various-concat-obfuscations.js:5:12:5:18 | tainted | -| various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | -| various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | -| various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | -| various-concat-obfuscations.js:6:19:6:25 | tainted | -| various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | -| various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | -| various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | -| various-concat-obfuscations.js:7:14:7:20 | tainted | -| various-concat-obfuscations.js:9:4:9:34 | "
" | -| various-concat-obfuscations.js:9:4:9:34 | "
" | -| various-concat-obfuscations.js:9:19:9:25 | tainted | -| various-concat-obfuscations.js:10:4:10:27 | `
` | -| various-concat-obfuscations.js:10:4:10:27 | `
` | -| various-concat-obfuscations.js:10:16:10:22 | tainted | -| various-concat-obfuscations.js:11:4:11:31 | "
") | -| various-concat-obfuscations.js:11:4:11:44 | "
") | -| various-concat-obfuscations.js:11:24:11:30 | tainted | -| various-concat-obfuscations.js:12:4:12:34 | ["
"] | -| various-concat-obfuscations.js:12:4:12:41 | ["
` | semmle.label | `` | +| classnames.js:7:47:7:69 | classNa ... w.name) | semmle.label | classNa ... w.name) | +| classnames.js:7:58:7:68 | window.name | semmle.label | window.name | +| classnames.js:8:31:8:85 | `` | semmle.label | `` | +| classnames.js:8:47:8:70 | classNa ... w.name) | semmle.label | classNa ... w.name) | +| classnames.js:8:59:8:69 | window.name | semmle.label | window.name | +| classnames.js:9:31:9:85 | `` | semmle.label | `` | +| classnames.js:9:47:9:70 | classNa ... w.name) | semmle.label | classNa ... w.name) | +| classnames.js:9:59:9:69 | window.name | semmle.label | window.name | +| classnames.js:10:45:10:55 | window.name | semmle.label | window.name | +| classnames.js:11:31:11:79 | `` | semmle.label | `` | +| classnames.js:11:47:11:64 | unsafeStyle('foo') | semmle.label | unsafeStyle('foo') | +| classnames.js:13:31:13:83 | `` | semmle.label | `` | +| classnames.js:13:47:13:68 | safeSty ... w.name) | semmle.label | safeSty ... w.name) | +| classnames.js:13:57:13:67 | window.name | semmle.label | window.name | +| classnames.js:15:31:15:78 | `` | semmle.label | `` | +| classnames.js:15:47:15:63 | clsx(window.name) | semmle.label | clsx(window.name) | +| classnames.js:15:52:15:62 | window.name | semmle.label | window.name | +| classnames.js:17:32:17:79 | `` | semmle.label | `` | +| classnames.js:17:48:17:64 | clsx(window.name) | semmle.label | clsx(window.name) | +| classnames.js:17:53:17:63 | window.name | semmle.label | window.name | +| clipboard.ts:8:11:8:51 | html | semmle.label | html | +| clipboard.ts:8:18:8:51 | clipboa ... /html') | semmle.label | clipboa ... /html') | +| clipboard.ts:15:25:15:28 | html | semmle.label | html | +| clipboard.ts:24:23:24:58 | e.clipb ... /html') | semmle.label | e.clipb ... /html') | +| clipboard.ts:29:19:29:54 | e.clipb ... /html') | semmle.label | e.clipb ... /html') | +| clipboard.ts:33:19:33:68 | e.origi ... /html') | semmle.label | e.origi ... /html') | +| clipboard.ts:43:15:43:55 | html | semmle.label | html | +| clipboard.ts:43:22:43:55 | clipboa ... /html') | semmle.label | clipboa ... /html') | +| clipboard.ts:50:29:50:32 | html | semmle.label | html | +| clipboard.ts:71:13:71:62 | droppedHtml | semmle.label | droppedHtml | +| clipboard.ts:71:27:71:62 | e.clipb ... /html') | semmle.label | e.clipb ... /html') | +| clipboard.ts:73:29:73:39 | droppedHtml | semmle.label | droppedHtml | +| clipboard.ts:98:15:98:54 | html | semmle.label | html | +| clipboard.ts:98:22:98:54 | dataTra ... /html') | semmle.label | dataTra ... /html') | +| clipboard.ts:99:23:99:26 | html | semmle.label | html | +| custom-element.js:5:26:5:36 | window.name | semmle.label | window.name | +| d3.js:4:12:4:22 | window.name | semmle.label | window.name | +| d3.js:11:15:11:24 | getTaint() | semmle.label | getTaint() | +| d3.js:12:20:12:29 | getTaint() | semmle.label | getTaint() | +| d3.js:14:20:14:29 | getTaint() | semmle.label | getTaint() | +| d3.js:21:15:21:24 | getTaint() | semmle.label | getTaint() | +| dates.js:9:9:9:69 | taint | semmle.label | taint | +| dates.js:9:17:9:69 | decodeU ... ing(1)) | semmle.label | decodeU ... ing(1)) | +| dates.js:9:36:9:55 | window.location.hash | semmle.label | window.location.hash | +| dates.js:9:36:9:68 | window. ... ring(1) | semmle.label | window. ... ring(1) | +| dates.js:11:31:11:70 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:11:42:11:68 | dateFns ... taint) | semmle.label | dateFns ... taint) | +| dates.js:11:63:11:67 | taint | semmle.label | taint | +| dates.js:12:31:12:73 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:12:42:12:71 | dateFns ... taint) | semmle.label | dateFns ... taint) | +| dates.js:12:66:12:70 | taint | semmle.label | taint | +| dates.js:13:31:13:72 | `Time i ... time)}` | semmle.label | `Time i ... time)}` | +| dates.js:13:42:13:70 | dateFns ... )(time) | semmle.label | dateFns ... )(time) | +| dates.js:13:59:13:63 | taint | semmle.label | taint | +| dates.js:16:31:16:69 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:16:42:16:67 | moment( ... (taint) | semmle.label | moment( ... (taint) | +| dates.js:16:62:16:66 | taint | semmle.label | taint | +| dates.js:18:31:18:66 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:18:42:18:64 | datefor ... taint) | semmle.label | datefor ... taint) | +| dates.js:18:59:18:63 | taint | semmle.label | taint | +| dates.js:21:31:21:68 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:21:42:21:66 | dayjs(t ... (taint) | semmle.label | dayjs(t ... (taint) | +| dates.js:21:61:21:65 | taint | semmle.label | taint | +| dates.js:30:9:30:69 | taint | semmle.label | taint | +| dates.js:30:17:30:69 | decodeU ... ing(1)) | semmle.label | decodeU ... ing(1)) | +| dates.js:30:36:30:55 | window.location.hash | semmle.label | window.location.hash | +| dates.js:30:36:30:68 | window. ... ring(1) | semmle.label | window. ... ring(1) | +| dates.js:37:31:37:84 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:37:42:37:82 | dateFns ... taint) | semmle.label | dateFns ... taint) | +| dates.js:37:77:37:81 | taint | semmle.label | taint | +| dates.js:38:31:38:84 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:38:42:38:82 | luxon.f ... taint) | semmle.label | luxon.f ... taint) | +| dates.js:38:77:38:81 | taint | semmle.label | taint | +| dates.js:39:31:39:86 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:39:42:39:84 | moment. ... taint) | semmle.label | moment. ... taint) | +| dates.js:39:79:39:83 | taint | semmle.label | taint | +| dates.js:40:31:40:84 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:40:42:40:82 | dayjs.f ... taint) | semmle.label | dayjs.f ... taint) | +| dates.js:40:77:40:81 | taint | semmle.label | taint | +| dates.js:46:9:46:69 | taint | semmle.label | taint | +| dates.js:46:17:46:69 | decodeU ... ing(1)) | semmle.label | decodeU ... ing(1)) | +| dates.js:46:36:46:55 | window.location.hash | semmle.label | window.location.hash | +| dates.js:46:36:46:68 | window. ... ring(1) | semmle.label | window. ... ring(1) | +| dates.js:48:31:48:90 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:48:42:48:88 | DateTim ... (taint) | semmle.label | DateTim ... (taint) | +| dates.js:48:83:48:87 | taint | semmle.label | taint | +| dates.js:49:31:49:89 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:49:42:49:87 | new Dat ... (taint) | semmle.label | new Dat ... (taint) | +| dates.js:49:82:49:86 | taint | semmle.label | taint | +| dates.js:50:31:50:104 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:50:42:50:102 | DateTim ... (taint) | semmle.label | DateTim ... (taint) | +| dates.js:50:97:50:101 | taint | semmle.label | taint | +| dates.js:54:9:54:69 | taint | semmle.label | taint | +| dates.js:54:17:54:69 | decodeU ... ing(1)) | semmle.label | decodeU ... ing(1)) | +| dates.js:54:36:54:55 | window.location.hash | semmle.label | window.location.hash | +| dates.js:54:36:54:68 | window. ... ring(1) | semmle.label | window. ... ring(1) | +| dates.js:57:31:57:101 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:57:42:57:99 | moment. ... (taint) | semmle.label | moment. ... (taint) | +| dates.js:57:94:57:98 | taint | semmle.label | taint | +| dates.js:59:31:59:87 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:59:42:59:85 | luxon.e ... (taint) | semmle.label | luxon.e ... (taint) | +| dates.js:59:80:59:84 | taint | semmle.label | taint | +| dates.js:61:31:61:88 | `Time i ... aint)}` | semmle.label | `Time i ... aint)}` | +| dates.js:61:42:61:86 | dayjs.s ... (taint) | semmle.label | dayjs.s ... (taint) | +| dates.js:61:81:61:85 | taint | semmle.label | taint | +| dragAndDrop.ts:8:11:8:50 | html | semmle.label | html | +| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | semmle.label | dataTra ... /html') | +| dragAndDrop.ts:15:25:15:28 | html | semmle.label | html | +| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | semmle.label | e.dataT ... /html') | +| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | semmle.label | e.dataT ... /html') | +| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | semmle.label | e.origi ... /html') | +| dragAndDrop.ts:43:15:43:54 | html | semmle.label | html | +| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | semmle.label | dataTra ... /html') | +| dragAndDrop.ts:50:29:50:32 | html | semmle.label | html | +| dragAndDrop.ts:71:13:71:61 | droppedHtml | semmle.label | droppedHtml | +| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | semmle.label | e.dataT ... /html') | +| dragAndDrop.ts:73:29:73:39 | droppedHtml | semmle.label | droppedHtml | +| event-handler-receiver.js:2:31:2:83 | '

' | semmle.label | '

' | +| event-handler-receiver.js:2:49:2:61 | location.href | semmle.label | location.href | +| express.js:7:15:7:33 | req.param("wobble") | semmle.label | req.param("wobble") | +| jquery.js:2:7:2:40 | tainted | semmle.label | tainted | +| jquery.js:2:17:2:40 | documen ... .search | semmle.label | documen ... .search | +| jquery.js:7:5:7:34 | "
" | semmle.label | "
" | +| jquery.js:7:20:7:26 | tainted | semmle.label | tainted | +| jquery.js:8:18:8:34 | "XSS: " + tainted | semmle.label | "XSS: " + tainted | +| jquery.js:8:28:8:34 | tainted | semmle.label | tainted | +| jquery.js:10:5:10:40 | "" + ... "" | semmle.label | "" + ... "" | +| jquery.js:10:13:10:20 | location | semmle.label | location | +| jquery.js:10:13:10:31 | location.toString() | semmle.label | location.toString() | +| jquery.js:14:19:14:58 | decodeU ... n.hash) | semmle.label | decodeU ... n.hash) | +| jquery.js:14:38:14:57 | window.location.hash | semmle.label | window.location.hash | +| jquery.js:15:19:15:60 | decodeU ... search) | semmle.label | decodeU ... search) | +| jquery.js:15:38:15:59 | window. ... .search | semmle.label | window. ... .search | +| jquery.js:16:19:16:64 | decodeU ... ring()) | semmle.label | decodeU ... ring()) | +| jquery.js:16:38:16:52 | window.location | semmle.label | window.location | +| jquery.js:16:38:16:63 | window. ... tring() | semmle.label | window. ... tring() | +| jquery.js:18:7:18:33 | hash | semmle.label | hash | +| jquery.js:18:14:18:33 | window.location.hash | semmle.label | window.location.hash | +| jquery.js:21:5:21:8 | hash | semmle.label | hash | +| jquery.js:21:5:21:21 | hash.substring(1) | semmle.label | hash.substring(1) | +| jquery.js:22:5:22:8 | hash | semmle.label | hash | +| jquery.js:22:5:22:25 | hash.su ... (1, 10) | semmle.label | hash.su ... (1, 10) | +| jquery.js:23:5:23:8 | hash | semmle.label | hash | +| jquery.js:23:5:23:18 | hash.substr(1) | semmle.label | hash.substr(1) | +| jquery.js:24:5:24:8 | hash | semmle.label | hash | +| jquery.js:24:5:24:17 | hash.slice(1) | semmle.label | hash.slice(1) | +| jquery.js:27:5:27:8 | hash | semmle.label | hash | +| jquery.js:27:5:27:25 | hash.re ... #', '') | semmle.label | hash.re ... #', '') | +| jquery.js:28:5:28:26 | window. ... .search | semmle.label | window. ... .search | +| jquery.js:28:5:28:43 | window. ... ?', '') | semmle.label | window. ... ?', '') | +| jquery.js:34:5:34:25 | '' + ... '' | semmle.label | '' + ... '' | +| jquery.js:34:13:34:16 | hash | semmle.label | hash | +| jquery.js:36:25:36:31 | tainted | semmle.label | tainted | +| jquery.js:37:25:37:37 | () => tainted | semmle.label | () => tainted | +| jquery.js:37:31:37:37 | tainted | semmle.label | tainted | +| json-stringify.jsx:5:9:5:36 | locale | semmle.label | locale | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | semmle.label | req.param("locale") | +| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | semmle.label | `https: ... ocale}` | +| json-stringify.jsx:11:51:11:56 | locale | semmle.label | locale | +| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | semmle.label | `https: ... ocale}` | +| json-stringify.jsx:19:56:19:61 | locale | semmle.label | locale | +| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | semmle.label | JSON.st ... locale) | +| json-stringify.jsx:31:55:31:60 | locale | semmle.label | locale | +| json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | semmle.label | JSON.st ... jsonLD) | +| jwt-server.js:7:9:7:35 | taint | semmle.label | taint | +| jwt-server.js:7:17:7:35 | req.param("wobble") | semmle.label | req.param("wobble") | +| jwt-server.js:9:16:9:20 | taint | semmle.label | taint | +| jwt-server.js:9:55:9:61 | decoded | semmle.label | decoded | +| jwt-server.js:11:19:11:25 | decoded | semmle.label | decoded | +| jwt-server.js:11:19:11:29 | decoded.foo | semmle.label | decoded.foo | +| jwt.js:4:36:4:39 | data | semmle.label | data | +| jwt.js:5:9:5:34 | decoded | semmle.label | decoded | +| jwt.js:5:19:5:34 | jwt_decode(data) | semmle.label | jwt_decode(data) | +| jwt.js:5:30:5:33 | data | semmle.label | data | +| jwt.js:6:14:6:20 | decoded | semmle.label | decoded | +| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | semmle.label | `Hi, yo ... sage}.` | +| nodemailer.js:13:50:13:66 | req.query.message | semmle.label | req.query.message | +| optionalSanitizer.js:2:7:2:39 | target | semmle.label | target | +| optionalSanitizer.js:2:16:2:39 | documen ... .search | semmle.label | documen ... .search | +| optionalSanitizer.js:6:18:6:23 | target | semmle.label | target | +| optionalSanitizer.js:8:7:8:22 | tainted | semmle.label | tainted | +| optionalSanitizer.js:8:17:8:22 | target | semmle.label | target | +| optionalSanitizer.js:9:18:9:24 | tainted | semmle.label | tainted | +| optionalSanitizer.js:15:9:15:14 | target | semmle.label | target | +| optionalSanitizer.js:16:18:16:18 | x | semmle.label | x | +| optionalSanitizer.js:17:20:17:20 | x | semmle.label | x | +| optionalSanitizer.js:26:7:26:39 | target | semmle.label | target | +| optionalSanitizer.js:26:16:26:39 | documen ... .search | semmle.label | documen ... .search | +| optionalSanitizer.js:28:24:28:24 | x | semmle.label | x | +| optionalSanitizer.js:29:12:29:12 | x | semmle.label | x | +| optionalSanitizer.js:31:7:31:23 | tainted2 | semmle.label | tainted2 | +| optionalSanitizer.js:31:18:31:23 | target | semmle.label | target | +| optionalSanitizer.js:32:18:32:25 | tainted2 | semmle.label | tainted2 | +| optionalSanitizer.js:34:5:34:36 | tainted2 | semmle.label | tainted2 | +| optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | semmle.label | sanitiz ... inted2) | +| optionalSanitizer.js:34:28:34:35 | tainted2 | semmle.label | tainted2 | +| optionalSanitizer.js:36:18:36:25 | tainted2 | semmle.label | tainted2 | +| optionalSanitizer.js:38:7:38:23 | tainted3 | semmle.label | tainted3 | +| optionalSanitizer.js:38:18:38:23 | target | semmle.label | target | +| optionalSanitizer.js:39:18:39:25 | tainted3 | semmle.label | tainted3 | +| optionalSanitizer.js:41:5:41:36 | tainted3 | semmle.label | tainted3 | +| optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | semmle.label | sanitiz ... inted3) | +| optionalSanitizer.js:41:28:41:35 | tainted3 | semmle.label | tainted3 | +| optionalSanitizer.js:43:18:43:25 | tainted3 | semmle.label | tainted3 | +| optionalSanitizer.js:45:18:45:56 | sanitiz ... target | semmle.label | sanitiz ... target | +| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | semmle.label | sanitizeBad(target) | +| optionalSanitizer.js:45:41:45:46 | target | semmle.label | target | +| optionalSanitizer.js:45:51:45:56 | target | semmle.label | target | +| pages/[id].jsx:3:30:3:35 | params [id] | semmle.label | params [id] | +| pages/[id].jsx:3:30:3:35 | params [q] | semmle.label | params [q] | +| pages/[id].jsx:5:9:5:14 | { id } | semmle.label | { id } | +| pages/[id].jsx:5:9:5:29 | id | semmle.label | id | +| pages/[id].jsx:5:11:5:12 | id | semmle.label | id | +| pages/[id].jsx:5:18:5:29 | router.query | semmle.label | router.query | +| pages/[id].jsx:10:44:10:45 | id | semmle.label | id | +| pages/[id].jsx:13:44:13:49 | params [id] | semmle.label | params [id] | +| pages/[id].jsx:13:44:13:52 | params.id | semmle.label | params.id | +| pages/[id].jsx:16:44:16:49 | params [q] | semmle.label | params [q] | +| pages/[id].jsx:16:44:16:51 | params.q | semmle.label | params.q | +| pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | semmle.label | {\\n ... ,\\n } [id] | +| pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | semmle.label | {\\n ... ,\\n } [q] | +| pages/[id].jsx:25:11:25:24 | context.params | semmle.label | context.params | +| pages/[id].jsx:25:11:25:27 | context.params.id | semmle.label | context.params.id | +| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | semmle.label | context ... d \|\| "" | +| pages/[id].jsx:26:10:26:22 | context.query | semmle.label | context.query | +| pages/[id].jsx:26:10:26:30 | context ... .foobar | semmle.label | context ... .foobar | +| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | semmle.label | context ... r \|\| "" | +| react-native.js:7:7:7:33 | tainted | semmle.label | tainted | +| react-native.js:7:17:7:33 | req.param("code") | semmle.label | req.param("code") | +| react-native.js:8:18:8:24 | tainted | semmle.label | tainted | +| react-native.js:9:27:9:33 | tainted | semmle.label | tainted | +| react-use-context.js:10:22:10:32 | window.name | semmle.label | window.name | +| react-use-context.js:16:26:16:36 | window.name | semmle.label | window.name | +| react-use-router.js:8:21:8:32 | router.query | semmle.label | router.query | +| react-use-router.js:8:21:8:39 | router.query.foobar | semmle.label | router.query.foobar | +| react-use-router.js:11:24:11:35 | router.query | semmle.label | router.query | +| react-use-router.js:11:24:11:42 | router.query.foobar | semmle.label | router.query.foobar | +| react-use-router.js:23:31:23:36 | [post update] router | semmle.label | [post update] router | +| react-use-router.js:23:43:23:48 | router | semmle.label | router | +| react-use-router.js:23:43:23:54 | router.query | semmle.label | router.query | +| react-use-router.js:23:43:23:61 | router.query.foobar | semmle.label | router.query.foobar | +| react-use-router.js:33:21:33:32 | router.query | semmle.label | router.query | +| react-use-router.js:33:21:33:39 | router.query.foobar | semmle.label | router.query.foobar | +| react-use-state.js:4:9:4:49 | state | semmle.label | state | +| react-use-state.js:4:10:4:14 | state | semmle.label | state | +| react-use-state.js:4:38:4:48 | window.name | semmle.label | window.name | +| react-use-state.js:5:51:5:55 | state | semmle.label | state | +| react-use-state.js:9:9:9:43 | state | semmle.label | state | +| react-use-state.js:9:10:9:14 | state | semmle.label | state | +| react-use-state.js:10:14:10:24 | window.name | semmle.label | window.name | +| react-use-state.js:11:51:11:55 | state | semmle.label | state | +| react-use-state.js:15:9:15:43 | state | semmle.label | state | +| react-use-state.js:15:10:15:14 | state | semmle.label | state | +| react-use-state.js:16:20:16:30 | window.name | semmle.label | window.name | +| react-use-state.js:17:51:17:55 | state | semmle.label | state | +| react-use-state.js:21:10:21:14 | state | semmle.label | state | +| react-use-state.js:22:14:22:17 | prev | semmle.label | prev | +| react-use-state.js:23:35:23:38 | prev | semmle.label | prev | +| react-use-state.js:25:20:25:30 | window.name | semmle.label | window.name | +| sanitiser.js:16:7:16:27 | tainted | semmle.label | tainted | +| sanitiser.js:16:17:16:27 | window.name | semmle.label | window.name | +| sanitiser.js:23:21:23:44 | '' + ... '' | semmle.label | '' + ... '' | +| sanitiser.js:23:29:23:35 | tainted | semmle.label | tainted | +| sanitiser.js:25:21:25:44 | '' + ... '' | semmle.label | '' + ... '' | +| sanitiser.js:25:29:25:35 | tainted | semmle.label | tainted | +| sanitiser.js:28:21:28:44 | '' + ... '' | semmle.label | '' + ... '' | +| sanitiser.js:28:29:28:35 | tainted | semmle.label | tainted | +| sanitiser.js:30:21:30:44 | '' + ... '' | semmle.label | '' + ... '' | +| sanitiser.js:30:29:30:35 | tainted | semmle.label | tainted | +| sanitiser.js:33:21:33:44 | '' + ... '' | semmle.label | '' + ... '' | +| sanitiser.js:33:29:33:35 | tainted | semmle.label | tainted | +| sanitiser.js:35:21:35:44 | '' + ... '' | semmle.label | '' + ... '' | +| sanitiser.js:35:29:35:35 | tainted | semmle.label | tainted | +| sanitiser.js:38:21:38:44 | '' + ... '' | semmle.label | '' + ... '' | +| sanitiser.js:38:29:38:35 | tainted | semmle.label | tainted | +| sanitiser.js:45:21:45:44 | '' + ... '' | semmle.label | '' + ... '' | +| sanitiser.js:45:29:45:35 | tainted | semmle.label | tainted | +| sanitiser.js:48:19:48:25 | tainted | semmle.label | tainted | +| sanitiser.js:48:19:48:46 | tainted ... /g, '') | semmle.label | tainted ... /g, '') | +| stored-xss.js:2:39:2:62 | documen ... .search | semmle.label | documen ... .search | +| stored-xss.js:3:35:3:58 | documen ... .search | semmle.label | documen ... .search | +| stored-xss.js:5:20:5:52 | session ... ssion') | semmle.label | session ... ssion') | +| stored-xss.js:8:20:8:48 | localSt ... local') | semmle.label | localSt ... local') | +| stored-xss.js:10:9:10:44 | href | semmle.label | href | +| stored-xss.js:10:16:10:44 | localSt ... local') | semmle.label | localSt ... local') | +| stored-xss.js:12:20:12:54 | "" | semmle.label | "" | +| stored-xss.js:12:35:12:38 | href | semmle.label | href | +| string-manipulations.js:3:16:3:32 | document.location | semmle.label | document.location | +| string-manipulations.js:4:16:4:37 | documen ... on.href | semmle.label | documen ... on.href | +| string-manipulations.js:5:16:5:37 | documen ... on.href | semmle.label | documen ... on.href | +| string-manipulations.js:5:16:5:47 | documen ... lueOf() | semmle.label | documen ... lueOf() | +| string-manipulations.js:6:16:6:37 | documen ... on.href | semmle.label | documen ... on.href | +| string-manipulations.js:6:16:6:43 | documen ... f.sup() | semmle.label | documen ... f.sup() | +| string-manipulations.js:7:16:7:37 | documen ... on.href | semmle.label | documen ... on.href | +| string-manipulations.js:7:16:7:51 | documen ... rCase() | semmle.label | documen ... rCase() | +| string-manipulations.js:8:16:8:37 | documen ... on.href | semmle.label | documen ... on.href | +| string-manipulations.js:8:16:8:48 | documen ... mLeft() | semmle.label | documen ... mLeft() | +| string-manipulations.js:9:16:9:58 | String. ... n.href) | semmle.label | String. ... n.href) | +| string-manipulations.js:9:36:9:57 | documen ... on.href | semmle.label | documen ... on.href | +| string-manipulations.js:10:16:10:45 | String( ... n.href) | semmle.label | String( ... n.href) | +| string-manipulations.js:10:23:10:44 | documen ... on.href | semmle.label | documen ... on.href | +| tooltip.jsx:6:11:6:30 | source | semmle.label | source | +| tooltip.jsx:6:20:6:30 | window.name | semmle.label | window.name | +| tooltip.jsx:10:25:10:30 | source | semmle.label | source | +| tooltip.jsx:11:25:11:30 | source | semmle.label | source | +| translate.js:6:7:6:39 | target | semmle.label | target | +| translate.js:6:16:6:39 | documen ... .search | semmle.label | documen ... .search | +| translate.js:7:7:7:61 | searchParams | semmle.label | searchParams | +| translate.js:7:22:7:61 | new URL ... ing(1)) | semmle.label | new URL ... ing(1)) | +| translate.js:7:42:7:47 | target | semmle.label | target | +| translate.js:7:42:7:60 | target.substring(1) | semmle.label | target.substring(1) | +| translate.js:9:27:9:38 | searchParams | semmle.label | searchParams | +| translate.js:9:27:9:50 | searchP ... 'term') | semmle.label | searchP ... 'term') | +| trusted-types-lib.js:1:28:1:28 | x | semmle.label | x | +| trusted-types-lib.js:2:12:2:12 | x | semmle.label | x | +| trusted-types.js:3:62:3:62 | x | semmle.label | x | +| trusted-types.js:3:67:3:67 | x | semmle.label | x | +| trusted-types.js:4:20:4:30 | window.name | semmle.label | window.name | +| trusted-types.js:13:20:13:30 | window.name | semmle.label | window.name | +| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | semmle.label | JSON.pa ... tr(1))) | +| tst3.js:2:23:2:74 | decodeU ... str(1)) | semmle.label | decodeU ... str(1)) | +| tst3.js:2:42:2:63 | window. ... .search | semmle.label | window. ... .search | +| tst3.js:2:42:2:73 | window. ... bstr(1) | semmle.label | window. ... bstr(1) | +| tst3.js:4:25:4:28 | data | semmle.label | data | +| tst3.js:4:25:4:32 | data.src | semmle.label | data.src | +| tst3.js:5:26:5:29 | data | semmle.label | data | +| tst3.js:5:26:5:31 | data.p | semmle.label | data.p | +| tst3.js:7:32:7:35 | data | semmle.label | data | +| tst3.js:7:32:7:37 | data.p | semmle.label | data.p | +| tst3.js:9:37:9:40 | data | semmle.label | data | +| tst3.js:9:37:9:42 | data.p | semmle.label | data.p | +| tst3.js:10:38:10:41 | data | semmle.label | data | +| tst3.js:10:38:10:43 | data.p | semmle.label | data.p | +| tst.js:2:7:2:39 | target | semmle.label | target | +| tst.js:2:16:2:39 | documen ... .search | semmle.label | documen ... .search | +| tst.js:5:18:5:23 | target | semmle.label | target | +| tst.js:8:18:8:126 | "" | semmle.label | "" | +| tst.js:8:37:8:58 | documen ... on.href | semmle.label | documen ... on.href | +| tst.js:8:37:8:114 | documen ... t=")+8) | semmle.label | documen ... t=")+8) | +| tst.js:12:5:12:42 | '
' | semmle.label | '
' | +| tst.js:12:28:12:33 | target | semmle.label | target | +| tst.js:17:7:17:56 | params | semmle.label | params | +| tst.js:17:16:17:43 | (new UR ... ation)) [searchParams] | semmle.label | (new UR ... ation)) [searchParams] | +| tst.js:17:16:17:56 | (new UR ... hParams | semmle.label | (new UR ... hParams | +| tst.js:17:17:17:42 | new URL ... cation) [searchParams] | semmle.label | new URL ... cation) [searchParams] | +| tst.js:17:25:17:41 | document.location | semmle.label | document.location | +| tst.js:18:18:18:23 | params | semmle.label | params | +| tst.js:18:18:18:35 | params.get('name') | semmle.label | params.get('name') | +| tst.js:20:7:20:61 | searchParams | semmle.label | searchParams | +| tst.js:20:22:20:61 | new URL ... ing(1)) | semmle.label | new URL ... ing(1)) | +| tst.js:20:42:20:47 | target | semmle.label | target | +| tst.js:20:42:20:60 | target.substring(1) | semmle.label | target.substring(1) | +| tst.js:21:18:21:29 | searchParams | semmle.label | searchParams | +| tst.js:21:18:21:41 | searchP ... 'name') | semmle.label | searchP ... 'name') | +| tst.js:24:14:24:19 | target | semmle.label | target | +| tst.js:26:18:26:23 | target | semmle.label | target | +| tst.js:28:5:28:28 | documen ... .search | semmle.label | documen ... .search | +| tst.js:31:10:31:33 | documen ... .search | semmle.label | documen ... .search | +| tst.js:34:16:34:20 | bar() | semmle.label | bar() | +| tst.js:36:14:36:14 | x | semmle.label | x | +| tst.js:37:10:37:10 | x | semmle.label | x | +| tst.js:40:16:40:44 | baz(doc ... search) | semmle.label | baz(doc ... search) | +| tst.js:40:20:40:43 | documen ... .search | semmle.label | documen ... .search | +| tst.js:42:15:42:15 | s | semmle.label | s | +| tst.js:43:10:43:31 | "
" ...
" | semmle.label | "
" ...
" | +| tst.js:43:20:43:20 | s | semmle.label | s | +| tst.js:46:16:46:45 | wrap(do ... search) | semmle.label | wrap(do ... search) | +| tst.js:46:21:46:44 | documen ... .search | semmle.label | documen ... .search | +| tst.js:48:15:48:15 | s | semmle.label | s | +| tst.js:50:12:50:12 | s | semmle.label | s | +| tst.js:50:12:50:22 | s.substr(1) | semmle.label | s.substr(1) | +| tst.js:54:16:54:45 | chop(do ... search) | semmle.label | chop(do ... search) | +| tst.js:54:21:54:44 | documen ... .search | semmle.label | documen ... .search | +| tst.js:56:16:56:45 | chop(do ... search) | semmle.label | chop(do ... search) | +| tst.js:56:21:56:44 | documen ... .search | semmle.label | documen ... .search | +| tst.js:58:16:58:32 | wrap(chop(bar())) | semmle.label | wrap(chop(bar())) | +| tst.js:58:21:58:31 | chop(bar()) | semmle.label | chop(bar()) | +| tst.js:58:26:58:30 | bar() | semmle.label | bar() | +| tst.js:60:34:60:34 | s | semmle.label | s | +| tst.js:62:18:62:18 | s | semmle.label | s | +| tst.js:64:25:64:48 | documen ... .search | semmle.label | documen ... .search | +| tst.js:65:25:65:48 | documen ... .search | semmle.label | documen ... .search | +| tst.js:68:16:68:20 | bar() | semmle.label | bar() | +| tst.js:70:1:70:27 | [,docum ... search] | semmle.label | [,docum ... search] | +| tst.js:70:1:70:27 | [,docum ... search] [1] | semmle.label | [,docum ... search] [1] | +| tst.js:70:3:70:26 | documen ... .search | semmle.label | documen ... .search | +| tst.js:70:46:70:46 | x | semmle.label | x | +| tst.js:73:20:73:20 | x | semmle.label | x | +| tst.js:77:49:77:72 | documen ... .search | semmle.label | documen ... .search | +| tst.js:81:26:81:49 | documen ... .search | semmle.label | documen ... .search | +| tst.js:82:25:82:48 | documen ... .search | semmle.label | documen ... .search | +| tst.js:84:33:84:56 | documen ... .search | semmle.label | documen ... .search | +| tst.js:85:32:85:55 | documen ... .search | semmle.label | documen ... .search | +| tst.js:90:39:90:62 | documen ... .search | semmle.label | documen ... .search | +| tst.js:96:30:96:53 | documen ... .search | semmle.label | documen ... .search | +| tst.js:102:25:102:48 | documen ... .search | semmle.label | documen ... .search | +| tst.js:107:7:107:44 | v | semmle.label | v | +| tst.js:107:11:107:34 | documen ... .search | semmle.label | documen ... .search | +| tst.js:107:11:107:44 | documen ... bstr(1) | semmle.label | documen ... bstr(1) | +| tst.js:110:18:110:18 | v | semmle.label | v | +| tst.js:136:18:136:18 | v | semmle.label | v | +| tst.js:148:29:148:50 | window. ... .search | semmle.label | window. ... .search | +| tst.js:151:29:151:29 | v | semmle.label | v | +| tst.js:151:49:151:49 | v | semmle.label | v | +| tst.js:155:29:155:46 | xssSourceService() | semmle.label | xssSourceService() | +| tst.js:158:40:158:61 | window. ... .search | semmle.label | window. ... .search | +| tst.js:177:9:177:41 | target | semmle.label | target | +| tst.js:177:18:177:41 | documen ... .search | semmle.label | documen ... .search | +| tst.js:180:28:180:33 | target | semmle.label | target | +| tst.js:184:9:184:42 | tainted | semmle.label | tainted | +| tst.js:184:19:184:42 | documen ... .search | semmle.label | documen ... .search | +| tst.js:186:31:186:37 | tainted | semmle.label | tainted | +| tst.js:188:42:188:48 | tainted | semmle.label | tainted | +| tst.js:189:33:189:39 | tainted | semmle.label | tainted | +| tst.js:191:54:191:60 | tainted | semmle.label | tainted | +| tst.js:192:45:192:51 | tainted | semmle.label | tainted | +| tst.js:193:49:193:55 | tainted | semmle.label | tainted | +| tst.js:197:9:197:42 | tainted | semmle.label | tainted | +| tst.js:197:19:197:42 | documen ... .search | semmle.label | documen ... .search | +| tst.js:199:67:199:73 | tainted | semmle.label | tainted | +| tst.js:200:67:200:73 | tainted | semmle.label | tainted | +| tst.js:204:35:204:41 | tainted | semmle.label | tainted | +| tst.js:206:46:206:52 | tainted | semmle.label | tainted | +| tst.js:207:38:207:44 | tainted | semmle.label | tainted | +| tst.js:208:35:208:41 | tainted | semmle.label | tainted | +| tst.js:212:28:212:46 | this.state.tainted1 | semmle.label | this.state.tainted1 | +| tst.js:213:28:213:46 | this.state.tainted2 | semmle.label | this.state.tainted2 | +| tst.js:214:28:214:46 | this.state.tainted3 | semmle.label | this.state.tainted3 | +| tst.js:218:32:218:49 | prevState.tainted4 | semmle.label | prevState.tainted4 | +| tst.js:225:28:225:46 | this.props.tainted1 | semmle.label | this.props.tainted1 | +| tst.js:226:28:226:46 | this.props.tainted2 | semmle.label | this.props.tainted2 | +| tst.js:227:28:227:46 | this.props.tainted3 | semmle.label | this.props.tainted3 | +| tst.js:231:32:231:49 | prevProps.tainted4 | semmle.label | prevProps.tainted4 | +| tst.js:236:35:236:41 | tainted | semmle.label | tainted | +| tst.js:238:20:238:26 | tainted | semmle.label | tainted | +| tst.js:240:23:240:29 | tainted | semmle.label | tainted | +| tst.js:241:23:241:29 | tainted | semmle.label | tainted | +| tst.js:247:39:247:55 | props.propTainted | semmle.label | props.propTainted | +| tst.js:251:60:251:82 | this.st ... Tainted | semmle.label | this.st ... Tainted | +| tst.js:255:23:255:29 | tainted | semmle.label | tainted | +| tst.js:259:7:259:17 | window.name | semmle.label | window.name | +| tst.js:260:7:260:10 | name | semmle.label | name | +| tst.js:264:11:264:21 | window.name | semmle.label | window.name | +| tst.js:280:22:280:29 | location | semmle.label | location | +| tst.js:285:9:285:29 | tainted | semmle.label | tainted | +| tst.js:285:19:285:29 | window.name | semmle.label | window.name | +| tst.js:288:59:288:65 | tainted | semmle.label | tainted | +| tst.js:301:9:301:16 | location | semmle.label | location | +| tst.js:302:10:302:10 | e | semmle.label | e | +| tst.js:303:20:303:20 | e | semmle.label | e | +| tst.js:308:10:308:17 | location | semmle.label | location | +| tst.js:310:10:310:10 | e | semmle.label | e | +| tst.js:311:20:311:20 | e | semmle.label | e | +| tst.js:316:35:316:42 | location | semmle.label | location | +| tst.js:327:10:327:35 | new URL ... cation) [searchParams] | semmle.label | new URL ... cation) [searchParams] | +| tst.js:327:18:327:34 | document.location | semmle.label | document.location | +| tst.js:331:7:331:43 | params | semmle.label | params | +| tst.js:331:16:331:30 | getTaintedUrl() [searchParams] | semmle.label | getTaintedUrl() [searchParams] | +| tst.js:331:16:331:43 | getTain ... hParams | semmle.label | getTain ... hParams | +| tst.js:332:18:332:23 | params | semmle.label | params | +| tst.js:332:18:332:35 | params.get('name') | semmle.label | params.get('name') | +| tst.js:341:12:341:37 | new URL ... cation) [hash] | semmle.label | new URL ... cation) [hash] | +| tst.js:341:20:341:36 | document.location | semmle.label | document.location | +| tst.js:343:5:343:12 | getUrl() [hash] | semmle.label | getUrl() [hash] | +| tst.js:343:5:343:17 | getUrl().hash | semmle.label | getUrl().hash | +| tst.js:343:5:343:30 | getUrl( ... ring(1) | semmle.label | getUrl( ... ring(1) | +| tst.js:348:7:348:39 | target | semmle.label | target | +| tst.js:348:16:348:39 | documen ... .search | semmle.label | documen ... .search | +| tst.js:349:12:349:17 | target | semmle.label | target | +| tst.js:355:10:355:42 | target | semmle.label | target | +| tst.js:355:19:355:42 | documen ... .search | semmle.label | documen ... .search | +| tst.js:356:16:356:21 | target | semmle.label | target | +| tst.js:360:21:360:26 | target | semmle.label | target | +| tst.js:363:18:363:23 | target | semmle.label | target | +| tst.js:371:7:371:39 | target | semmle.label | target | +| tst.js:371:16:371:39 | documen ... .search | semmle.label | documen ... .search | +| tst.js:374:18:374:23 | target | semmle.label | target | +| tst.js:381:7:381:39 | target | semmle.label | target | +| tst.js:381:7:381:39 | target [taint3] | semmle.label | target [taint3] | +| tst.js:381:7:381:39 | target [taint8] | semmle.label | target [taint8] | +| tst.js:381:16:381:39 | documen ... .search | semmle.label | documen ... .search | +| tst.js:384:18:384:23 | target | semmle.label | target | +| tst.js:386:18:386:23 | target | semmle.label | target | +| tst.js:386:18:386:29 | target.taint | semmle.label | target.taint | +| tst.js:391:3:391:8 | [post update] target [taint3] | semmle.label | [post update] target [taint3] | +| tst.js:391:19:391:42 | documen ... .search | semmle.label | documen ... .search | +| tst.js:392:18:392:23 | target [taint3] | semmle.label | target [taint3] | +| tst.js:392:18:392:30 | target.taint3 | semmle.label | target.taint3 | +| tst.js:397:18:397:23 | target | semmle.label | target | +| tst.js:397:18:397:30 | target.taint5 | semmle.label | target.taint5 | +| tst.js:406:18:406:23 | target | semmle.label | target | +| tst.js:406:18:406:30 | target.taint7 | semmle.label | target.taint7 | +| tst.js:408:3:408:8 | [post update] target [taint8] | semmle.label | [post update] target [taint8] | +| tst.js:408:19:408:24 | target | semmle.label | target | +| tst.js:408:19:408:24 | target [taint8] | semmle.label | target [taint8] | +| tst.js:408:19:408:31 | target.taint8 | semmle.label | target.taint8 | +| tst.js:409:18:409:23 | target [taint8] | semmle.label | target [taint8] | +| tst.js:409:18:409:30 | target.taint8 | semmle.label | target.taint8 | +| tst.js:416:7:416:46 | payload | semmle.label | payload | +| tst.js:416:17:416:36 | window.location.hash | semmle.label | window.location.hash | +| tst.js:416:17:416:46 | window. ... bstr(1) | semmle.label | window. ... bstr(1) | +| tst.js:417:18:417:24 | payload | semmle.label | payload | +| tst.js:419:7:419:55 | match | semmle.label | match | +| tst.js:419:15:419:34 | window.location.hash | semmle.label | window.location.hash | +| tst.js:419:15:419:55 | window. ... (\\w+)/) | semmle.label | window. ... (\\w+)/) | +| tst.js:421:20:421:24 | match | semmle.label | match | +| tst.js:421:20:421:27 | match[1] | semmle.label | match[1] | +| tst.js:424:18:424:37 | window.location.hash | semmle.label | window.location.hash | +| tst.js:424:18:424:48 | window. ... it('#') | semmle.label | window. ... it('#') | +| tst.js:424:18:424:51 | window. ... '#')[1] | semmle.label | window. ... '#')[1] | +| tst.js:428:7:428:39 | target | semmle.label | target | +| tst.js:428:16:428:39 | documen ... .search | semmle.label | documen ... .search | +| tst.js:430:18:430:23 | target | semmle.label | target | +| tst.js:430:18:430:89 | target. ... data>') | semmle.label | target. ... data>') | +| tst.js:436:6:436:38 | source | semmle.label | source | +| tst.js:436:15:436:38 | documen ... .search | semmle.label | documen ... .search | +| tst.js:440:28:440:33 | source | semmle.label | source | +| tst.js:441:33:441:38 | source | semmle.label | source | +| tst.js:442:34:442:39 | source | semmle.label | source | +| tst.js:443:41:443:46 | source | semmle.label | source | +| tst.js:444:44:444:49 | source | semmle.label | source | +| tst.js:445:32:445:37 | source | semmle.label | source | +| tst.js:453:7:453:39 | source | semmle.label | source | +| tst.js:453:16:453:39 | documen ... .search | semmle.label | documen ... .search | +| tst.js:455:18:455:23 | source | semmle.label | source | +| tst.js:456:18:456:42 | ansiToH ... source) | semmle.label | ansiToH ... source) | +| tst.js:456:36:456:41 | source | semmle.label | source | +| tst.js:460:6:460:38 | source | semmle.label | source | +| tst.js:460:15:460:38 | documen ... .search | semmle.label | documen ... .search | +| tst.js:463:21:463:26 | source | semmle.label | source | +| tst.js:465:19:465:24 | source | semmle.label | source | +| tst.js:467:20:467:25 | source | semmle.label | source | +| tst.js:471:7:471:46 | url | semmle.label | url | +| tst.js:471:13:471:36 | documen ... .search | semmle.label | documen ... .search | +| tst.js:471:13:471:46 | documen ... bstr(1) | semmle.label | documen ... bstr(1) | +| tst.js:473:19:473:21 | url | semmle.label | url | +| tst.js:474:26:474:28 | url | semmle.label | url | +| tst.js:475:25:475:27 | url | semmle.label | url | +| tst.js:476:20:476:22 | url | semmle.label | url | +| tst.js:486:22:486:24 | url | semmle.label | url | +| tst.js:491:23:491:35 | location.hash | semmle.label | location.hash | +| tst.js:491:23:491:45 | locatio ... bstr(1) | semmle.label | locatio ... bstr(1) | +| tst.js:494:18:494:30 | location.hash | semmle.label | location.hash | +| tst.js:494:18:494:40 | locatio ... bstr(1) | semmle.label | locatio ... bstr(1) | +| tst.js:501:33:501:63 | decodeU ... n.hash) | semmle.label | decodeU ... n.hash) | +| tst.js:501:43:501:62 | window.location.hash | semmle.label | window.location.hash | +| typeahead.js:9:28:9:30 | loc | semmle.label | loc | +| typeahead.js:10:16:10:18 | loc | semmle.label | loc | +| typeahead.js:20:13:20:45 | target | semmle.label | target | +| typeahead.js:20:22:20:45 | documen ... .search | semmle.label | documen ... .search | +| typeahead.js:21:12:21:17 | target | semmle.label | target | +| typeahead.js:24:30:24:32 | val | semmle.label | val | +| typeahead.js:25:18:25:20 | val | semmle.label | val | +| various-concat-obfuscations.js:2:6:2:39 | tainted | semmle.label | tainted | +| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | semmle.label | documen ... .search | +| various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | semmle.label | "
" ...
" | +| various-concat-obfuscations.js:4:14:4:20 | tainted | semmle.label | tainted | +| various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | semmle.label | `
$ ...
` | +| various-concat-obfuscations.js:5:12:5:18 | tainted | semmle.label | tainted | +| various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | semmle.label | "
" ... ainted) | +| various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | semmle.label | "
" ... /div>") | +| various-concat-obfuscations.js:6:19:6:25 | tainted | semmle.label | tainted | +| various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | semmle.label | ["
... /div>"] | +| various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | semmle.label | ["
... .join() | +| various-concat-obfuscations.js:7:14:7:20 | tainted | semmle.label | tainted | +| various-concat-obfuscations.js:9:4:9:34 | "
" | semmle.label | "
" | +| various-concat-obfuscations.js:9:19:9:25 | tainted | semmle.label | tainted | +| various-concat-obfuscations.js:10:4:10:27 | `
` | semmle.label | `
` | +| various-concat-obfuscations.js:10:16:10:22 | tainted | semmle.label | tainted | +| various-concat-obfuscations.js:11:4:11:31 | "
") | semmle.label | "
") | +| various-concat-obfuscations.js:11:24:11:30 | tainted | semmle.label | tainted | +| various-concat-obfuscations.js:12:4:12:34 | ["
"] | semmle.label | ["
"] | +| various-concat-obfuscations.js:12:4:12:41 | ["
' | semmle.label | '
' | +| various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | semmle.label | (attrs. ... 'left') | +| various-concat-obfuscations.js:15:28:15:32 | attrs | semmle.label | attrs | +| various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | semmle.label | attrs.defaultattr | +| various-concat-obfuscations.js:17:24:17:28 | attrs | semmle.label | attrs | +| various-concat-obfuscations.js:18:10:18:59 | '
') | semmle.label | '
') | +| various-concat-obfuscations.js:18:32:18:36 | attrs | semmle.label | attrs | +| various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | semmle.label | attrs.defaultattr | +| various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | semmle.label | attrs.d ... 'left' | +| various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) | semmle.label | indirec ... .attrs) | +| various-concat-obfuscations.js:20:17:20:40 | documen ... .search | semmle.label | documen ... .search | +| various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | semmle.label | documen ... h.attrs | +| various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | semmle.label | indirec ... .attrs) | +| various-concat-obfuscations.js:21:17:21:40 | documen ... .search | semmle.label | documen ... .search | +| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | semmle.label | documen ... h.attrs | +| winjs.js:2:7:2:53 | tainted | semmle.label | tainted | +| winjs.js:2:17:2:40 | documen ... .search | semmle.label | documen ... .search | +| winjs.js:2:17:2:53 | documen ... ring(1) | semmle.label | documen ... ring(1) | +| winjs.js:3:43:3:49 | tainted | semmle.label | tainted | +| winjs.js:4:43:4:49 | tainted | semmle.label | tainted | +| xmlRequest.js:8:13:8:47 | json | semmle.label | json | +| xmlRequest.js:8:20:8:47 | JSON.pa ... seText) | semmle.label | JSON.pa ... seText) | +| xmlRequest.js:8:31:8:46 | xhr.responseText | semmle.label | xhr.responseText | +| xmlRequest.js:9:28:9:31 | json | semmle.label | json | +| xmlRequest.js:9:28:9:39 | json.message | semmle.label | json.message | +| xmlRequest.js:20:11:20:48 | resp | semmle.label | resp | +| xmlRequest.js:20:18:20:48 | await g ... rl }}") | semmle.label | await g ... rl }}") | +| xmlRequest.js:20:24:20:48 | got.get ... rl }}") | semmle.label | got.get ... rl }}") | +| xmlRequest.js:21:11:21:38 | json | semmle.label | json | +| xmlRequest.js:21:18:21:38 | JSON.pa ... p.body) | semmle.label | JSON.pa ... p.body) | +| xmlRequest.js:21:29:21:32 | resp | semmle.label | resp | +| xmlRequest.js:21:29:21:37 | resp.body | semmle.label | resp.body | +| xmlRequest.js:22:24:22:27 | json | semmle.label | json | +| xmlRequest.js:22:24:22:35 | json.message | semmle.label | json.message | edges | addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | -| addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | -| addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | -| addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | -| addEventListener.js:2:20:2:24 | event | addEventListener.js:2:20:2:29 | event.data | -| addEventListener.js:2:20:2:24 | event | addEventListener.js:2:20:2:29 | event.data | -| addEventListener.js:2:20:2:24 | event | addEventListener.js:2:20:2:29 | event.data | | addEventListener.js:2:20:2:24 | event | addEventListener.js:2:20:2:29 | event.data | | addEventListener.js:5:43:5:48 | data | addEventListener.js:6:20:6:23 | data | -| addEventListener.js:5:43:5:48 | data | addEventListener.js:6:20:6:23 | data | -| addEventListener.js:5:43:5:48 | data | addEventListener.js:6:20:6:23 | data | -| addEventListener.js:5:43:5:48 | data | addEventListener.js:6:20:6:23 | data | -| addEventListener.js:5:43:5:48 | {data} | addEventListener.js:5:44:5:47 | data | -| addEventListener.js:5:43:5:48 | {data} | addEventListener.js:5:44:5:47 | data | -| addEventListener.js:5:43:5:48 | {data} | addEventListener.js:5:44:5:47 | data | | addEventListener.js:5:43:5:48 | {data} | addEventListener.js:5:44:5:47 | data | | addEventListener.js:5:44:5:47 | data | addEventListener.js:5:43:5:48 | data | -| addEventListener.js:5:44:5:47 | data | addEventListener.js:5:43:5:48 | data | -| addEventListener.js:10:21:10:25 | event | addEventListener.js:12:24:12:28 | event | -| addEventListener.js:10:21:10:25 | event | addEventListener.js:12:24:12:28 | event | -| addEventListener.js:10:21:10:25 | event | addEventListener.js:12:24:12:28 | event | | addEventListener.js:10:21:10:25 | event | addEventListener.js:12:24:12:28 | event | | addEventListener.js:12:24:12:28 | event | addEventListener.js:12:24:12:33 | event.data | -| addEventListener.js:12:24:12:28 | event | addEventListener.js:12:24:12:33 | event.data | -| addEventListener.js:12:24:12:28 | event | addEventListener.js:12:24:12:33 | event.data | -| addEventListener.js:12:24:12:28 | event | addEventListener.js:12:24:12:33 | event.data | -| angular2-client.ts:22:44:22:71 | \\u0275getDOM ... ().href | angular2-client.ts:22:44:22:71 | \\u0275getDOM ... ().href | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | | angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | | angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:26:44:26:71 | this.ro ... ragment | angular2-client.ts:26:44:26:71 | this.ro ... ragment | -| angular2-client.ts:27:44:27:82 | this.ro ... ('foo') | angular2-client.ts:27:44:27:82 | this.ro ... ('foo') | -| angular2-client.ts:28:44:28:87 | this.ro ... ('foo') | angular2-client.ts:28:44:28:87 | this.ro ... ('foo') | -| angular2-client.ts:30:46:30:59 | map.get('foo') | angular2-client.ts:30:46:30:59 | map.get('foo') | -| angular2-client.ts:33:44:33:74 | this.ro ... 1].path | angular2-client.ts:33:44:33:74 | this.ro ... 1].path | | angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:35:44:35:91 | this.ro ... et('x') | angular2-client.ts:35:44:35:91 | this.ro ... et('x') | | angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:38:44:38:58 | this.router.url | angular2-client.ts:38:44:38:58 | this.router.url | -| angular2-client.ts:40:45:40:59 | this.router.url | angular2-client.ts:40:45:40:59 | this.router.url | -| angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | -| classnames.js:7:47:7:69 | classNa ... w.name) | classnames.js:7:31:7:84 | `` | | classnames.js:7:47:7:69 | classNa ... w.name) | classnames.js:7:31:7:84 | `` | | classnames.js:7:58:7:68 | window.name | classnames.js:7:47:7:69 | classNa ... w.name) | -| classnames.js:7:58:7:68 | window.name | classnames.js:7:47:7:69 | classNa ... w.name) | -| classnames.js:8:47:8:70 | classNa ... w.name) | classnames.js:8:31:8:85 | `` | | classnames.js:8:47:8:70 | classNa ... w.name) | classnames.js:8:31:8:85 | `` | | classnames.js:8:59:8:69 | window.name | classnames.js:8:47:8:70 | classNa ... w.name) | -| classnames.js:8:59:8:69 | window.name | classnames.js:8:47:8:70 | classNa ... w.name) | -| classnames.js:9:47:9:70 | classNa ... w.name) | classnames.js:9:31:9:85 | `` | | classnames.js:9:47:9:70 | classNa ... w.name) | classnames.js:9:31:9:85 | `` | | classnames.js:9:59:9:69 | window.name | classnames.js:9:47:9:70 | classNa ... w.name) | -| classnames.js:9:59:9:69 | window.name | classnames.js:9:47:9:70 | classNa ... w.name) | -| classnames.js:10:45:10:55 | window.name | classnames.js:11:47:11:64 | unsafeStyle('foo') | | classnames.js:10:45:10:55 | window.name | classnames.js:11:47:11:64 | unsafeStyle('foo') | | classnames.js:11:47:11:64 | unsafeStyle('foo') | classnames.js:11:31:11:79 | `` | -| classnames.js:11:47:11:64 | unsafeStyle('foo') | classnames.js:11:31:11:79 | `` | -| classnames.js:13:47:13:68 | safeSty ... w.name) | classnames.js:13:31:13:83 | `` | | classnames.js:13:47:13:68 | safeSty ... w.name) | classnames.js:13:31:13:83 | `` | | classnames.js:13:57:13:67 | window.name | classnames.js:13:47:13:68 | safeSty ... w.name) | -| classnames.js:13:57:13:67 | window.name | classnames.js:13:47:13:68 | safeSty ... w.name) | -| classnames.js:15:47:15:63 | clsx(window.name) | classnames.js:15:31:15:78 | `` | | classnames.js:15:47:15:63 | clsx(window.name) | classnames.js:15:31:15:78 | `` | | classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) | -| classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) | -| classnames.js:17:48:17:64 | clsx(window.name) | classnames.js:17:32:17:79 | `` | | classnames.js:17:48:17:64 | clsx(window.name) | classnames.js:17:32:17:79 | `` | | classnames.js:17:53:17:63 | window.name | classnames.js:17:48:17:64 | clsx(window.name) | -| classnames.js:17:53:17:63 | window.name | classnames.js:17:48:17:64 | clsx(window.name) | -| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | -| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | -| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | | clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | | clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:43:15:43:55 | html | clipboard.ts:50:29:50:32 | html | -| clipboard.ts:43:15:43:55 | html | clipboard.ts:50:29:50:32 | html | -| clipboard.ts:43:15:43:55 | html | clipboard.ts:50:29:50:32 | html | | clipboard.ts:43:15:43:55 | html | clipboard.ts:50:29:50:32 | html | | clipboard.ts:43:22:43:55 | clipboa ... /html') | clipboard.ts:43:15:43:55 | html | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | clipboard.ts:43:15:43:55 | html | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | clipboard.ts:43:15:43:55 | html | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | clipboard.ts:43:15:43:55 | html | -| clipboard.ts:71:13:71:62 | droppedHtml | clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:71:13:71:62 | droppedHtml | clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:71:13:71:62 | droppedHtml | clipboard.ts:73:29:73:39 | droppedHtml | | clipboard.ts:71:13:71:62 | droppedHtml | clipboard.ts:73:29:73:39 | droppedHtml | | clipboard.ts:71:27:71:62 | e.clipb ... /html') | clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:98:15:98:54 | html | clipboard.ts:99:23:99:26 | html | -| clipboard.ts:98:15:98:54 | html | clipboard.ts:99:23:99:26 | html | -| clipboard.ts:98:15:98:54 | html | clipboard.ts:99:23:99:26 | html | | clipboard.ts:98:15:98:54 | html | clipboard.ts:99:23:99:26 | html | | clipboard.ts:98:22:98:54 | dataTra ... /html') | clipboard.ts:98:15:98:54 | html | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | clipboard.ts:98:15:98:54 | html | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | clipboard.ts:98:15:98:54 | html | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | clipboard.ts:98:15:98:54 | html | -| custom-element.js:5:26:5:36 | window.name | custom-element.js:5:26:5:36 | window.name | -| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | | d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | | d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | | d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | | d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | | dates.js:9:9:9:69 | taint | dates.js:11:63:11:67 | taint | -| dates.js:9:9:9:69 | taint | dates.js:11:63:11:67 | taint | -| dates.js:9:9:9:69 | taint | dates.js:12:66:12:70 | taint | | dates.js:9:9:9:69 | taint | dates.js:12:66:12:70 | taint | | dates.js:9:9:9:69 | taint | dates.js:13:59:13:63 | taint | -| dates.js:9:9:9:69 | taint | dates.js:13:59:13:63 | taint | -| dates.js:9:9:9:69 | taint | dates.js:16:62:16:66 | taint | | dates.js:9:9:9:69 | taint | dates.js:16:62:16:66 | taint | | dates.js:9:9:9:69 | taint | dates.js:18:59:18:63 | taint | -| dates.js:9:9:9:69 | taint | dates.js:18:59:18:63 | taint | -| dates.js:9:9:9:69 | taint | dates.js:21:61:21:65 | taint | | dates.js:9:9:9:69 | taint | dates.js:21:61:21:65 | taint | | dates.js:9:17:9:69 | decodeU ... ing(1)) | dates.js:9:9:9:69 | taint | -| dates.js:9:17:9:69 | decodeU ... ing(1)) | dates.js:9:9:9:69 | taint | -| dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | -| dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | -| dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | | dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | | dates.js:9:36:9:68 | window. ... ring(1) | dates.js:9:17:9:69 | decodeU ... ing(1)) | -| dates.js:9:36:9:68 | window. ... ring(1) | dates.js:9:17:9:69 | decodeU ... ing(1)) | -| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | | dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | | dates.js:11:63:11:67 | taint | dates.js:11:42:11:68 | dateFns ... taint) | -| dates.js:11:63:11:67 | taint | dates.js:11:42:11:68 | dateFns ... taint) | -| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | | dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | | dates.js:12:66:12:70 | taint | dates.js:12:42:12:71 | dateFns ... taint) | -| dates.js:12:66:12:70 | taint | dates.js:12:42:12:71 | dateFns ... taint) | -| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | | dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | | dates.js:13:59:13:63 | taint | dates.js:13:42:13:70 | dateFns ... )(time) | -| dates.js:13:59:13:63 | taint | dates.js:13:42:13:70 | dateFns ... )(time) | -| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | | dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | | dates.js:16:62:16:66 | taint | dates.js:16:42:16:67 | moment( ... (taint) | -| dates.js:16:62:16:66 | taint | dates.js:16:42:16:67 | moment( ... (taint) | -| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | | dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | | dates.js:18:59:18:63 | taint | dates.js:18:42:18:64 | datefor ... taint) | -| dates.js:18:59:18:63 | taint | dates.js:18:42:18:64 | datefor ... taint) | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | | dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | | dates.js:21:61:21:65 | taint | dates.js:21:42:21:66 | dayjs(t ... (taint) | -| dates.js:21:61:21:65 | taint | dates.js:21:42:21:66 | dayjs(t ... (taint) | -| dates.js:30:9:30:69 | taint | dates.js:37:77:37:81 | taint | | dates.js:30:9:30:69 | taint | dates.js:37:77:37:81 | taint | | dates.js:30:9:30:69 | taint | dates.js:38:77:38:81 | taint | -| dates.js:30:9:30:69 | taint | dates.js:38:77:38:81 | taint | -| dates.js:30:9:30:69 | taint | dates.js:39:79:39:83 | taint | | dates.js:30:9:30:69 | taint | dates.js:39:79:39:83 | taint | | dates.js:30:9:30:69 | taint | dates.js:40:77:40:81 | taint | -| dates.js:30:9:30:69 | taint | dates.js:40:77:40:81 | taint | -| dates.js:30:17:30:69 | decodeU ... ing(1)) | dates.js:30:9:30:69 | taint | | dates.js:30:17:30:69 | decodeU ... ing(1)) | dates.js:30:9:30:69 | taint | | dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:30:36:30:68 | window. ... ring(1) | dates.js:30:17:30:69 | decodeU ... ing(1)) | | dates.js:30:36:30:68 | window. ... ring(1) | dates.js:30:17:30:69 | decodeU ... ing(1)) | | dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:77:37:81 | taint | dates.js:37:42:37:82 | dateFns ... taint) | | dates.js:37:77:37:81 | taint | dates.js:37:42:37:82 | dateFns ... taint) | | dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:77:38:81 | taint | dates.js:38:42:38:82 | luxon.f ... taint) | | dates.js:38:77:38:81 | taint | dates.js:38:42:38:82 | luxon.f ... taint) | | dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:79:39:83 | taint | dates.js:39:42:39:84 | moment. ... taint) | | dates.js:39:79:39:83 | taint | dates.js:39:42:39:84 | moment. ... taint) | | dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:77:40:81 | taint | dates.js:40:42:40:82 | dayjs.f ... taint) | | dates.js:40:77:40:81 | taint | dates.js:40:42:40:82 | dayjs.f ... taint) | | dates.js:46:9:46:69 | taint | dates.js:48:83:48:87 | taint | -| dates.js:46:9:46:69 | taint | dates.js:48:83:48:87 | taint | -| dates.js:46:9:46:69 | taint | dates.js:49:82:49:86 | taint | | dates.js:46:9:46:69 | taint | dates.js:49:82:49:86 | taint | | dates.js:46:9:46:69 | taint | dates.js:50:97:50:101 | taint | -| dates.js:46:9:46:69 | taint | dates.js:50:97:50:101 | taint | -| dates.js:46:17:46:69 | decodeU ... ing(1)) | dates.js:46:9:46:69 | taint | | dates.js:46:17:46:69 | decodeU ... ing(1)) | dates.js:46:9:46:69 | taint | | dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:46:36:46:68 | window. ... ring(1) | dates.js:46:17:46:69 | decodeU ... ing(1)) | | dates.js:46:36:46:68 | window. ... ring(1) | dates.js:46:17:46:69 | decodeU ... ing(1)) | | dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:83:48:87 | taint | dates.js:48:42:48:88 | DateTim ... (taint) | | dates.js:48:83:48:87 | taint | dates.js:48:42:48:88 | DateTim ... (taint) | | dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:82:49:86 | taint | dates.js:49:42:49:87 | new Dat ... (taint) | | dates.js:49:82:49:86 | taint | dates.js:49:42:49:87 | new Dat ... (taint) | | dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:97:50:101 | taint | dates.js:50:42:50:102 | DateTim ... (taint) | | dates.js:50:97:50:101 | taint | dates.js:50:42:50:102 | DateTim ... (taint) | | dates.js:54:9:54:69 | taint | dates.js:57:94:57:98 | taint | -| dates.js:54:9:54:69 | taint | dates.js:57:94:57:98 | taint | -| dates.js:54:9:54:69 | taint | dates.js:59:80:59:84 | taint | | dates.js:54:9:54:69 | taint | dates.js:59:80:59:84 | taint | | dates.js:54:9:54:69 | taint | dates.js:61:81:61:85 | taint | -| dates.js:54:9:54:69 | taint | dates.js:61:81:61:85 | taint | -| dates.js:54:17:54:69 | decodeU ... ing(1)) | dates.js:54:9:54:69 | taint | | dates.js:54:17:54:69 | decodeU ... ing(1)) | dates.js:54:9:54:69 | taint | | dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:54:36:54:68 | window. ... ring(1) | dates.js:54:17:54:69 | decodeU ... ing(1)) | | dates.js:54:36:54:68 | window. ... ring(1) | dates.js:54:17:54:69 | decodeU ... ing(1)) | | dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:94:57:98 | taint | dates.js:57:42:57:99 | moment. ... (taint) | | dates.js:57:94:57:98 | taint | dates.js:57:42:57:99 | moment. ... (taint) | | dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:80:59:84 | taint | dates.js:59:42:59:85 | luxon.e ... (taint) | | dates.js:59:80:59:84 | taint | dates.js:59:42:59:85 | luxon.e ... (taint) | | dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:81:61:85 | taint | dates.js:61:42:61:86 | dayjs.s ... (taint) | | dates.js:61:81:61:85 | taint | dates.js:61:42:61:86 | dayjs.s ... (taint) | | dragAndDrop.ts:8:11:8:50 | html | dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:8:11:8:50 | html | dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:8:11:8:50 | html | dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:8:11:8:50 | html | dragAndDrop.ts:15:25:15:28 | html | | dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:43:15:43:54 | html | dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:43:15:43:54 | html | dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:43:15:43:54 | html | dragAndDrop.ts:50:29:50:32 | html | | dragAndDrop.ts:43:15:43:54 | html | dragAndDrop.ts:50:29:50:32 | html | | dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:71:13:71:61 | droppedHtml | dragAndDrop.ts:73:29:73:39 | droppedHtml | -| dragAndDrop.ts:71:13:71:61 | droppedHtml | dragAndDrop.ts:73:29:73:39 | droppedHtml | -| dragAndDrop.ts:71:13:71:61 | droppedHtml | dragAndDrop.ts:73:29:73:39 | droppedHtml | | dragAndDrop.ts:71:13:71:61 | droppedHtml | dragAndDrop.ts:73:29:73:39 | droppedHtml | | dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | | event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | -| express.js:7:15:7:33 | req.param("wobble") | express.js:7:15:7:33 | req.param("wobble") | | jquery.js:2:7:2:40 | tainted | jquery.js:7:20:7:26 | tainted | | jquery.js:2:7:2:40 | tainted | jquery.js:8:28:8:34 | tainted | | jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | -| jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | | jquery.js:2:7:2:40 | tainted | jquery.js:37:31:37:37 | tainted | | jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | -| jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | -| jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "
" | | jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "
" | | jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | -| jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | -| jquery.js:10:13:10:20 | location | jquery.js:10:13:10:31 | location.toString() | | jquery.js:10:13:10:20 | location | jquery.js:10:13:10:31 | location.toString() | | jquery.js:10:13:10:31 | location.toString() | jquery.js:10:5:10:40 | "" + ... "" | -| jquery.js:10:13:10:31 | location.toString() | jquery.js:10:5:10:40 | "" + ... "" | | jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | -| jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | -| jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | | jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | | jquery.js:16:38:16:52 | window.location | jquery.js:16:38:16:63 | window. ... tring() | -| jquery.js:16:38:16:52 | window.location | jquery.js:16:38:16:63 | window. ... tring() | -| jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) | | jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) | | jquery.js:18:7:18:33 | hash | jquery.js:21:5:21:8 | hash | | jquery.js:18:7:18:33 | hash | jquery.js:22:5:22:8 | hash | @@ -1633,350 +766,149 @@ edges | jquery.js:18:7:18:33 | hash | jquery.js:27:5:27:8 | hash | | jquery.js:18:7:18:33 | hash | jquery.js:34:13:34:16 | hash | | jquery.js:18:14:18:33 | window.location.hash | jquery.js:18:7:18:33 | hash | -| jquery.js:18:14:18:33 | window.location.hash | jquery.js:18:7:18:33 | hash | -| jquery.js:21:5:21:8 | hash | jquery.js:21:5:21:21 | hash.substring(1) | -| jquery.js:21:5:21:8 | hash | jquery.js:21:5:21:21 | hash.substring(1) | | jquery.js:21:5:21:8 | hash | jquery.js:21:5:21:21 | hash.substring(1) | | jquery.js:22:5:22:8 | hash | jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:22:5:22:8 | hash | jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:22:5:22:8 | hash | jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:23:5:23:8 | hash | jquery.js:23:5:23:18 | hash.substr(1) | -| jquery.js:23:5:23:8 | hash | jquery.js:23:5:23:18 | hash.substr(1) | | jquery.js:23:5:23:8 | hash | jquery.js:23:5:23:18 | hash.substr(1) | | jquery.js:24:5:24:8 | hash | jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:24:5:24:8 | hash | jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:24:5:24:8 | hash | jquery.js:24:5:24:17 | hash.slice(1) | | jquery.js:27:5:27:8 | hash | jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:27:5:27:8 | hash | jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:27:5:27:8 | hash | jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | | jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | | jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '' + ... '' | -| jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '' + ... '' | -| jquery.js:37:31:37:37 | tainted | jquery.js:37:25:37:37 | () => tainted | | jquery.js:37:31:37:37 | tainted | jquery.js:37:25:37:37 | () => tainted | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:11:51:11:56 | locale | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:19:56:19:61 | locale | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:31:55:31:60 | locale | -| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:31:55:31:60 | locale | | json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | | json-stringify.jsx:11:51:11:56 | locale | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | | json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | -| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | | json-stringify.jsx:19:56:19:61 | locale | json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | | json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| jwt-server.js:7:9:7:35 | taint | jwt-server.js:9:16:9:20 | taint | | jwt-server.js:7:9:7:35 | taint | jwt-server.js:9:16:9:20 | taint | | jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:9:16:9:20 | taint | jwt-server.js:9:55:9:61 | decoded | | jwt-server.js:9:16:9:20 | taint | jwt-server.js:9:55:9:61 | decoded | | jwt-server.js:9:55:9:61 | decoded | jwt-server.js:11:19:11:25 | decoded | -| jwt-server.js:9:55:9:61 | decoded | jwt-server.js:11:19:11:25 | decoded | -| jwt-server.js:11:19:11:25 | decoded | jwt-server.js:11:19:11:29 | decoded.foo | -| jwt-server.js:11:19:11:25 | decoded | jwt-server.js:11:19:11:29 | decoded.foo | -| jwt-server.js:11:19:11:25 | decoded | jwt-server.js:11:19:11:29 | decoded.foo | | jwt-server.js:11:19:11:25 | decoded | jwt-server.js:11:19:11:29 | decoded.foo | | jwt.js:4:36:4:39 | data | jwt.js:5:30:5:33 | data | -| jwt.js:4:36:4:39 | data | jwt.js:5:30:5:33 | data | -| jwt.js:4:36:4:39 | data | jwt.js:5:30:5:33 | data | -| jwt.js:4:36:4:39 | data | jwt.js:5:30:5:33 | data | -| jwt.js:5:9:5:34 | decoded | jwt.js:6:14:6:20 | decoded | -| jwt.js:5:9:5:34 | decoded | jwt.js:6:14:6:20 | decoded | -| jwt.js:5:9:5:34 | decoded | jwt.js:6:14:6:20 | decoded | | jwt.js:5:9:5:34 | decoded | jwt.js:6:14:6:20 | decoded | | jwt.js:5:19:5:34 | jwt_decode(data) | jwt.js:5:9:5:34 | decoded | -| jwt.js:5:19:5:34 | jwt_decode(data) | jwt.js:5:9:5:34 | decoded | -| jwt.js:5:30:5:33 | data | jwt.js:5:19:5:34 | jwt_decode(data) | | jwt.js:5:30:5:33 | data | jwt.js:5:19:5:34 | jwt_decode(data) | | nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:6:18:6:23 | target | | optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:6:18:6:23 | target | | optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:8:17:8:22 | target | | optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:15:9:15:14 | target | | optionalSanitizer.js:2:16:2:39 | documen ... .search | optionalSanitizer.js:2:7:2:39 | target | -| optionalSanitizer.js:2:16:2:39 | documen ... .search | optionalSanitizer.js:2:7:2:39 | target | -| optionalSanitizer.js:8:7:8:22 | tainted | optionalSanitizer.js:9:18:9:24 | tainted | | optionalSanitizer.js:8:7:8:22 | tainted | optionalSanitizer.js:9:18:9:24 | tainted | | optionalSanitizer.js:8:17:8:22 | target | optionalSanitizer.js:8:7:8:22 | tainted | | optionalSanitizer.js:15:9:15:14 | target | optionalSanitizer.js:16:18:16:18 | x | | optionalSanitizer.js:16:18:16:18 | x | optionalSanitizer.js:17:20:17:20 | x | -| optionalSanitizer.js:16:18:16:18 | x | optionalSanitizer.js:17:20:17:20 | x | | optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:31:18:31:23 | target | | optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:38:18:38:23 | target | | optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:45:41:45:46 | target | | optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:45:51:45:56 | target | | optionalSanitizer.js:26:16:26:39 | documen ... .search | optionalSanitizer.js:26:7:26:39 | target | -| optionalSanitizer.js:26:16:26:39 | documen ... .search | optionalSanitizer.js:26:7:26:39 | target | -| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:32:18:32:25 | tainted2 | +| optionalSanitizer.js:28:24:28:24 | x | optionalSanitizer.js:29:12:29:12 | x | | optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:32:18:32:25 | tainted2 | | optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:34:28:34:35 | tainted2 | | optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 | -| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 | | optionalSanitizer.js:31:18:31:23 | target | optionalSanitizer.js:31:7:31:23 | tainted2 | | optionalSanitizer.js:34:5:34:36 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 | -| optionalSanitizer.js:34:5:34:36 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 | | optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | optionalSanitizer.js:34:5:34:36 | tainted2 | +| optionalSanitizer.js:34:28:34:35 | tainted2 | optionalSanitizer.js:28:24:28:24 | x | | optionalSanitizer.js:34:28:34:35 | tainted2 | optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | | optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:39:18:39:25 | tainted3 | -| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:39:18:39:25 | tainted3 | | optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:41:28:41:35 | tainted3 | | optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 | -| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 | | optionalSanitizer.js:38:18:38:23 | target | optionalSanitizer.js:38:7:38:23 | tainted3 | | optionalSanitizer.js:41:5:41:36 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 | -| optionalSanitizer.js:41:5:41:36 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 | | optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | optionalSanitizer.js:41:5:41:36 | tainted3 | +| optionalSanitizer.js:41:28:41:35 | tainted3 | optionalSanitizer.js:28:24:28:24 | x | | optionalSanitizer.js:41:28:41:35 | tainted3 | optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | | optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | +| optionalSanitizer.js:45:41:45:46 | target | optionalSanitizer.js:28:24:28:24 | x | | optionalSanitizer.js:45:41:45:46 | target | optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | | optionalSanitizer.js:45:51:45:56 | target | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| optionalSanitizer.js:45:51:45:56 | target | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| pages/[id].jsx:5:9:5:14 | { id } | pages/[id].jsx:5:11:5:12 | id | +| pages/[id].jsx:3:30:3:35 | params [id] | pages/[id].jsx:13:44:13:49 | params [id] | +| pages/[id].jsx:3:30:3:35 | params [q] | pages/[id].jsx:16:44:16:49 | params [q] | | pages/[id].jsx:5:9:5:14 | { id } | pages/[id].jsx:5:11:5:12 | id | | pages/[id].jsx:5:9:5:29 | id | pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:5:9:5:29 | id | pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:5:9:5:29 | id | pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:5:9:5:29 | id | pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:5:11:5:12 | id | pages/[id].jsx:5:9:5:29 | id | | pages/[id].jsx:5:11:5:12 | id | pages/[id].jsx:5:9:5:29 | id | | pages/[id].jsx:5:18:5:29 | router.query | pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:5:18:5:29 | router.query | pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:5:18:5:29 | router.query | pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:5:18:5:29 | router.query | pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:25:11:25:24 | context.params | pages/[id].jsx:25:11:25:27 | context.params.id | -| pages/[id].jsx:25:11:25:24 | context.params | pages/[id].jsx:25:11:25:27 | context.params.id | -| pages/[id].jsx:25:11:25:24 | context.params | pages/[id].jsx:25:11:25:27 | context.params.id | +| pages/[id].jsx:13:44:13:49 | params [id] | pages/[id].jsx:13:44:13:52 | params.id | +| pages/[id].jsx:16:44:16:49 | params [q] | pages/[id].jsx:16:44:16:51 | params.q | +| pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | pages/[id].jsx:3:30:3:35 | params [id] | +| pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | pages/[id].jsx:3:30:3:35 | params [q] | | pages/[id].jsx:25:11:25:24 | context.params | pages/[id].jsx:25:11:25:27 | context.params.id | | pages/[id].jsx:25:11:25:27 | context.params.id | pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | -| pages/[id].jsx:25:11:25:27 | context.params.id | pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:26:10:26:22 | context.query | pages/[id].jsx:26:10:26:30 | context ... .foobar | -| pages/[id].jsx:26:10:26:22 | context.query | pages/[id].jsx:26:10:26:30 | context ... .foobar | -| pages/[id].jsx:26:10:26:22 | context.query | pages/[id].jsx:26:10:26:30 | context ... .foobar | +| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | | pages/[id].jsx:26:10:26:22 | context.query | pages/[id].jsx:26:10:26:30 | context ... .foobar | | pages/[id].jsx:26:10:26:30 | context ... .foobar | pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | -| pages/[id].jsx:26:10:26:30 | context ... .foobar | pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | pages/[id].jsx:16:44:16:51 | params.q | -| react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted | +| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | | react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted | | react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted | | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | -| react-use-context.js:10:22:10:32 | window.name | react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:16:26:16:36 | window.name | react-use-context.js:16:26:16:36 | window.name | -| react-use-router.js:4:9:4:28 | router | react-use-router.js:8:21:8:26 | router | -| react-use-router.js:4:9:4:28 | router | react-use-router.js:11:24:11:29 | router | -| react-use-router.js:4:18:4:28 | useRouter() | react-use-router.js:4:9:4:28 | router | -| react-use-router.js:8:21:8:26 | router | react-use-router.js:8:21:8:32 | router.query | | react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:8:21:8:39 | router.query.foobar | react-use-router.js:4:18:4:28 | useRouter() | -| react-use-router.js:11:24:11:29 | router | react-use-router.js:11:24:11:35 | router.query | | react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:22:15:22:24 | router | react-use-router.js:23:43:23:48 | router | -| react-use-router.js:22:17:22:22 | router | react-use-router.js:22:15:22:24 | router | +| react-use-router.js:23:31:23:36 | [post update] router | react-use-router.js:23:43:23:48 | router | | react-use-router.js:23:43:23:48 | router | react-use-router.js:23:43:23:54 | router.query | | react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:22:17:22:22 | router | -| react-use-router.js:29:9:29:30 | router | react-use-router.js:33:21:33:26 | router | -| react-use-router.js:29:18:29:30 | myUseRouter() | react-use-router.js:29:9:29:30 | router | -| react-use-router.js:33:21:33:26 | router | react-use-router.js:33:21:33:32 | router.query | +| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:31:23:36 | [post update] router | | react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-router.js:33:21:33:39 | router.query.foobar | react-use-router.js:29:18:29:30 | myUseRouter() | -| react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | -| react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | -| react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | | react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | | react-use-state.js:4:10:4:14 | state | react-use-state.js:4:9:4:49 | state | -| react-use-state.js:4:10:4:14 | state | react-use-state.js:4:9:4:49 | state | | react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:10:4:14 | state | -| react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:10:4:14 | state | -| react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:10:4:14 | state | -| react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:10:4:14 | state | -| react-use-state.js:9:9:9:43 | state | react-use-state.js:11:51:11:55 | state | -| react-use-state.js:9:9:9:43 | state | react-use-state.js:11:51:11:55 | state | -| react-use-state.js:9:9:9:43 | state | react-use-state.js:11:51:11:55 | state | | react-use-state.js:9:9:9:43 | state | react-use-state.js:11:51:11:55 | state | | react-use-state.js:9:10:9:14 | state | react-use-state.js:9:9:9:43 | state | -| react-use-state.js:9:10:9:14 | state | react-use-state.js:9:9:9:43 | state | | react-use-state.js:10:14:10:24 | window.name | react-use-state.js:9:10:9:14 | state | -| react-use-state.js:10:14:10:24 | window.name | react-use-state.js:9:10:9:14 | state | -| react-use-state.js:10:14:10:24 | window.name | react-use-state.js:9:10:9:14 | state | -| react-use-state.js:10:14:10:24 | window.name | react-use-state.js:9:10:9:14 | state | -| react-use-state.js:15:9:15:43 | state | react-use-state.js:17:51:17:55 | state | -| react-use-state.js:15:9:15:43 | state | react-use-state.js:17:51:17:55 | state | -| react-use-state.js:15:9:15:43 | state | react-use-state.js:17:51:17:55 | state | | react-use-state.js:15:9:15:43 | state | react-use-state.js:17:51:17:55 | state | | react-use-state.js:15:10:15:14 | state | react-use-state.js:15:9:15:43 | state | -| react-use-state.js:15:10:15:14 | state | react-use-state.js:15:9:15:43 | state | -| react-use-state.js:16:20:16:30 | window.name | react-use-state.js:15:10:15:14 | state | -| react-use-state.js:16:20:16:30 | window.name | react-use-state.js:15:10:15:14 | state | -| react-use-state.js:16:20:16:30 | window.name | react-use-state.js:15:10:15:14 | state | | react-use-state.js:16:20:16:30 | window.name | react-use-state.js:15:10:15:14 | state | | react-use-state.js:21:10:21:14 | state | react-use-state.js:22:14:22:17 | prev | -| react-use-state.js:21:10:21:14 | state | react-use-state.js:22:14:22:17 | prev | | react-use-state.js:22:14:22:17 | prev | react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:22:14:22:17 | prev | react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:22:14:22:17 | prev | react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:22:14:22:17 | prev | react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:25:20:25:30 | window.name | react-use-state.js:21:10:21:14 | state | -| react-use-state.js:25:20:25:30 | window.name | react-use-state.js:21:10:21:14 | state | -| react-use-state.js:25:20:25:30 | window.name | react-use-state.js:21:10:21:14 | state | | react-use-state.js:25:20:25:30 | window.name | react-use-state.js:21:10:21:14 | state | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:23:29:23:35 | tainted | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:25:29:25:35 | tainted | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:28:29:28:35 | tainted | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:30:29:30:35 | tainted | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:33:29:33:35 | tainted | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:35:29:35:35 | tainted | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:38:29:38:35 | tainted | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:45:29:45:35 | tainted | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:48:19:48:25 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:48:19:48:25 | tainted | -| sanitiser.js:16:17:16:27 | window.name | sanitiser.js:16:7:16:27 | tainted | -| sanitiser.js:16:17:16:27 | window.name | sanitiser.js:16:7:16:27 | tainted | -| sanitiser.js:16:17:16:27 | window.name | sanitiser.js:16:7:16:27 | tainted | | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:16:7:16:27 | tainted | | sanitiser.js:23:29:23:35 | tainted | sanitiser.js:23:21:23:44 | '' + ... '' | -| sanitiser.js:23:29:23:35 | tainted | sanitiser.js:23:21:23:44 | '' + ... '' | -| sanitiser.js:30:29:30:35 | tainted | sanitiser.js:30:21:30:44 | '' + ... '' | +| sanitiser.js:25:29:25:35 | tainted | sanitiser.js:25:21:25:44 | '' + ... '' | +| sanitiser.js:28:29:28:35 | tainted | sanitiser.js:28:21:28:44 | '' + ... '' | | sanitiser.js:30:29:30:35 | tainted | sanitiser.js:30:21:30:44 | '' + ... '' | | sanitiser.js:33:29:33:35 | tainted | sanitiser.js:33:21:33:44 | '' + ... '' | -| sanitiser.js:33:29:33:35 | tainted | sanitiser.js:33:21:33:44 | '' + ... '' | -| sanitiser.js:38:29:38:35 | tainted | sanitiser.js:38:21:38:44 | '' + ... '' | +| sanitiser.js:35:29:35:35 | tainted | sanitiser.js:35:21:35:44 | '' + ... '' | | sanitiser.js:38:29:38:35 | tainted | sanitiser.js:38:21:38:44 | '' + ... '' | | sanitiser.js:45:29:45:35 | tainted | sanitiser.js:45:21:45:44 | '' + ... '' | -| sanitiser.js:45:29:45:35 | tainted | sanitiser.js:45:21:45:44 | '' + ... '' | -| sanitiser.js:48:19:48:25 | tainted | sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| sanitiser.js:48:19:48:25 | tainted | sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| sanitiser.js:48:19:48:25 | tainted | sanitiser.js:48:19:48:46 | tainted ... /g, '') | | sanitiser.js:48:19:48:25 | tainted | sanitiser.js:48:19:48:46 | tainted ... /g, '') | | stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | -| stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | -| stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | -| stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | | stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:10:16:10:44 | localSt ... local') | | stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:10:16:10:44 | localSt ... local') | | stored-xss.js:10:9:10:44 | href | stored-xss.js:12:35:12:38 | href | | stored-xss.js:10:16:10:44 | localSt ... local') | stored-xss.js:10:9:10:44 | href | | stored-xss.js:12:35:12:38 | href | stored-xss.js:12:20:12:54 | "" | -| stored-xss.js:12:35:12:38 | href | stored-xss.js:12:20:12:54 | "" | -| stored-xss.js:12:35:12:38 | href | stored-xss.js:12:20:12:54 | "" | -| string-manipulations.js:3:16:3:32 | document.location | string-manipulations.js:3:16:3:32 | document.location | -| string-manipulations.js:4:16:4:37 | documen ... on.href | string-manipulations.js:4:16:4:37 | documen ... on.href | -| string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | -| string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | -| string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | | string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | | string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | -| string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | -| string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | | string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | | string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | -| string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | -| string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | | string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | | string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | -| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | -| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | -| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | -| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | | tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | | tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source | -| tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source | -| tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source | | tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source | | translate.js:6:7:6:39 | target | translate.js:7:42:7:47 | target | | translate.js:6:16:6:39 | documen ... .search | translate.js:6:7:6:39 | target | -| translate.js:6:16:6:39 | documen ... .search | translate.js:6:7:6:39 | target | | translate.js:7:7:7:61 | searchParams | translate.js:9:27:9:38 | searchParams | | translate.js:7:22:7:61 | new URL ... ing(1)) | translate.js:7:7:7:61 | searchParams | | translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | -| translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | -| translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | | translate.js:7:42:7:60 | target.substring(1) | translate.js:7:22:7:61 | new URL ... ing(1)) | -| translate.js:7:42:7:60 | target.substring(1) | translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:7:42:7:60 | target.substring(1) | translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:7:42:7:60 | target.substring(1) | translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:7:42:7:60 | target.substring(1) | translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:7:42:7:60 | target.substring(1) | translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:7:42:7:60 | target.substring(1) | translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:9:27:9:38 | searchParams | translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:9:27:9:38 | searchParams | translate.js:9:27:9:50 | searchP ... 'term') | | translate.js:9:27:9:38 | searchParams | translate.js:9:27:9:50 | searchP ... 'term') | | trusted-types-lib.js:1:28:1:28 | x | trusted-types-lib.js:2:12:2:12 | x | -| trusted-types-lib.js:1:28:1:28 | x | trusted-types-lib.js:2:12:2:12 | x | -| trusted-types-lib.js:1:28:1:28 | x | trusted-types-lib.js:2:12:2:12 | x | -| trusted-types-lib.js:1:28:1:28 | x | trusted-types-lib.js:2:12:2:12 | x | -| trusted-types.js:3:62:3:62 | x | trusted-types.js:3:67:3:67 | x | -| trusted-types.js:3:62:3:62 | x | trusted-types.js:3:67:3:67 | x | -| trusted-types.js:3:62:3:62 | x | trusted-types.js:3:67:3:67 | x | | trusted-types.js:3:62:3:62 | x | trusted-types.js:3:67:3:67 | x | | trusted-types.js:4:20:4:30 | window.name | trusted-types.js:3:62:3:62 | x | -| trusted-types.js:4:20:4:30 | window.name | trusted-types.js:3:62:3:62 | x | -| trusted-types.js:4:20:4:30 | window.name | trusted-types.js:3:62:3:62 | x | -| trusted-types.js:4:20:4:30 | window.name | trusted-types.js:3:62:3:62 | x | -| trusted-types.js:13:20:13:30 | window.name | trusted-types-lib.js:1:28:1:28 | x | -| trusted-types.js:13:20:13:30 | window.name | trusted-types-lib.js:1:28:1:28 | x | -| trusted-types.js:13:20:13:30 | window.name | trusted-types-lib.js:1:28:1:28 | x | | trusted-types.js:13:20:13:30 | window.name | trusted-types-lib.js:1:28:1:28 | x | | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:4:25:4:28 | data | | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:5:26:5:29 | data | @@ -1985,179 +917,77 @@ edges | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:10:38:10:41 | data | | tst3.js:2:23:2:74 | decodeU ... str(1)) | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | | tst3.js:2:42:2:63 | window. ... .search | tst3.js:2:42:2:73 | window. ... bstr(1) | -| tst3.js:2:42:2:63 | window. ... .search | tst3.js:2:42:2:73 | window. ... bstr(1) | | tst3.js:2:42:2:73 | window. ... bstr(1) | tst3.js:2:23:2:74 | decodeU ... str(1)) | | tst3.js:4:25:4:28 | data | tst3.js:4:25:4:32 | data.src | -| tst3.js:4:25:4:28 | data | tst3.js:4:25:4:32 | data.src | -| tst3.js:5:26:5:29 | data | tst3.js:5:26:5:31 | data.p | | tst3.js:5:26:5:29 | data | tst3.js:5:26:5:31 | data.p | | tst3.js:7:32:7:35 | data | tst3.js:7:32:7:37 | data.p | -| tst3.js:7:32:7:35 | data | tst3.js:7:32:7:37 | data.p | -| tst3.js:9:37:9:40 | data | tst3.js:9:37:9:42 | data.p | | tst3.js:9:37:9:40 | data | tst3.js:9:37:9:42 | data.p | | tst3.js:10:38:10:41 | data | tst3.js:10:38:10:43 | data.p | -| tst3.js:10:38:10:41 | data | tst3.js:10:38:10:43 | data.p | -| tst.js:2:7:2:39 | target | tst.js:5:18:5:23 | target | | tst.js:2:7:2:39 | target | tst.js:5:18:5:23 | target | | tst.js:2:7:2:39 | target | tst.js:12:28:12:33 | target | | tst.js:2:7:2:39 | target | tst.js:20:42:20:47 | target | | tst.js:2:16:2:39 | documen ... .search | tst.js:2:7:2:39 | target | -| tst.js:2:16:2:39 | documen ... .search | tst.js:2:7:2:39 | target | -| tst.js:8:37:8:58 | documen ... on.href | tst.js:8:37:8:114 | documen ... t=")+8) | -| tst.js:8:37:8:58 | documen ... on.href | tst.js:8:37:8:114 | documen ... t=")+8) | -| tst.js:8:37:8:58 | documen ... on.href | tst.js:8:37:8:114 | documen ... t=")+8) | | tst.js:8:37:8:58 | documen ... on.href | tst.js:8:37:8:114 | documen ... t=")+8) | | tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:126 | "" | -| tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:126 | "" | -| tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:126 | "" | -| tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:126 | "" | -| tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:126 | "" | -| tst.js:12:28:12:33 | target | tst.js:12:5:12:42 | '
' | | tst.js:12:28:12:33 | target | tst.js:12:5:12:42 | '
' | | tst.js:17:7:17:56 | params | tst.js:18:18:18:23 | params | +| tst.js:17:16:17:43 | (new UR ... ation)) [searchParams] | tst.js:17:16:17:56 | (new UR ... hParams | | tst.js:17:16:17:56 | (new UR ... hParams | tst.js:17:7:17:56 | params | -| tst.js:17:25:17:41 | document.location | tst.js:17:16:17:56 | (new UR ... hParams | -| tst.js:17:25:17:41 | document.location | tst.js:17:16:17:56 | (new UR ... hParams | -| tst.js:17:25:17:41 | document.location | tst.js:18:18:18:35 | params.get('name') | -| tst.js:17:25:17:41 | document.location | tst.js:18:18:18:35 | params.get('name') | -| tst.js:17:25:17:41 | document.location | tst.js:18:18:18:35 | params.get('name') | -| tst.js:17:25:17:41 | document.location | tst.js:18:18:18:35 | params.get('name') | -| tst.js:18:18:18:23 | params | tst.js:18:18:18:35 | params.get('name') | -| tst.js:18:18:18:23 | params | tst.js:18:18:18:35 | params.get('name') | +| tst.js:17:17:17:42 | new URL ... cation) [searchParams] | tst.js:17:16:17:43 | (new UR ... ation)) [searchParams] | +| tst.js:17:25:17:41 | document.location | tst.js:17:17:17:42 | new URL ... cation) [searchParams] | | tst.js:18:18:18:23 | params | tst.js:18:18:18:35 | params.get('name') | | tst.js:20:7:20:61 | searchParams | tst.js:21:18:21:29 | searchParams | | tst.js:20:22:20:61 | new URL ... ing(1)) | tst.js:20:7:20:61 | searchParams | | tst.js:20:42:20:47 | target | tst.js:20:42:20:60 | target.substring(1) | -| tst.js:20:42:20:47 | target | tst.js:20:42:20:60 | target.substring(1) | -| tst.js:20:42:20:47 | target | tst.js:20:42:20:60 | target.substring(1) | | tst.js:20:42:20:60 | target.substring(1) | tst.js:20:22:20:61 | new URL ... ing(1)) | -| tst.js:20:42:20:60 | target.substring(1) | tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:20:42:20:60 | target.substring(1) | tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:20:42:20:60 | target.substring(1) | tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:20:42:20:60 | target.substring(1) | tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:20:42:20:60 | target.substring(1) | tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:20:42:20:60 | target.substring(1) | tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:21:18:21:29 | searchParams | tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:21:18:21:29 | searchParams | tst.js:21:18:21:41 | searchP ... 'name') | | tst.js:21:18:21:29 | searchParams | tst.js:21:18:21:41 | searchP ... 'name') | | tst.js:24:14:24:19 | target | tst.js:26:18:26:23 | target | -| tst.js:24:14:24:19 | target | tst.js:26:18:26:23 | target | -| tst.js:28:5:28:28 | documen ... .search | tst.js:24:14:24:19 | target | | tst.js:28:5:28:28 | documen ... .search | tst.js:24:14:24:19 | target | | tst.js:31:10:31:33 | documen ... .search | tst.js:34:16:34:20 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:34:16:34:20 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:34:16:34:20 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:34:16:34:20 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:58:26:58:30 | bar() | | tst.js:31:10:31:33 | documen ... .search | tst.js:58:26:58:30 | bar() | | tst.js:31:10:31:33 | documen ... .search | tst.js:68:16:68:20 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:68:16:68:20 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:68:16:68:20 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:68:16:68:20 | bar() | -| tst.js:40:20:40:43 | documen ... .search | tst.js:40:16:40:44 | baz(doc ... search) | -| tst.js:40:20:40:43 | documen ... .search | tst.js:40:16:40:44 | baz(doc ... search) | -| tst.js:40:20:40:43 | documen ... .search | tst.js:40:16:40:44 | baz(doc ... search) | +| tst.js:36:14:36:14 | x | tst.js:37:10:37:10 | x | +| tst.js:40:20:40:43 | documen ... .search | tst.js:36:14:36:14 | x | | tst.js:40:20:40:43 | documen ... .search | tst.js:40:16:40:44 | baz(doc ... search) | +| tst.js:42:15:42:15 | s | tst.js:43:20:43:20 | s | +| tst.js:43:20:43:20 | s | tst.js:43:10:43:31 | "
" ...
" | +| tst.js:46:21:46:44 | documen ... .search | tst.js:42:15:42:15 | s | | tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | +| tst.js:48:15:48:15 | s | tst.js:50:12:50:12 | s | +| tst.js:50:12:50:12 | s | tst.js:50:12:50:22 | s.substr(1) | +| tst.js:54:21:54:44 | documen ... .search | tst.js:48:15:48:15 | s | | tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | +| tst.js:56:21:56:44 | documen ... .search | tst.js:48:15:48:15 | s | | tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | +| tst.js:58:21:58:31 | chop(bar()) | tst.js:42:15:42:15 | s | | tst.js:58:21:58:31 | chop(bar()) | tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:21:58:31 | chop(bar()) | tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:21:58:31 | chop(bar()) | tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:21:58:31 | chop(bar()) | tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:21:58:31 | chop(bar()) | tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:26:58:30 | bar() | tst.js:58:21:58:31 | chop(bar()) | +| tst.js:58:26:58:30 | bar() | tst.js:48:15:48:15 | s | | tst.js:58:26:58:30 | bar() | tst.js:58:21:58:31 | chop(bar()) | | tst.js:60:34:60:34 | s | tst.js:62:18:62:18 | s | -| tst.js:60:34:60:34 | s | tst.js:62:18:62:18 | s | | tst.js:64:25:64:48 | documen ... .search | tst.js:60:34:60:34 | s | -| tst.js:64:25:64:48 | documen ... .search | tst.js:60:34:60:34 | s | -| tst.js:65:25:65:48 | documen ... .search | tst.js:60:34:60:34 | s | | tst.js:65:25:65:48 | documen ... .search | tst.js:60:34:60:34 | s | | tst.js:70:1:70:27 | [,docum ... search] | tst.js:70:46:70:46 | x | +| tst.js:70:1:70:27 | [,docum ... search] [1] | tst.js:70:46:70:46 | x | | tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] | -| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] | -| tst.js:70:3:70:26 | documen ... .search | tst.js:70:46:70:46 | x | -| tst.js:70:3:70:26 | documen ... .search | tst.js:70:46:70:46 | x | +| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] [1] | | tst.js:70:46:70:46 | x | tst.js:73:20:73:20 | x | -| tst.js:70:46:70:46 | x | tst.js:73:20:73:20 | x | -| tst.js:77:49:77:72 | documen ... .search | tst.js:77:49:77:72 | documen ... .search | -| tst.js:81:26:81:49 | documen ... .search | tst.js:81:26:81:49 | documen ... .search | -| tst.js:82:25:82:48 | documen ... .search | tst.js:82:25:82:48 | documen ... .search | -| tst.js:84:33:84:56 | documen ... .search | tst.js:84:33:84:56 | documen ... .search | -| tst.js:85:32:85:55 | documen ... .search | tst.js:85:32:85:55 | documen ... .search | -| tst.js:90:39:90:62 | documen ... .search | tst.js:90:39:90:62 | documen ... .search | -| tst.js:96:30:96:53 | documen ... .search | tst.js:96:30:96:53 | documen ... .search | -| tst.js:102:25:102:48 | documen ... .search | tst.js:102:25:102:48 | documen ... .search | -| tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | -| tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | -| tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | -| tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | -| tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | | tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | | tst.js:107:7:107:44 | v | tst.js:136:18:136:18 | v | -| tst.js:107:7:107:44 | v | tst.js:136:18:136:18 | v | -| tst.js:107:7:107:44 | v | tst.js:136:18:136:18 | v | -| tst.js:107:7:107:44 | v | tst.js:136:18:136:18 | v | -| tst.js:107:7:107:44 | v | tst.js:136:18:136:18 | v | -| tst.js:107:7:107:44 | v | tst.js:136:18:136:18 | v | | tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:44 | documen ... bstr(1) | tst.js:107:7:107:44 | v | -| tst.js:107:11:107:44 | documen ... bstr(1) | tst.js:107:7:107:44 | v | | tst.js:107:11:107:44 | documen ... bstr(1) | tst.js:107:7:107:44 | v | | tst.js:148:29:148:50 | window. ... .search | tst.js:151:29:151:29 | v | -| tst.js:148:29:148:50 | window. ... .search | tst.js:151:29:151:29 | v | -| tst.js:151:29:151:29 | v | tst.js:151:49:151:49 | v | | tst.js:151:29:151:29 | v | tst.js:151:49:151:49 | v | | tst.js:158:40:158:61 | window. ... .search | tst.js:155:29:155:46 | xssSourceService() | -| tst.js:158:40:158:61 | window. ... .search | tst.js:155:29:155:46 | xssSourceService() | -| tst.js:158:40:158:61 | window. ... .search | tst.js:155:29:155:46 | xssSourceService() | -| tst.js:158:40:158:61 | window. ... .search | tst.js:155:29:155:46 | xssSourceService() | -| tst.js:177:9:177:41 | target | tst.js:180:28:180:33 | target | | tst.js:177:9:177:41 | target | tst.js:180:28:180:33 | target | | tst.js:177:18:177:41 | documen ... .search | tst.js:177:9:177:41 | target | -| tst.js:177:18:177:41 | documen ... .search | tst.js:177:9:177:41 | target | -| tst.js:184:9:184:42 | tainted | tst.js:186:31:186:37 | tainted | | tst.js:184:9:184:42 | tainted | tst.js:186:31:186:37 | tainted | | tst.js:184:9:184:42 | tainted | tst.js:188:42:188:48 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:188:42:188:48 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:189:33:189:39 | tainted | | tst.js:184:9:184:42 | tainted | tst.js:189:33:189:39 | tainted | | tst.js:184:9:184:42 | tainted | tst.js:191:54:191:60 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:191:54:191:60 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:192:45:192:51 | tainted | | tst.js:184:9:184:42 | tainted | tst.js:192:45:192:51 | tainted | | tst.js:184:9:184:42 | tainted | tst.js:193:49:193:55 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:193:49:193:55 | tainted | -| tst.js:184:19:184:42 | documen ... .search | tst.js:184:9:184:42 | tainted | | tst.js:184:19:184:42 | documen ... .search | tst.js:184:9:184:42 | tainted | | tst.js:197:9:197:42 | tainted | tst.js:199:67:199:73 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:199:67:199:73 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:200:67:200:73 | tainted | | tst.js:197:9:197:42 | tainted | tst.js:200:67:200:73 | tainted | | tst.js:197:9:197:42 | tainted | tst.js:204:35:204:41 | tainted | | tst.js:197:9:197:42 | tainted | tst.js:206:46:206:52 | tainted | @@ -2169,210 +999,102 @@ edges | tst.js:197:9:197:42 | tainted | tst.js:241:23:241:29 | tainted | | tst.js:197:9:197:42 | tainted | tst.js:255:23:255:29 | tainted | | tst.js:197:19:197:42 | documen ... .search | tst.js:197:9:197:42 | tainted | -| tst.js:197:19:197:42 | documen ... .search | tst.js:197:9:197:42 | tainted | -| tst.js:204:35:204:41 | tainted | tst.js:212:28:212:46 | this.state.tainted1 | | tst.js:204:35:204:41 | tainted | tst.js:212:28:212:46 | this.state.tainted1 | | tst.js:206:46:206:52 | tainted | tst.js:213:28:213:46 | this.state.tainted2 | -| tst.js:206:46:206:52 | tainted | tst.js:213:28:213:46 | this.state.tainted2 | -| tst.js:207:38:207:44 | tainted | tst.js:214:28:214:46 | this.state.tainted3 | | tst.js:207:38:207:44 | tainted | tst.js:214:28:214:46 | this.state.tainted3 | | tst.js:208:35:208:41 | tainted | tst.js:218:32:218:49 | prevState.tainted4 | -| tst.js:208:35:208:41 | tainted | tst.js:218:32:218:49 | prevState.tainted4 | -| tst.js:236:35:236:41 | tainted | tst.js:225:28:225:46 | this.props.tainted1 | | tst.js:236:35:236:41 | tainted | tst.js:225:28:225:46 | this.props.tainted1 | | tst.js:238:20:238:26 | tainted | tst.js:226:28:226:46 | this.props.tainted2 | -| tst.js:238:20:238:26 | tainted | tst.js:226:28:226:46 | this.props.tainted2 | -| tst.js:240:23:240:29 | tainted | tst.js:227:28:227:46 | this.props.tainted3 | | tst.js:240:23:240:29 | tainted | tst.js:227:28:227:46 | this.props.tainted3 | | tst.js:241:23:241:29 | tainted | tst.js:231:32:231:49 | prevProps.tainted4 | -| tst.js:241:23:241:29 | tainted | tst.js:231:32:231:49 | prevProps.tainted4 | -| tst.js:247:39:247:55 | props.propTainted | tst.js:251:60:251:82 | this.st ... Tainted | | tst.js:247:39:247:55 | props.propTainted | tst.js:251:60:251:82 | this.st ... Tainted | | tst.js:255:23:255:29 | tainted | tst.js:247:39:247:55 | props.propTainted | -| tst.js:259:7:259:17 | window.name | tst.js:259:7:259:17 | window.name | -| tst.js:260:7:260:10 | name | tst.js:260:7:260:10 | name | -| tst.js:264:11:264:21 | window.name | tst.js:264:11:264:21 | window.name | -| tst.js:280:22:280:29 | location | tst.js:280:22:280:29 | location | | tst.js:285:9:285:29 | tainted | tst.js:288:59:288:65 | tainted | -| tst.js:285:9:285:29 | tainted | tst.js:288:59:288:65 | tainted | -| tst.js:285:9:285:29 | tainted | tst.js:288:59:288:65 | tainted | -| tst.js:285:9:285:29 | tainted | tst.js:288:59:288:65 | tainted | -| tst.js:285:19:285:29 | window.name | tst.js:285:9:285:29 | tainted | -| tst.js:285:19:285:29 | window.name | tst.js:285:9:285:29 | tainted | -| tst.js:285:19:285:29 | window.name | tst.js:285:9:285:29 | tainted | | tst.js:285:19:285:29 | window.name | tst.js:285:9:285:29 | tainted | | tst.js:301:9:301:16 | location | tst.js:302:10:302:10 | e | -| tst.js:301:9:301:16 | location | tst.js:302:10:302:10 | e | -| tst.js:302:10:302:10 | e | tst.js:303:20:303:20 | e | | tst.js:302:10:302:10 | e | tst.js:303:20:303:20 | e | | tst.js:308:10:308:17 | location | tst.js:310:10:310:10 | e | -| tst.js:308:10:308:17 | location | tst.js:310:10:310:10 | e | | tst.js:310:10:310:10 | e | tst.js:311:20:311:20 | e | -| tst.js:310:10:310:10 | e | tst.js:311:20:311:20 | e | -| tst.js:316:35:316:42 | location | tst.js:316:35:316:42 | location | -| tst.js:327:18:327:34 | document.location | tst.js:331:16:331:43 | getTain ... hParams | -| tst.js:327:18:327:34 | document.location | tst.js:331:16:331:43 | getTain ... hParams | -| tst.js:327:18:327:34 | document.location | tst.js:332:18:332:35 | params.get('name') | -| tst.js:327:18:327:34 | document.location | tst.js:332:18:332:35 | params.get('name') | -| tst.js:327:18:327:34 | document.location | tst.js:332:18:332:35 | params.get('name') | -| tst.js:327:18:327:34 | document.location | tst.js:332:18:332:35 | params.get('name') | +| tst.js:327:10:327:35 | new URL ... cation) [searchParams] | tst.js:331:16:331:30 | getTaintedUrl() [searchParams] | +| tst.js:327:18:327:34 | document.location | tst.js:327:10:327:35 | new URL ... cation) [searchParams] | | tst.js:331:7:331:43 | params | tst.js:332:18:332:23 | params | +| tst.js:331:16:331:30 | getTaintedUrl() [searchParams] | tst.js:331:16:331:43 | getTain ... hParams | | tst.js:331:16:331:43 | getTain ... hParams | tst.js:331:7:331:43 | params | | tst.js:332:18:332:23 | params | tst.js:332:18:332:35 | params.get('name') | -| tst.js:332:18:332:23 | params | tst.js:332:18:332:35 | params.get('name') | -| tst.js:332:18:332:23 | params | tst.js:332:18:332:35 | params.get('name') | -| tst.js:341:20:341:36 | document.location | tst.js:343:5:343:17 | getUrl().hash | -| tst.js:341:20:341:36 | document.location | tst.js:343:5:343:17 | getUrl().hash | -| tst.js:343:5:343:17 | getUrl().hash | tst.js:343:5:343:30 | getUrl( ... ring(1) | -| tst.js:343:5:343:17 | getUrl().hash | tst.js:343:5:343:30 | getUrl( ... ring(1) | +| tst.js:341:12:341:37 | new URL ... cation) [hash] | tst.js:343:5:343:12 | getUrl() [hash] | +| tst.js:341:20:341:36 | document.location | tst.js:341:12:341:37 | new URL ... cation) [hash] | +| tst.js:343:5:343:12 | getUrl() [hash] | tst.js:343:5:343:17 | getUrl().hash | | tst.js:343:5:343:17 | getUrl().hash | tst.js:343:5:343:30 | getUrl( ... ring(1) | | tst.js:348:7:348:39 | target | tst.js:349:12:349:17 | target | -| tst.js:348:7:348:39 | target | tst.js:349:12:349:17 | target | -| tst.js:348:16:348:39 | documen ... .search | tst.js:348:7:348:39 | target | | tst.js:348:16:348:39 | documen ... .search | tst.js:348:7:348:39 | target | | tst.js:355:10:355:42 | target | tst.js:356:16:356:21 | target | -| tst.js:355:10:355:42 | target | tst.js:356:16:356:21 | target | -| tst.js:355:10:355:42 | target | tst.js:360:21:360:26 | target | | tst.js:355:10:355:42 | target | tst.js:360:21:360:26 | target | | tst.js:355:10:355:42 | target | tst.js:363:18:363:23 | target | -| tst.js:355:10:355:42 | target | tst.js:363:18:363:23 | target | -| tst.js:355:19:355:42 | documen ... .search | tst.js:355:10:355:42 | target | | tst.js:355:19:355:42 | documen ... .search | tst.js:355:10:355:42 | target | | tst.js:371:7:371:39 | target | tst.js:374:18:374:23 | target | -| tst.js:371:7:371:39 | target | tst.js:374:18:374:23 | target | | tst.js:371:16:371:39 | documen ... .search | tst.js:371:7:371:39 | target | -| tst.js:371:16:371:39 | documen ... .search | tst.js:371:7:371:39 | target | -| tst.js:381:7:381:39 | target | tst.js:384:18:384:23 | target | | tst.js:381:7:381:39 | target | tst.js:384:18:384:23 | target | | tst.js:381:7:381:39 | target | tst.js:386:18:386:23 | target | | tst.js:381:7:381:39 | target | tst.js:397:18:397:23 | target | | tst.js:381:7:381:39 | target | tst.js:406:18:406:23 | target | | tst.js:381:7:381:39 | target | tst.js:408:19:408:24 | target | -| tst.js:381:16:381:39 | documen ... .search | tst.js:381:7:381:39 | target | +| tst.js:381:7:381:39 | target [taint3] | tst.js:392:18:392:23 | target [taint3] | +| tst.js:381:7:381:39 | target [taint8] | tst.js:408:19:408:24 | target [taint8] | +| tst.js:381:7:381:39 | target [taint8] | tst.js:409:18:409:23 | target [taint8] | | tst.js:381:16:381:39 | documen ... .search | tst.js:381:7:381:39 | target | | tst.js:386:18:386:23 | target | tst.js:386:18:386:29 | target.taint | -| tst.js:386:18:386:23 | target | tst.js:386:18:386:29 | target.taint | -| tst.js:391:19:391:42 | documen ... .search | tst.js:392:18:392:30 | target.taint3 | -| tst.js:391:19:391:42 | documen ... .search | tst.js:392:18:392:30 | target.taint3 | -| tst.js:391:19:391:42 | documen ... .search | tst.js:392:18:392:30 | target.taint3 | -| tst.js:391:19:391:42 | documen ... .search | tst.js:392:18:392:30 | target.taint3 | -| tst.js:397:18:397:23 | target | tst.js:397:18:397:30 | target.taint5 | +| tst.js:391:3:391:8 | [post update] target [taint3] | tst.js:381:7:381:39 | target [taint3] | +| tst.js:391:19:391:42 | documen ... .search | tst.js:391:3:391:8 | [post update] target [taint3] | +| tst.js:392:18:392:23 | target [taint3] | tst.js:392:18:392:30 | target.taint3 | | tst.js:397:18:397:23 | target | tst.js:397:18:397:30 | target.taint5 | | tst.js:406:18:406:23 | target | tst.js:406:18:406:30 | target.taint7 | -| tst.js:406:18:406:23 | target | tst.js:406:18:406:30 | target.taint7 | +| tst.js:408:3:408:8 | [post update] target [taint8] | tst.js:381:7:381:39 | target [taint8] | | tst.js:408:19:408:24 | target | tst.js:408:19:408:31 | target.taint8 | -| tst.js:408:19:408:31 | target.taint8 | tst.js:408:19:408:31 | target.taint8 | -| tst.js:408:19:408:31 | target.taint8 | tst.js:409:18:409:30 | target.taint8 | -| tst.js:408:19:408:31 | target.taint8 | tst.js:409:18:409:30 | target.taint8 | -| tst.js:416:7:416:46 | payload | tst.js:417:18:417:24 | payload | -| tst.js:416:7:416:46 | payload | tst.js:417:18:417:24 | payload | -| tst.js:416:7:416:46 | payload | tst.js:417:18:417:24 | payload | -| tst.js:416:7:416:46 | payload | tst.js:417:18:417:24 | payload | -| tst.js:416:7:416:46 | payload | tst.js:417:18:417:24 | payload | +| tst.js:408:19:408:24 | target [taint8] | tst.js:408:19:408:31 | target.taint8 | +| tst.js:408:19:408:31 | target.taint8 | tst.js:408:3:408:8 | [post update] target [taint8] | +| tst.js:409:18:409:23 | target [taint8] | tst.js:409:18:409:30 | target.taint8 | | tst.js:416:7:416:46 | payload | tst.js:417:18:417:24 | payload | | tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:46 | window. ... bstr(1) | tst.js:416:7:416:46 | payload | -| tst.js:416:17:416:46 | window. ... bstr(1) | tst.js:416:7:416:46 | payload | | tst.js:416:17:416:46 | window. ... bstr(1) | tst.js:416:7:416:46 | payload | | tst.js:419:7:419:55 | match | tst.js:421:20:421:24 | match | | tst.js:419:15:419:34 | window.location.hash | tst.js:419:15:419:55 | window. ... (\\w+)/) | -| tst.js:419:15:419:34 | window.location.hash | tst.js:419:15:419:55 | window. ... (\\w+)/) | | tst.js:419:15:419:55 | window. ... (\\w+)/) | tst.js:419:7:419:55 | match | | tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | -| tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | | tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | | tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | | tst.js:428:7:428:39 | target | tst.js:430:18:430:23 | target | | tst.js:428:16:428:39 | documen ... .search | tst.js:428:7:428:39 | target | -| tst.js:428:16:428:39 | documen ... .search | tst.js:428:7:428:39 | target | -| tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | | tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | | tst.js:436:6:436:38 | source | tst.js:440:28:440:33 | source | -| tst.js:436:6:436:38 | source | tst.js:440:28:440:33 | source | -| tst.js:436:6:436:38 | source | tst.js:441:33:441:38 | source | | tst.js:436:6:436:38 | source | tst.js:441:33:441:38 | source | | tst.js:436:6:436:38 | source | tst.js:442:34:442:39 | source | -| tst.js:436:6:436:38 | source | tst.js:442:34:442:39 | source | -| tst.js:436:6:436:38 | source | tst.js:443:41:443:46 | source | | tst.js:436:6:436:38 | source | tst.js:443:41:443:46 | source | | tst.js:436:6:436:38 | source | tst.js:444:44:444:49 | source | -| tst.js:436:6:436:38 | source | tst.js:444:44:444:49 | source | -| tst.js:436:6:436:38 | source | tst.js:445:32:445:37 | source | | tst.js:436:6:436:38 | source | tst.js:445:32:445:37 | source | | tst.js:436:15:436:38 | documen ... .search | tst.js:436:6:436:38 | source | -| tst.js:436:15:436:38 | documen ... .search | tst.js:436:6:436:38 | source | -| tst.js:453:7:453:39 | source | tst.js:455:18:455:23 | source | | tst.js:453:7:453:39 | source | tst.js:455:18:455:23 | source | | tst.js:453:7:453:39 | source | tst.js:456:36:456:41 | source | | tst.js:453:16:453:39 | documen ... .search | tst.js:453:7:453:39 | source | -| tst.js:453:16:453:39 | documen ... .search | tst.js:453:7:453:39 | source | -| tst.js:456:36:456:41 | source | tst.js:456:18:456:42 | ansiToH ... source) | | tst.js:456:36:456:41 | source | tst.js:456:18:456:42 | ansiToH ... source) | | tst.js:460:6:460:38 | source | tst.js:463:21:463:26 | source | -| tst.js:460:6:460:38 | source | tst.js:463:21:463:26 | source | -| tst.js:460:6:460:38 | source | tst.js:465:19:465:24 | source | | tst.js:460:6:460:38 | source | tst.js:465:19:465:24 | source | | tst.js:460:6:460:38 | source | tst.js:467:20:467:25 | source | -| tst.js:460:6:460:38 | source | tst.js:467:20:467:25 | source | -| tst.js:460:15:460:38 | documen ... .search | tst.js:460:6:460:38 | source | | tst.js:460:15:460:38 | documen ... .search | tst.js:460:6:460:38 | source | | tst.js:471:7:471:46 | url | tst.js:473:19:473:21 | url | -| tst.js:471:7:471:46 | url | tst.js:473:19:473:21 | url | -| tst.js:471:7:471:46 | url | tst.js:474:26:474:28 | url | | tst.js:471:7:471:46 | url | tst.js:474:26:474:28 | url | | tst.js:471:7:471:46 | url | tst.js:475:25:475:27 | url | -| tst.js:471:7:471:46 | url | tst.js:475:25:475:27 | url | -| tst.js:471:7:471:46 | url | tst.js:476:20:476:22 | url | | tst.js:471:7:471:46 | url | tst.js:476:20:476:22 | url | | tst.js:471:7:471:46 | url | tst.js:486:22:486:24 | url | -| tst.js:471:7:471:46 | url | tst.js:486:22:486:24 | url | -| tst.js:471:13:471:36 | documen ... .search | tst.js:471:13:471:46 | documen ... bstr(1) | | tst.js:471:13:471:36 | documen ... .search | tst.js:471:13:471:46 | documen ... bstr(1) | | tst.js:471:13:471:46 | documen ... bstr(1) | tst.js:471:7:471:46 | url | | tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | -| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | -| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | | tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | | tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | -| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | -| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | -| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | -| typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | -| typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | -| typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | -| typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | -| typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | -| typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | | typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | | typeahead.js:20:13:20:45 | target | typeahead.js:21:12:21:17 | target | | typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target | -| typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target | | typeahead.js:21:12:21:17 | target | typeahead.js:24:30:24:32 | val | | typeahead.js:24:30:24:32 | val | typeahead.js:25:18:25:20 | val | -| typeahead.js:24:30:24:32 | val | typeahead.js:25:18:25:20 | val | -| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | -| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | -| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | -| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | | various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:4:14:4:20 | tainted | | various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:5:12:5:18 | tainted | | various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:6:19:6:25 | tainted | @@ -2382,88 +1104,64 @@ edges | various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:11:24:11:30 | tainted | | various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:12:19:12:25 | tainted | | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:2:6:2:39 | tainted | -| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:2:6:2:39 | tainted | -| various-concat-obfuscations.js:4:14:4:20 | tainted | various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | | various-concat-obfuscations.js:4:14:4:20 | tainted | various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | | various-concat-obfuscations.js:5:12:5:18 | tainted | various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | -| various-concat-obfuscations.js:5:12:5:18 | tainted | various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | -| various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | | various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | | various-concat-obfuscations.js:6:19:6:25 | tainted | various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | | various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | -| various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | | various-concat-obfuscations.js:7:14:7:20 | tainted | various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | | various-concat-obfuscations.js:9:19:9:25 | tainted | various-concat-obfuscations.js:9:4:9:34 | "
" | -| various-concat-obfuscations.js:9:19:9:25 | tainted | various-concat-obfuscations.js:9:4:9:34 | "
" | | various-concat-obfuscations.js:10:16:10:22 | tainted | various-concat-obfuscations.js:10:4:10:27 | `
` | -| various-concat-obfuscations.js:10:16:10:22 | tainted | various-concat-obfuscations.js:10:4:10:27 | `
` | -| various-concat-obfuscations.js:11:4:11:31 | "
") | | various-concat-obfuscations.js:11:4:11:31 | "
") | | various-concat-obfuscations.js:11:24:11:30 | tainted | various-concat-obfuscations.js:11:4:11:31 | "
"] | various-concat-obfuscations.js:12:4:12:41 | ["
"] | various-concat-obfuscations.js:12:4:12:41 | ["
"] | +| various-concat-obfuscations.js:14:24:14:28 | attrs | various-concat-obfuscations.js:15:28:15:32 | attrs | +| various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | various-concat-obfuscations.js:15:10:15:83 | '
' | +| various-concat-obfuscations.js:15:28:15:32 | attrs | various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | +| various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | +| various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:32:18:36 | attrs | +| various-concat-obfuscations.js:18:10:18:59 | '
') | +| various-concat-obfuscations.js:18:10:18:88 | '
') | +| various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | +| various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | +| various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | various-concat-obfuscations.js:18:10:18:59 | '
" ...
" | tst.js:46:16:46:45 | wrap(do ... search) | +| tst.js:54:21:54:44 | documen ... .search | tst.js:48:15:48:15 | s | tst.js:50:12:50:22 | s.substr(1) | tst.js:54:16:54:45 | chop(do ... search) | +| tst.js:56:21:56:44 | documen ... .search | tst.js:48:15:48:15 | s | tst.js:50:12:50:22 | s.substr(1) | tst.js:56:16:56:45 | chop(do ... search) | +| tst.js:58:21:58:31 | chop(bar()) | tst.js:42:15:42:15 | s | tst.js:43:10:43:31 | "
" ...
" | tst.js:58:16:58:32 | wrap(chop(bar())) | +| tst.js:58:26:58:30 | bar() | tst.js:48:15:48:15 | s | tst.js:50:12:50:22 | s.substr(1) | tst.js:58:21:58:31 | chop(bar()) | +| various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:14:24:14:28 | attrs | various-concat-obfuscations.js:15:10:15:83 | '
' | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) | +| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:10:18:105 | '
') | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | #select | jwt.js:6:14:6:20 | decoded | jwt.js:4:36:4:39 | data | jwt.js:6:14:6:20 | decoded | Cross-site scripting vulnerability due to $@. | jwt.js:4:36:4:39 | data | user-provided value | | typeahead.js:10:16:10:18 | loc | typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | Cross-site scripting vulnerability due to $@. | typeahead.js:9:28:9:30 | loc | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.ql b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.ql index 9a27e9db4d4..a2e4dad22fe 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.ql @@ -13,11 +13,13 @@ import javascript import semmle.javascript.security.dataflow.DomBasedXssQuery -import DataFlow::PathGraph +import DataFlow::DeduplicatePathGraph import semmle.javascript.heuristics.AdditionalSources -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource +from PathNode source, PathNode sink +where + DomBasedXssFlow::flowPath(source.getAnOriginalPathNode(), sink.getAnOriginalPathNode()) and + source.getNode() instanceof HeuristicSource select sink.getNode(), source, sink, sink.getNode().(Sink).getVulnerabilityKind() + " vulnerability due to $@.", source.getNode(), "user-provided value" From 46b90e51fc818e62ee27ef437543333f71fb4fc8 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:30:06 +0200 Subject: [PATCH 049/514] JS: Port ReflectedXss --- .../security/dataflow/ReflectedXssQuery.qll | 29 +- .../ql/src/Security/CWE-079/ReflectedXss.ql | 6 +- .../ReflectedXss/ReflectedXss.expected | 580 +++++++----------- 3 files changed, 246 insertions(+), 369 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ReflectedXssQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ReflectedXssQuery.qll index 75ccaeeb9d8..9af157fe423 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ReflectedXssQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ReflectedXssQuery.qll @@ -5,12 +5,30 @@ import javascript import ReflectedXssCustomizations::ReflectedXss -private import Xss::Shared as Shared +private import Xss::Shared as SharedXss /** - * A taint-tracking configuration for reasoning about XSS. + * A taint-tracking configuration for reasoning about reflected XSS. */ -class Configuration extends TaintTracking::Configuration { +module ReflectedXssConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { + node instanceof Sanitizer or node = SharedXss::BarrierGuard::getABarrierNode() + } +} + +/** + * Taint-tracking for reasoning about reflected XSS. + */ +module ReflectedXssFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `ReflectedXssFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "ReflectedXss" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -28,11 +46,10 @@ class Configuration extends TaintTracking::Configuration { } } -private class QuoteGuard extends TaintTracking::SanitizerGuardNode, Shared::QuoteGuard { +private class QuoteGuard extends SharedXss::QuoteGuard { QuoteGuard() { this = this } } -private class ContainsHtmlGuard extends TaintTracking::SanitizerGuardNode, Shared::ContainsHtmlGuard -{ +private class ContainsHtmlGuard extends SharedXss::ContainsHtmlGuard { ContainsHtmlGuard() { this = this } } diff --git a/javascript/ql/src/Security/CWE-079/ReflectedXss.ql b/javascript/ql/src/Security/CWE-079/ReflectedXss.ql index a95a7aec205..5f4c85a0be5 100644 --- a/javascript/ql/src/Security/CWE-079/ReflectedXss.ql +++ b/javascript/ql/src/Security/CWE-079/ReflectedXss.ql @@ -14,9 +14,9 @@ import javascript import semmle.javascript.security.dataflow.ReflectedXssQuery -import DataFlow::PathGraph +import ReflectedXssFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from ReflectedXssFlow::PathNode source, ReflectedXssFlow::PathNode sink +where ReflectedXssFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Cross-site scripting vulnerability due to a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected index 3c625dccdd3..4dd4aa11995 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected @@ -1,444 +1,304 @@ -nodes -| ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | -| ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | -| ReflectedXss.js:8:33:8:45 | req.params.id | -| ReflectedXss.js:8:33:8:45 | req.params.id | -| ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | -| ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | -| ReflectedXss.js:17:31:17:39 | params.id | -| ReflectedXss.js:17:31:17:39 | params.id | -| ReflectedXss.js:22:12:22:19 | req.body | -| ReflectedXss.js:22:12:22:19 | req.body | -| ReflectedXss.js:22:12:22:19 | req.body | -| ReflectedXss.js:23:12:23:27 | marked(req.body) | -| ReflectedXss.js:23:12:23:27 | marked(req.body) | -| ReflectedXss.js:23:19:23:26 | req.body | -| ReflectedXss.js:23:19:23:26 | req.body | -| ReflectedXss.js:29:12:29:19 | req.body | -| ReflectedXss.js:29:12:29:19 | req.body | -| ReflectedXss.js:29:12:29:19 | req.body | -| ReflectedXss.js:30:7:33:4 | mytable | -| ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | -| ReflectedXss.js:30:23:33:3 | [\\n [ ... dy]\\n ] | -| ReflectedXss.js:32:5:32:22 | ['body', req.body] | -| ReflectedXss.js:32:14:32:21 | req.body | -| ReflectedXss.js:32:14:32:21 | req.body | -| ReflectedXss.js:34:12:34:18 | mytable | -| ReflectedXss.js:34:12:34:18 | mytable | -| ReflectedXss.js:41:12:41:19 | req.body | -| ReflectedXss.js:41:12:41:19 | req.body | -| ReflectedXss.js:41:12:41:19 | req.body | -| ReflectedXss.js:42:12:42:39 | convert ... q.body) | -| ReflectedXss.js:42:12:42:39 | convert ... q.body) | -| ReflectedXss.js:42:31:42:38 | req.body | -| ReflectedXss.js:42:31:42:38 | req.body | -| ReflectedXss.js:56:12:56:19 | req.body | -| ReflectedXss.js:56:12:56:19 | req.body | -| ReflectedXss.js:56:12:56:19 | req.body | -| ReflectedXss.js:64:14:64:21 | req.body | -| ReflectedXss.js:64:14:64:21 | req.body | -| ReflectedXss.js:64:39:64:42 | file | -| ReflectedXss.js:65:16:65:19 | file | -| ReflectedXss.js:65:16:65:19 | file | -| ReflectedXss.js:68:12:68:41 | remark( ... q.body) | -| ReflectedXss.js:68:12:68:52 | remark( ... tring() | -| ReflectedXss.js:68:12:68:52 | remark( ... tring() | -| ReflectedXss.js:68:33:68:40 | req.body | -| ReflectedXss.js:68:33:68:40 | req.body | -| ReflectedXss.js:72:12:72:56 | unified ... q.body) | -| ReflectedXss.js:72:12:72:65 | unified ... oString | -| ReflectedXss.js:72:12:72:65 | unified ... oString | -| ReflectedXss.js:72:48:72:55 | req.body | -| ReflectedXss.js:72:48:72:55 | req.body | -| ReflectedXss.js:74:20:74:27 | req.body | -| ReflectedXss.js:74:20:74:27 | req.body | -| ReflectedXss.js:74:34:74:34 | f | -| ReflectedXss.js:75:14:75:14 | f | -| ReflectedXss.js:75:14:75:14 | f | -| ReflectedXss.js:83:12:83:19 | req.body | -| ReflectedXss.js:83:12:83:19 | req.body | -| ReflectedXss.js:83:12:83:19 | req.body | -| ReflectedXss.js:84:12:84:30 | snarkdown(req.body) | -| ReflectedXss.js:84:12:84:30 | snarkdown(req.body) | -| ReflectedXss.js:84:22:84:29 | req.body | -| ReflectedXss.js:84:22:84:29 | req.body | -| ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) | -| ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) | -| ReflectedXss.js:85:23:85:30 | req.body | -| ReflectedXss.js:85:23:85:30 | req.body | -| ReflectedXss.js:97:12:97:19 | req.body | -| ReflectedXss.js:97:12:97:19 | req.body | -| ReflectedXss.js:97:12:97:19 | req.body | -| ReflectedXss.js:98:12:98:38 | markdow ... q.body) | -| ReflectedXss.js:98:12:98:38 | markdow ... q.body) | -| ReflectedXss.js:98:30:98:37 | req.body | -| ReflectedXss.js:98:30:98:37 | req.body | -| ReflectedXss.js:100:12:100:39 | markdow ... q.body) | -| ReflectedXss.js:100:12:100:39 | markdow ... q.body) | -| ReflectedXss.js:100:31:100:38 | req.body | -| ReflectedXss.js:100:31:100:38 | req.body | -| ReflectedXss.js:103:12:103:84 | markdow ... q.body) | -| ReflectedXss.js:103:12:103:84 | markdow ... q.body) | -| ReflectedXss.js:103:76:103:83 | req.body | -| ReflectedXss.js:103:76:103:83 | req.body | -| ReflectedXss.js:110:16:110:30 | request.query.p | -| ReflectedXss.js:110:16:110:30 | request.query.p | -| ReflectedXss.js:110:16:110:30 | request.query.p | -| ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | -| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | -| ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | -| ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | -| ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | -| ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | -| ReflectedXssContentTypes.js:70:12:70:34 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:70:12:70:34 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:70:22:70:34 | req.params.id | -| ReflectedXssContentTypes.js:70:22:70:34 | req.params.id | -| ReflectedXssGood3.js:135:9:135:27 | url | -| ReflectedXssGood3.js:135:15:135:27 | req.params.id | -| ReflectedXssGood3.js:135:15:135:27 | req.params.id | -| ReflectedXssGood3.js:139:12:139:27 | escapeHtml3(url) | -| ReflectedXssGood3.js:139:12:139:27 | escapeHtml3(url) | -| ReflectedXssGood3.js:139:24:139:26 | url | -| etherpad.js:9:5:9:53 | response | -| etherpad.js:9:16:9:30 | req.query.jsonp | -| etherpad.js:9:16:9:30 | req.query.jsonp | -| etherpad.js:9:16:9:53 | req.que ... e + ")" | -| etherpad.js:11:12:11:19 | response | -| etherpad.js:11:12:11:19 | response | -| formatting.js:4:9:4:29 | evil | -| formatting.js:4:16:4:29 | req.query.evil | -| formatting.js:4:16:4:29 | req.query.evil | -| formatting.js:6:14:6:47 | util.fo ... , evil) | -| formatting.js:6:14:6:47 | util.fo ... , evil) | -| formatting.js:6:43:6:46 | evil | -| formatting.js:7:14:7:53 | require ... , evil) | -| formatting.js:7:14:7:53 | require ... , evil) | -| formatting.js:7:49:7:52 | evil | -| live-server.js:4:11:4:27 | tainted | -| live-server.js:4:21:4:27 | req.url | -| live-server.js:4:21:4:27 | req.url | -| live-server.js:6:13:6:50 | ` ... /html>` | -| live-server.js:6:13:6:50 | ` ... /html>` | -| live-server.js:6:28:6:34 | tainted | -| live-server.js:10:11:10:27 | tainted | -| live-server.js:10:21:10:27 | req.url | -| live-server.js:10:21:10:27 | req.url | -| live-server.js:12:13:12:50 | ` ... /html>` | -| live-server.js:12:13:12:50 | ` ... /html>` | -| live-server.js:12:28:12:34 | tainted | -| pages/Next.jsx:8:13:8:19 | req.url | -| pages/Next.jsx:8:13:8:19 | req.url | -| pages/Next.jsx:8:13:8:19 | req.url | -| pages/Next.jsx:15:13:15:19 | req.url | -| pages/Next.jsx:15:13:15:19 | req.url | -| pages/Next.jsx:15:13:15:19 | req.url | -| pages/api/myapi.js:2:14:2:20 | req.url | -| pages/api/myapi.js:2:14:2:20 | req.url | -| pages/api/myapi.js:2:14:2:20 | req.url | -| partial.js:9:25:9:25 | x | -| partial.js:10:14:10:14 | x | -| partial.js:10:14:10:18 | x + y | -| partial.js:10:14:10:18 | x + y | -| partial.js:13:42:13:48 | req.url | -| partial.js:13:42:13:48 | req.url | -| partial.js:18:25:18:25 | x | -| partial.js:19:14:19:14 | x | -| partial.js:19:14:19:18 | x + y | -| partial.js:19:14:19:18 | x + y | -| partial.js:22:51:22:57 | req.url | -| partial.js:22:51:22:57 | req.url | -| partial.js:27:25:27:25 | x | -| partial.js:28:14:28:14 | x | -| partial.js:28:14:28:18 | x + y | -| partial.js:28:14:28:18 | x + y | -| partial.js:31:47:31:53 | req.url | -| partial.js:31:47:31:53 | req.url | -| partial.js:36:25:36:25 | x | -| partial.js:37:14:37:14 | x | -| partial.js:37:14:37:18 | x + y | -| partial.js:37:14:37:18 | x + y | -| partial.js:40:43:40:49 | req.url | -| partial.js:40:43:40:49 | req.url | -| promises.js:5:3:5:59 | new Pro ... .data)) | -| promises.js:5:44:5:57 | req.query.data | -| promises.js:5:44:5:57 | req.query.data | -| promises.js:6:11:6:11 | x | -| promises.js:6:25:6:25 | x | -| promises.js:6:25:6:25 | x | -| tst2.js:6:7:6:30 | p | -| tst2.js:6:7:6:30 | r | -| tst2.js:6:9:6:9 | p | -| tst2.js:6:9:6:9 | p | -| tst2.js:6:12:6:15 | q: r | -| tst2.js:6:12:6:15 | q: r | -| tst2.js:7:12:7:12 | p | -| tst2.js:7:12:7:12 | p | -| tst2.js:8:12:8:12 | r | -| tst2.js:8:12:8:12 | r | -| tst2.js:14:7:14:24 | p | -| tst2.js:14:9:14:9 | p | -| tst2.js:14:9:14:9 | p | -| tst2.js:18:12:18:12 | p | -| tst2.js:18:12:18:12 | p | -| tst2.js:21:14:21:14 | p | -| tst2.js:21:14:21:14 | p | -| tst2.js:30:7:30:24 | p | -| tst2.js:30:9:30:9 | p | -| tst2.js:30:9:30:9 | p | -| tst2.js:33:11:33:11 | p | -| tst2.js:36:12:36:12 | p | -| 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 | -| tst2.js:57:7:57:24 | p | -| tst2.js:57:9:57:9 | p | -| tst2.js:57:9:57:9 | p | -| tst2.js:60:11:60:11 | p | -| tst2.js:63:12:63:12 | p | -| tst2.js:63:12:63:12 | p | -| tst2.js:64:12:64:18 | other.p | -| tst2.js:64:12:64:18 | other.p | -| tst2.js:69:7:69:24 | p | -| tst2.js:69:9:69:9 | p | -| tst2.js:69:9:69:9 | p | -| tst2.js:72:11:72:11 | p | -| tst2.js:75:12:75:12 | p | -| tst2.js:75:12:75:12 | p | -| tst2.js:76:12:76:18 | other.p | -| tst2.js:76:12:76:18 | other.p | -| tst2.js:82:7:82:24 | p | -| tst2.js:82:9:82:9 | p | -| tst2.js:82:9:82:9 | p | -| tst2.js:85:11:85:11 | p | -| tst2.js:88:12:88:12 | p | -| tst2.js:88:12:88:12 | p | -| tst2.js:89:12:89:18 | other.p | -| tst2.js:89:12:89:18 | other.p | -| tst3.js:5:7:5:24 | p | -| tst3.js:5:9:5:9 | p | -| tst3.js:5:9:5:9 | p | -| tst3.js:6:12:6:12 | p | -| tst3.js:6:12:6:12 | p | -| tst3.js:11:9:11:74 | code | -| tst3.js:11:16:11:74 | prettie ... bel" }) | -| tst3.js:11:32:11:39 | reg.body | -| tst3.js:11:32:11:39 | reg.body | -| tst3.js:12:12:12:15 | code | -| tst3.js:12:12:12:15 | code | edges | ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | -| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | -| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | -| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | | ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | -| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | -| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | -| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | -| ReflectedXss.js:22:12:22:19 | req.body | ReflectedXss.js:22:12:22:19 | req.body | | ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) | -| ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) | -| ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) | -| ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) | -| ReflectedXss.js:29:12:29:19 | req.body | ReflectedXss.js:29:12:29:19 | req.body | -| ReflectedXss.js:30:7:33:4 | mytable | ReflectedXss.js:34:12:34:18 | mytable | | ReflectedXss.js:30:7:33:4 | mytable | ReflectedXss.js:34:12:34:18 | mytable | | ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | ReflectedXss.js:30:7:33:4 | mytable | -| ReflectedXss.js:30:23:33:3 | [\\n [ ... dy]\\n ] | ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | -| ReflectedXss.js:32:5:32:22 | ['body', req.body] | ReflectedXss.js:30:23:33:3 | [\\n [ ... dy]\\n ] | -| ReflectedXss.js:32:14:32:21 | req.body | ReflectedXss.js:32:5:32:22 | ['body', req.body] | -| ReflectedXss.js:32:14:32:21 | req.body | ReflectedXss.js:32:5:32:22 | ['body', req.body] | -| ReflectedXss.js:41:12:41:19 | req.body | ReflectedXss.js:41:12:41:19 | req.body | +| ReflectedXss.js:32:14:32:21 | req.body | ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | | ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) | -| ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) | -| ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) | -| ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) | -| ReflectedXss.js:56:12:56:19 | req.body | ReflectedXss.js:56:12:56:19 | req.body | -| ReflectedXss.js:64:14:64:21 | req.body | ReflectedXss.js:64:39:64:42 | file | | ReflectedXss.js:64:14:64:21 | req.body | ReflectedXss.js:64:39:64:42 | file | | ReflectedXss.js:64:39:64:42 | file | ReflectedXss.js:65:16:65:19 | file | -| ReflectedXss.js:64:39:64:42 | file | ReflectedXss.js:65:16:65:19 | file | -| ReflectedXss.js:68:12:68:41 | remark( ... q.body) | ReflectedXss.js:68:12:68:52 | remark( ... tring() | | ReflectedXss.js:68:12:68:41 | remark( ... q.body) | ReflectedXss.js:68:12:68:52 | remark( ... tring() | | ReflectedXss.js:68:33:68:40 | req.body | ReflectedXss.js:68:12:68:41 | remark( ... q.body) | -| ReflectedXss.js:68:33:68:40 | req.body | ReflectedXss.js:68:12:68:41 | remark( ... q.body) | -| ReflectedXss.js:72:12:72:56 | unified ... q.body) | ReflectedXss.js:72:12:72:65 | unified ... oString | | ReflectedXss.js:72:12:72:56 | unified ... q.body) | ReflectedXss.js:72:12:72:65 | unified ... oString | | ReflectedXss.js:72:48:72:55 | req.body | ReflectedXss.js:72:12:72:56 | unified ... q.body) | -| ReflectedXss.js:72:48:72:55 | req.body | ReflectedXss.js:72:12:72:56 | unified ... q.body) | -| ReflectedXss.js:74:20:74:27 | req.body | ReflectedXss.js:74:34:74:34 | f | | ReflectedXss.js:74:20:74:27 | req.body | ReflectedXss.js:74:34:74:34 | f | | ReflectedXss.js:74:34:74:34 | f | ReflectedXss.js:75:14:75:14 | f | -| ReflectedXss.js:74:34:74:34 | f | ReflectedXss.js:75:14:75:14 | f | -| ReflectedXss.js:83:12:83:19 | req.body | ReflectedXss.js:83:12:83:19 | req.body | -| ReflectedXss.js:84:22:84:29 | req.body | ReflectedXss.js:84:12:84:30 | snarkdown(req.body) | -| ReflectedXss.js:84:22:84:29 | req.body | ReflectedXss.js:84:12:84:30 | snarkdown(req.body) | -| ReflectedXss.js:84:22:84:29 | req.body | ReflectedXss.js:84:12:84:30 | snarkdown(req.body) | | ReflectedXss.js:84:22:84:29 | req.body | ReflectedXss.js:84:12:84:30 | snarkdown(req.body) | | ReflectedXss.js:85:23:85:30 | req.body | ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) | -| ReflectedXss.js:85:23:85:30 | req.body | ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) | -| ReflectedXss.js:85:23:85:30 | req.body | ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) | -| ReflectedXss.js:85:23:85:30 | req.body | ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) | -| ReflectedXss.js:97:12:97:19 | req.body | ReflectedXss.js:97:12:97:19 | req.body | -| ReflectedXss.js:98:30:98:37 | req.body | ReflectedXss.js:98:12:98:38 | markdow ... q.body) | -| ReflectedXss.js:98:30:98:37 | req.body | ReflectedXss.js:98:12:98:38 | markdow ... q.body) | -| ReflectedXss.js:98:30:98:37 | req.body | ReflectedXss.js:98:12:98:38 | markdow ... q.body) | | ReflectedXss.js:98:30:98:37 | req.body | ReflectedXss.js:98:12:98:38 | markdow ... q.body) | | ReflectedXss.js:100:31:100:38 | req.body | ReflectedXss.js:100:12:100:39 | markdow ... q.body) | -| ReflectedXss.js:100:31:100:38 | req.body | ReflectedXss.js:100:12:100:39 | markdow ... q.body) | -| ReflectedXss.js:100:31:100:38 | req.body | ReflectedXss.js:100:12:100:39 | markdow ... q.body) | -| ReflectedXss.js:100:31:100:38 | req.body | ReflectedXss.js:100:12:100:39 | markdow ... q.body) | | ReflectedXss.js:103:76:103:83 | req.body | ReflectedXss.js:103:12:103:84 | markdow ... q.body) | -| ReflectedXss.js:103:76:103:83 | req.body | ReflectedXss.js:103:12:103:84 | markdow ... q.body) | -| ReflectedXss.js:103:76:103:83 | req.body | ReflectedXss.js:103:12:103:84 | markdow ... q.body) | -| ReflectedXss.js:103:76:103:83 | req.body | ReflectedXss.js:103:12:103:84 | markdow ... q.body) | -| ReflectedXss.js:110:16:110:30 | request.query.p | ReflectedXss.js:110:16:110:30 | request.query.p | -| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | | ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | | ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | | ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | | ReflectedXssContentTypes.js:70:22:70:34 | req.params.id | ReflectedXssContentTypes.js:70:12:70:34 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:70:22:70:34 | req.params.id | ReflectedXssContentTypes.js:70:12:70:34 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:70:22:70:34 | req.params.id | ReflectedXssContentTypes.js:70:12:70:34 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:70:22:70:34 | req.params.id | ReflectedXssContentTypes.js:70:12:70:34 | "FOO: " ... rams.id | +| ReflectedXssGood3.js:68:22:68:26 | value | ReflectedXssGood3.js:77:16:77:20 | value | +| ReflectedXssGood3.js:68:22:68:26 | value | ReflectedXssGood3.js:105:18:105:22 | value | +| ReflectedXssGood3.js:77:7:77:37 | parts | ReflectedXssGood3.js:108:10:108:14 | parts | +| ReflectedXssGood3.js:77:16:77:20 | value | ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | +| ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | ReflectedXssGood3.js:77:7:77:37 | parts | +| ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | +| ReflectedXssGood3.js:105:7:105:11 | [post update] parts | ReflectedXssGood3.js:77:7:77:37 | parts | +| ReflectedXssGood3.js:105:7:105:11 | [post update] parts | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | +| ReflectedXssGood3.js:105:18:105:22 | value | ReflectedXssGood3.js:105:18:105:38 | value.s ... g(j, i) | +| ReflectedXssGood3.js:105:18:105:38 | value.s ... g(j, i) | ReflectedXssGood3.js:105:7:105:11 | [post update] parts | +| ReflectedXssGood3.js:108:10:108:14 | parts | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | | ReflectedXssGood3.js:135:9:135:27 | url | ReflectedXssGood3.js:139:24:139:26 | url | | ReflectedXssGood3.js:135:15:135:27 | req.params.id | ReflectedXssGood3.js:135:9:135:27 | url | -| ReflectedXssGood3.js:135:15:135:27 | req.params.id | ReflectedXssGood3.js:135:9:135:27 | url | -| ReflectedXssGood3.js:139:24:139:26 | url | ReflectedXssGood3.js:139:12:139:27 | escapeHtml3(url) | +| ReflectedXssGood3.js:139:24:139:26 | url | ReflectedXssGood3.js:68:22:68:26 | value | | ReflectedXssGood3.js:139:24:139:26 | url | ReflectedXssGood3.js:139:12:139:27 | escapeHtml3(url) | | etherpad.js:9:5:9:53 | response | etherpad.js:11:12:11:19 | response | -| etherpad.js:9:5:9:53 | response | etherpad.js:11:12:11:19 | response | -| etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:9:16:9:53 | req.que ... e + ")" | -| etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:9:16:9:53 | req.que ... e + ")" | -| etherpad.js:9:16:9:53 | req.que ... e + ")" | etherpad.js:9:5:9:53 | response | +| etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:9:5:9:53 | response | | formatting.js:4:9:4:29 | evil | formatting.js:6:43:6:46 | evil | | formatting.js:4:9:4:29 | evil | formatting.js:7:49:7:52 | evil | | formatting.js:4:16:4:29 | req.query.evil | formatting.js:4:9:4:29 | evil | -| formatting.js:4:16:4:29 | req.query.evil | formatting.js:4:9:4:29 | evil | | formatting.js:6:43:6:46 | evil | formatting.js:6:14:6:47 | util.fo ... , evil) | -| formatting.js:6:43:6:46 | evil | formatting.js:6:14:6:47 | util.fo ... , evil) | -| formatting.js:7:49:7:52 | evil | formatting.js:7:14:7:53 | require ... , evil) | | formatting.js:7:49:7:52 | evil | formatting.js:7:14:7:53 | require ... , evil) | | live-server.js:4:11:4:27 | tainted | live-server.js:6:28:6:34 | tainted | | live-server.js:4:21:4:27 | req.url | live-server.js:4:11:4:27 | tainted | -| live-server.js:4:21:4:27 | req.url | live-server.js:4:11:4:27 | tainted | -| live-server.js:6:28:6:34 | tainted | live-server.js:6:13:6:50 | ` ... /html>` | | live-server.js:6:28:6:34 | tainted | live-server.js:6:13:6:50 | ` ... /html>` | | live-server.js:10:11:10:27 | tainted | live-server.js:12:28:12:34 | tainted | | live-server.js:10:21:10:27 | req.url | live-server.js:10:11:10:27 | tainted | -| live-server.js:10:21:10:27 | req.url | live-server.js:10:11:10:27 | tainted | | live-server.js:12:28:12:34 | tainted | live-server.js:12:13:12:50 | ` ... /html>` | -| live-server.js:12:28:12:34 | tainted | live-server.js:12:13:12:50 | ` ... /html>` | -| pages/Next.jsx:8:13:8:19 | req.url | pages/Next.jsx:8:13:8:19 | req.url | -| pages/Next.jsx:15:13:15:19 | req.url | pages/Next.jsx:15:13:15:19 | req.url | -| pages/api/myapi.js:2:14:2:20 | req.url | pages/api/myapi.js:2:14:2:20 | req.url | | partial.js:9:25:9:25 | x | partial.js:10:14:10:14 | x | | partial.js:10:14:10:14 | x | partial.js:10:14:10:18 | x + y | -| partial.js:10:14:10:14 | x | partial.js:10:14:10:18 | x + y | -| partial.js:13:42:13:48 | req.url | partial.js:9:25:9:25 | x | | partial.js:13:42:13:48 | req.url | partial.js:9:25:9:25 | x | | partial.js:18:25:18:25 | x | partial.js:19:14:19:14 | x | | partial.js:19:14:19:14 | x | partial.js:19:14:19:18 | x + y | -| partial.js:19:14:19:14 | x | partial.js:19:14:19:18 | x + y | -| partial.js:22:51:22:57 | req.url | partial.js:18:25:18:25 | x | | partial.js:22:51:22:57 | req.url | partial.js:18:25:18:25 | x | | partial.js:27:25:27:25 | x | partial.js:28:14:28:14 | x | | partial.js:28:14:28:14 | x | partial.js:28:14:28:18 | x + y | -| partial.js:28:14:28:14 | x | partial.js:28:14:28:18 | x + y | -| partial.js:31:47:31:53 | req.url | partial.js:27:25:27:25 | x | | partial.js:31:47:31:53 | req.url | partial.js:27:25:27:25 | x | | partial.js:36:25:36:25 | x | partial.js:37:14:37:14 | x | | partial.js:37:14:37:14 | x | partial.js:37:14:37:18 | x + y | -| partial.js:37:14:37:14 | x | partial.js:37:14:37:18 | x + y | | partial.js:40:43:40:49 | req.url | partial.js:36:25:36:25 | x | -| partial.js:40:43:40:49 | req.url | partial.js:36:25:36:25 | x | -| promises.js:5:3:5:59 | new Pro ... .data)) | promises.js:6:11:6:11 | x | -| promises.js:5:44:5:57 | req.query.data | promises.js:5:3:5:59 | new Pro ... .data)) | -| promises.js:5:44:5:57 | req.query.data | promises.js:5:3:5:59 | new Pro ... .data)) | -| promises.js:5:44:5:57 | req.query.data | promises.js:6:11:6:11 | x | -| promises.js:5:44:5:57 | req.query.data | promises.js:6:11:6:11 | x | -| promises.js:6:11:6:11 | x | promises.js:6:25:6:25 | x | +| promises.js:5:3:5:59 | new Pro ... .data)) [PromiseValue] | promises.js:6:11:6:11 | x | +| promises.js:5:36:5:42 | [post update] resolve [resolve-value] | promises.js:5:3:5:59 | new Pro ... .data)) [PromiseValue] | +| promises.js:5:44:5:57 | req.query.data | promises.js:5:36:5:42 | [post update] resolve [resolve-value] | | promises.js:6:11:6:11 | x | promises.js:6:25:6:25 | x | | tst2.js:6:7:6:30 | p | tst2.js:7:12:7:12 | p | -| tst2.js:6:7:6:30 | p | tst2.js:7:12:7:12 | p | -| tst2.js:6:7:6:30 | r | tst2.js:8:12:8:12 | r | | tst2.js:6:7:6:30 | r | tst2.js:8:12:8:12 | r | | tst2.js:6:9:6:9 | p | tst2.js:6:7:6:30 | p | -| tst2.js:6:9:6:9 | p | tst2.js:6:7:6:30 | p | -| tst2.js:6:12:6:15 | q: r | tst2.js:6:7:6:30 | r | | tst2.js:6:12:6:15 | q: r | tst2.js:6:7:6:30 | r | | tst2.js:14:7:14:24 | p | tst2.js:18:12:18:12 | p | -| tst2.js:14:7:14:24 | p | tst2.js:18:12:18:12 | p | | tst2.js:14:7:14:24 | p | tst2.js:21:14:21:14 | p | -| tst2.js:14:7:14:24 | p | tst2.js:21:14:21:14 | p | -| tst2.js:14:9:14:9 | p | tst2.js:14:7:14:24 | p | | tst2.js:14:9:14:9 | p | tst2.js:14:7:14:24 | p | | tst2.js:30:7:30:24 | p | tst2.js:33:11:33:11 | p | | tst2.js:30:7:30:24 | p | tst2.js:36:12:36:12 | p | -| tst2.js:30:7:30:24 | p | tst2.js:36:12:36:12 | p | | tst2.js:30:9:30:9 | p | tst2.js:30:7:30:24 | p | -| 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:32:7:32:14 | obj [p] | tst2.js:34:21:34:23 | obj [p] | +| tst2.js:33:3:33:5 | [post update] obj [p] | tst2.js:32:7:32:14 | obj [p] | +| tst2.js:33:11:33:11 | p | tst2.js:33:3:33:5 | [post update] obj [p] | +| tst2.js:34:7:34:24 | other [p] | tst2.js:37:12:37:16 | other [p] | +| tst2.js:34:15:34:24 | clone(obj) [p] | tst2.js:34:7:34:24 | other [p] | +| tst2.js:34:21:34:23 | obj [p] | tst2.js:34:15:34:24 | clone(obj) [p] | +| tst2.js:37:12:37:16 | other [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}) | | tst2.js:57:7:57:24 | p | tst2.js:60:11:60:11 | p | | tst2.js:57:7:57:24 | p | tst2.js:63:12:63:12 | p | -| tst2.js:57:7:57:24 | p | tst2.js:63:12:63:12 | p | | tst2.js:57:9:57:9 | p | tst2.js:57:7:57:24 | p | -| tst2.js:57:9:57:9 | p | tst2.js:57:7:57:24 | p | -| tst2.js:60:11:60:11 | p | tst2.js:64:12:64:18 | other.p | -| tst2.js:60:11:60:11 | p | tst2.js:64:12:64:18 | other.p | +| tst2.js:59:7:59:14 | obj [p] | tst2.js:61:22:61:24 | obj [p] | +| tst2.js:60:3:60:5 | [post update] obj [p] | tst2.js:59:7:59:14 | obj [p] | +| tst2.js:60:11:60:11 | p | tst2.js:60:3:60:5 | [post update] obj [p] | +| tst2.js:61:7:61:25 | other [p] | tst2.js:64:12:64:16 | other [p] | +| tst2.js:61:15:61:25 | fclone(obj) [p] | tst2.js:61:7:61:25 | other [p] | +| tst2.js:61:22:61:24 | obj [p] | tst2.js:61:15:61:25 | fclone(obj) [p] | +| tst2.js:64:12:64:16 | other [p] | tst2.js:64:12:64:18 | other.p | | tst2.js:69:7:69:24 | p | tst2.js:72:11:72:11 | p | | tst2.js:69:7:69:24 | p | tst2.js:75:12:75:12 | p | -| tst2.js:69:7:69:24 | p | tst2.js:75:12:75:12 | p | | tst2.js:69:9:69:9 | p | tst2.js:69:7:69:24 | p | -| tst2.js:69:9:69:9 | p | tst2.js:69:7:69:24 | p | -| tst2.js:72:11:72:11 | p | tst2.js:76:12:76:18 | other.p | -| tst2.js:72:11:72:11 | p | tst2.js:76:12:76:18 | other.p | +| tst2.js:71:7:71:14 | obj [p] | tst2.js:73:40:73:42 | obj [p] | +| tst2.js:72:3:72:5 | [post update] obj [p] | tst2.js:71:7:71:14 | obj [p] | +| tst2.js:72:11:72:11 | p | tst2.js:72:3:72:5 | [post update] obj [p] | +| tst2.js:73:7:73:44 | other [p] | tst2.js:76:12:76:16 | other [p] | +| tst2.js:73:15:73:44 | jc.retr ... e(obj)) [p] | tst2.js:73:7:73:44 | other [p] | +| tst2.js:73:29:73:43 | jc.decycle(obj) [p] | tst2.js:73:15:73:44 | jc.retr ... e(obj)) [p] | +| tst2.js:73:40:73:42 | obj [p] | tst2.js:73:29:73:43 | jc.decycle(obj) [p] | +| tst2.js:76:12:76:16 | other [p] | tst2.js:76:12:76:18 | other.p | | tst2.js:82:7:82:24 | p | tst2.js:85:11:85:11 | p | | tst2.js:82:7:82:24 | p | tst2.js:88:12:88:12 | p | -| tst2.js:82:7:82:24 | p | tst2.js:88:12:88:12 | p | | tst2.js:82:9:82:9 | p | tst2.js:82:7:82:24 | p | -| tst2.js:82:9:82:9 | p | tst2.js:82:7:82:24 | p | -| tst2.js:85:11:85:11 | p | tst2.js:89:12:89:18 | other.p | -| tst2.js:85:11:85:11 | p | tst2.js:89:12:89:18 | other.p | -| tst3.js:5:7:5:24 | p | tst3.js:6:12:6:12 | p | +| tst2.js:84:7:84:14 | obj [p] | tst2.js:86:24:86:26 | obj [p] | +| tst2.js:85:3:85:5 | [post update] obj [p] | tst2.js:84:7:84:14 | obj [p] | +| tst2.js:85:11:85:11 | p | tst2.js:85:3:85:5 | [post update] obj [p] | +| tst2.js:86:7:86:27 | other [p] | tst2.js:89:12:89:16 | other [p] | +| tst2.js:86:15:86:27 | sortKeys(obj) [p] | tst2.js:86:7:86:27 | other [p] | +| tst2.js:86:24:86:26 | obj [p] | tst2.js:86:15:86:27 | sortKeys(obj) [p] | +| tst2.js:89:12:89:16 | other [p] | tst2.js:89:12:89:18 | other.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 | -| tst3.js:5:9:5:9 | p | tst3.js:5:7:5:24 | p | -| tst3.js:11:9:11:74 | code | tst3.js:12:12:12:15 | code | | tst3.js:11:9:11:74 | code | tst3.js:12:12:12:15 | code | | tst3.js:11:16:11:74 | prettie ... bel" }) | tst3.js:11:9:11:74 | code | | tst3.js:11:32:11:39 | reg.body | tst3.js:11:16:11:74 | prettie ... bel" }) | -| tst3.js:11:32:11:39 | reg.body | tst3.js:11:16:11:74 | prettie ... bel" }) | +nodes +| ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | semmle.label | "Unknow ... rams.id | +| ReflectedXss.js:8:33:8:45 | req.params.id | semmle.label | req.params.id | +| ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | semmle.label | "Unknow ... rams.id | +| ReflectedXss.js:17:31:17:39 | params.id | semmle.label | params.id | +| ReflectedXss.js:22:12:22:19 | req.body | semmle.label | req.body | +| ReflectedXss.js:23:12:23:27 | marked(req.body) | semmle.label | marked(req.body) | +| ReflectedXss.js:23:19:23:26 | req.body | semmle.label | req.body | +| ReflectedXss.js:29:12:29:19 | req.body | semmle.label | req.body | +| ReflectedXss.js:30:7:33:4 | mytable | semmle.label | mytable | +| ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | semmle.label | table([ ... y]\\n ]) | +| ReflectedXss.js:32:14:32:21 | req.body | semmle.label | req.body | +| ReflectedXss.js:34:12:34:18 | mytable | semmle.label | mytable | +| ReflectedXss.js:41:12:41:19 | req.body | semmle.label | req.body | +| ReflectedXss.js:42:12:42:39 | convert ... q.body) | semmle.label | convert ... q.body) | +| ReflectedXss.js:42:31:42:38 | req.body | semmle.label | req.body | +| ReflectedXss.js:56:12:56:19 | req.body | semmle.label | req.body | +| ReflectedXss.js:64:14:64:21 | req.body | semmle.label | req.body | +| ReflectedXss.js:64:39:64:42 | file | semmle.label | file | +| ReflectedXss.js:65:16:65:19 | file | semmle.label | file | +| ReflectedXss.js:68:12:68:41 | remark( ... q.body) | semmle.label | remark( ... q.body) | +| ReflectedXss.js:68:12:68:52 | remark( ... tring() | semmle.label | remark( ... tring() | +| ReflectedXss.js:68:33:68:40 | req.body | semmle.label | req.body | +| ReflectedXss.js:72:12:72:56 | unified ... q.body) | semmle.label | unified ... q.body) | +| ReflectedXss.js:72:12:72:65 | unified ... oString | semmle.label | unified ... oString | +| ReflectedXss.js:72:48:72:55 | req.body | semmle.label | req.body | +| ReflectedXss.js:74:20:74:27 | req.body | semmle.label | req.body | +| ReflectedXss.js:74:34:74:34 | f | semmle.label | f | +| ReflectedXss.js:75:14:75:14 | f | semmle.label | f | +| ReflectedXss.js:83:12:83:19 | req.body | semmle.label | req.body | +| ReflectedXss.js:84:12:84:30 | snarkdown(req.body) | semmle.label | snarkdown(req.body) | +| ReflectedXss.js:84:22:84:29 | req.body | semmle.label | req.body | +| ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) | semmle.label | snarkdown2(req.body) | +| ReflectedXss.js:85:23:85:30 | req.body | semmle.label | req.body | +| ReflectedXss.js:97:12:97:19 | req.body | semmle.label | req.body | +| ReflectedXss.js:98:12:98:38 | markdow ... q.body) | semmle.label | markdow ... q.body) | +| ReflectedXss.js:98:30:98:37 | req.body | semmle.label | req.body | +| ReflectedXss.js:100:12:100:39 | markdow ... q.body) | semmle.label | markdow ... q.body) | +| ReflectedXss.js:100:31:100:38 | req.body | semmle.label | req.body | +| ReflectedXss.js:103:12:103:84 | markdow ... q.body) | semmle.label | markdow ... q.body) | +| ReflectedXss.js:103:76:103:83 | req.body | semmle.label | req.body | +| ReflectedXss.js:110:16:110:30 | request.query.p | semmle.label | request.query.p | +| ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | semmle.label | "FOO: " ... rams.id | +| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | semmle.label | req.params.id | +| ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | semmle.label | "FOO: " ... rams.id | +| ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | semmle.label | req.params.id | +| ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | semmle.label | "FOO: " ... rams.id | +| ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | semmle.label | req.params.id | +| ReflectedXssContentTypes.js:70:12:70:34 | "FOO: " ... rams.id | semmle.label | "FOO: " ... rams.id | +| ReflectedXssContentTypes.js:70:22:70:34 | req.params.id | semmle.label | req.params.id | +| ReflectedXssGood3.js:68:22:68:26 | value | semmle.label | value | +| ReflectedXssGood3.js:77:7:77:37 | parts | semmle.label | parts | +| ReflectedXssGood3.js:77:16:77:20 | value | semmle.label | value | +| ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | semmle.label | value.s ... g(0, i) | +| ReflectedXssGood3.js:105:7:105:11 | [post update] parts | semmle.label | [post update] parts | +| ReflectedXssGood3.js:105:18:105:22 | value | semmle.label | value | +| ReflectedXssGood3.js:105:18:105:38 | value.s ... g(j, i) | semmle.label | value.s ... g(j, i) | +| ReflectedXssGood3.js:108:10:108:14 | parts | semmle.label | parts | +| ReflectedXssGood3.js:108:10:108:23 | parts.join('') | semmle.label | parts.join('') | +| ReflectedXssGood3.js:135:9:135:27 | url | semmle.label | url | +| ReflectedXssGood3.js:135:15:135:27 | req.params.id | semmle.label | req.params.id | +| ReflectedXssGood3.js:139:12:139:27 | escapeHtml3(url) | semmle.label | escapeHtml3(url) | +| ReflectedXssGood3.js:139:24:139:26 | url | semmle.label | url | +| etherpad.js:9:5:9:53 | response | semmle.label | response | +| etherpad.js:9:16:9:30 | req.query.jsonp | semmle.label | req.query.jsonp | +| etherpad.js:11:12:11:19 | response | semmle.label | response | +| formatting.js:4:9:4:29 | evil | semmle.label | evil | +| formatting.js:4:16:4:29 | req.query.evil | semmle.label | req.query.evil | +| formatting.js:6:14:6:47 | util.fo ... , evil) | semmle.label | util.fo ... , evil) | +| formatting.js:6:43:6:46 | evil | semmle.label | evil | +| formatting.js:7:14:7:53 | require ... , evil) | semmle.label | require ... , evil) | +| formatting.js:7:49:7:52 | evil | semmle.label | evil | +| live-server.js:4:11:4:27 | tainted | semmle.label | tainted | +| live-server.js:4:21:4:27 | req.url | semmle.label | req.url | +| live-server.js:6:13:6:50 | ` ... /html>` | semmle.label | ` ... /html>` | +| live-server.js:6:28:6:34 | tainted | semmle.label | tainted | +| live-server.js:10:11:10:27 | tainted | semmle.label | tainted | +| live-server.js:10:21:10:27 | req.url | semmle.label | req.url | +| live-server.js:12:13:12:50 | ` ... /html>` | semmle.label | ` ... /html>` | +| live-server.js:12:28:12:34 | tainted | semmle.label | tainted | +| pages/Next.jsx:8:13:8:19 | req.url | semmle.label | req.url | +| pages/Next.jsx:15:13:15:19 | req.url | semmle.label | req.url | +| pages/api/myapi.js:2:14:2:20 | req.url | semmle.label | req.url | +| partial.js:9:25:9:25 | x | semmle.label | x | +| partial.js:10:14:10:14 | x | semmle.label | x | +| partial.js:10:14:10:18 | x + y | semmle.label | x + y | +| partial.js:13:42:13:48 | req.url | semmle.label | req.url | +| partial.js:18:25:18:25 | x | semmle.label | x | +| partial.js:19:14:19:14 | x | semmle.label | x | +| partial.js:19:14:19:18 | x + y | semmle.label | x + y | +| partial.js:22:51:22:57 | req.url | semmle.label | req.url | +| partial.js:27:25:27:25 | x | semmle.label | x | +| partial.js:28:14:28:14 | x | semmle.label | x | +| partial.js:28:14:28:18 | x + y | semmle.label | x + y | +| partial.js:31:47:31:53 | req.url | semmle.label | req.url | +| partial.js:36:25:36:25 | x | semmle.label | x | +| partial.js:37:14:37:14 | x | semmle.label | x | +| partial.js:37:14:37:18 | x + y | semmle.label | x + y | +| partial.js:40:43:40:49 | req.url | semmle.label | req.url | +| promises.js:5:3:5:59 | new Pro ... .data)) [PromiseValue] | semmle.label | new Pro ... .data)) [PromiseValue] | +| promises.js:5:36:5:42 | [post update] resolve [resolve-value] | semmle.label | [post update] resolve [resolve-value] | +| promises.js:5:44:5:57 | req.query.data | semmle.label | req.query.data | +| promises.js:6:11:6:11 | x | semmle.label | x | +| promises.js:6:25:6:25 | x | semmle.label | x | +| tst2.js:6:7:6:30 | p | semmle.label | p | +| tst2.js:6:7:6:30 | r | semmle.label | r | +| tst2.js:6:9:6:9 | p | semmle.label | p | +| tst2.js:6:12:6:15 | q: r | semmle.label | q: r | +| tst2.js:7:12:7:12 | p | semmle.label | p | +| tst2.js:8:12:8:12 | r | semmle.label | r | +| tst2.js:14:7:14:24 | p | semmle.label | p | +| tst2.js:14:9:14:9 | p | semmle.label | p | +| tst2.js:18:12:18:12 | p | semmle.label | p | +| tst2.js:21:14:21:14 | p | semmle.label | p | +| tst2.js:30:7:30:24 | p | semmle.label | p | +| tst2.js:30:9:30:9 | p | semmle.label | p | +| tst2.js:32:7:32:14 | obj [p] | semmle.label | obj [p] | +| tst2.js:33:3:33:5 | [post update] obj [p] | semmle.label | [post update] obj [p] | +| tst2.js:33:11:33:11 | p | semmle.label | p | +| tst2.js:34:7:34:24 | other [p] | semmle.label | other [p] | +| tst2.js:34:15:34:24 | clone(obj) [p] | semmle.label | clone(obj) [p] | +| tst2.js:34:21:34:23 | obj [p] | semmle.label | obj [p] | +| tst2.js:36:12:36:12 | p | semmle.label | p | +| tst2.js:37:12:37:16 | other [p] | semmle.label | other [p] | +| tst2.js:37:12:37:18 | other.p | semmle.label | other.p | +| tst2.js:43:7:43:24 | p | semmle.label | p | +| tst2.js:43:9:43:9 | p | semmle.label | p | +| tst2.js:49:7:49:53 | unsafe | semmle.label | unsafe | +| tst2.js:49:16:49:53 | seriali ... true}) | semmle.label | seriali ... true}) | +| tst2.js:49:36:49:36 | p | semmle.label | p | +| tst2.js:51:12:51:17 | unsafe | semmle.label | unsafe | +| tst2.js:57:7:57:24 | p | semmle.label | p | +| tst2.js:57:9:57:9 | p | semmle.label | p | +| tst2.js:59:7:59:14 | obj [p] | semmle.label | obj [p] | +| tst2.js:60:3:60:5 | [post update] obj [p] | semmle.label | [post update] obj [p] | +| tst2.js:60:11:60:11 | p | semmle.label | p | +| tst2.js:61:7:61:25 | other [p] | semmle.label | other [p] | +| tst2.js:61:15:61:25 | fclone(obj) [p] | semmle.label | fclone(obj) [p] | +| tst2.js:61:22:61:24 | obj [p] | semmle.label | obj [p] | +| tst2.js:63:12:63:12 | p | semmle.label | p | +| tst2.js:64:12:64:16 | other [p] | semmle.label | other [p] | +| tst2.js:64:12:64:18 | other.p | semmle.label | other.p | +| tst2.js:69:7:69:24 | p | semmle.label | p | +| tst2.js:69:9:69:9 | p | semmle.label | p | +| tst2.js:71:7:71:14 | obj [p] | semmle.label | obj [p] | +| tst2.js:72:3:72:5 | [post update] obj [p] | semmle.label | [post update] obj [p] | +| tst2.js:72:11:72:11 | p | semmle.label | p | +| tst2.js:73:7:73:44 | other [p] | semmle.label | other [p] | +| tst2.js:73:15:73:44 | jc.retr ... e(obj)) [p] | semmle.label | jc.retr ... e(obj)) [p] | +| tst2.js:73:29:73:43 | jc.decycle(obj) [p] | semmle.label | jc.decycle(obj) [p] | +| tst2.js:73:40:73:42 | obj [p] | semmle.label | obj [p] | +| tst2.js:75:12:75:12 | p | semmle.label | p | +| tst2.js:76:12:76:16 | other [p] | semmle.label | other [p] | +| tst2.js:76:12:76:18 | other.p | semmle.label | other.p | +| tst2.js:82:7:82:24 | p | semmle.label | p | +| tst2.js:82:9:82:9 | p | semmle.label | p | +| tst2.js:84:7:84:14 | obj [p] | semmle.label | obj [p] | +| tst2.js:85:3:85:5 | [post update] obj [p] | semmle.label | [post update] obj [p] | +| tst2.js:85:11:85:11 | p | semmle.label | p | +| tst2.js:86:7:86:27 | other [p] | semmle.label | other [p] | +| tst2.js:86:15:86:27 | sortKeys(obj) [p] | semmle.label | sortKeys(obj) [p] | +| tst2.js:86:24:86:26 | obj [p] | semmle.label | obj [p] | +| tst2.js:88:12:88:12 | p | semmle.label | p | +| tst2.js:89:12:89:16 | other [p] | semmle.label | other [p] | +| tst2.js:89:12:89:18 | other.p | semmle.label | other.p | +| tst3.js:5:7:5:24 | p | semmle.label | p | +| tst3.js:5:9:5:9 | p | semmle.label | p | +| tst3.js:6:12:6:12 | p | semmle.label | p | +| tst3.js:11:9:11:74 | code | semmle.label | code | +| tst3.js:11:16:11:74 | prettie ... bel" }) | semmle.label | prettie ... bel" }) | +| tst3.js:11:32:11:39 | reg.body | semmle.label | reg.body | +| tst3.js:12:12:12:15 | code | semmle.label | code | +subpaths +| ReflectedXssGood3.js:139:24:139:26 | url | ReflectedXssGood3.js:68:22:68:26 | value | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | ReflectedXssGood3.js:139:12:139:27 | escapeHtml3(url) | #select | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:8:33:8:45 | req.params.id | user-provided value | | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:17:31:17:39 | params.id | user-provided value | From 5f05232e023536a57e5ec851b4e3608ce5ee58a1 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:31:50 +0200 Subject: [PATCH 050/514] JS: Port StoredXss --- .../dataflow/StoredXssCustomizations.qll | 15 +++ .../security/dataflow/StoredXssQuery.qll | 25 ++++- .../ql/src/Security/CWE-079/StoredXss.ql | 6 +- .../CWE-079/StoredXss/StoredXss.expected | 95 ++++++++++--------- 4 files changed, 90 insertions(+), 51 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssCustomizations.qll index 16fe8e44a9c..b0de349a53d 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssCustomizations.qll @@ -21,6 +21,21 @@ module StoredXss { /** A sanitizer for stored XSS vulnerabilities. */ abstract class Sanitizer extends Shared::Sanitizer { } + /** + * A barrier guard for stored XSS. + */ + 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() } + } + + /** 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) } + } + /** An arbitrary XSS sink, considered as a flow sink for stored XSS. */ private class AnySink extends Sink { AnySink() { this instanceof Shared::Sink } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssQuery.qll index cc2f3947186..b40b610b71e 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssQuery.qll @@ -8,9 +8,25 @@ import StoredXssCustomizations::StoredXss private import Xss::Shared as Shared /** - * A taint-tracking configuration for reasoning about XSS. + * A taint-tracking configuration for reasoning about stored XSS. */ -class Configuration extends TaintTracking::Configuration { +module StoredXssConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint-tracking for reasoning about stored XSS. + */ +module StoredXssFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `StoredXssFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "StoredXss" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -28,11 +44,10 @@ class Configuration extends TaintTracking::Configuration { } } -private class QuoteGuard extends TaintTracking::SanitizerGuardNode, Shared::QuoteGuard { +private class QuoteGuard extends Shared::QuoteGuard { QuoteGuard() { this = this } } -private class ContainsHtmlGuard extends TaintTracking::SanitizerGuardNode, Shared::ContainsHtmlGuard -{ +private class ContainsHtmlGuard extends Shared::ContainsHtmlGuard { ContainsHtmlGuard() { this = this } } diff --git a/javascript/ql/src/Security/CWE-079/StoredXss.ql b/javascript/ql/src/Security/CWE-079/StoredXss.ql index d5f28b28e55..5aabb1cd115 100644 --- a/javascript/ql/src/Security/CWE-079/StoredXss.ql +++ b/javascript/ql/src/Security/CWE-079/StoredXss.ql @@ -14,9 +14,9 @@ import javascript import semmle.javascript.security.dataflow.StoredXssQuery -import DataFlow::PathGraph +import StoredXssFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from StoredXssFlow::PathNode source, StoredXssFlow::PathNode sink +where StoredXssFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Stored cross-site scripting vulnerability due to $@.", source.getNode(), "stored value" diff --git a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected index d6142c980b6..53f02ae19f2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected @@ -1,55 +1,64 @@ -nodes -| xss-through-filenames.js:7:43:7:48 | files1 | -| xss-through-filenames.js:7:43:7:48 | files1 | -| xss-through-filenames.js:8:18:8:23 | files1 | -| xss-through-filenames.js:8:18:8:23 | files1 | -| xss-through-filenames.js:25:43:25:48 | files1 | -| xss-through-filenames.js:25:43:25:48 | files1 | -| xss-through-filenames.js:26:19:26:24 | files1 | -| xss-through-filenames.js:26:19:26:24 | files1 | -| xss-through-filenames.js:29:13:29:23 | files2 | -| xss-through-filenames.js:29:22:29:23 | [] | -| xss-through-filenames.js:30:9:30:14 | files1 | -| xss-through-filenames.js:30:34:30:37 | file | -| xss-through-filenames.js:31:25:31:28 | file | -| xss-through-filenames.js:33:19:33:24 | files2 | -| xss-through-filenames.js:33:19:33:24 | files2 | -| xss-through-filenames.js:35:13:35:35 | files3 | -| xss-through-filenames.js:35:22:35:35 | format(files2) | -| xss-through-filenames.js:35:29:35:34 | files2 | -| xss-through-filenames.js:37:19:37:24 | files3 | -| xss-through-filenames.js:37:19:37:24 | files3 | -| xss-through-torrent.js:6:6:6:24 | name | -| xss-through-torrent.js:6:13:6:24 | torrent.name | -| xss-through-torrent.js:6:13:6:24 | torrent.name | -| xss-through-torrent.js:7:11:7:14 | name | -| xss-through-torrent.js:7:11:7:14 | name | edges | xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 | -| xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 | -| xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 | -| xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 | -| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 | -| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 | -| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 | +| xss-through-filenames.js:17:21:17:26 | files2 | xss-through-filenames.js:19:9:19:14 | files2 | +| xss-through-filenames.js:17:21:17:26 | files2 [ArrayElement] | xss-through-filenames.js:19:9:19:14 | files2 [ArrayElement] | +| xss-through-filenames.js:19:9:19:14 | files2 | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | +| xss-through-filenames.js:19:9:19:14 | files2 | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | +| xss-through-filenames.js:19:9:19:14 | files2 [ArrayElement] | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | +| xss-through-filenames.js:19:9:19:14 | files2 [ArrayElement] | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:22:16:22:21 | files3 | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:22:16:22:21 | files3 | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 | +| xss-through-filenames.js:22:16:22:21 | files3 | xss-through-filenames.js:22:16:22:30 | files3.join('') | +| xss-through-filenames.js:22:16:22:21 | files3 | xss-through-filenames.js:22:16:22:30 | files3.join('') | | xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 | | xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:30:9:30:14 | files1 | -| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:30:9:30:14 | files1 | -| xss-through-filenames.js:29:13:29:23 | files2 | xss-through-filenames.js:33:19:33:24 | files2 | -| xss-through-filenames.js:29:13:29:23 | files2 | xss-through-filenames.js:33:19:33:24 | files2 | -| xss-through-filenames.js:29:13:29:23 | files2 | xss-through-filenames.js:35:29:35:34 | files2 | -| xss-through-filenames.js:29:22:29:23 | [] | xss-through-filenames.js:29:13:29:23 | files2 | -| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:30:34:30:37 | file | -| xss-through-filenames.js:30:34:30:37 | file | xss-through-filenames.js:31:25:31:28 | file | -| xss-through-filenames.js:31:25:31:28 | file | xss-through-filenames.js:29:22:29:23 | [] | -| xss-through-filenames.js:35:13:35:35 | files3 | xss-through-filenames.js:37:19:37:24 | files3 | +| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:33:19:33:24 | files2 | +| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:33:19:33:24 | files2 | +| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | +| xss-through-filenames.js:33:19:33:24 | files2 | xss-through-filenames.js:35:29:35:34 | files2 | +| xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | | xss-through-filenames.js:35:13:35:35 | files3 | xss-through-filenames.js:37:19:37:24 | files3 | | xss-through-filenames.js:35:22:35:35 | format(files2) | xss-through-filenames.js:35:13:35:35 | files3 | +| xss-through-filenames.js:35:29:35:34 | files2 | xss-through-filenames.js:17:21:17:26 | files2 | | xss-through-filenames.js:35:29:35:34 | files2 | xss-through-filenames.js:35:22:35:35 | format(files2) | -| xss-through-torrent.js:6:6:6:24 | name | xss-through-torrent.js:7:11:7:14 | name | +| xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | xss-through-filenames.js:17:21:17:26 | files2 [ArrayElement] | +| xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | xss-through-filenames.js:35:22:35:35 | format(files2) | | xss-through-torrent.js:6:6:6:24 | name | xss-through-torrent.js:7:11:7:14 | name | | xss-through-torrent.js:6:13:6:24 | torrent.name | xss-through-torrent.js:6:6:6:24 | name | -| xss-through-torrent.js:6:13:6:24 | torrent.name | xss-through-torrent.js:6:6:6:24 | name | +nodes +| xss-through-filenames.js:7:43:7:48 | files1 | semmle.label | files1 | +| xss-through-filenames.js:8:18:8:23 | files1 | semmle.label | files1 | +| xss-through-filenames.js:17:21:17:26 | files2 | semmle.label | files2 | +| xss-through-filenames.js:17:21:17:26 | files2 [ArrayElement] | semmle.label | files2 [ArrayElement] | +| xss-through-filenames.js:19:9:19:14 | files2 | semmle.label | files2 | +| xss-through-filenames.js:19:9:19:14 | files2 [ArrayElement] | semmle.label | files2 [ArrayElement] | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | semmle.label | files2.sort(sort) | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | semmle.label | files2.sort(sort) | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | semmle.label | files2.sort(sort) [ArrayElement] | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | semmle.label | files2.sort(sort) [ArrayElement] | +| xss-through-filenames.js:22:16:22:21 | files3 | semmle.label | files3 | +| xss-through-filenames.js:22:16:22:21 | files3 | semmle.label | files3 | +| xss-through-filenames.js:22:16:22:30 | files3.join('') | semmle.label | files3.join('') | +| xss-through-filenames.js:22:16:22:30 | files3.join('') | semmle.label | files3.join('') | +| xss-through-filenames.js:25:43:25:48 | files1 | semmle.label | files1 | +| xss-through-filenames.js:26:19:26:24 | files1 | semmle.label | files1 | +| xss-through-filenames.js:30:9:30:14 | files1 | semmle.label | files1 | +| xss-through-filenames.js:33:19:33:24 | files2 | semmle.label | files2 | +| xss-through-filenames.js:33:19:33:24 | files2 | semmle.label | files2 | +| xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | semmle.label | files2 [ArrayElement] | +| xss-through-filenames.js:35:13:35:35 | files3 | semmle.label | files3 | +| xss-through-filenames.js:35:22:35:35 | format(files2) | semmle.label | format(files2) | +| xss-through-filenames.js:35:29:35:34 | files2 | semmle.label | files2 | +| xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | semmle.label | files2 [ArrayElement] | +| xss-through-filenames.js:37:19:37:24 | files3 | semmle.label | files3 | +| xss-through-torrent.js:6:6:6:24 | name | semmle.label | name | +| xss-through-torrent.js:6:13:6:24 | torrent.name | semmle.label | torrent.name | +| xss-through-torrent.js:7:11:7:14 | name | semmle.label | name | +subpaths +| xss-through-filenames.js:35:29:35:34 | files2 | xss-through-filenames.js:17:21:17:26 | files2 | xss-through-filenames.js:22:16:22:30 | files3.join('') | xss-through-filenames.js:35:22:35:35 | format(files2) | +| xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | xss-through-filenames.js:17:21:17:26 | files2 [ArrayElement] | xss-through-filenames.js:22:16:22:30 | files3.join('') | xss-through-filenames.js:35:22:35:35 | format(files2) | #select | xss-through-filenames.js:8:18:8:23 | files1 | xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 | Stored cross-site scripting vulnerability due to $@. | xss-through-filenames.js:7:43:7:48 | files1 | stored value | | xss-through-filenames.js:26:19:26:24 | files1 | xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 | Stored cross-site scripting vulnerability due to $@. | xss-through-filenames.js:25:43:25:48 | files1 | stored value | From cf5450dbd55a59bf4a6369f2da01938907a1995c Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:32:04 +0200 Subject: [PATCH 051/514] JS: Port XssThroughDom --- .../dataflow/XssThroughDomCustomizations.qll | 15 + .../security/dataflow/XssThroughDomQuery.qll | 52 ++- .../ql/src/Security/CWE-079/XssThroughDom.ql | 8 +- .../XssThroughDom/ConsistencyXssThroughDom.ql | 13 +- .../XssThroughDom/XssThroughDom.expected | 319 +++++------------- 5 files changed, 160 insertions(+), 247 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll index a1074e49eb2..7e543712331 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll @@ -16,6 +16,21 @@ module XssThroughDom { /** A data flow source for XSS through DOM vulnerabilities. */ abstract class Source extends Shared::Source { } + /** + * A barrier guard for XSS through the DOM. + */ + 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() } + } + + /** 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) } + } + /** * Gets an attribute name that could store user-controlled data. * diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll index cc75078fd67..c9d8112ba5d 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll @@ -11,7 +11,44 @@ private import semmle.javascript.security.dataflow.UnsafeJQueryPluginCustomizati /** * A taint-tracking configuration for reasoning about XSS through the DOM. */ -class Configuration extends TaintTracking::Configuration { +module XssThroughDomConfig implements DataFlow::ConfigSig { + // NOTE: Gained FP in Lucifier due to spurious source but with more data flow (I think). + // TODO: Seen unexplained FP in meteor, likely due to spurious flow into a callback coming from another call site + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof DomBasedXss::Sink } + + predicate isBarrier(DataFlow::Node node) { + node instanceof DomBasedXss::Sanitizer or + DomBasedXss::isOptionallySanitizedNode(node) or + node = DataFlow::MakeBarrierGuard::getABarrierNode() or + node = DataFlow::MakeBarrierGuard::getABarrierNode() + } + + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { + succ = DataFlow::globalVarRef("URL").getAMemberCall("createObjectURL") and + pred = succ.(DataFlow::InvokeNode).getArgument(0) + } +} + +/** + * Taint-tracking configuration for reasoning about XSS through the DOM. + */ +module XssThroughDomFlow = TaintTracking::Global; + +/** + * Holds if the `source,sink` pair should not be reported. + */ +bindingset[source, sink] +predicate isIgnoredSourceSinkPair(Source source, DomBasedXss::Sink sink) { + source.(DomPropertySource).getPropertyName() = "src" and + sink instanceof DomBasedXss::WriteUrlSink +} + +/** + * DEPRECATED. Use the `XssThroughDomFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "XssThroughDOM" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -49,14 +86,14 @@ class Configuration extends TaintTracking::Configuration { } /** A test for the value of `typeof x`, restricting the potential types of `x`. */ -class TypeTestGuard extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode { +class TypeTestGuard extends BarrierGuardLegacy, DataFlow::ValueNode { override EqualityTest astNode; Expr operand; boolean polarity; TypeTestGuard() { TaintTracking::isStringTypeGuard(astNode, operand, polarity) } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { polarity = outcome and e = operand } @@ -64,9 +101,7 @@ class TypeTestGuard extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNo private import semmle.javascript.security.dataflow.Xss::Shared as Shared -private class PrefixStringSanitizer extends TaintTracking::SanitizerGuardNode, - DomBasedXss::PrefixStringSanitizer -{ +private class PrefixStringSanitizer extends DomBasedXss::PrefixStringSanitizer { PrefixStringSanitizer() { this = this } } @@ -74,11 +109,10 @@ private class PrefixString extends DataFlow::FlowLabel, DomBasedXss::PrefixStrin PrefixString() { this = this } } -private class QuoteGuard extends TaintTracking::SanitizerGuardNode, Shared::QuoteGuard { +private class QuoteGuard extends Shared::QuoteGuard { QuoteGuard() { this = this } } -private class ContainsHtmlGuard extends TaintTracking::SanitizerGuardNode, Shared::ContainsHtmlGuard -{ +private class ContainsHtmlGuard extends Shared::ContainsHtmlGuard { ContainsHtmlGuard() { this = this } } diff --git a/javascript/ql/src/Security/CWE-079/XssThroughDom.ql b/javascript/ql/src/Security/CWE-079/XssThroughDom.ql index 87a76d82227..e690e2bab28 100644 --- a/javascript/ql/src/Security/CWE-079/XssThroughDom.ql +++ b/javascript/ql/src/Security/CWE-079/XssThroughDom.ql @@ -14,9 +14,11 @@ import javascript import semmle.javascript.security.dataflow.XssThroughDomQuery -import DataFlow::PathGraph +import XssThroughDomFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from XssThroughDomFlow::PathNode source, XssThroughDomFlow::PathNode sink +where + XssThroughDomFlow::flowPath(source, sink) and + not isIgnoredSourceSinkPair(source.getNode(), sink.getNode()) select sink.getNode(), source, sink, "$@ is reinterpreted as HTML without escaping meta-characters.", source.getNode(), "DOM text" diff --git a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql index 75416d5a0dc..08eb6eda7fb 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql @@ -1,3 +1,14 @@ import javascript import testUtilities.ConsistencyChecking -import semmle.javascript.security.dataflow.XssThroughDomQuery as ThroughDomXss +import semmle.javascript.security.dataflow.XssThroughDomQuery + +class ConsistencyConfig extends ConsistencyConfiguration { + ConsistencyConfig() { this = "ConsistencyConfig" } + + override DataFlow::Node getAnAlert() { + exists(DataFlow::Node source | + XssThroughDomFlow::flow(source, result) and + not isIgnoredSourceSinkPair(source, result) + ) + } +} diff --git a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected index 83147705499..156b4b7e2f2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected @@ -1,277 +1,128 @@ -nodes -| forms.js:8:23:8:28 | values | -| forms.js:8:23:8:28 | values | -| forms.js:9:31:9:36 | values | -| forms.js:9:31:9:40 | values.foo | -| forms.js:9:31:9:40 | values.foo | -| forms.js:11:24:11:29 | values | -| forms.js:11:24:11:29 | values | -| forms.js:12:31:12:36 | values | -| forms.js:12:31:12:40 | values.bar | -| forms.js:12:31:12:40 | values.bar | -| forms.js:24:15:24:20 | values | -| forms.js:24:15:24:20 | values | -| forms.js:25:23:25:28 | values | -| forms.js:25:23:25:34 | values.email | -| forms.js:25:23:25:34 | values.email | -| forms.js:28:20:28:25 | values | -| forms.js:28:20:28:25 | values | -| forms.js:29:23:29:28 | values | -| forms.js:29:23:29:34 | values.email | -| forms.js:29:23:29:34 | values.email | -| forms.js:34:11:34:53 | values | -| forms.js:34:13:34:18 | values | -| forms.js:34:13:34:18 | values | -| forms.js:35:19:35:24 | values | -| forms.js:35:19:35:30 | values.email | -| forms.js:35:19:35:30 | values.email | -| forms.js:44:21:44:26 | values | -| forms.js:44:21:44:26 | values | -| forms.js:45:21:45:26 | values | -| forms.js:45:21:45:33 | values.stooge | -| forms.js:45:21:45:33 | values.stooge | -| forms.js:57:19:57:32 | e.target.value | -| forms.js:57:19:57:32 | e.target.value | -| forms.js:57:19:57:32 | e.target.value | -| forms.js:71:21:71:24 | data | -| forms.js:71:21:71:24 | data | -| forms.js:72:19:72:22 | data | -| forms.js:72:19:72:27 | data.name | -| forms.js:72:19:72:27 | data.name | -| forms.js:92:17:92:36 | values | -| forms.js:92:26:92:36 | getValues() | -| forms.js:92:26:92:36 | getValues() | -| forms.js:93:25:93:30 | values | -| forms.js:93:25:93:35 | values.name | -| forms.js:93:25:93:35 | values.name | -| forms.js:103:23:103:36 | e.target.value | -| forms.js:103:23:103:36 | e.target.value | -| forms.js:103:23:103:36 | e.target.value | -| forms.js:107:23:107:36 | e.target.value | -| forms.js:107:23:107:36 | e.target.value | -| forms.js:107:23:107:36 | e.target.value | -| xss-through-dom.js:2:16:2:34 | $("textarea").val() | -| xss-through-dom.js:2:16:2:34 | $("textarea").val() | -| xss-through-dom.js:2:16:2:34 | $("textarea").val() | -| xss-through-dom.js:4:16:4:40 | $(".som ... .text() | -| xss-through-dom.js:4:16:4:40 | $(".som ... .text() | -| xss-through-dom.js:4:16:4:40 | $(".som ... .text() | -| xss-through-dom.js:8:16:8:53 | $(".som ... arget") | -| xss-through-dom.js:8:16:8:53 | $(".som ... arget") | -| xss-through-dom.js:8:16:8:53 | $(".som ... arget") | -| xss-through-dom.js:11:3:11:42 | documen ... nerText | -| xss-through-dom.js:11:3:11:42 | documen ... nerText | -| xss-through-dom.js:11:3:11:42 | documen ... nerText | -| xss-through-dom.js:19:3:19:44 | documen ... Content | -| xss-through-dom.js:19:3:19:44 | documen ... Content | -| xss-through-dom.js:19:3:19:44 | documen ... Content | -| xss-through-dom.js:23:3:23:48 | documen ... ].value | -| xss-through-dom.js:23:3:23:48 | documen ... ].value | -| xss-through-dom.js:23:3:23:48 | documen ... ].value | -| xss-through-dom.js:27:3:27:61 | documen ... arget') | -| xss-through-dom.js:27:3:27:61 | documen ... arget') | -| xss-through-dom.js:27:3:27:61 | documen ... arget') | -| xss-through-dom.js:51:30:51:48 | $("textarea").val() | -| xss-through-dom.js:51:30:51:48 | $("textarea").val() | -| xss-through-dom.js:51:30:51:48 | $("textarea").val() | -| xss-through-dom.js:54:31:54:49 | $("textarea").val() | -| xss-through-dom.js:54:31:54:49 | $("textarea").val() | -| xss-through-dom.js:54:31:54:49 | $("textarea").val() | -| xss-through-dom.js:56:30:56:51 | $("inpu ... 0).name | -| xss-through-dom.js:56:30:56:51 | $("inpu ... 0).name | -| xss-through-dom.js:56:30:56:51 | $("inpu ... 0).name | -| xss-through-dom.js:57:30:57:67 | $("inpu ... "name") | -| xss-through-dom.js:57:30:57:67 | $("inpu ... "name") | -| xss-through-dom.js:57:30:57:67 | $("inpu ... "name") | -| xss-through-dom.js:61:30:61:69 | $(docum ... value") | -| xss-through-dom.js:61:30:61:69 | $(docum ... value") | -| xss-through-dom.js:61:30:61:69 | $(docum ... value") | -| xss-through-dom.js:64:30:64:40 | valMethod() | -| xss-through-dom.js:64:30:64:40 | valMethod() | -| xss-through-dom.js:64:30:64:40 | valMethod() | -| xss-through-dom.js:71:11:71:32 | $("inpu ... 0).name | -| xss-through-dom.js:71:11:71:32 | $("inpu ... 0).name | -| xss-through-dom.js:71:11:71:32 | $("inpu ... 0).name | -| xss-through-dom.js:73:9:73:41 | selector | -| xss-through-dom.js:73:20:73:41 | $("inpu ... 0).name | -| xss-through-dom.js:73:20:73:41 | $("inpu ... 0).name | -| xss-through-dom.js:77:4:77:11 | selector | -| xss-through-dom.js:77:4:77:11 | selector | -| xss-through-dom.js:79:4:79:34 | documen ... t.value | -| xss-through-dom.js:79:4:79:34 | documen ... t.value | -| xss-through-dom.js:79:4:79:34 | documen ... t.value | -| xss-through-dom.js:81:17:81:43 | $('#foo ... rText') | -| xss-through-dom.js:81:17:81:43 | $('#foo ... rText') | -| xss-through-dom.js:81:17:81:43 | $('#foo ... rText') | -| xss-through-dom.js:84:8:84:30 | text | -| xss-through-dom.js:84:15:84:30 | $("text").text() | -| xss-through-dom.js:84:15:84:30 | $("text").text() | -| xss-through-dom.js:86:16:86:37 | anser.a ... l(text) | -| xss-through-dom.js:86:16:86:37 | anser.a ... l(text) | -| xss-through-dom.js:86:33:86:36 | text | -| xss-through-dom.js:87:16:87:40 | new ans ... s(text) | -| xss-through-dom.js:87:16:87:40 | new ans ... s(text) | -| xss-through-dom.js:87:36:87:39 | text | -| xss-through-dom.js:93:16:93:46 | $("#foo ... ].value | -| xss-through-dom.js:93:16:93:46 | $("#foo ... ].value | -| xss-through-dom.js:93:16:93:46 | $("#foo ... ].value | -| xss-through-dom.js:96:17:96:47 | $("#foo ... ].value | -| xss-through-dom.js:96:17:96:47 | $("#foo ... ].value | -| xss-through-dom.js:96:17:96:47 | $("#foo ... ].value | -| xss-through-dom.js:109:31:109:70 | "" | -| xss-through-dom.js:109:31:109:70 | "" | -| xss-through-dom.js:109:45:109:55 | this.el.src | -| xss-through-dom.js:109:45:109:55 | this.el.src | -| xss-through-dom.js:114:11:114:52 | src | -| xss-through-dom.js:114:17:114:52 | documen ... k").src | -| xss-through-dom.js:114:17:114:52 | documen ... k").src | -| xss-through-dom.js:115:16:115:18 | src | -| xss-through-dom.js:115:16:115:18 | src | -| xss-through-dom.js:117:26:117:28 | src | -| xss-through-dom.js:117:26:117:28 | src | -| xss-through-dom.js:120:23:120:37 | ev.target.files | -| xss-through-dom.js:120:23:120:37 | ev.target.files | -| xss-through-dom.js:120:23:120:40 | ev.target.files[0] | -| xss-through-dom.js:120:23:120:45 | ev.targ ... 0].name | -| xss-through-dom.js:120:23:120:45 | ev.targ ... 0].name | -| xss-through-dom.js:122:33:122:71 | URL.cre ... les[0]) | -| xss-through-dom.js:122:33:122:71 | URL.cre ... les[0]) | -| xss-through-dom.js:122:53:122:67 | ev.target.files | -| xss-through-dom.js:122:53:122:67 | ev.target.files | -| xss-through-dom.js:122:53:122:70 | ev.target.files[0] | -| xss-through-dom.js:130:6:130:68 | linkText | -| xss-through-dom.js:130:17:130:37 | wSelect ... tring() | -| xss-through-dom.js:130:17:130:37 | wSelect ... tring() | -| xss-through-dom.js:130:17:130:62 | wSelect ... tring() | -| xss-through-dom.js:130:17:130:68 | wSelect ... ) \|\| '' | -| xss-through-dom.js:130:42:130:62 | dSelect ... tring() | -| xss-through-dom.js:130:42:130:62 | dSelect ... tring() | -| xss-through-dom.js:131:19:131:26 | linkText | -| xss-through-dom.js:131:19:131:26 | linkText | -| xss-through-dom.js:132:16:132:23 | linkText | -| xss-through-dom.js:132:16:132:23 | linkText | -| xss-through-dom.js:139:11:139:52 | src | -| xss-through-dom.js:139:17:139:52 | documen ... k").src | -| xss-through-dom.js:139:17:139:52 | documen ... k").src | -| xss-through-dom.js:140:19:140:21 | src | -| xss-through-dom.js:140:19:140:21 | src | -| xss-through-dom.js:141:25:141:27 | src | -| xss-through-dom.js:141:25:141:27 | src | -| xss-through-dom.js:150:24:150:26 | src | -| xss-through-dom.js:150:24:150:26 | src | -| xss-through-dom.js:154:25:154:27 | msg | -| xss-through-dom.js:155:27:155:29 | msg | -| xss-through-dom.js:155:27:155:29 | msg | -| xss-through-dom.js:159:34:159:52 | $("textarea").val() | -| xss-through-dom.js:159:34:159:52 | $("textarea").val() | edges | forms.js:8:23:8:28 | values | forms.js:9:31:9:36 | values | -| forms.js:8:23:8:28 | values | forms.js:9:31:9:36 | values | -| forms.js:9:31:9:36 | values | forms.js:9:31:9:40 | values.foo | | forms.js:9:31:9:36 | values | forms.js:9:31:9:40 | values.foo | | forms.js:11:24:11:29 | values | forms.js:12:31:12:36 | values | -| forms.js:11:24:11:29 | values | forms.js:12:31:12:36 | values | -| forms.js:12:31:12:36 | values | forms.js:12:31:12:40 | values.bar | | forms.js:12:31:12:36 | values | forms.js:12:31:12:40 | values.bar | | forms.js:24:15:24:20 | values | forms.js:25:23:25:28 | values | -| forms.js:24:15:24:20 | values | forms.js:25:23:25:28 | values | -| forms.js:25:23:25:28 | values | forms.js:25:23:25:34 | values.email | | forms.js:25:23:25:28 | values | forms.js:25:23:25:34 | values.email | | forms.js:28:20:28:25 | values | forms.js:29:23:29:28 | values | -| forms.js:28:20:28:25 | values | forms.js:29:23:29:28 | values | -| forms.js:29:23:29:28 | values | forms.js:29:23:29:34 | values.email | | forms.js:29:23:29:28 | values | forms.js:29:23:29:34 | values.email | | forms.js:34:11:34:53 | values | forms.js:35:19:35:24 | values | | forms.js:34:13:34:18 | values | forms.js:34:11:34:53 | values | -| forms.js:34:13:34:18 | values | forms.js:34:11:34:53 | values | -| forms.js:35:19:35:24 | values | forms.js:35:19:35:30 | values.email | | forms.js:35:19:35:24 | values | forms.js:35:19:35:30 | values.email | | forms.js:44:21:44:26 | values | forms.js:45:21:45:26 | values | -| forms.js:44:21:44:26 | values | forms.js:45:21:45:26 | values | | forms.js:45:21:45:26 | values | forms.js:45:21:45:33 | values.stooge | -| forms.js:45:21:45:26 | values | forms.js:45:21:45:33 | values.stooge | -| forms.js:57:19:57:32 | e.target.value | forms.js:57:19:57:32 | e.target.value | | forms.js:71:21:71:24 | data | forms.js:72:19:72:22 | data | -| forms.js:71:21:71:24 | data | forms.js:72:19:72:22 | data | -| forms.js:72:19:72:22 | data | forms.js:72:19:72:27 | data.name | | forms.js:72:19:72:22 | data | forms.js:72:19:72:27 | data.name | | forms.js:92:17:92:36 | values | forms.js:93:25:93:30 | values | | forms.js:92:26:92:36 | getValues() | forms.js:92:17:92:36 | values | -| forms.js:92:26:92:36 | getValues() | forms.js:92:17:92:36 | values | | forms.js:93:25:93:30 | values | forms.js:93:25:93:35 | values.name | -| forms.js:93:25:93:30 | values | forms.js:93:25:93:35 | values.name | -| forms.js:103:23:103:36 | e.target.value | forms.js:103:23:103:36 | e.target.value | -| forms.js:107:23:107:36 | e.target.value | forms.js:107:23:107:36 | e.target.value | -| xss-through-dom.js:2:16:2:34 | $("textarea").val() | xss-through-dom.js:2:16:2:34 | $("textarea").val() | -| xss-through-dom.js:4:16:4:40 | $(".som ... .text() | xss-through-dom.js:4:16:4:40 | $(".som ... .text() | -| xss-through-dom.js:8:16:8:53 | $(".som ... arget") | xss-through-dom.js:8:16:8:53 | $(".som ... arget") | -| xss-through-dom.js:11:3:11:42 | documen ... nerText | xss-through-dom.js:11:3:11:42 | documen ... nerText | -| xss-through-dom.js:19:3:19:44 | documen ... Content | xss-through-dom.js:19:3:19:44 | documen ... Content | -| xss-through-dom.js:23:3:23:48 | documen ... ].value | xss-through-dom.js:23:3:23:48 | documen ... ].value | -| xss-through-dom.js:27:3:27:61 | documen ... arget') | xss-through-dom.js:27:3:27:61 | documen ... arget') | -| xss-through-dom.js:51:30:51:48 | $("textarea").val() | xss-through-dom.js:51:30:51:48 | $("textarea").val() | -| xss-through-dom.js:54:31:54:49 | $("textarea").val() | xss-through-dom.js:54:31:54:49 | $("textarea").val() | -| xss-through-dom.js:56:30:56:51 | $("inpu ... 0).name | xss-through-dom.js:56:30:56:51 | $("inpu ... 0).name | -| xss-through-dom.js:57:30:57:67 | $("inpu ... "name") | xss-through-dom.js:57:30:57:67 | $("inpu ... "name") | -| xss-through-dom.js:61:30:61:69 | $(docum ... value") | xss-through-dom.js:61:30:61:69 | $(docum ... value") | -| xss-through-dom.js:64:30:64:40 | valMethod() | xss-through-dom.js:64:30:64:40 | valMethod() | -| xss-through-dom.js:71:11:71:32 | $("inpu ... 0).name | xss-through-dom.js:71:11:71:32 | $("inpu ... 0).name | -| xss-through-dom.js:73:9:73:41 | selector | xss-through-dom.js:77:4:77:11 | selector | | xss-through-dom.js:73:9:73:41 | selector | xss-through-dom.js:77:4:77:11 | selector | | xss-through-dom.js:73:20:73:41 | $("inpu ... 0).name | xss-through-dom.js:73:9:73:41 | selector | -| xss-through-dom.js:73:20:73:41 | $("inpu ... 0).name | xss-through-dom.js:73:9:73:41 | selector | -| xss-through-dom.js:79:4:79:34 | documen ... t.value | xss-through-dom.js:79:4:79:34 | documen ... t.value | -| xss-through-dom.js:81:17:81:43 | $('#foo ... rText') | xss-through-dom.js:81:17:81:43 | $('#foo ... rText') | | xss-through-dom.js:84:8:84:30 | text | xss-through-dom.js:86:33:86:36 | text | | xss-through-dom.js:84:8:84:30 | text | xss-through-dom.js:87:36:87:39 | text | | xss-through-dom.js:84:15:84:30 | $("text").text() | xss-through-dom.js:84:8:84:30 | text | -| xss-through-dom.js:84:15:84:30 | $("text").text() | xss-through-dom.js:84:8:84:30 | text | -| xss-through-dom.js:86:33:86:36 | text | xss-through-dom.js:86:16:86:37 | anser.a ... l(text) | | xss-through-dom.js:86:33:86:36 | text | xss-through-dom.js:86:16:86:37 | anser.a ... l(text) | | xss-through-dom.js:87:36:87:39 | text | xss-through-dom.js:87:16:87:40 | new ans ... s(text) | -| xss-through-dom.js:87:36:87:39 | text | xss-through-dom.js:87:16:87:40 | new ans ... s(text) | -| xss-through-dom.js:93:16:93:46 | $("#foo ... ].value | xss-through-dom.js:93:16:93:46 | $("#foo ... ].value | -| xss-through-dom.js:96:17:96:47 | $("#foo ... ].value | xss-through-dom.js:96:17:96:47 | $("#foo ... ].value | -| xss-through-dom.js:109:45:109:55 | this.el.src | xss-through-dom.js:109:31:109:70 | "" | -| xss-through-dom.js:109:45:109:55 | this.el.src | xss-through-dom.js:109:31:109:70 | "" | -| xss-through-dom.js:109:45:109:55 | this.el.src | xss-through-dom.js:109:31:109:70 | "" | | xss-through-dom.js:109:45:109:55 | this.el.src | xss-through-dom.js:109:31:109:70 | "" | | xss-through-dom.js:114:11:114:52 | src | xss-through-dom.js:115:16:115:18 | src | -| xss-through-dom.js:114:11:114:52 | src | xss-through-dom.js:115:16:115:18 | src | -| xss-through-dom.js:114:11:114:52 | src | xss-through-dom.js:117:26:117:28 | src | | xss-through-dom.js:114:11:114:52 | src | xss-through-dom.js:117:26:117:28 | src | | xss-through-dom.js:114:17:114:52 | documen ... k").src | xss-through-dom.js:114:11:114:52 | src | -| xss-through-dom.js:114:17:114:52 | documen ... k").src | xss-through-dom.js:114:11:114:52 | src | -| xss-through-dom.js:120:23:120:37 | ev.target.files | xss-through-dom.js:120:23:120:40 | ev.target.files[0] | -| xss-through-dom.js:120:23:120:37 | ev.target.files | xss-through-dom.js:120:23:120:40 | ev.target.files[0] | -| xss-through-dom.js:120:23:120:40 | ev.target.files[0] | xss-through-dom.js:120:23:120:45 | ev.targ ... 0].name | -| xss-through-dom.js:120:23:120:40 | ev.target.files[0] | xss-through-dom.js:120:23:120:45 | ev.targ ... 0].name | -| xss-through-dom.js:122:53:122:67 | ev.target.files | xss-through-dom.js:122:53:122:70 | ev.target.files[0] | +| xss-through-dom.js:120:23:120:37 | ev.target.files | xss-through-dom.js:120:23:120:45 | ev.targ ... 0].name | | xss-through-dom.js:122:53:122:67 | ev.target.files | xss-through-dom.js:122:53:122:70 | ev.target.files[0] | | xss-through-dom.js:122:53:122:70 | ev.target.files[0] | xss-through-dom.js:122:33:122:71 | URL.cre ... les[0]) | -| xss-through-dom.js:122:53:122:70 | ev.target.files[0] | xss-through-dom.js:122:33:122:71 | URL.cre ... les[0]) | -| xss-through-dom.js:130:6:130:68 | linkText | xss-through-dom.js:131:19:131:26 | linkText | | xss-through-dom.js:130:6:130:68 | linkText | xss-through-dom.js:131:19:131:26 | linkText | | xss-through-dom.js:130:6:130:68 | linkText | xss-through-dom.js:132:16:132:23 | linkText | -| xss-through-dom.js:130:6:130:68 | linkText | xss-through-dom.js:132:16:132:23 | linkText | -| xss-through-dom.js:130:17:130:37 | wSelect ... tring() | xss-through-dom.js:130:17:130:62 | wSelect ... tring() | -| xss-through-dom.js:130:17:130:37 | wSelect ... tring() | xss-through-dom.js:130:17:130:62 | wSelect ... tring() | -| xss-through-dom.js:130:17:130:62 | wSelect ... tring() | xss-through-dom.js:130:17:130:68 | wSelect ... ) \|\| '' | -| xss-through-dom.js:130:17:130:68 | wSelect ... ) \|\| '' | xss-through-dom.js:130:6:130:68 | linkText | -| xss-through-dom.js:130:42:130:62 | dSelect ... tring() | xss-through-dom.js:130:17:130:62 | wSelect ... tring() | -| xss-through-dom.js:130:42:130:62 | dSelect ... tring() | xss-through-dom.js:130:17:130:62 | wSelect ... tring() | -| xss-through-dom.js:139:11:139:52 | src | xss-through-dom.js:140:19:140:21 | src | +| xss-through-dom.js:130:17:130:37 | wSelect ... tring() | xss-through-dom.js:130:6:130:68 | linkText | +| xss-through-dom.js:130:42:130:62 | dSelect ... tring() | xss-through-dom.js:130:6:130:68 | linkText | | xss-through-dom.js:139:11:139:52 | src | xss-through-dom.js:140:19:140:21 | src | | xss-through-dom.js:139:11:139:52 | src | xss-through-dom.js:141:25:141:27 | src | -| xss-through-dom.js:139:11:139:52 | src | xss-through-dom.js:141:25:141:27 | src | -| xss-through-dom.js:139:11:139:52 | src | xss-through-dom.js:150:24:150:26 | src | | xss-through-dom.js:139:11:139:52 | src | xss-through-dom.js:150:24:150:26 | src | | xss-through-dom.js:139:17:139:52 | documen ... k").src | xss-through-dom.js:139:11:139:52 | src | -| xss-through-dom.js:139:17:139:52 | documen ... k").src | xss-through-dom.js:139:11:139:52 | src | -| xss-through-dom.js:154:25:154:27 | msg | xss-through-dom.js:155:27:155:29 | msg | | xss-through-dom.js:154:25:154:27 | msg | xss-through-dom.js:155:27:155:29 | msg | | xss-through-dom.js:159:34:159:52 | $("textarea").val() | xss-through-dom.js:154:25:154:27 | msg | -| xss-through-dom.js:159:34:159:52 | $("textarea").val() | xss-through-dom.js:154:25:154:27 | msg | +nodes +| forms.js:8:23:8:28 | values | semmle.label | values | +| forms.js:9:31:9:36 | values | semmle.label | values | +| forms.js:9:31:9:40 | values.foo | semmle.label | values.foo | +| forms.js:11:24:11:29 | values | semmle.label | values | +| forms.js:12:31:12:36 | values | semmle.label | values | +| forms.js:12:31:12:40 | values.bar | semmle.label | values.bar | +| forms.js:24:15:24:20 | values | semmle.label | values | +| forms.js:25:23:25:28 | values | semmle.label | values | +| forms.js:25:23:25:34 | values.email | semmle.label | values.email | +| forms.js:28:20:28:25 | values | semmle.label | values | +| forms.js:29:23:29:28 | values | semmle.label | values | +| forms.js:29:23:29:34 | values.email | semmle.label | values.email | +| forms.js:34:11:34:53 | values | semmle.label | values | +| forms.js:34:13:34:18 | values | semmle.label | values | +| forms.js:35:19:35:24 | values | semmle.label | values | +| forms.js:35:19:35:30 | values.email | semmle.label | values.email | +| forms.js:44:21:44:26 | values | semmle.label | values | +| forms.js:45:21:45:26 | values | semmle.label | values | +| forms.js:45:21:45:33 | values.stooge | semmle.label | values.stooge | +| forms.js:57:19:57:32 | e.target.value | semmle.label | e.target.value | +| forms.js:71:21:71:24 | data | semmle.label | data | +| forms.js:72:19:72:22 | data | semmle.label | data | +| forms.js:72:19:72:27 | data.name | semmle.label | data.name | +| forms.js:92:17:92:36 | values | semmle.label | values | +| forms.js:92:26:92:36 | getValues() | semmle.label | getValues() | +| forms.js:93:25:93:30 | values | semmle.label | values | +| forms.js:93:25:93:35 | values.name | semmle.label | values.name | +| forms.js:103:23:103:36 | e.target.value | semmle.label | e.target.value | +| forms.js:107:23:107:36 | e.target.value | semmle.label | e.target.value | +| xss-through-dom.js:2:16:2:34 | $("textarea").val() | semmle.label | $("textarea").val() | +| xss-through-dom.js:4:16:4:40 | $(".som ... .text() | semmle.label | $(".som ... .text() | +| xss-through-dom.js:8:16:8:53 | $(".som ... arget") | semmle.label | $(".som ... arget") | +| xss-through-dom.js:11:3:11:42 | documen ... nerText | semmle.label | documen ... nerText | +| xss-through-dom.js:19:3:19:44 | documen ... Content | semmle.label | documen ... Content | +| xss-through-dom.js:23:3:23:48 | documen ... ].value | semmle.label | documen ... ].value | +| xss-through-dom.js:27:3:27:61 | documen ... arget') | semmle.label | documen ... arget') | +| xss-through-dom.js:51:30:51:48 | $("textarea").val() | semmle.label | $("textarea").val() | +| xss-through-dom.js:54:31:54:49 | $("textarea").val() | semmle.label | $("textarea").val() | +| xss-through-dom.js:56:30:56:51 | $("inpu ... 0).name | semmle.label | $("inpu ... 0).name | +| xss-through-dom.js:57:30:57:67 | $("inpu ... "name") | semmle.label | $("inpu ... "name") | +| xss-through-dom.js:61:30:61:69 | $(docum ... value") | semmle.label | $(docum ... value") | +| xss-through-dom.js:64:30:64:40 | valMethod() | semmle.label | valMethod() | +| xss-through-dom.js:71:11:71:32 | $("inpu ... 0).name | semmle.label | $("inpu ... 0).name | +| xss-through-dom.js:73:9:73:41 | selector | semmle.label | selector | +| xss-through-dom.js:73:20:73:41 | $("inpu ... 0).name | semmle.label | $("inpu ... 0).name | +| xss-through-dom.js:77:4:77:11 | selector | semmle.label | selector | +| xss-through-dom.js:79:4:79:34 | documen ... t.value | semmle.label | documen ... t.value | +| xss-through-dom.js:81:17:81:43 | $('#foo ... rText') | semmle.label | $('#foo ... rText') | +| xss-through-dom.js:84:8:84:30 | text | semmle.label | text | +| xss-through-dom.js:84:15:84:30 | $("text").text() | semmle.label | $("text").text() | +| xss-through-dom.js:86:16:86:37 | anser.a ... l(text) | semmle.label | anser.a ... l(text) | +| xss-through-dom.js:86:33:86:36 | text | semmle.label | text | +| xss-through-dom.js:87:16:87:40 | new ans ... s(text) | semmle.label | new ans ... s(text) | +| xss-through-dom.js:87:36:87:39 | text | semmle.label | text | +| xss-through-dom.js:93:16:93:46 | $("#foo ... ].value | semmle.label | $("#foo ... ].value | +| xss-through-dom.js:96:17:96:47 | $("#foo ... ].value | semmle.label | $("#foo ... ].value | +| xss-through-dom.js:109:31:109:70 | "" | semmle.label | "" | +| xss-through-dom.js:109:45:109:55 | this.el.src | semmle.label | this.el.src | +| xss-through-dom.js:114:11:114:52 | src | semmle.label | src | +| xss-through-dom.js:114:17:114:52 | documen ... k").src | semmle.label | documen ... k").src | +| xss-through-dom.js:115:16:115:18 | src | semmle.label | src | +| xss-through-dom.js:117:26:117:28 | src | semmle.label | src | +| xss-through-dom.js:120:23:120:37 | ev.target.files | semmle.label | ev.target.files | +| xss-through-dom.js:120:23:120:45 | ev.targ ... 0].name | semmle.label | ev.targ ... 0].name | +| xss-through-dom.js:122:33:122:71 | URL.cre ... les[0]) | semmle.label | URL.cre ... les[0]) | +| xss-through-dom.js:122:53:122:67 | ev.target.files | semmle.label | ev.target.files | +| xss-through-dom.js:122:53:122:70 | ev.target.files[0] | semmle.label | ev.target.files[0] | +| xss-through-dom.js:130:6:130:68 | linkText | semmle.label | linkText | +| xss-through-dom.js:130:17:130:37 | wSelect ... tring() | semmle.label | wSelect ... tring() | +| xss-through-dom.js:130:42:130:62 | dSelect ... tring() | semmle.label | dSelect ... tring() | +| xss-through-dom.js:131:19:131:26 | linkText | semmle.label | linkText | +| xss-through-dom.js:132:16:132:23 | linkText | semmle.label | linkText | +| xss-through-dom.js:139:11:139:52 | src | semmle.label | src | +| xss-through-dom.js:139:17:139:52 | documen ... k").src | semmle.label | documen ... k").src | +| xss-through-dom.js:140:19:140:21 | src | semmle.label | src | +| xss-through-dom.js:141:25:141:27 | src | semmle.label | src | +| xss-through-dom.js:150:24:150:26 | src | semmle.label | src | +| xss-through-dom.js:154:25:154:27 | msg | semmle.label | msg | +| xss-through-dom.js:155:27:155:29 | msg | semmle.label | msg | +| xss-through-dom.js:159:34:159:52 | $("textarea").val() | semmle.label | $("textarea").val() | +subpaths #select | forms.js:9:31:9:40 | values.foo | forms.js:8:23:8:28 | values | forms.js:9:31:9:40 | values.foo | $@ is reinterpreted as HTML without escaping meta-characters. | forms.js:8:23:8:28 | values | DOM text | | forms.js:12:31:12:40 | values.bar | forms.js:11:24:11:29 | values | forms.js:12:31:12:40 | values.bar | $@ is reinterpreted as HTML without escaping meta-characters. | forms.js:11:24:11:29 | values | DOM text | From d7b4e0c206c72a0f594bfffe9e279d2491922b70 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:32:10 +0200 Subject: [PATCH 052/514] JS: Port ExceptionXss --- .../security/dataflow/ExceptionXssQuery.qll | 41 +++- .../ql/src/Security/CWE-079/ExceptionXss.ql | 6 +- .../ExceptionXss/ExceptionXss.expected | 224 +++++++++--------- 3 files changed, 145 insertions(+), 126 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ExceptionXssQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ExceptionXssQuery.qll index a8418898e1b..9a748c0c301 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ExceptionXssQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ExceptionXssQuery.qll @@ -126,10 +126,41 @@ private DataFlow::Node getExceptionTarget(DataFlow::Node pred) { /** * A taint-tracking configuration for reasoning about XSS with possible exceptional flow. - * Flow labels are used to ensure that we only report taint-flow that has been thrown in + * Flow states are used to ensure that we only report taint-flow that has been thrown in * an exception. */ -class Configuration extends TaintTracking::Configuration { +module ExceptionXssConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; + + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { + source.(Source).getAFlowLabel() = label + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { + sink instanceof XssShared::Sink and not label instanceof NotYetThrown + } + + predicate isBarrier(DataFlow::Node node) { node instanceof XssShared::Sanitizer } + + predicate isAdditionalFlowStep( + DataFlow::Node pred, DataFlow::FlowLabel inlbl, DataFlow::Node succ, DataFlow::FlowLabel outlbl + ) { + inlbl instanceof NotYetThrown and + (outlbl.isTaint() or outlbl instanceof NotYetThrown) and + canThrowSensitiveInformation(pred) and + succ = getExceptionTarget(pred) + } +} + +/** + * Taint-tracking for reasoning about XSS with possible exceptional flow. + */ +module ExceptionXssFlow = TaintTracking::GlobalWithState; + +/** + * DEPRECATED. Use the `ExceptionXssFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "ExceptionXss" } override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { @@ -145,12 +176,10 @@ class Configuration extends TaintTracking::Configuration { override predicate isAdditionalFlowStep( DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl ) { - inlbl instanceof NotYetThrown and - (outlbl.isTaint() or outlbl instanceof NotYetThrown) and - canThrowSensitiveInformation(pred) and - succ = getExceptionTarget(pred) + ExceptionXssConfig::isAdditionalFlowStep(pred, inlbl, succ, outlbl) or // All the usual taint-flow steps apply on data-flow before it has been thrown in an exception. + // Note: this step is not needed in StateConfigSig module since flow states inherit taint steps. this.isAdditionalFlowStep(pred, succ) and inlbl instanceof NotYetThrown and outlbl instanceof NotYetThrown diff --git a/javascript/ql/src/Security/CWE-079/ExceptionXss.ql b/javascript/ql/src/Security/CWE-079/ExceptionXss.ql index c43206abb66..76e56f1494d 100644 --- a/javascript/ql/src/Security/CWE-079/ExceptionXss.ql +++ b/javascript/ql/src/Security/CWE-079/ExceptionXss.ql @@ -14,10 +14,10 @@ import javascript import semmle.javascript.security.dataflow.ExceptionXssQuery -import DataFlow::PathGraph +import DataFlow::DeduplicatePathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from PathNode source, PathNode sink +where ExceptionXssFlow::flowPath(source.getAnOriginalPathNode(), sink.getAnOriginalPathNode()) select sink.getNode(), source, sink, "$@ is reinterpreted as HTML without escaping meta-characters.", source.getNode(), source.getNode().(Source).getDescription() diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ExceptionXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ExceptionXss.expected index 0ff9bcb932a..ed59047c25e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ExceptionXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ExceptionXss.expected @@ -1,98 +1,85 @@ nodes -| ajv.js:11:18:11:33 | ajv.errorsText() | -| ajv.js:11:18:11:33 | ajv.errorsText() | -| ajv.js:11:18:11:33 | ajv.errorsText() | -| ajv.js:24:18:24:26 | val.error | -| ajv.js:24:18:24:26 | val.error | -| ajv.js:24:18:24:26 | val.error | -| exception-xss.js:2:6:2:28 | foo | -| exception-xss.js:2:12:2:28 | document.location | -| exception-xss.js:2:12:2:28 | document.location | -| exception-xss.js:9:11:9:13 | foo | -| exception-xss.js:10:11:10:11 | e | -| exception-xss.js:11:18:11:18 | e | -| exception-xss.js:11:18:11:18 | e | -| exception-xss.js:15:3:15:12 | exceptional return of inner(foo) | -| exception-xss.js:15:9:15:11 | foo | -| exception-xss.js:16:11:16:11 | e | -| exception-xss.js:17:18:17:18 | e | -| exception-xss.js:17:18:17:18 | e | -| exception-xss.js:21:11:21:13 | foo | -| exception-xss.js:21:11:21:21 | foo + "bar" | -| exception-xss.js:22:11:22:11 | e | -| exception-xss.js:23:18:23:18 | e | -| exception-xss.js:23:18:23:18 | e | -| exception-xss.js:33:11:33:22 | ["bar", foo] | -| exception-xss.js:33:19:33:21 | foo | -| exception-xss.js:34:11:34:11 | e | -| exception-xss.js:35:18:35:18 | e | -| exception-xss.js:35:18:35:18 | e | -| exception-xss.js:46:3:46:19 | exceptional return of deep("bar" + foo) | -| exception-xss.js:46:8:46:18 | "bar" + foo | -| exception-xss.js:46:16:46:18 | foo | -| exception-xss.js:47:11:47:11 | e | -| exception-xss.js:48:18:48:18 | e | -| exception-xss.js:48:18:48:18 | e | -| exception-xss.js:81:3:81:19 | exceptional return of myWeirdInner(foo) | -| exception-xss.js:81:16:81:18 | foo | -| exception-xss.js:82:11:82:11 | e | -| exception-xss.js:83:18:83:18 | e | -| exception-xss.js:83:18:83:18 | e | -| exception-xss.js:89:11:89:13 | foo | -| exception-xss.js:89:11:89:26 | foo.match(/foo/) | -| exception-xss.js:90:11:90:11 | e | -| exception-xss.js:91:18:91:18 | e | -| exception-xss.js:91:18:91:18 | e | -| exception-xss.js:95:11:95:22 | [foo, "bar"] | -| exception-xss.js:95:12:95:14 | foo | -| exception-xss.js:96:11:96:11 | e | -| exception-xss.js:97:18:97:18 | e | -| exception-xss.js:97:18:97:18 | e | -| exception-xss.js:102:12:102:14 | foo | -| exception-xss.js:106:11:106:11 | e | -| exception-xss.js:107:18:107:18 | e | -| exception-xss.js:107:18:107:18 | e | -| exception-xss.js:117:11:117:23 | req.params.id | -| exception-xss.js:117:11:117:23 | req.params.id | -| exception-xss.js:118:11:118:11 | e | -| exception-xss.js:119:12:119:28 | "Exception: " + e | -| exception-xss.js:119:12:119:28 | "Exception: " + e | -| exception-xss.js:119:28:119:28 | e | -| exception-xss.js:125:45:125:68 | documen ... .search | -| exception-xss.js:125:45:125:68 | documen ... .search | -| exception-xss.js:128:11:128:52 | session ... ssion') | -| exception-xss.js:129:11:129:11 | e | -| exception-xss.js:130:18:130:18 | e | -| exception-xss.js:130:18:130:18 | e | -| exception-xss.js:136:10:136:22 | req.params.id | -| exception-xss.js:136:10:136:22 | req.params.id | -| exception-xss.js:136:26:136:30 | error | -| exception-xss.js:138:19:138:23 | error | -| exception-xss.js:138:19:138:23 | error | -| exception-xss.js:146:6:146:35 | foo | -| exception-xss.js:146:12:146:35 | documen ... .search | -| exception-xss.js:146:12:146:35 | documen ... .search | -| exception-xss.js:148:33:148:35 | foo | -| exception-xss.js:148:55:148:55 | e | -| exception-xss.js:149:18:149:18 | e | -| exception-xss.js:149:18:149:18 | e | -| exception-xss.js:153:8:153:10 | foo | -| exception-xss.js:154:11:154:11 | e | -| exception-xss.js:155:18:155:18 | e | -| exception-xss.js:155:18:155:18 | e | -| exception-xss.js:174:25:174:43 | exceptional return of inner(foo, resolve) | -| exception-xss.js:174:31:174:33 | foo | -| exception-xss.js:174:53:174:53 | e | -| exception-xss.js:175:18:175:18 | e | -| exception-xss.js:175:18:175:18 | e | -| exception-xss.js:180:10:180:22 | req.params.id | -| exception-xss.js:180:10:180:22 | req.params.id | -| exception-xss.js:180:26:180:30 | error | -| exception-xss.js:182:19:182:23 | error | -| exception-xss.js:182:19:182:23 | error | +| ajv.js:11:18:11:33 | ajv.errorsText() | semmle.label | ajv.errorsText() | +| ajv.js:24:18:24:26 | val.error | semmle.label | val.error | +| exception-xss.js:2:6:2:28 | foo | semmle.label | foo | +| exception-xss.js:2:12:2:28 | document.location | semmle.label | document.location | +| exception-xss.js:4:17:4:17 | x | semmle.label | x | +| exception-xss.js:5:11:5:11 | x | semmle.label | x | +| exception-xss.js:9:11:9:13 | foo | semmle.label | foo | +| exception-xss.js:10:11:10:11 | e | semmle.label | e | +| exception-xss.js:11:18:11:18 | e | semmle.label | e | +| exception-xss.js:15:3:15:12 | exceptional return of inner(foo) | semmle.label | exceptional return of inner(foo) | +| exception-xss.js:15:9:15:11 | foo | semmle.label | foo | +| exception-xss.js:16:11:16:11 | e | semmle.label | e | +| exception-xss.js:17:18:17:18 | e | semmle.label | e | +| exception-xss.js:21:11:21:13 | foo | semmle.label | foo | +| exception-xss.js:21:11:21:21 | foo + "bar" | semmle.label | foo + "bar" | +| exception-xss.js:22:11:22:11 | e | semmle.label | e | +| exception-xss.js:23:18:23:18 | e | semmle.label | e | +| exception-xss.js:33:11:33:22 | ["bar", foo] | semmle.label | ["bar", foo] | +| exception-xss.js:33:19:33:21 | foo | semmle.label | foo | +| exception-xss.js:34:11:34:11 | e | semmle.label | e | +| exception-xss.js:35:18:35:18 | e | semmle.label | e | +| exception-xss.js:38:16:38:16 | x | semmle.label | x | +| exception-xss.js:39:3:39:10 | exceptional return of deep2(x) | semmle.label | exceptional return of deep2(x) | +| exception-xss.js:39:9:39:9 | x | semmle.label | x | +| exception-xss.js:41:17:41:17 | x | semmle.label | x | +| exception-xss.js:42:3:42:10 | exceptional return of inner(x) | semmle.label | exceptional return of inner(x) | +| exception-xss.js:42:9:42:9 | x | semmle.label | x | +| exception-xss.js:46:3:46:19 | exceptional return of deep("bar" + foo) | semmle.label | exceptional return of deep("bar" + foo) | +| exception-xss.js:46:8:46:18 | "bar" + foo | semmle.label | "bar" + foo | +| exception-xss.js:46:16:46:18 | foo | semmle.label | foo | +| exception-xss.js:47:11:47:11 | e | semmle.label | e | +| exception-xss.js:48:18:48:18 | e | semmle.label | e | +| exception-xss.js:74:28:74:28 | x | semmle.label | x | +| exception-xss.js:75:4:75:11 | exceptional return of inner(x) | semmle.label | exceptional return of inner(x) | +| exception-xss.js:75:10:75:10 | x | semmle.label | x | +| exception-xss.js:81:3:81:19 | exceptional return of myWeirdInner(foo) | semmle.label | exceptional return of myWeirdInner(foo) | +| exception-xss.js:81:16:81:18 | foo | semmle.label | foo | +| exception-xss.js:82:11:82:11 | e | semmle.label | e | +| exception-xss.js:83:18:83:18 | e | semmle.label | e | +| exception-xss.js:89:11:89:13 | foo | semmle.label | foo | +| exception-xss.js:89:11:89:26 | foo.match(/foo/) | semmle.label | foo.match(/foo/) | +| exception-xss.js:90:11:90:11 | e | semmle.label | e | +| exception-xss.js:91:18:91:18 | e | semmle.label | e | +| exception-xss.js:95:11:95:22 | [foo, "bar"] | semmle.label | [foo, "bar"] | +| exception-xss.js:95:12:95:14 | foo | semmle.label | foo | +| exception-xss.js:96:11:96:11 | e | semmle.label | e | +| exception-xss.js:97:18:97:18 | e | semmle.label | e | +| exception-xss.js:102:12:102:14 | foo | semmle.label | foo | +| exception-xss.js:106:11:106:11 | e | semmle.label | e | +| exception-xss.js:107:18:107:18 | e | semmle.label | e | +| exception-xss.js:117:11:117:23 | req.params.id | semmle.label | req.params.id | +| exception-xss.js:118:11:118:11 | e | semmle.label | e | +| exception-xss.js:119:12:119:28 | "Exception: " + e | semmle.label | "Exception: " + e | +| exception-xss.js:119:28:119:28 | e | semmle.label | e | +| exception-xss.js:125:45:125:68 | documen ... .search | semmle.label | documen ... .search | +| exception-xss.js:128:11:128:52 | session ... ssion') | semmle.label | session ... ssion') | +| exception-xss.js:129:11:129:11 | e | semmle.label | e | +| exception-xss.js:130:18:130:18 | e | semmle.label | e | +| exception-xss.js:136:10:136:22 | req.params.id | semmle.label | req.params.id | +| exception-xss.js:136:26:136:30 | error | semmle.label | error | +| exception-xss.js:138:19:138:23 | error | semmle.label | error | +| exception-xss.js:146:6:146:35 | foo | semmle.label | foo | +| exception-xss.js:146:12:146:35 | documen ... .search | semmle.label | documen ... .search | +| exception-xss.js:148:2:148:46 | new Pro ... solve)) [PromiseError] | semmle.label | new Pro ... solve)) [PromiseError] | +| exception-xss.js:148:33:148:35 | foo | semmle.label | foo | +| exception-xss.js:148:55:148:55 | e | semmle.label | e | +| exception-xss.js:149:18:149:18 | e | semmle.label | e | +| exception-xss.js:153:8:153:10 | foo | semmle.label | foo | +| exception-xss.js:154:11:154:11 | e | semmle.label | e | +| exception-xss.js:155:18:155:18 | e | semmle.label | e | +| exception-xss.js:170:17:170:23 | tainted | semmle.label | tainted | +| exception-xss.js:171:11:171:17 | tainted | semmle.label | tainted | +| exception-xss.js:174:2:174:44 | new Pro ... solve)) [PromiseError] | semmle.label | new Pro ... solve)) [PromiseError] | +| exception-xss.js:174:25:174:43 | exceptional return of inner(foo, resolve) | semmle.label | exceptional return of inner(foo, resolve) | +| exception-xss.js:174:31:174:33 | foo | semmle.label | foo | +| exception-xss.js:174:53:174:53 | e | semmle.label | e | +| exception-xss.js:175:18:175:18 | e | semmle.label | e | +| exception-xss.js:180:10:180:22 | req.params.id | semmle.label | req.params.id | +| exception-xss.js:180:26:180:30 | error | semmle.label | error | +| exception-xss.js:182:19:182:23 | error | semmle.label | error | edges -| ajv.js:11:18:11:33 | ajv.errorsText() | ajv.js:11:18:11:33 | ajv.errorsText() | -| ajv.js:24:18:24:26 | val.error | ajv.js:24:18:24:26 | val.error | | exception-xss.js:2:6:2:28 | foo | exception-xss.js:9:11:9:13 | foo | | exception-xss.js:2:6:2:28 | foo | exception-xss.js:15:9:15:11 | foo | | exception-xss.js:2:6:2:28 | foo | exception-xss.js:21:11:21:13 | foo | @@ -103,75 +90,78 @@ edges | exception-xss.js:2:6:2:28 | foo | exception-xss.js:95:12:95:14 | foo | | exception-xss.js:2:6:2:28 | foo | exception-xss.js:102:12:102:14 | foo | | exception-xss.js:2:12:2:28 | document.location | exception-xss.js:2:6:2:28 | foo | -| exception-xss.js:2:12:2:28 | document.location | exception-xss.js:2:6:2:28 | foo | +| exception-xss.js:4:17:4:17 | x | exception-xss.js:5:11:5:11 | x | | exception-xss.js:9:11:9:13 | foo | exception-xss.js:10:11:10:11 | e | | exception-xss.js:10:11:10:11 | e | exception-xss.js:11:18:11:18 | e | -| exception-xss.js:10:11:10:11 | e | exception-xss.js:11:18:11:18 | e | | exception-xss.js:15:3:15:12 | exceptional return of inner(foo) | exception-xss.js:16:11:16:11 | e | +| exception-xss.js:15:9:15:11 | foo | exception-xss.js:4:17:4:17 | x | | exception-xss.js:15:9:15:11 | foo | exception-xss.js:15:3:15:12 | exceptional return of inner(foo) | | exception-xss.js:16:11:16:11 | e | exception-xss.js:17:18:17:18 | e | -| exception-xss.js:16:11:16:11 | e | exception-xss.js:17:18:17:18 | e | | exception-xss.js:21:11:21:13 | foo | exception-xss.js:21:11:21:21 | foo + "bar" | | exception-xss.js:21:11:21:21 | foo + "bar" | exception-xss.js:22:11:22:11 | e | | exception-xss.js:22:11:22:11 | e | exception-xss.js:23:18:23:18 | e | -| exception-xss.js:22:11:22:11 | e | exception-xss.js:23:18:23:18 | e | | exception-xss.js:33:11:33:22 | ["bar", foo] | exception-xss.js:34:11:34:11 | e | | exception-xss.js:33:19:33:21 | foo | exception-xss.js:33:11:33:22 | ["bar", foo] | | exception-xss.js:34:11:34:11 | e | exception-xss.js:35:18:35:18 | e | -| exception-xss.js:34:11:34:11 | e | exception-xss.js:35:18:35:18 | e | +| exception-xss.js:38:16:38:16 | x | exception-xss.js:39:9:39:9 | x | +| exception-xss.js:39:9:39:9 | x | exception-xss.js:39:3:39:10 | exceptional return of deep2(x) | +| exception-xss.js:39:9:39:9 | x | exception-xss.js:41:17:41:17 | x | +| exception-xss.js:41:17:41:17 | x | exception-xss.js:42:9:42:9 | x | +| exception-xss.js:42:9:42:9 | x | exception-xss.js:4:17:4:17 | x | +| exception-xss.js:42:9:42:9 | x | exception-xss.js:42:3:42:10 | exceptional return of inner(x) | | exception-xss.js:46:3:46:19 | exceptional return of deep("bar" + foo) | exception-xss.js:47:11:47:11 | e | +| exception-xss.js:46:8:46:18 | "bar" + foo | exception-xss.js:38:16:38:16 | x | | exception-xss.js:46:8:46:18 | "bar" + foo | exception-xss.js:46:3:46:19 | exceptional return of deep("bar" + foo) | | exception-xss.js:46:16:46:18 | foo | exception-xss.js:46:8:46:18 | "bar" + foo | | exception-xss.js:47:11:47:11 | e | exception-xss.js:48:18:48:18 | e | -| exception-xss.js:47:11:47:11 | e | exception-xss.js:48:18:48:18 | e | +| exception-xss.js:74:28:74:28 | x | exception-xss.js:75:10:75:10 | x | +| exception-xss.js:75:10:75:10 | x | exception-xss.js:4:17:4:17 | x | +| exception-xss.js:75:10:75:10 | x | exception-xss.js:75:4:75:11 | exceptional return of inner(x) | | exception-xss.js:81:3:81:19 | exceptional return of myWeirdInner(foo) | exception-xss.js:82:11:82:11 | e | +| exception-xss.js:81:16:81:18 | foo | exception-xss.js:74:28:74:28 | x | | exception-xss.js:81:16:81:18 | foo | exception-xss.js:81:3:81:19 | exceptional return of myWeirdInner(foo) | | exception-xss.js:82:11:82:11 | e | exception-xss.js:83:18:83:18 | e | -| exception-xss.js:82:11:82:11 | e | exception-xss.js:83:18:83:18 | e | | exception-xss.js:89:11:89:13 | foo | exception-xss.js:89:11:89:26 | foo.match(/foo/) | | exception-xss.js:89:11:89:26 | foo.match(/foo/) | exception-xss.js:90:11:90:11 | e | | exception-xss.js:90:11:90:11 | e | exception-xss.js:91:18:91:18 | e | -| exception-xss.js:90:11:90:11 | e | exception-xss.js:91:18:91:18 | e | | exception-xss.js:95:11:95:22 | [foo, "bar"] | exception-xss.js:96:11:96:11 | e | | exception-xss.js:95:12:95:14 | foo | exception-xss.js:95:11:95:22 | [foo, "bar"] | | exception-xss.js:96:11:96:11 | e | exception-xss.js:97:18:97:18 | e | -| exception-xss.js:96:11:96:11 | e | exception-xss.js:97:18:97:18 | e | | exception-xss.js:102:12:102:14 | foo | exception-xss.js:106:11:106:11 | e | | exception-xss.js:106:11:106:11 | e | exception-xss.js:107:18:107:18 | e | -| exception-xss.js:106:11:106:11 | e | exception-xss.js:107:18:107:18 | e | -| exception-xss.js:117:11:117:23 | req.params.id | exception-xss.js:118:11:118:11 | e | | exception-xss.js:117:11:117:23 | req.params.id | exception-xss.js:118:11:118:11 | e | | exception-xss.js:118:11:118:11 | e | exception-xss.js:119:28:119:28 | e | | exception-xss.js:119:28:119:28 | e | exception-xss.js:119:12:119:28 | "Exception: " + e | -| exception-xss.js:119:28:119:28 | e | exception-xss.js:119:12:119:28 | "Exception: " + e | -| exception-xss.js:125:45:125:68 | documen ... .search | exception-xss.js:128:11:128:52 | session ... ssion') | | exception-xss.js:125:45:125:68 | documen ... .search | exception-xss.js:128:11:128:52 | session ... ssion') | | exception-xss.js:128:11:128:52 | session ... ssion') | exception-xss.js:129:11:129:11 | e | | exception-xss.js:129:11:129:11 | e | exception-xss.js:130:18:130:18 | e | -| exception-xss.js:129:11:129:11 | e | exception-xss.js:130:18:130:18 | e | | exception-xss.js:136:10:136:22 | req.params.id | exception-xss.js:136:26:136:30 | error | -| exception-xss.js:136:10:136:22 | req.params.id | exception-xss.js:136:26:136:30 | error | -| exception-xss.js:136:26:136:30 | error | exception-xss.js:138:19:138:23 | error | | exception-xss.js:136:26:136:30 | error | exception-xss.js:138:19:138:23 | error | | exception-xss.js:146:6:146:35 | foo | exception-xss.js:148:33:148:35 | foo | | exception-xss.js:146:6:146:35 | foo | exception-xss.js:153:8:153:10 | foo | | exception-xss.js:146:6:146:35 | foo | exception-xss.js:174:31:174:33 | foo | | exception-xss.js:146:12:146:35 | documen ... .search | exception-xss.js:146:6:146:35 | foo | -| exception-xss.js:146:12:146:35 | documen ... .search | exception-xss.js:146:6:146:35 | foo | -| exception-xss.js:148:33:148:35 | foo | exception-xss.js:148:55:148:55 | e | -| exception-xss.js:148:55:148:55 | e | exception-xss.js:149:18:149:18 | e | +| exception-xss.js:148:2:148:46 | new Pro ... solve)) [PromiseError] | exception-xss.js:148:55:148:55 | e | +| exception-xss.js:148:33:148:35 | foo | exception-xss.js:148:2:148:46 | new Pro ... solve)) [PromiseError] | | exception-xss.js:148:55:148:55 | e | exception-xss.js:149:18:149:18 | e | | exception-xss.js:153:8:153:10 | foo | exception-xss.js:154:11:154:11 | e | | exception-xss.js:154:11:154:11 | e | exception-xss.js:155:18:155:18 | e | -| exception-xss.js:154:11:154:11 | e | exception-xss.js:155:18:155:18 | e | -| exception-xss.js:174:25:174:43 | exceptional return of inner(foo, resolve) | exception-xss.js:174:53:174:53 | e | +| exception-xss.js:170:17:170:23 | tainted | exception-xss.js:171:11:171:17 | tainted | +| exception-xss.js:174:2:174:44 | new Pro ... solve)) [PromiseError] | exception-xss.js:174:53:174:53 | e | +| exception-xss.js:174:25:174:43 | exceptional return of inner(foo, resolve) | exception-xss.js:174:2:174:44 | new Pro ... solve)) [PromiseError] | +| exception-xss.js:174:31:174:33 | foo | exception-xss.js:170:17:170:23 | tainted | | exception-xss.js:174:31:174:33 | foo | exception-xss.js:174:25:174:43 | exceptional return of inner(foo, resolve) | | exception-xss.js:174:53:174:53 | e | exception-xss.js:175:18:175:18 | e | -| exception-xss.js:174:53:174:53 | e | exception-xss.js:175:18:175:18 | e | -| exception-xss.js:180:10:180:22 | req.params.id | exception-xss.js:180:26:180:30 | error | | exception-xss.js:180:10:180:22 | req.params.id | exception-xss.js:180:26:180:30 | error | | exception-xss.js:180:26:180:30 | error | exception-xss.js:182:19:182:23 | error | -| exception-xss.js:180:26:180:30 | error | exception-xss.js:182:19:182:23 | error | +subpaths +| exception-xss.js:15:9:15:11 | foo | exception-xss.js:4:17:4:17 | x | exception-xss.js:5:11:5:11 | x | exception-xss.js:15:3:15:12 | exceptional return of inner(foo) | +| exception-xss.js:39:9:39:9 | x | exception-xss.js:41:17:41:17 | x | exception-xss.js:42:3:42:10 | exceptional return of inner(x) | exception-xss.js:39:3:39:10 | exceptional return of deep2(x) | +| exception-xss.js:42:9:42:9 | x | exception-xss.js:4:17:4:17 | x | exception-xss.js:5:11:5:11 | x | exception-xss.js:42:3:42:10 | exceptional return of inner(x) | +| exception-xss.js:46:8:46:18 | "bar" + foo | exception-xss.js:38:16:38:16 | x | exception-xss.js:39:3:39:10 | exceptional return of deep2(x) | exception-xss.js:46:3:46:19 | exceptional return of deep("bar" + foo) | +| exception-xss.js:75:10:75:10 | x | exception-xss.js:4:17:4:17 | x | exception-xss.js:5:11:5:11 | x | exception-xss.js:75:4:75:11 | exceptional return of inner(x) | +| exception-xss.js:81:16:81:18 | foo | exception-xss.js:74:28:74:28 | x | exception-xss.js:75:4:75:11 | exceptional return of inner(x) | exception-xss.js:81:3:81:19 | exceptional return of myWeirdInner(foo) | +| exception-xss.js:174:31:174:33 | foo | exception-xss.js:170:17:170:23 | tainted | exception-xss.js:171:11:171:17 | tainted | exception-xss.js:174:25:174:43 | exceptional return of inner(foo, resolve) | #select | ajv.js:11:18:11:33 | ajv.errorsText() | ajv.js:11:18:11:33 | ajv.errorsText() | ajv.js:11:18:11:33 | ajv.errorsText() | $@ is reinterpreted as HTML without escaping meta-characters. | ajv.js:11:18:11:33 | ajv.errorsText() | JSON schema validation error | | ajv.js:24:18:24:26 | val.error | ajv.js:24:18:24:26 | val.error | ajv.js:24:18:24:26 | val.error | $@ is reinterpreted as HTML without escaping meta-characters. | ajv.js:24:18:24:26 | val.error | JSON schema validation error | From b2216627be79a5f74e7768401c8bd6de8b6acbc5 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:33:25 +0200 Subject: [PATCH 053/514] JS: Port RequestForgery --- .../security/dataflow/RequestForgeryQuery.qll | 49 +++- .../ql/src/Security/CWE-918/RequestForgery.ql | 6 +- .../Security/CWE-918/RequestForgery.expected | 226 ++++++------------ 3 files changed, 108 insertions(+), 173 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/RequestForgeryQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/RequestForgeryQuery.qll index 9c67df35ed9..09c956d12ee 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/RequestForgeryQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/RequestForgeryQuery.qll @@ -12,23 +12,48 @@ import UrlConcatenation import RequestForgeryCustomizations::RequestForgery /** - * A taint tracking configuration for request forgery. + * A taint tracking configuration for server-side request forgery. */ -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "RequestForgery" } +module RequestForgeryConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.(Source).isServerSide() } - override predicate isSource(DataFlow::Node source) { source.(Source).isServerSide() } + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } + predicate isBarrierOut(DataFlow::Node node) { sanitizingPrefixEdge(node, _) } - override predicate isSanitizerOut(DataFlow::Node node) { sanitizingPrefixEdge(node, _) } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { isAdditionalRequestForgeryStep(pred, succ) } } + +/** + * Taint tracking for server-side request forgery. + */ +module RequestForgeryFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `RequestForgeryFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { + Configuration() { this = "RequestForgery" } + + override predicate isSource(DataFlow::Node source) { RequestForgeryConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { RequestForgeryConfig::isSink(sink) } + + override predicate isSanitizer(DataFlow::Node node) { + super.isSanitizer(node) + or + node instanceof Sanitizer + } + + override predicate isSanitizerOut(DataFlow::Node node) { + RequestForgeryConfig::isBarrierOut(node) + } + + override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + RequestForgeryConfig::isAdditionalFlowStep(pred, succ) + } +} diff --git a/javascript/ql/src/Security/CWE-918/RequestForgery.ql b/javascript/ql/src/Security/CWE-918/RequestForgery.ql index c84f5f7d1cb..6546104068b 100644 --- a/javascript/ql/src/Security/CWE-918/RequestForgery.ql +++ b/javascript/ql/src/Security/CWE-918/RequestForgery.ql @@ -12,11 +12,11 @@ import javascript import semmle.javascript.security.dataflow.RequestForgeryQuery -import DataFlow::PathGraph +import RequestForgeryFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node request +from RequestForgeryFlow::PathNode source, RequestForgeryFlow::PathNode sink, DataFlow::Node request where - cfg.hasFlowPath(source, sink) and + RequestForgeryFlow::flowPath(source, sink) and request = sink.getNode().(Sink).getARequest() select request, source, sink, "The $@ of this request depends on a $@.", sink.getNode(), sink.getNode().(Sink).getKind(), source, "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected b/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected index 012033fce62..4d97d522e54 100644 --- a/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected +++ b/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected @@ -1,202 +1,112 @@ -nodes -| serverSide.js:14:9:14:52 | tainted | -| serverSide.js:14:19:14:42 | url.par ... , true) | -| serverSide.js:14:19:14:48 | url.par ... ).query | -| serverSide.js:14:19:14:52 | url.par ... ery.url | -| serverSide.js:14:29:14:35 | req.url | -| serverSide.js:14:29:14:35 | req.url | -| serverSide.js:18:13:18:19 | tainted | -| serverSide.js:18:13:18:19 | tainted | -| serverSide.js:20:17:20:23 | tainted | -| serverSide.js:20:17:20:23 | tainted | -| serverSide.js:23:19:23:25 | tainted | -| serverSide.js:23:19:23:25 | tainted | -| serverSide.js:26:13:26:31 | "http://" + tainted | -| serverSide.js:26:13:26:31 | "http://" + tainted | -| serverSide.js:26:25:26:31 | tainted | -| serverSide.js:28:13:28:42 | "http:/ ... tainted | -| serverSide.js:28:13:28:42 | "http:/ ... tainted | -| serverSide.js:28:36:28:42 | tainted | -| serverSide.js:30:13:30:43 | "http:/ ... tainted | -| serverSide.js:30:13:30:43 | "http:/ ... tainted | -| serverSide.js:30:37:30:43 | tainted | -| serverSide.js:34:34:34:40 | tainted | -| serverSide.js:34:34:34:40 | tainted | -| serverSide.js:36:16:36:31 | new Uri(tainted) | -| serverSide.js:36:16:36:31 | new Uri(tainted) | -| serverSide.js:36:24:36:30 | tainted | -| serverSide.js:37:22:37:37 | new Uri(tainted) | -| serverSide.js:37:22:37:37 | new Uri(tainted) | -| serverSide.js:37:30:37:36 | tainted | -| serverSide.js:41:13:41:51 | `http:/ ... inted}` | -| serverSide.js:41:13:41:51 | `http:/ ... inted}` | -| serverSide.js:41:43:41:49 | tainted | -| serverSide.js:43:13:43:54 | `http:/ ... inted}` | -| serverSide.js:43:13:43:54 | `http:/ ... inted}` | -| serverSide.js:43:46:43:52 | tainted | -| serverSide.js:45:13:45:56 | 'http:/ ... tainted | -| serverSide.js:45:13:45:56 | 'http:/ ... tainted | -| serverSide.js:45:50:45:56 | tainted | -| serverSide.js:58:9:58:52 | tainted | -| serverSide.js:58:19:58:42 | url.par ... , true) | -| serverSide.js:58:19:58:48 | url.par ... ).query | -| serverSide.js:58:19:58:52 | url.par ... ery.url | -| serverSide.js:58:29:58:35 | req.url | -| serverSide.js:58:29:58:35 | req.url | -| serverSide.js:61:29:61:35 | tainted | -| serverSide.js:61:29:61:35 | tainted | -| serverSide.js:64:30:64:36 | tainted | -| serverSide.js:64:30:64:36 | tainted | -| serverSide.js:68:30:68:36 | tainted | -| serverSide.js:68:30:68:36 | tainted | -| serverSide.js:74:9:74:52 | tainted | -| serverSide.js:74:19:74:42 | url.par ... , true) | -| serverSide.js:74:19:74:48 | url.par ... ).query | -| serverSide.js:74:19:74:52 | url.par ... ery.url | -| serverSide.js:74:29:74:35 | req.url | -| serverSide.js:74:29:74:35 | req.url | -| serverSide.js:76:19:76:25 | tainted | -| serverSide.js:76:19:76:25 | tainted | -| serverSide.js:83:38:83:43 | param1 | -| serverSide.js:83:38:83:43 | param1 | -| serverSide.js:84:19:84:24 | param1 | -| serverSide.js:84:19:84:24 | param1 | -| serverSide.js:90:19:90:28 | ctx.params | -| serverSide.js:90:19:90:28 | ctx.params | -| serverSide.js:90:19:90:32 | ctx.params.foo | -| serverSide.js:90:19:90:32 | ctx.params.foo | -| serverSide.js:92:19:92:28 | ctx.params | -| serverSide.js:92:19:92:28 | ctx.params | -| serverSide.js:92:19:92:32 | ctx.params.foo | -| serverSide.js:92:19:92:32 | ctx.params.foo | -| serverSide.js:98:9:98:52 | tainted | -| serverSide.js:98:19:98:42 | url.par ... , true) | -| serverSide.js:98:19:98:48 | url.par ... ).query | -| serverSide.js:98:19:98:52 | url.par ... ery.url | -| serverSide.js:98:29:98:35 | req.url | -| serverSide.js:98:29:98:35 | req.url | -| serverSide.js:100:19:100:25 | tainted | -| serverSide.js:100:19:100:25 | tainted | -| serverSide.js:108:11:108:27 | url | -| serverSide.js:108:17:108:27 | request.url | -| serverSide.js:108:17:108:27 | request.url | -| serverSide.js:109:27:109:29 | url | -| serverSide.js:109:27:109:29 | url | -| serverSide.js:115:11:115:42 | url | -| serverSide.js:115:17:115:42 | new URL ... , base) | -| serverSide.js:115:25:115:35 | request.url | -| serverSide.js:115:25:115:35 | request.url | -| serverSide.js:117:27:117:29 | url | -| serverSide.js:117:27:117:29 | url | -| serverSide.js:123:9:123:52 | tainted | -| serverSide.js:123:19:123:42 | url.par ... , true) | -| serverSide.js:123:19:123:48 | url.par ... ).query | -| serverSide.js:123:19:123:52 | url.par ... ery.url | -| serverSide.js:123:29:123:35 | req.url | -| serverSide.js:123:29:123:35 | req.url | -| serverSide.js:127:14:127:20 | tainted | -| serverSide.js:127:14:127:20 | tainted | -| serverSide.js:130:9:130:45 | myUrl | -| serverSide.js:130:17:130:45 | `${some ... inted}` | -| serverSide.js:130:37:130:43 | tainted | -| serverSide.js:131:15:131:19 | myUrl | -| serverSide.js:131:15:131:19 | myUrl | edges | serverSide.js:14:9:14:52 | tainted | serverSide.js:18:13:18:19 | tainted | -| serverSide.js:14:9:14:52 | tainted | serverSide.js:18:13:18:19 | tainted | | serverSide.js:14:9:14:52 | tainted | serverSide.js:20:17:20:23 | tainted | -| serverSide.js:14:9:14:52 | tainted | serverSide.js:20:17:20:23 | tainted | -| serverSide.js:14:9:14:52 | tainted | serverSide.js:23:19:23:25 | tainted | | serverSide.js:14:9:14:52 | tainted | serverSide.js:23:19:23:25 | tainted | | serverSide.js:14:9:14:52 | tainted | serverSide.js:26:25:26:31 | tainted | | serverSide.js:14:9:14:52 | tainted | serverSide.js:28:36:28:42 | tainted | | serverSide.js:14:9:14:52 | tainted | serverSide.js:30:37:30:43 | tainted | | serverSide.js:14:9:14:52 | tainted | serverSide.js:34:34:34:40 | tainted | -| serverSide.js:14:9:14:52 | tainted | serverSide.js:34:34:34:40 | tainted | | serverSide.js:14:9:14:52 | tainted | serverSide.js:36:24:36:30 | tainted | | serverSide.js:14:9:14:52 | tainted | serverSide.js:37:30:37:36 | tainted | | serverSide.js:14:9:14:52 | tainted | serverSide.js:41:43:41:49 | tainted | | serverSide.js:14:9:14:52 | tainted | serverSide.js:43:46:43:52 | tainted | | serverSide.js:14:9:14:52 | tainted | serverSide.js:45:50:45:56 | tainted | -| serverSide.js:14:19:14:42 | url.par ... , true) | serverSide.js:14:19:14:48 | url.par ... ).query | -| serverSide.js:14:19:14:48 | url.par ... ).query | serverSide.js:14:19:14:52 | url.par ... ery.url | -| serverSide.js:14:19:14:52 | url.par ... ery.url | serverSide.js:14:9:14:52 | tainted | -| serverSide.js:14:29:14:35 | req.url | serverSide.js:14:19:14:42 | url.par ... , true) | +| serverSide.js:14:19:14:42 | url.par ... , true) | serverSide.js:14:9:14:52 | tainted | | serverSide.js:14:29:14:35 | req.url | serverSide.js:14:19:14:42 | url.par ... , true) | | serverSide.js:26:25:26:31 | tainted | serverSide.js:26:13:26:31 | "http://" + tainted | -| serverSide.js:26:25:26:31 | tainted | serverSide.js:26:13:26:31 | "http://" + tainted | -| serverSide.js:28:36:28:42 | tainted | serverSide.js:28:13:28:42 | "http:/ ... tainted | | serverSide.js:28:36:28:42 | tainted | serverSide.js:28:13:28:42 | "http:/ ... tainted | | serverSide.js:30:37:30:43 | tainted | serverSide.js:30:13:30:43 | "http:/ ... tainted | -| serverSide.js:30:37:30:43 | tainted | serverSide.js:30:13:30:43 | "http:/ ... tainted | -| serverSide.js:36:24:36:30 | tainted | serverSide.js:36:16:36:31 | new Uri(tainted) | | serverSide.js:36:24:36:30 | tainted | serverSide.js:36:16:36:31 | new Uri(tainted) | | serverSide.js:37:30:37:36 | tainted | serverSide.js:37:22:37:37 | new Uri(tainted) | -| serverSide.js:37:30:37:36 | tainted | serverSide.js:37:22:37:37 | new Uri(tainted) | -| serverSide.js:41:43:41:49 | tainted | serverSide.js:41:13:41:51 | `http:/ ... inted}` | | serverSide.js:41:43:41:49 | tainted | serverSide.js:41:13:41:51 | `http:/ ... inted}` | | serverSide.js:43:46:43:52 | tainted | serverSide.js:43:13:43:54 | `http:/ ... inted}` | -| serverSide.js:43:46:43:52 | tainted | serverSide.js:43:13:43:54 | `http:/ ... inted}` | -| serverSide.js:45:50:45:56 | tainted | serverSide.js:45:13:45:56 | 'http:/ ... tainted | | serverSide.js:45:50:45:56 | tainted | serverSide.js:45:13:45:56 | 'http:/ ... tainted | | serverSide.js:58:9:58:52 | tainted | serverSide.js:61:29:61:35 | tainted | | serverSide.js:58:9:58:52 | tainted | serverSide.js:61:29:61:35 | tainted | -| serverSide.js:58:9:58:52 | tainted | serverSide.js:64:30:64:36 | tainted | -| serverSide.js:58:9:58:52 | tainted | serverSide.js:64:30:64:36 | tainted | -| serverSide.js:58:9:58:52 | tainted | serverSide.js:68:30:68:36 | tainted | -| serverSide.js:58:9:58:52 | tainted | serverSide.js:68:30:68:36 | tainted | -| serverSide.js:58:19:58:42 | url.par ... , true) | serverSide.js:58:19:58:48 | url.par ... ).query | -| serverSide.js:58:19:58:48 | url.par ... ).query | serverSide.js:58:19:58:52 | url.par ... ery.url | -| serverSide.js:58:19:58:52 | url.par ... ery.url | serverSide.js:58:9:58:52 | tainted | -| serverSide.js:58:29:58:35 | req.url | serverSide.js:58:19:58:42 | url.par ... , true) | +| serverSide.js:58:19:58:42 | url.par ... , true) | serverSide.js:58:9:58:52 | tainted | | serverSide.js:58:29:58:35 | req.url | serverSide.js:58:19:58:42 | url.par ... , true) | +| serverSide.js:61:29:61:35 | tainted | serverSide.js:64:30:64:36 | tainted | +| serverSide.js:61:29:61:35 | tainted | serverSide.js:68:30:68:36 | tainted | | serverSide.js:74:9:74:52 | tainted | serverSide.js:76:19:76:25 | tainted | -| serverSide.js:74:9:74:52 | tainted | serverSide.js:76:19:76:25 | tainted | -| serverSide.js:74:19:74:42 | url.par ... , true) | serverSide.js:74:19:74:48 | url.par ... ).query | -| serverSide.js:74:19:74:48 | url.par ... ).query | serverSide.js:74:19:74:52 | url.par ... ery.url | -| serverSide.js:74:19:74:52 | url.par ... ery.url | serverSide.js:74:9:74:52 | tainted | -| serverSide.js:74:29:74:35 | req.url | serverSide.js:74:19:74:42 | url.par ... , true) | +| serverSide.js:74:19:74:42 | url.par ... , true) | serverSide.js:74:9:74:52 | tainted | | serverSide.js:74:29:74:35 | req.url | serverSide.js:74:19:74:42 | url.par ... , true) | | serverSide.js:83:38:83:43 | param1 | serverSide.js:84:19:84:24 | param1 | -| serverSide.js:83:38:83:43 | param1 | serverSide.js:84:19:84:24 | param1 | -| serverSide.js:83:38:83:43 | param1 | serverSide.js:84:19:84:24 | param1 | -| serverSide.js:83:38:83:43 | param1 | serverSide.js:84:19:84:24 | param1 | | serverSide.js:90:19:90:28 | ctx.params | serverSide.js:90:19:90:32 | ctx.params.foo | -| serverSide.js:90:19:90:28 | ctx.params | serverSide.js:90:19:90:32 | ctx.params.foo | -| serverSide.js:90:19:90:28 | ctx.params | serverSide.js:90:19:90:32 | ctx.params.foo | -| serverSide.js:90:19:90:28 | ctx.params | serverSide.js:90:19:90:32 | ctx.params.foo | -| serverSide.js:92:19:92:28 | ctx.params | serverSide.js:92:19:92:32 | ctx.params.foo | -| serverSide.js:92:19:92:28 | ctx.params | serverSide.js:92:19:92:32 | ctx.params.foo | -| serverSide.js:92:19:92:28 | ctx.params | serverSide.js:92:19:92:32 | ctx.params.foo | | serverSide.js:92:19:92:28 | ctx.params | serverSide.js:92:19:92:32 | ctx.params.foo | | serverSide.js:98:9:98:52 | tainted | serverSide.js:100:19:100:25 | tainted | -| serverSide.js:98:9:98:52 | tainted | serverSide.js:100:19:100:25 | tainted | -| serverSide.js:98:19:98:42 | url.par ... , true) | serverSide.js:98:19:98:48 | url.par ... ).query | -| serverSide.js:98:19:98:48 | url.par ... ).query | serverSide.js:98:19:98:52 | url.par ... ery.url | -| serverSide.js:98:19:98:52 | url.par ... ery.url | serverSide.js:98:9:98:52 | tainted | -| serverSide.js:98:29:98:35 | req.url | serverSide.js:98:19:98:42 | url.par ... , true) | +| serverSide.js:98:19:98:42 | url.par ... , true) | serverSide.js:98:9:98:52 | tainted | | serverSide.js:98:29:98:35 | req.url | serverSide.js:98:19:98:42 | url.par ... , true) | | serverSide.js:108:11:108:27 | url | serverSide.js:109:27:109:29 | url | -| serverSide.js:108:11:108:27 | url | serverSide.js:109:27:109:29 | url | | serverSide.js:108:17:108:27 | request.url | serverSide.js:108:11:108:27 | url | -| serverSide.js:108:17:108:27 | request.url | serverSide.js:108:11:108:27 | url | -| serverSide.js:115:11:115:42 | url | serverSide.js:117:27:117:29 | url | | serverSide.js:115:11:115:42 | url | serverSide.js:117:27:117:29 | url | | serverSide.js:115:17:115:42 | new URL ... , base) | serverSide.js:115:11:115:42 | url | | serverSide.js:115:25:115:35 | request.url | serverSide.js:115:17:115:42 | new URL ... , base) | -| serverSide.js:115:25:115:35 | request.url | serverSide.js:115:17:115:42 | new URL ... , base) | -| serverSide.js:123:9:123:52 | tainted | serverSide.js:127:14:127:20 | tainted | | serverSide.js:123:9:123:52 | tainted | serverSide.js:127:14:127:20 | tainted | | serverSide.js:123:9:123:52 | tainted | serverSide.js:130:37:130:43 | tainted | -| serverSide.js:123:19:123:42 | url.par ... , true) | serverSide.js:123:19:123:48 | url.par ... ).query | -| serverSide.js:123:19:123:48 | url.par ... ).query | serverSide.js:123:19:123:52 | url.par ... ery.url | -| serverSide.js:123:19:123:52 | url.par ... ery.url | serverSide.js:123:9:123:52 | tainted | -| serverSide.js:123:29:123:35 | req.url | serverSide.js:123:19:123:42 | url.par ... , true) | +| serverSide.js:123:19:123:42 | url.par ... , true) | serverSide.js:123:9:123:52 | tainted | | serverSide.js:123:29:123:35 | req.url | serverSide.js:123:19:123:42 | url.par ... , true) | | serverSide.js:130:9:130:45 | myUrl | serverSide.js:131:15:131:19 | myUrl | -| serverSide.js:130:9:130:45 | myUrl | serverSide.js:131:15:131:19 | myUrl | -| serverSide.js:130:17:130:45 | `${some ... inted}` | serverSide.js:130:9:130:45 | myUrl | -| serverSide.js:130:37:130:43 | tainted | serverSide.js:130:17:130:45 | `${some ... inted}` | +| serverSide.js:130:37:130:43 | tainted | serverSide.js:130:9:130:45 | myUrl | +nodes +| serverSide.js:14:9:14:52 | tainted | semmle.label | tainted | +| serverSide.js:14:19:14:42 | url.par ... , true) | semmle.label | url.par ... , true) | +| serverSide.js:14:29:14:35 | req.url | semmle.label | req.url | +| serverSide.js:18:13:18:19 | tainted | semmle.label | tainted | +| serverSide.js:20:17:20:23 | tainted | semmle.label | tainted | +| serverSide.js:23:19:23:25 | tainted | semmle.label | tainted | +| serverSide.js:26:13:26:31 | "http://" + tainted | semmle.label | "http://" + tainted | +| serverSide.js:26:25:26:31 | tainted | semmle.label | tainted | +| serverSide.js:28:13:28:42 | "http:/ ... tainted | semmle.label | "http:/ ... tainted | +| serverSide.js:28:36:28:42 | tainted | semmle.label | tainted | +| serverSide.js:30:13:30:43 | "http:/ ... tainted | semmle.label | "http:/ ... tainted | +| serverSide.js:30:37:30:43 | tainted | semmle.label | tainted | +| serverSide.js:34:34:34:40 | tainted | semmle.label | tainted | +| serverSide.js:36:16:36:31 | new Uri(tainted) | semmle.label | new Uri(tainted) | +| serverSide.js:36:24:36:30 | tainted | semmle.label | tainted | +| serverSide.js:37:22:37:37 | new Uri(tainted) | semmle.label | new Uri(tainted) | +| serverSide.js:37:30:37:36 | tainted | semmle.label | tainted | +| serverSide.js:41:13:41:51 | `http:/ ... inted}` | semmle.label | `http:/ ... inted}` | +| serverSide.js:41:43:41:49 | tainted | semmle.label | tainted | +| serverSide.js:43:13:43:54 | `http:/ ... inted}` | semmle.label | `http:/ ... inted}` | +| serverSide.js:43:46:43:52 | tainted | semmle.label | tainted | +| serverSide.js:45:13:45:56 | 'http:/ ... tainted | semmle.label | 'http:/ ... tainted | +| serverSide.js:45:50:45:56 | tainted | semmle.label | tainted | +| serverSide.js:58:9:58:52 | tainted | semmle.label | tainted | +| serverSide.js:58:19:58:42 | url.par ... , true) | semmle.label | url.par ... , true) | +| serverSide.js:58:29:58:35 | req.url | semmle.label | req.url | +| serverSide.js:61:29:61:35 | tainted | semmle.label | tainted | +| serverSide.js:61:29:61:35 | tainted | semmle.label | tainted | +| serverSide.js:64:30:64:36 | tainted | semmle.label | tainted | +| serverSide.js:68:30:68:36 | tainted | semmle.label | tainted | +| serverSide.js:74:9:74:52 | tainted | semmle.label | tainted | +| serverSide.js:74:19:74:42 | url.par ... , true) | semmle.label | url.par ... , true) | +| serverSide.js:74:29:74:35 | req.url | semmle.label | req.url | +| serverSide.js:76:19:76:25 | tainted | semmle.label | tainted | +| serverSide.js:83:38:83:43 | param1 | semmle.label | param1 | +| serverSide.js:84:19:84:24 | param1 | semmle.label | param1 | +| serverSide.js:90:19:90:28 | ctx.params | semmle.label | ctx.params | +| serverSide.js:90:19:90:32 | ctx.params.foo | semmle.label | ctx.params.foo | +| serverSide.js:92:19:92:28 | ctx.params | semmle.label | ctx.params | +| serverSide.js:92:19:92:32 | ctx.params.foo | semmle.label | ctx.params.foo | +| serverSide.js:98:9:98:52 | tainted | semmle.label | tainted | +| serverSide.js:98:19:98:42 | url.par ... , true) | semmle.label | url.par ... , true) | +| serverSide.js:98:29:98:35 | req.url | semmle.label | req.url | +| serverSide.js:100:19:100:25 | tainted | semmle.label | tainted | +| serverSide.js:108:11:108:27 | url | semmle.label | url | +| serverSide.js:108:17:108:27 | request.url | semmle.label | request.url | +| serverSide.js:109:27:109:29 | url | semmle.label | url | +| serverSide.js:115:11:115:42 | url | semmle.label | url | +| serverSide.js:115:17:115:42 | new URL ... , base) | semmle.label | new URL ... , base) | +| serverSide.js:115:25:115:35 | request.url | semmle.label | request.url | +| serverSide.js:117:27:117:29 | url | semmle.label | url | +| serverSide.js:123:9:123:52 | tainted | semmle.label | tainted | +| serverSide.js:123:19:123:42 | url.par ... , true) | semmle.label | url.par ... , true) | +| serverSide.js:123:29:123:35 | req.url | semmle.label | req.url | +| serverSide.js:127:14:127:20 | tainted | semmle.label | tainted | +| serverSide.js:130:9:130:45 | myUrl | semmle.label | myUrl | +| serverSide.js:130:37:130:43 | tainted | semmle.label | tainted | +| serverSide.js:131:15:131:19 | myUrl | semmle.label | myUrl | +subpaths #select | serverSide.js:18:5:18:20 | request(tainted) | serverSide.js:14:29:14:35 | req.url | serverSide.js:18:13:18:19 | tainted | The $@ of this request depends on a $@. | serverSide.js:18:13:18:19 | tainted | URL | serverSide.js:14:29:14:35 | req.url | user-provided value | | serverSide.js:20:5:20:24 | request.get(tainted) | serverSide.js:14:29:14:35 | req.url | serverSide.js:20:17:20:23 | tainted | The $@ of this request depends on a $@. | serverSide.js:20:17:20:23 | tainted | URL | serverSide.js:14:29:14:35 | req.url | user-provided value | From 92816b1c9ad77bf78d630399da0388ae9daf3712 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:34:26 +0200 Subject: [PATCH 054/514] JS: Port ClientSideRequestForgery --- .../ClientSideRequestForgeryQuery.qll | 29 ++++++++++- .../CWE-918/ClientSideRequestForgery.ql | 8 +-- .../CWE-918/ClientSideRequestForgery.expected | 52 +++++++------------ .../Security/CWE-918/Consistency.ql | 16 ++++-- 4 files changed, 63 insertions(+), 42 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideRequestForgeryQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideRequestForgeryQuery.qll index 8e5a46576f2..c3856e5bcd2 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideRequestForgeryQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideRequestForgeryQuery.qll @@ -14,7 +14,34 @@ import RequestForgeryCustomizations::RequestForgery /** * A taint tracking configuration for client-side request forgery. */ -class Configuration extends TaintTracking::Configuration { +module ClientSideRequestForgeryConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + exists(Source src | + source = src and + not src.isServerSide() + ) + } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate isBarrierOut(DataFlow::Node node) { sanitizingPrefixEdge(node, _) } + + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { + isAdditionalRequestForgeryStep(pred, succ) + } +} + +/** + * Taint tracking for client-side request forgery. + */ +module ClientSideRequestForgeryFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `ClientSideRequestForgeryFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "ClientSideRequestForgery" } override predicate isSource(DataFlow::Node source) { diff --git a/javascript/ql/src/Security/CWE-918/ClientSideRequestForgery.ql b/javascript/ql/src/Security/CWE-918/ClientSideRequestForgery.ql index 4e03a62b198..1f8fb9c2d41 100644 --- a/javascript/ql/src/Security/CWE-918/ClientSideRequestForgery.ql +++ b/javascript/ql/src/Security/CWE-918/ClientSideRequestForgery.ql @@ -13,11 +13,13 @@ import javascript import semmle.javascript.security.dataflow.ClientSideRequestForgeryQuery -import DataFlow::PathGraph +import ClientSideRequestForgeryFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node request +from + ClientSideRequestForgeryFlow::PathNode source, ClientSideRequestForgeryFlow::PathNode sink, + DataFlow::Node request where - cfg.hasFlowPath(source, sink) and + ClientSideRequestForgeryFlow::flowPath(source, sink) and request = sink.getNode().(Sink).getARequest() select request, source, sink, "The $@ of this request depends on a $@.", sink.getNode(), sink.getNode().(Sink).getKind(), source, "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-918/ClientSideRequestForgery.expected b/javascript/ql/test/query-tests/Security/CWE-918/ClientSideRequestForgery.expected index 1390cf8cd32..b11a9d20a64 100644 --- a/javascript/ql/test/query-tests/Security/CWE-918/ClientSideRequestForgery.expected +++ b/javascript/ql/test/query-tests/Security/CWE-918/ClientSideRequestForgery.expected @@ -1,50 +1,34 @@ -nodes -| clientSide.js:11:11:11:53 | query | -| clientSide.js:11:19:11:40 | window. ... .search | -| clientSide.js:11:19:11:40 | window. ... .search | -| clientSide.js:11:19:11:53 | window. ... ring(1) | -| clientSide.js:12:13:12:54 | 'https: ... + '/id' | -| clientSide.js:12:13:12:54 | 'https: ... + '/id' | -| clientSide.js:12:42:12:46 | query | -| clientSide.js:14:13:14:63 | 'https: ... .search | -| clientSide.js:14:13:14:63 | 'https: ... .search | -| clientSide.js:14:42:14:63 | window. ... .search | -| clientSide.js:14:42:14:63 | window. ... .search | -| clientSide.js:16:11:16:54 | fragment | -| clientSide.js:16:22:16:41 | window.location.hash | -| clientSide.js:16:22:16:41 | window.location.hash | -| clientSide.js:16:22:16:54 | window. ... ring(1) | -| clientSide.js:17:13:17:57 | 'https: ... + '/id' | -| clientSide.js:17:13:17:57 | 'https: ... + '/id' | -| clientSide.js:17:42:17:49 | fragment | -| clientSide.js:20:11:20:28 | name | -| clientSide.js:20:18:20:28 | window.name | -| clientSide.js:20:18:20:28 | window.name | -| clientSide.js:21:13:21:53 | 'https: ... + '/id' | -| clientSide.js:21:13:21:53 | 'https: ... + '/id' | -| clientSide.js:21:42:21:45 | name | edges | clientSide.js:11:11:11:53 | query | clientSide.js:12:42:12:46 | query | | clientSide.js:11:19:11:40 | window. ... .search | clientSide.js:11:19:11:53 | window. ... ring(1) | -| clientSide.js:11:19:11:40 | window. ... .search | clientSide.js:11:19:11:53 | window. ... ring(1) | | clientSide.js:11:19:11:53 | window. ... ring(1) | clientSide.js:11:11:11:53 | query | | clientSide.js:12:42:12:46 | query | clientSide.js:12:13:12:54 | 'https: ... + '/id' | -| clientSide.js:12:42:12:46 | query | clientSide.js:12:13:12:54 | 'https: ... + '/id' | -| clientSide.js:14:42:14:63 | window. ... .search | clientSide.js:14:13:14:63 | 'https: ... .search | -| clientSide.js:14:42:14:63 | window. ... .search | clientSide.js:14:13:14:63 | 'https: ... .search | -| clientSide.js:14:42:14:63 | window. ... .search | clientSide.js:14:13:14:63 | 'https: ... .search | | clientSide.js:14:42:14:63 | window. ... .search | clientSide.js:14:13:14:63 | 'https: ... .search | | clientSide.js:16:11:16:54 | fragment | clientSide.js:17:42:17:49 | fragment | | clientSide.js:16:22:16:41 | window.location.hash | clientSide.js:16:22:16:54 | window. ... ring(1) | -| clientSide.js:16:22:16:41 | window.location.hash | clientSide.js:16:22:16:54 | window. ... ring(1) | | clientSide.js:16:22:16:54 | window. ... ring(1) | clientSide.js:16:11:16:54 | fragment | | clientSide.js:17:42:17:49 | fragment | clientSide.js:17:13:17:57 | 'https: ... + '/id' | -| clientSide.js:17:42:17:49 | fragment | clientSide.js:17:13:17:57 | 'https: ... + '/id' | | clientSide.js:20:11:20:28 | name | clientSide.js:21:42:21:45 | name | | clientSide.js:20:18:20:28 | window.name | clientSide.js:20:11:20:28 | name | -| clientSide.js:20:18:20:28 | window.name | clientSide.js:20:11:20:28 | name | -| clientSide.js:21:42:21:45 | name | clientSide.js:21:13:21:53 | 'https: ... + '/id' | | clientSide.js:21:42:21:45 | name | clientSide.js:21:13:21:53 | 'https: ... + '/id' | +nodes +| clientSide.js:11:11:11:53 | query | semmle.label | query | +| clientSide.js:11:19:11:40 | window. ... .search | semmle.label | window. ... .search | +| clientSide.js:11:19:11:53 | window. ... ring(1) | semmle.label | window. ... ring(1) | +| clientSide.js:12:13:12:54 | 'https: ... + '/id' | semmle.label | 'https: ... + '/id' | +| clientSide.js:12:42:12:46 | query | semmle.label | query | +| clientSide.js:14:13:14:63 | 'https: ... .search | semmle.label | 'https: ... .search | +| clientSide.js:14:42:14:63 | window. ... .search | semmle.label | window. ... .search | +| clientSide.js:16:11:16:54 | fragment | semmle.label | fragment | +| clientSide.js:16:22:16:41 | window.location.hash | semmle.label | window.location.hash | +| clientSide.js:16:22:16:54 | window. ... ring(1) | semmle.label | window. ... ring(1) | +| clientSide.js:17:13:17:57 | 'https: ... + '/id' | semmle.label | 'https: ... + '/id' | +| clientSide.js:17:42:17:49 | fragment | semmle.label | fragment | +| clientSide.js:20:11:20:28 | name | semmle.label | name | +| clientSide.js:20:18:20:28 | window.name | semmle.label | window.name | +| clientSide.js:21:13:21:53 | 'https: ... + '/id' | semmle.label | 'https: ... + '/id' | +| clientSide.js:21:42:21:45 | name | semmle.label | name | +subpaths #select | clientSide.js:12:5:12:55 | request ... '/id') | clientSide.js:11:19:11:40 | window. ... .search | clientSide.js:12:13:12:54 | 'https: ... + '/id' | The $@ of this request depends on a $@. | clientSide.js:12:13:12:54 | 'https: ... + '/id' | URL | clientSide.js:11:19:11:40 | window. ... .search | user-provided value | | clientSide.js:14:5:14:64 | request ... search) | clientSide.js:14:42:14:63 | window. ... .search | clientSide.js:14:13:14:63 | 'https: ... .search | The $@ of this request depends on a $@. | clientSide.js:14:13:14:63 | 'https: ... .search | URL | clientSide.js:14:42:14:63 | window. ... .search | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-918/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-918/Consistency.ql index 7950d897e8f..1e81213b108 100644 --- a/javascript/ql/test/query-tests/Security/CWE-918/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-918/Consistency.ql @@ -4,14 +4,22 @@ import semmle.javascript.security.dataflow.ClientSideRequestForgeryQuery as Clie import testUtilities.ConsistencyChecking query predicate resultInWrongFile(DataFlow::Node node) { - exists(DataFlow::Configuration cfg, string filePattern | - cfg instanceof RequestForgery::Configuration and + exists(string filePattern | + RequestForgery::RequestForgeryFlow::flowTo(node) and filePattern = ".*serverSide.*" or - cfg instanceof ClientSideRequestForgery::Configuration and + ClientSideRequestForgery::ClientSideRequestForgeryFlow::flowTo(node) and filePattern = ".*clientSide.*" | - cfg.hasFlow(_, node) and not node.getFile().getRelativePath().regexpMatch(filePattern) ) } + +class Consistency extends ConsistencyConfiguration { + Consistency() { this = "Consistency" } + + override DataFlow::Node getAnAlert() { + RequestForgery::RequestForgeryFlow::flowTo(result) or + ClientSideRequestForgery::ClientSideRequestForgeryFlow::flowTo(result) + } +} From 46fd727a55895447ceb6155e4274f04b14d5e428 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:35:49 +0200 Subject: [PATCH 055/514] JS: Port ServerSideUrlRedirect --- .../dataflow/ServerSideUrlRedirectQuery.qll | 42 ++- .../Security/CWE-601/ServerSideUrlRedirect.ql | 6 +- .../ServerSideUrlRedirect.expected | 255 ++++++------------ 3 files changed, 113 insertions(+), 190 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirectQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirectQuery.qll index 7f16f7f49dd..94614094cb1 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirectQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirectQuery.qll @@ -15,7 +15,32 @@ import ServerSideUrlRedirectCustomizations::ServerSideUrlRedirect /** * A taint-tracking configuration for reasoning about unvalidated URL redirections. */ -class Configuration extends TaintTracking::Configuration { +module ServerSideUrlRedirectConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate isBarrierOut(DataFlow::Node node) { hostnameSanitizingPrefixEdge(node, _) } + + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { + exists(HtmlSanitizerCall call | + pred = call.getInput() and + succ = call + ) + } +} + +/** + * Taint-tracking for reasoning about unvalidated URL redirections. + */ +module ServerSideUrlRedirectFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `ServerSideUrlRedirectFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "ServerSideUrlRedirect" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -27,7 +52,9 @@ class Configuration extends TaintTracking::Configuration { node instanceof Sanitizer } - override predicate isSanitizerOut(DataFlow::Node node) { hostnameSanitizingPrefixEdge(node, _) } + override predicate isSanitizerOut(DataFlow::Node node) { + ServerSideUrlRedirectConfig::isBarrierOut(node) + } override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) { guard instanceof LocalUrlSanitizingGuard or @@ -35,10 +62,7 @@ class Configuration extends TaintTracking::Configuration { } override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(HtmlSanitizerCall call | - pred = call.getInput() and - succ = call - ) + ServerSideUrlRedirectConfig::isAdditionalFlowStep(pred, succ) } } @@ -49,8 +73,10 @@ class Configuration extends TaintTracking::Configuration { class LocalUrlSanitizingGuard extends TaintTracking::SanitizerGuardNode, DataFlow::CallNode { LocalUrlSanitizingGuard() { this.getCalleeName().regexpMatch("(?i)(is_?)?local_?url") } - override predicate sanitizes(boolean outcome, Expr e) { - // `isLocalUrl(e)` sanitizes `e` if it evaluates to `true` + override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + /** Holds if this node blocks flow through `e`, provided it evaluates to `outcome`. */ + predicate blocksExpr(boolean outcome, Expr e) { this.getAnArgument().asExpr() = e and outcome = true } diff --git a/javascript/ql/src/Security/CWE-601/ServerSideUrlRedirect.ql b/javascript/ql/src/Security/CWE-601/ServerSideUrlRedirect.ql index 76402706586..e3bc53ec436 100644 --- a/javascript/ql/src/Security/CWE-601/ServerSideUrlRedirect.ql +++ b/javascript/ql/src/Security/CWE-601/ServerSideUrlRedirect.ql @@ -13,9 +13,9 @@ import javascript import semmle.javascript.security.dataflow.ServerSideUrlRedirectQuery -import DataFlow::PathGraph +import ServerSideUrlRedirectFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from ServerSideUrlRedirectFlow::PathNode source, ServerSideUrlRedirectFlow::PathNode sink +where ServerSideUrlRedirectFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Untrusted URL redirection depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected b/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected index c03f57e7dd5..4497676ff2e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected +++ b/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected @@ -1,223 +1,120 @@ -nodes -| ServerSideUrlRedirect.js:5:16:5:34 | req.query["target"] | -| ServerSideUrlRedirect.js:5:16:5:34 | req.query["target"] | -| ServerSideUrlRedirect.js:5:16:5:34 | req.query["target"] | -| express.js:7:16:7:34 | req.param("target") | -| express.js:7:16:7:34 | req.param("target") | -| express.js:7:16:7:34 | req.param("target") | -| express.js:12:26:12:44 | req.param("target") | -| express.js:12:26:12:44 | req.param("target") | -| express.js:12:26:12:44 | req.param("target") | -| express.js:27:7:27:34 | target | -| express.js:27:16:27:34 | req.param("target") | -| express.js:27:16:27:34 | req.param("target") | -| express.js:33:18:33:23 | target | -| express.js:33:18:33:23 | target | -| express.js:35:16:35:21 | target | -| express.js:35:16:35:21 | target | -| express.js:40:16:40:108 | (req.pa ... ntacts" | -| express.js:40:16:40:108 | (req.pa ... ntacts" | -| express.js:40:69:40:87 | req.param('action') | -| express.js:40:69:40:87 | req.param('action') | -| express.js:74:16:74:43 | `${req. ... )}/foo` | -| express.js:74:16:74:43 | `${req. ... )}/foo` | -| express.js:74:19:74:37 | req.param("target") | -| express.js:74:19:74:37 | req.param("target") | -| express.js:83:7:83:34 | target | -| express.js:83:16:83:34 | req.param("target") | -| express.js:83:16:83:34 | req.param("target") | -| express.js:90:18:90:23 | target | -| express.js:90:18:90:23 | target | -| express.js:97:16:97:21 | target | -| express.js:97:16:97:21 | target | -| express.js:118:16:118:63 | [req.qu ... ection] | -| express.js:118:16:118:72 | [req.qu ... oin('') | -| express.js:118:16:118:72 | [req.qu ... oin('') | -| express.js:118:17:118:30 | req.query.page | -| express.js:118:17:118:30 | req.query.page | -| express.js:134:16:134:36 | '/' + r ... ms.user | -| express.js:134:16:134:36 | '/' + r ... ms.user | -| express.js:134:22:134:36 | req.params.user | -| express.js:134:22:134:36 | req.params.user | -| express.js:135:16:135:37 | '//' + ... ms.user | -| express.js:135:16:135:37 | '//' + ... ms.user | -| express.js:135:23:135:37 | req.params.user | -| express.js:135:23:135:37 | req.params.user | -| express.js:136:16:136:36 | 'u' + r ... ms.user | -| express.js:136:16:136:36 | 'u' + r ... ms.user | -| express.js:136:22:136:36 | req.params.user | -| express.js:136:22:136:36 | req.params.user | -| express.js:143:16:143:28 | req.query.foo | -| express.js:143:16:143:28 | req.query.foo | -| express.js:143:16:143:28 | req.query.foo | -| express.js:146:16:146:24 | query.foo | -| express.js:146:16:146:24 | query.foo | -| express.js:146:16:146:24 | query.foo | -| express.js:150:7:150:34 | target | -| express.js:150:16:150:34 | req.param("target") | -| express.js:150:16:150:34 | req.param("target") | -| express.js:155:18:155:23 | target | -| express.js:155:18:155:23 | target | -| express.js:160:18:160:23 | target | -| express.js:160:18:160:23 | target | -| express.js:164:7:164:54 | myThing | -| express.js:164:17:164:41 | JSON.st ... .query) | -| express.js:164:17:164:54 | JSON.st ... (1, -1) | -| express.js:164:32:164:40 | req.query | -| express.js:164:32:164:40 | req.query | -| express.js:165:16:165:22 | myThing | -| express.js:165:16:165:22 | myThing | -| koa.js:6:6:6:27 | url | -| koa.js:6:12:6:27 | ctx.query.target | -| koa.js:6:12:6:27 | ctx.query.target | -| koa.js:7:15:7:17 | url | -| koa.js:7:15:7:17 | url | -| koa.js:8:15:8:26 | `${url}${x}` | -| koa.js:8:15:8:26 | `${url}${x}` | -| koa.js:8:18:8:20 | url | -| koa.js:14:16:14:18 | url | -| koa.js:14:16:14:18 | url | -| koa.js:20:16:20:18 | url | -| koa.js:20:16:20:18 | url | -| next.ts:11:31:11:38 | req.body | -| next.ts:11:31:11:38 | req.body | -| next.ts:11:31:11:50 | req.body.callbackUrl | -| next.ts:11:31:11:50 | req.body.callbackUrl | -| node.js:5:7:5:52 | target | -| node.js:5:16:5:39 | url.par ... , true) | -| node.js:5:16:5:45 | url.par ... ).query | -| node.js:5:16:5:52 | url.par ... .target | -| node.js:5:26:5:32 | req.url | -| node.js:5:26:5:32 | req.url | -| node.js:6:34:6:39 | target | -| node.js:6:34:6:39 | target | -| node.js:10:7:10:52 | target | -| node.js:10:16:10:39 | url.par ... , true) | -| node.js:10:16:10:45 | url.par ... ).query | -| node.js:10:16:10:52 | url.par ... .target | -| node.js:10:26:10:32 | req.url | -| node.js:10:26:10:32 | req.url | -| node.js:14:34:14:45 | '/' + target | -| node.js:14:34:14:45 | '/' + target | -| node.js:14:40:14:45 | target | -| node.js:28:7:28:52 | target | -| node.js:28:16:28:39 | url.par ... , true) | -| node.js:28:16:28:45 | url.par ... ).query | -| node.js:28:16:28:52 | url.par ... .target | -| node.js:28:26:28:32 | req.url | -| node.js:28:26:28:32 | req.url | -| node.js:31:34:31:39 | target | -| node.js:31:34:31:55 | target ... =" + me | -| node.js:31:34:31:55 | target ... =" + me | -| react-native.js:7:7:7:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:8:17:8:23 | tainted | -| react-native.js:8:17:8:23 | tainted | -| react-native.js:9:26:9:32 | tainted | -| react-native.js:9:26:9:32 | tainted | edges -| ServerSideUrlRedirect.js:5:16:5:34 | req.query["target"] | ServerSideUrlRedirect.js:5:16:5:34 | req.query["target"] | -| express.js:7:16:7:34 | req.param("target") | express.js:7:16:7:34 | req.param("target") | -| express.js:12:26:12:44 | req.param("target") | express.js:12:26:12:44 | req.param("target") | -| express.js:27:7:27:34 | target | express.js:33:18:33:23 | target | +| ServerSideUrlRedirectGood2.js:16:7:16:34 | target | ServerSideUrlRedirectGood2.js:18:18:18:23 | target | +| ServerSideUrlRedirectGood2.js:16:16:16:34 | req.query["target"] | ServerSideUrlRedirectGood2.js:16:7:16:34 | target | +| express.js:27:7:27:34 | target | express.js:30:18:30:23 | target | | express.js:27:7:27:34 | target | express.js:33:18:33:23 | target | | express.js:27:7:27:34 | target | express.js:35:16:35:21 | target | -| express.js:27:7:27:34 | target | express.js:35:16:35:21 | target | -| express.js:27:16:27:34 | req.param("target") | express.js:27:7:27:34 | target | | express.js:27:16:27:34 | req.param("target") | express.js:27:7:27:34 | target | | express.js:40:69:40:87 | req.param('action') | express.js:40:16:40:108 | (req.pa ... ntacts" | -| express.js:40:69:40:87 | req.param('action') | express.js:40:16:40:108 | (req.pa ... ntacts" | -| express.js:40:69:40:87 | req.param('action') | express.js:40:16:40:108 | (req.pa ... ntacts" | -| express.js:40:69:40:87 | req.param('action') | express.js:40:16:40:108 | (req.pa ... ntacts" | -| express.js:74:19:74:37 | req.param("target") | express.js:74:16:74:43 | `${req. ... )}/foo` | -| express.js:74:19:74:37 | req.param("target") | express.js:74:16:74:43 | `${req. ... )}/foo` | -| express.js:74:19:74:37 | req.param("target") | express.js:74:16:74:43 | `${req. ... )}/foo` | | express.js:74:19:74:37 | req.param("target") | express.js:74:16:74:43 | `${req. ... )}/foo` | | express.js:83:7:83:34 | target | express.js:90:18:90:23 | target | -| express.js:83:7:83:34 | target | express.js:90:18:90:23 | target | -| express.js:83:7:83:34 | target | express.js:97:16:97:21 | target | | express.js:83:7:83:34 | target | express.js:97:16:97:21 | target | | express.js:83:16:83:34 | req.param("target") | express.js:83:7:83:34 | target | -| express.js:83:16:83:34 | req.param("target") | express.js:83:7:83:34 | target | -| express.js:118:16:118:63 | [req.qu ... ection] | express.js:118:16:118:72 | [req.qu ... oin('') | -| express.js:118:16:118:63 | [req.qu ... ection] | express.js:118:16:118:72 | [req.qu ... oin('') | -| express.js:118:17:118:30 | req.query.page | express.js:118:16:118:63 | [req.qu ... ection] | -| express.js:118:17:118:30 | req.query.page | express.js:118:16:118:63 | [req.qu ... ection] | -| express.js:134:22:134:36 | req.params.user | express.js:134:16:134:36 | '/' + r ... ms.user | -| express.js:134:22:134:36 | req.params.user | express.js:134:16:134:36 | '/' + r ... ms.user | -| express.js:134:22:134:36 | req.params.user | express.js:134:16:134:36 | '/' + r ... ms.user | +| express.js:118:17:118:30 | req.query.page | express.js:118:16:118:72 | [req.qu ... oin('') | | express.js:134:22:134:36 | req.params.user | express.js:134:16:134:36 | '/' + r ... ms.user | | express.js:135:23:135:37 | req.params.user | express.js:135:16:135:37 | '//' + ... ms.user | -| express.js:135:23:135:37 | req.params.user | express.js:135:16:135:37 | '//' + ... ms.user | -| express.js:135:23:135:37 | req.params.user | express.js:135:16:135:37 | '//' + ... ms.user | -| express.js:135:23:135:37 | req.params.user | express.js:135:16:135:37 | '//' + ... ms.user | | express.js:136:22:136:36 | req.params.user | express.js:136:16:136:36 | 'u' + r ... ms.user | -| express.js:136:22:136:36 | req.params.user | express.js:136:16:136:36 | 'u' + r ... ms.user | -| express.js:136:22:136:36 | req.params.user | express.js:136:16:136:36 | 'u' + r ... ms.user | -| express.js:136:22:136:36 | req.params.user | express.js:136:16:136:36 | 'u' + r ... ms.user | -| express.js:143:16:143:28 | req.query.foo | express.js:143:16:143:28 | req.query.foo | -| express.js:146:16:146:24 | query.foo | express.js:146:16:146:24 | query.foo | -| express.js:150:7:150:34 | target | express.js:155:18:155:23 | target | | express.js:150:7:150:34 | target | express.js:155:18:155:23 | target | | express.js:150:7:150:34 | target | express.js:160:18:160:23 | target | -| express.js:150:7:150:34 | target | express.js:160:18:160:23 | target | | express.js:150:16:150:34 | req.param("target") | express.js:150:7:150:34 | target | -| express.js:150:16:150:34 | req.param("target") | express.js:150:7:150:34 | target | -| express.js:164:7:164:54 | myThing | express.js:165:16:165:22 | myThing | | express.js:164:7:164:54 | myThing | express.js:165:16:165:22 | myThing | | express.js:164:17:164:41 | JSON.st ... .query) | express.js:164:17:164:54 | JSON.st ... (1, -1) | | express.js:164:17:164:54 | JSON.st ... (1, -1) | express.js:164:7:164:54 | myThing | | express.js:164:32:164:40 | req.query | express.js:164:17:164:41 | JSON.st ... .query) | -| express.js:164:32:164:40 | req.query | express.js:164:17:164:41 | JSON.st ... .query) | -| koa.js:6:6:6:27 | url | koa.js:7:15:7:17 | url | | koa.js:6:6:6:27 | url | koa.js:7:15:7:17 | url | | koa.js:6:6:6:27 | url | koa.js:8:18:8:20 | url | | koa.js:6:6:6:27 | url | koa.js:14:16:14:18 | url | -| koa.js:6:6:6:27 | url | koa.js:14:16:14:18 | url | -| koa.js:6:6:6:27 | url | koa.js:20:16:20:18 | url | | koa.js:6:6:6:27 | url | koa.js:20:16:20:18 | url | | koa.js:6:12:6:27 | ctx.query.target | koa.js:6:6:6:27 | url | -| koa.js:6:12:6:27 | ctx.query.target | koa.js:6:6:6:27 | url | -| koa.js:8:18:8:20 | url | koa.js:8:15:8:26 | `${url}${x}` | | koa.js:8:18:8:20 | url | koa.js:8:15:8:26 | `${url}${x}` | | next.ts:11:31:11:38 | req.body | next.ts:11:31:11:50 | req.body.callbackUrl | -| next.ts:11:31:11:38 | req.body | next.ts:11:31:11:50 | req.body.callbackUrl | -| next.ts:11:31:11:38 | req.body | next.ts:11:31:11:50 | req.body.callbackUrl | -| next.ts:11:31:11:38 | req.body | next.ts:11:31:11:50 | req.body.callbackUrl | | node.js:5:7:5:52 | target | node.js:6:34:6:39 | target | -| node.js:5:7:5:52 | target | node.js:6:34:6:39 | target | -| node.js:5:16:5:39 | url.par ... , true) | node.js:5:16:5:45 | url.par ... ).query | -| node.js:5:16:5:45 | url.par ... ).query | node.js:5:16:5:52 | url.par ... .target | -| node.js:5:16:5:52 | url.par ... .target | node.js:5:7:5:52 | target | -| node.js:5:26:5:32 | req.url | node.js:5:16:5:39 | url.par ... , true) | +| node.js:5:16:5:39 | url.par ... , true) | node.js:5:7:5:52 | target | | node.js:5:26:5:32 | req.url | node.js:5:16:5:39 | url.par ... , true) | | node.js:10:7:10:52 | target | node.js:14:40:14:45 | target | -| node.js:10:16:10:39 | url.par ... , true) | node.js:10:16:10:45 | url.par ... ).query | -| node.js:10:16:10:45 | url.par ... ).query | node.js:10:16:10:52 | url.par ... .target | -| node.js:10:16:10:52 | url.par ... .target | node.js:10:7:10:52 | target | +| node.js:10:16:10:39 | url.par ... , true) | node.js:10:7:10:52 | target | | node.js:10:26:10:32 | req.url | node.js:10:16:10:39 | url.par ... , true) | -| node.js:10:26:10:32 | req.url | node.js:10:16:10:39 | url.par ... , true) | -| node.js:14:40:14:45 | target | node.js:14:34:14:45 | '/' + target | | node.js:14:40:14:45 | target | node.js:14:34:14:45 | '/' + target | | node.js:28:7:28:52 | target | node.js:31:34:31:39 | target | -| node.js:28:16:28:39 | url.par ... , true) | node.js:28:16:28:45 | url.par ... ).query | -| node.js:28:16:28:45 | url.par ... ).query | node.js:28:16:28:52 | url.par ... .target | -| node.js:28:16:28:52 | url.par ... .target | node.js:28:7:28:52 | target | -| node.js:28:26:28:32 | req.url | node.js:28:16:28:39 | url.par ... , true) | +| node.js:28:16:28:39 | url.par ... , true) | node.js:28:7:28:52 | target | | node.js:28:26:28:32 | req.url | node.js:28:16:28:39 | url.par ... , true) | | node.js:31:34:31:39 | target | node.js:31:34:31:55 | target ... =" + me | -| node.js:31:34:31:39 | target | node.js:31:34:31:55 | target ... =" + me | -| react-native.js:7:7:7:33 | tainted | react-native.js:8:17:8:23 | tainted | | react-native.js:7:7:7:33 | tainted | react-native.js:8:17:8:23 | tainted | | react-native.js:7:7:7:33 | tainted | react-native.js:9:26:9:32 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:9:26:9:32 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | +nodes +| ServerSideUrlRedirect.js:5:16:5:34 | req.query["target"] | semmle.label | req.query["target"] | +| ServerSideUrlRedirectGood2.js:16:7:16:34 | target | semmle.label | target | +| ServerSideUrlRedirectGood2.js:16:16:16:34 | req.query["target"] | semmle.label | req.query["target"] | +| ServerSideUrlRedirectGood2.js:18:18:18:23 | target | semmle.label | target | +| express.js:7:16:7:34 | req.param("target") | semmle.label | req.param("target") | +| express.js:12:26:12:44 | req.param("target") | semmle.label | req.param("target") | +| express.js:27:7:27:34 | target | semmle.label | target | +| express.js:27:16:27:34 | req.param("target") | semmle.label | req.param("target") | +| express.js:30:18:30:23 | target | semmle.label | target | +| express.js:33:18:33:23 | target | semmle.label | target | +| express.js:35:16:35:21 | target | semmle.label | target | +| express.js:40:16:40:108 | (req.pa ... ntacts" | semmle.label | (req.pa ... ntacts" | +| express.js:40:69:40:87 | req.param('action') | semmle.label | req.param('action') | +| express.js:74:16:74:43 | `${req. ... )}/foo` | semmle.label | `${req. ... )}/foo` | +| express.js:74:19:74:37 | req.param("target") | semmle.label | req.param("target") | +| express.js:83:7:83:34 | target | semmle.label | target | +| express.js:83:16:83:34 | req.param("target") | semmle.label | req.param("target") | +| express.js:90:18:90:23 | target | semmle.label | target | +| express.js:97:16:97:21 | target | semmle.label | target | +| express.js:118:16:118:72 | [req.qu ... oin('') | semmle.label | [req.qu ... oin('') | +| express.js:118:17:118:30 | req.query.page | semmle.label | req.query.page | +| express.js:134:16:134:36 | '/' + r ... ms.user | semmle.label | '/' + r ... ms.user | +| express.js:134:22:134:36 | req.params.user | semmle.label | req.params.user | +| express.js:135:16:135:37 | '//' + ... ms.user | semmle.label | '//' + ... ms.user | +| express.js:135:23:135:37 | req.params.user | semmle.label | req.params.user | +| express.js:136:16:136:36 | 'u' + r ... ms.user | semmle.label | 'u' + r ... ms.user | +| express.js:136:22:136:36 | req.params.user | semmle.label | req.params.user | +| express.js:143:16:143:28 | req.query.foo | semmle.label | req.query.foo | +| express.js:146:16:146:24 | query.foo | semmle.label | query.foo | +| express.js:150:7:150:34 | target | semmle.label | target | +| express.js:150:16:150:34 | req.param("target") | semmle.label | req.param("target") | +| express.js:155:18:155:23 | target | semmle.label | target | +| express.js:160:18:160:23 | target | semmle.label | target | +| express.js:164:7:164:54 | myThing | semmle.label | myThing | +| express.js:164:17:164:41 | JSON.st ... .query) | semmle.label | JSON.st ... .query) | +| express.js:164:17:164:54 | JSON.st ... (1, -1) | semmle.label | JSON.st ... (1, -1) | +| express.js:164:32:164:40 | req.query | semmle.label | req.query | +| express.js:165:16:165:22 | myThing | semmle.label | myThing | +| koa.js:6:6:6:27 | url | semmle.label | url | +| koa.js:6:12:6:27 | ctx.query.target | semmle.label | ctx.query.target | +| koa.js:7:15:7:17 | url | semmle.label | url | +| koa.js:8:15:8:26 | `${url}${x}` | semmle.label | `${url}${x}` | +| koa.js:8:18:8:20 | url | semmle.label | url | +| koa.js:14:16:14:18 | url | semmle.label | url | +| koa.js:20:16:20:18 | url | semmle.label | url | +| next.ts:11:31:11:38 | req.body | semmle.label | req.body | +| next.ts:11:31:11:50 | req.body.callbackUrl | semmle.label | req.body.callbackUrl | +| node.js:5:7:5:52 | target | semmle.label | target | +| node.js:5:16:5:39 | url.par ... , true) | semmle.label | url.par ... , true) | +| node.js:5:26:5:32 | req.url | semmle.label | req.url | +| node.js:6:34:6:39 | target | semmle.label | target | +| node.js:10:7:10:52 | target | semmle.label | target | +| node.js:10:16:10:39 | url.par ... , true) | semmle.label | url.par ... , true) | +| node.js:10:26:10:32 | req.url | semmle.label | req.url | +| node.js:14:34:14:45 | '/' + target | semmle.label | '/' + target | +| node.js:14:40:14:45 | target | semmle.label | target | +| node.js:28:7:28:52 | target | semmle.label | target | +| node.js:28:16:28:39 | url.par ... , true) | semmle.label | url.par ... , true) | +| node.js:28:26:28:32 | req.url | semmle.label | req.url | +| node.js:31:34:31:39 | target | semmle.label | target | +| node.js:31:34:31:55 | target ... =" + me | semmle.label | target ... =" + me | +| react-native.js:7:7:7:33 | tainted | semmle.label | tainted | +| react-native.js:7:17:7:33 | req.param("code") | semmle.label | req.param("code") | +| react-native.js:8:17:8:23 | tainted | semmle.label | tainted | +| react-native.js:9:26:9:32 | tainted | semmle.label | tainted | +subpaths #select | ServerSideUrlRedirect.js:5:16:5:34 | req.query["target"] | ServerSideUrlRedirect.js:5:16:5:34 | req.query["target"] | ServerSideUrlRedirect.js:5:16:5:34 | req.query["target"] | Untrusted URL redirection depends on a $@. | ServerSideUrlRedirect.js:5:16:5:34 | req.query["target"] | user-provided value | +| ServerSideUrlRedirectGood2.js:18:18:18:23 | target | ServerSideUrlRedirectGood2.js:16:16:16:34 | req.query["target"] | ServerSideUrlRedirectGood2.js:18:18:18:23 | target | Untrusted URL redirection depends on a $@. | ServerSideUrlRedirectGood2.js:16:16:16:34 | req.query["target"] | user-provided value | | express.js:7:16:7:34 | req.param("target") | express.js:7:16:7:34 | req.param("target") | express.js:7:16:7:34 | req.param("target") | Untrusted URL redirection depends on a $@. | express.js:7:16:7:34 | req.param("target") | user-provided value | | express.js:12:26:12:44 | req.param("target") | express.js:12:26:12:44 | req.param("target") | express.js:12:26:12:44 | req.param("target") | Untrusted URL redirection depends on a $@. | express.js:12:26:12:44 | req.param("target") | user-provided value | +| express.js:30:18:30:23 | target | express.js:27:16:27:34 | req.param("target") | express.js:30:18:30:23 | target | Untrusted URL redirection depends on a $@. | express.js:27:16:27:34 | req.param("target") | user-provided value | | express.js:33:18:33:23 | target | express.js:27:16:27:34 | req.param("target") | express.js:33:18:33:23 | target | Untrusted URL redirection depends on a $@. | express.js:27:16:27:34 | req.param("target") | user-provided value | | express.js:35:16:35:21 | target | express.js:27:16:27:34 | req.param("target") | express.js:35:16:35:21 | target | Untrusted URL redirection depends on a $@. | express.js:27:16:27:34 | req.param("target") | user-provided value | | express.js:40:16:40:108 | (req.pa ... ntacts" | express.js:40:69:40:87 | req.param('action') | express.js:40:16:40:108 | (req.pa ... ntacts" | Untrusted URL redirection depends on a $@. | express.js:40:69:40:87 | req.param('action') | user-provided value | From 81d2721248627049e45ab81e1f2b138022d1e886 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:36:01 +0200 Subject: [PATCH 056/514] JS: Port ClientSideUrlRedirect --- .../ClientSideUrlRedirectCustomizations.qll | 10 + .../dataflow/ClientSideUrlRedirectQuery.qll | 77 ++- .../Security/CWE-601/ClientSideUrlRedirect.ql | 7 +- .../ClientSideUrlRedirect.expected | 476 +++++------------- .../CWE-601/ClientSideUrlRedirect/tst15.js | 12 + 5 files changed, 211 insertions(+), 371 deletions(-) create mode 100644 javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst15.js diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll index 7b3b098b730..edf3bb06ca8 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll @@ -49,6 +49,16 @@ module ClientSideUrlRedirect { } } + /** + * Holds if `node` extracts a part of a URL that does not contain the suffix. + */ + pragma[inline] + predicate isPrefixExtraction(DataFlow::MethodCallNode node) { + // Block flow through prefix-extraction `substring(0, ...)` and `split("#")[0]` + node.getMethodName() = [StringOps::substringMethodName(), "split"] and + not untrustedUrlSubstring(_, node) + } + /** * Holds if `substring` refers to a substring of `base` which is considered untrusted * when `base` is the current URL. diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectQuery.qll index 0e1ceb955dd..33962696484 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectQuery.qll @@ -19,7 +19,55 @@ private class ConcreteDocumentUrl extends DocumentUrl { /** * A taint-tracking configuration for reasoning about unvalidated URL redirections. */ -class Configuration extends TaintTracking::Configuration { +module ClientSideUrlRedirectConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; + + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel state) { + source.(Source).getAFlowLabel() = state + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel state) { + sink instanceof Sink and state.isTaint() + } + + predicate isBarrier(DataFlow::Node node) { + node instanceof Sanitizer or node = HostnameSanitizerGuard::getABarrierNode() + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel state) { + isPrefixExtraction(node) and + state instanceof DocumentUrl + } + + predicate isBarrierOut(DataFlow::Node node) { hostnameSanitizingPrefixEdge(node, _) } + + predicate isBarrierOut(DataFlow::Node node, DataFlow::FlowLabel label) { isSink(node, label) } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowLabel state1, DataFlow::Node node2, + DataFlow::FlowLabel state2 + ) { + untrustedUrlSubstring(node1, node2) and + state1 instanceof DocumentUrl and + state2.isTaint() + or + exists(HtmlSanitizerCall call | + node1 = call.getInput() and + node2 = call and + state1 = state2 + ) + } +} + +/** + * Taint-tracking flow for reasoning about unvalidated URL redirections. + */ +module ClientSideUrlRedirectFlow = TaintTracking::GlobalWithState; + +/** + * A taint-tracking configuration for reasoning about unvalidated URL redirections. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "ClientSideUrlRedirect" } override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel lbl) { @@ -36,21 +84,22 @@ class Configuration extends TaintTracking::Configuration { override predicate isSanitizerOut(DataFlow::Node node) { hostnameSanitizingPrefixEdge(node, _) } override predicate isAdditionalFlowStep( - DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel f, DataFlow::FlowLabel g + DataFlow::Node node1, DataFlow::Node node2, DataFlow::FlowLabel state1, + DataFlow::FlowLabel state2 ) { - untrustedUrlSubstring(pred, succ) and - f instanceof DocumentUrl and - g.isTaint() + ClientSideUrlRedirectConfig::isAdditionalFlowStep(node1, state1, node2, state2) or - // preserve document.url label in step from `location` to `location.href` - f instanceof DocumentUrl and - g instanceof DocumentUrl and - succ.(DataFlow::PropRead).accesses(pred, "href") - or - exists(HtmlSanitizerCall call | - pred = call.getInput() and - succ = call and - f = g + // Preserve document.url label in step from `location` to `location.href` or `location.toString()` + state1 instanceof DocumentUrl and + state2 instanceof DocumentUrl and + ( + node2.(DataFlow::PropRead).accesses(node1, "href") + or + exists(DataFlow::CallNode call | + call.getCalleeName() = "toString" and + node1 = call.getReceiver() and + node2 = call + ) ) } diff --git a/javascript/ql/src/Security/CWE-601/ClientSideUrlRedirect.ql b/javascript/ql/src/Security/CWE-601/ClientSideUrlRedirect.ql index 6f29d388268..a4b08e385ba 100644 --- a/javascript/ql/src/Security/CWE-601/ClientSideUrlRedirect.ql +++ b/javascript/ql/src/Security/CWE-601/ClientSideUrlRedirect.ql @@ -15,9 +15,10 @@ import javascript import semmle.javascript.security.dataflow.ClientSideUrlRedirectQuery -import DataFlow::PathGraph +import DataFlow::DeduplicatePathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from PathNode source, PathNode sink +where + ClientSideUrlRedirectFlow::flowPath(source.getAnOriginalPathNode(), sink.getAnOriginalPathNode()) select sink.getNode(), source, sink, "Untrusted URL redirection depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected index 20114c9aa53..fbac71a1779 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected @@ -1,435 +1,210 @@ nodes -| electron.js:4:12:4:22 | window.name | -| electron.js:4:12:4:22 | window.name | -| electron.js:7:20:7:29 | getTaint() | -| electron.js:7:20:7:29 | getTaint() | -| react.js:10:60:10:81 | documen ... on.hash | -| react.js:10:60:10:81 | documen ... on.hash | -| react.js:10:60:10:81 | documen ... on.hash | -| react.js:21:24:21:45 | documen ... on.hash | -| react.js:21:24:21:45 | documen ... on.hash | -| react.js:21:24:21:45 | documen ... on.hash | -| react.js:28:43:28:64 | documen ... on.hash | -| react.js:28:43:28:64 | documen ... on.hash | -| react.js:28:43:28:74 | documen ... bstr(1) | -| react.js:28:43:28:74 | documen ... bstr(1) | -| react.js:34:43:34:64 | documen ... on.hash | -| react.js:34:43:34:64 | documen ... on.hash | -| react.js:34:43:34:74 | documen ... bstr(1) | -| react.js:34:43:34:74 | documen ... bstr(1) | -| react.js:40:19:40:40 | documen ... on.hash | -| react.js:40:19:40:40 | documen ... on.hash | -| react.js:40:19:40:50 | documen ... bstr(1) | -| react.js:40:19:40:50 | documen ... bstr(1) | -| sanitizer.js:2:9:2:25 | url | -| sanitizer.js:2:15:2:25 | window.name | -| sanitizer.js:2:15:2:25 | window.name | -| sanitizer.js:4:27:4:29 | url | -| sanitizer.js:4:27:4:29 | url | -| sanitizer.js:16:27:16:29 | url | -| sanitizer.js:16:27:16:29 | url | -| sanitizer.js:19:27:19:29 | url | -| sanitizer.js:19:27:19:29 | url | -| sanitizer.js:22:27:22:29 | url | -| sanitizer.js:22:27:22:29 | url | -| sanitizer.js:25:27:25:29 | url | -| sanitizer.js:25:27:25:29 | url | -| sanitizer.js:28:27:28:29 | url | -| sanitizer.js:28:27:28:29 | url | -| sanitizer.js:31:27:31:29 | url | -| sanitizer.js:31:27:31:29 | url | -| sanitizer.js:37:27:37:29 | url | -| sanitizer.js:37:27:37:29 | url | -| tst2.js:2:7:2:33 | href | -| tst2.js:2:14:2:28 | window.location | -| tst2.js:2:14:2:28 | window.location | -| tst2.js:2:14:2:33 | window.location.href | -| tst2.js:2:14:2:33 | window.location.href | -| tst2.js:4:21:4:24 | href | -| tst2.js:4:21:4:55 | href.su ... '?')+1) | -| tst2.js:4:21:4:55 | href.su ... '?')+1) | -| tst6.js:2:7:2:45 | redirect | -| tst6.js:2:18:2:45 | $locati ... irect') | -| tst6.js:2:18:2:45 | $locati ... irect') | -| tst6.js:4:21:4:28 | redirect | -| tst6.js:4:21:4:28 | redirect | -| tst6.js:6:17:6:24 | redirect | -| tst6.js:6:17:6:24 | redirect | -| tst6.js:8:21:8:48 | $locati ... irect') | -| tst6.js:8:21:8:48 | $locati ... irect') | -| tst6.js:8:21:8:56 | $locati ... + "foo" | -| tst6.js:8:21:8:56 | $locati ... + "foo" | -| tst7.js:2:12:2:35 | documen ... .search | -| tst7.js:2:12:2:35 | documen ... .search | -| tst7.js:2:12:2:35 | documen ... .search | -| tst7.js:5:27:5:50 | documen ... .search | -| tst7.js:5:27:5:50 | documen ... .search | -| tst7.js:5:27:5:50 | documen ... .search | -| tst9.js:2:21:2:42 | documen ... on.hash | -| tst9.js:2:21:2:42 | documen ... on.hash | -| tst9.js:2:21:2:55 | documen ... ring(1) | -| tst9.js:2:21:2:55 | documen ... ring(1) | -| tst10.js:5:17:5:46 | '/' + d ... .search | -| tst10.js:5:17:5:46 | '/' + d ... .search | -| tst10.js:5:23:5:46 | documen ... .search | -| tst10.js:5:23:5:46 | documen ... .search | -| tst10.js:8:17:8:47 | '//' + ... .search | -| tst10.js:8:17:8:47 | '//' + ... .search | -| tst10.js:8:24:8:47 | documen ... .search | -| tst10.js:8:24:8:47 | documen ... .search | -| tst10.js:11:17:11:50 | '//foo' ... .search | -| tst10.js:11:17:11:50 | '//foo' ... .search | -| tst10.js:11:27:11:50 | documen ... .search | -| tst10.js:11:27:11:50 | documen ... .search | -| tst10.js:14:17:14:56 | 'https: ... .search | -| tst10.js:14:17:14:56 | 'https: ... .search | -| tst10.js:14:33:14:56 | documen ... .search | -| tst10.js:14:33:14:56 | documen ... .search | -| tst12.js:3:9:3:50 | urlParts | -| tst12.js:3:20:3:39 | window.location.hash | -| tst12.js:3:20:3:39 | window.location.hash | -| tst12.js:3:20:3:50 | window. ... it('?') | -| tst12.js:4:9:4:45 | loc | -| tst12.js:4:15:4:22 | urlParts | -| tst12.js:4:15:4:25 | urlParts[0] | -| tst12.js:4:15:4:45 | urlPart ... s.value | -| tst12.js:5:23:5:25 | loc | -| tst12.js:5:23:5:25 | loc | -| tst13.js:2:9:2:52 | payload | -| tst13.js:2:19:2:42 | documen ... .search | -| tst13.js:2:19:2:42 | documen ... .search | -| tst13.js:2:19:2:52 | documen ... bstr(1) | -| tst13.js:4:15:4:21 | payload | -| tst13.js:4:15:4:21 | payload | -| tst13.js:8:21:8:27 | payload | -| tst13.js:8:21:8:27 | payload | -| tst13.js:12:14:12:20 | payload | -| tst13.js:12:14:12:20 | payload | -| tst13.js:16:17:16:23 | payload | -| tst13.js:16:17:16:23 | payload | -| tst13.js:20:14:20:20 | payload | -| tst13.js:20:14:20:20 | payload | -| tst13.js:24:14:24:20 | payload | -| tst13.js:24:14:24:20 | payload | -| tst13.js:28:21:28:27 | payload | -| tst13.js:28:21:28:27 | payload | -| tst13.js:32:17:32:23 | payload | -| tst13.js:32:17:32:23 | payload | -| tst13.js:36:21:36:27 | payload | -| tst13.js:36:21:36:27 | payload | -| tst13.js:40:15:40:21 | payload | -| tst13.js:40:15:40:21 | payload | -| tst13.js:44:14:44:20 | payload | -| tst13.js:44:14:44:20 | payload | -| tst13.js:49:32:49:32 | e | -| tst13.js:49:32:49:32 | e | -| tst13.js:50:23:50:23 | e | -| tst13.js:50:23:50:23 | e | -| tst13.js:52:34:52:34 | e | -| tst13.js:52:34:52:34 | e | -| tst13.js:53:28:53:28 | e | -| tst13.js:53:28:53:28 | e | -| tst13.js:59:9:59:52 | payload | -| tst13.js:59:19:59:42 | documen ... .search | -| tst13.js:59:19:59:42 | documen ... .search | -| tst13.js:59:19:59:52 | documen ... bstr(1) | -| tst13.js:61:18:61:24 | payload | -| tst13.js:61:18:61:24 | payload | -| tst13.js:65:9:65:49 | payload | -| tst13.js:65:19:65:39 | history ... on.hash | -| tst13.js:65:19:65:39 | history ... on.hash | -| tst13.js:65:19:65:49 | history ... bstr(1) | -| tst13.js:67:21:67:27 | payload | -| tst13.js:67:21:67:27 | payload | -| tst13.js:72:9:72:49 | payload | -| tst13.js:72:19:72:39 | history ... on.hash | -| tst13.js:72:19:72:39 | history ... on.hash | -| tst13.js:72:19:72:49 | history ... bstr(1) | -| tst13.js:74:21:74:27 | payload | -| tst13.js:74:21:74:27 | payload | -| tst13.js:78:9:78:48 | url | -| tst13.js:78:15:78:38 | documen ... .search | -| tst13.js:78:15:78:38 | documen ... .search | -| tst13.js:78:15:78:48 | documen ... bstr(1) | -| tst13.js:80:21:80:23 | url | -| tst13.js:80:21:80:23 | url | -| tst13.js:81:28:81:30 | url | -| tst13.js:81:28:81:30 | url | -| tst13.js:82:27:82:29 | url | -| tst13.js:82:27:82:29 | url | -| tst13.js:83:22:83:24 | url | -| tst13.js:83:22:83:24 | url | -| tst.js:2:19:2:69 | /.*redi ... n.href) | -| tst.js:2:19:2:72 | /.*redi ... ref)[1] | -| tst.js:2:19:2:72 | /.*redi ... ref)[1] | -| tst.js:2:47:2:63 | document.location | -| tst.js:2:47:2:63 | document.location | -| tst.js:2:47:2:68 | documen ... on.href | -| tst.js:2:47:2:68 | documen ... on.href | -| tst.js:6:20:6:56 | indirec ... n.href) | -| tst.js:6:20:6:59 | indirec ... ref)[1] | -| tst.js:6:20:6:59 | indirec ... ref)[1] | -| tst.js:6:34:6:50 | document.location | -| tst.js:6:34:6:50 | document.location | -| tst.js:6:34:6:55 | documen ... on.href | -| tst.js:6:34:6:55 | documen ... on.href | -| tst.js:10:19:10:81 | new Reg ... n.href) | -| tst.js:10:19:10:84 | new Reg ... ref)[1] | -| tst.js:10:19:10:84 | new Reg ... ref)[1] | -| tst.js:10:59:10:75 | document.location | -| tst.js:10:59:10:75 | document.location | -| tst.js:10:59:10:80 | documen ... on.href | -| tst.js:10:59:10:80 | documen ... on.href | -| tst.js:14:20:14:56 | indirec ... n.href) | -| tst.js:14:20:14:59 | indirec ... ref)[1] | -| tst.js:14:20:14:59 | indirec ... ref)[1] | -| tst.js:14:34:14:50 | document.location | -| tst.js:14:34:14:50 | document.location | -| tst.js:14:34:14:55 | documen ... on.href | -| tst.js:14:34:14:55 | documen ... on.href | -| tst.js:18:19:18:81 | new Reg ... n.href) | -| tst.js:18:19:18:84 | new Reg ... ref)[1] | -| tst.js:18:19:18:84 | new Reg ... ref)[1] | -| tst.js:18:59:18:75 | document.location | -| tst.js:18:59:18:75 | document.location | -| tst.js:18:59:18:80 | documen ... on.href | -| tst.js:18:59:18:80 | documen ... on.href | -| tst.js:22:20:22:56 | indirec ... n.href) | -| tst.js:22:20:22:59 | indirec ... ref)[1] | -| tst.js:22:20:22:59 | indirec ... ref)[1] | -| tst.js:22:34:22:50 | document.location | -| tst.js:22:34:22:50 | document.location | -| tst.js:22:34:22:55 | documen ... on.href | -| tst.js:22:34:22:55 | documen ... on.href | -| tst.js:26:22:26:79 | new Reg ... n.href) | -| tst.js:26:22:26:82 | new Reg ... ref)[1] | -| tst.js:26:22:26:82 | new Reg ... ref)[1] | -| tst.js:26:62:26:78 | win.location.href | -| tst.js:26:62:26:78 | win.location.href | -| typed.ts:4:13:4:36 | params | -| typed.ts:4:22:4:36 | location.search | -| typed.ts:4:22:4:36 | location.search | -| typed.ts:5:25:5:30 | params | -| typed.ts:7:24:7:34 | redirectUri | -| typed.ts:8:33:8:43 | redirectUri | -| typed.ts:8:33:8:43 | redirectUri | -| typed.ts:25:25:25:34 | loc.search | -| typed.ts:25:25:25:34 | loc.search | -| typed.ts:28:24:28:34 | redirectUri | -| typed.ts:29:33:29:43 | redirectUri | -| typed.ts:29:33:29:43 | redirectUri | -| typed.ts:47:25:47:34 | loc.search | -| typed.ts:47:25:47:34 | loc.search | -| typed.ts:48:26:48:36 | loc2.search | -| typed.ts:48:26:48:36 | loc2.search | -| typed.ts:51:24:51:34 | redirectUri | -| typed.ts:52:33:52:43 | redirectUri | -| typed.ts:52:33:52:43 | redirectUri | -| typed.ts:55:25:55:35 | redirectUri | -| typed.ts:56:33:56:43 | redirectUri | -| typed.ts:56:33:56:43 | redirectUri | +| electron.js:4:12:4:22 | window.name | semmle.label | window.name | +| electron.js:7:20:7:29 | getTaint() | semmle.label | getTaint() | +| react.js:10:60:10:81 | documen ... on.hash | semmle.label | documen ... on.hash | +| react.js:21:24:21:45 | documen ... on.hash | semmle.label | documen ... on.hash | +| react.js:28:43:28:64 | documen ... on.hash | semmle.label | documen ... on.hash | +| react.js:28:43:28:74 | documen ... bstr(1) | semmle.label | documen ... bstr(1) | +| react.js:34:43:34:64 | documen ... on.hash | semmle.label | documen ... on.hash | +| react.js:34:43:34:74 | documen ... bstr(1) | semmle.label | documen ... bstr(1) | +| react.js:40:19:40:40 | documen ... on.hash | semmle.label | documen ... on.hash | +| react.js:40:19:40:50 | documen ... bstr(1) | semmle.label | documen ... bstr(1) | +| sanitizer.js:2:9:2:25 | url | semmle.label | url | +| sanitizer.js:2:15:2:25 | window.name | semmle.label | window.name | +| sanitizer.js:4:27:4:29 | url | semmle.label | url | +| sanitizer.js:16:27:16:29 | url | semmle.label | url | +| sanitizer.js:19:27:19:29 | url | semmle.label | url | +| sanitizer.js:22:27:22:29 | url | semmle.label | url | +| sanitizer.js:25:27:25:29 | url | semmle.label | url | +| sanitizer.js:28:27:28:29 | url | semmle.label | url | +| sanitizer.js:31:27:31:29 | url | semmle.label | url | +| sanitizer.js:37:27:37:29 | url | semmle.label | url | +| tst2.js:2:7:2:33 | href | semmle.label | href | +| tst2.js:2:14:2:33 | window.location.href | semmle.label | window.location.href | +| tst2.js:4:21:4:24 | href | semmle.label | href | +| tst2.js:4:21:4:55 | href.su ... '?')+1) | semmle.label | href.su ... '?')+1) | +| tst6.js:2:7:2:45 | redirect | semmle.label | redirect | +| tst6.js:2:18:2:45 | $locati ... irect') | semmle.label | $locati ... irect') | +| tst6.js:4:21:4:28 | redirect | semmle.label | redirect | +| tst6.js:6:17:6:24 | redirect | semmle.label | redirect | +| tst6.js:8:21:8:48 | $locati ... irect') | semmle.label | $locati ... irect') | +| tst6.js:8:21:8:56 | $locati ... + "foo" | semmle.label | $locati ... + "foo" | +| tst7.js:2:12:2:35 | documen ... .search | semmle.label | documen ... .search | +| tst7.js:5:27:5:50 | documen ... .search | semmle.label | documen ... .search | +| tst9.js:2:21:2:42 | documen ... on.hash | semmle.label | documen ... on.hash | +| tst9.js:2:21:2:55 | documen ... ring(1) | semmle.label | documen ... ring(1) | +| tst10.js:5:17:5:46 | '/' + d ... .search | semmle.label | '/' + d ... .search | +| tst10.js:5:23:5:46 | documen ... .search | semmle.label | documen ... .search | +| tst10.js:8:17:8:47 | '//' + ... .search | semmle.label | '//' + ... .search | +| tst10.js:8:24:8:47 | documen ... .search | semmle.label | documen ... .search | +| tst10.js:11:17:11:50 | '//foo' ... .search | semmle.label | '//foo' ... .search | +| tst10.js:11:27:11:50 | documen ... .search | semmle.label | documen ... .search | +| tst10.js:14:17:14:56 | 'https: ... .search | semmle.label | 'https: ... .search | +| tst10.js:14:33:14:56 | documen ... .search | semmle.label | documen ... .search | +| tst12.js:3:9:3:50 | urlParts | semmle.label | urlParts | +| tst12.js:3:20:3:39 | window.location.hash | semmle.label | window.location.hash | +| tst12.js:3:20:3:50 | window. ... it('?') | semmle.label | window. ... it('?') | +| tst12.js:4:9:4:45 | loc | semmle.label | loc | +| tst12.js:4:15:4:22 | urlParts | semmle.label | urlParts | +| tst12.js:5:23:5:25 | loc | semmle.label | loc | +| tst13.js:2:9:2:52 | payload | semmle.label | payload | +| tst13.js:2:19:2:42 | documen ... .search | semmle.label | documen ... .search | +| tst13.js:2:19:2:52 | documen ... bstr(1) | semmle.label | documen ... bstr(1) | +| tst13.js:4:15:4:21 | payload | semmle.label | payload | +| tst13.js:8:21:8:27 | payload | semmle.label | payload | +| tst13.js:12:14:12:20 | payload | semmle.label | payload | +| tst13.js:16:17:16:23 | payload | semmle.label | payload | +| tst13.js:20:14:20:20 | payload | semmle.label | payload | +| tst13.js:24:14:24:20 | payload | semmle.label | payload | +| tst13.js:28:21:28:27 | payload | semmle.label | payload | +| tst13.js:32:17:32:23 | payload | semmle.label | payload | +| tst13.js:36:21:36:27 | payload | semmle.label | payload | +| tst13.js:40:15:40:21 | payload | semmle.label | payload | +| tst13.js:44:14:44:20 | payload | semmle.label | payload | +| tst13.js:49:32:49:32 | e | semmle.label | e | +| tst13.js:50:23:50:23 | e | semmle.label | e | +| tst13.js:52:34:52:34 | e | semmle.label | e | +| tst13.js:53:28:53:28 | e | semmle.label | e | +| tst13.js:59:9:59:52 | payload | semmle.label | payload | +| tst13.js:59:19:59:42 | documen ... .search | semmle.label | documen ... .search | +| tst13.js:59:19:59:52 | documen ... bstr(1) | semmle.label | documen ... bstr(1) | +| tst13.js:61:18:61:24 | payload | semmle.label | payload | +| tst13.js:65:9:65:49 | payload | semmle.label | payload | +| tst13.js:65:19:65:39 | history ... on.hash | semmle.label | history ... on.hash | +| tst13.js:65:19:65:49 | history ... bstr(1) | semmle.label | history ... bstr(1) | +| tst13.js:67:21:67:27 | payload | semmle.label | payload | +| tst13.js:72:9:72:49 | payload | semmle.label | payload | +| tst13.js:72:19:72:39 | history ... on.hash | semmle.label | history ... on.hash | +| tst13.js:72:19:72:49 | history ... bstr(1) | semmle.label | history ... bstr(1) | +| tst13.js:74:21:74:27 | payload | semmle.label | payload | +| tst13.js:78:9:78:48 | url | semmle.label | url | +| tst13.js:78:15:78:38 | documen ... .search | semmle.label | documen ... .search | +| tst13.js:78:15:78:48 | documen ... bstr(1) | semmle.label | documen ... bstr(1) | +| tst13.js:80:21:80:23 | url | semmle.label | url | +| tst13.js:81:28:81:30 | url | semmle.label | url | +| tst13.js:82:27:82:29 | url | semmle.label | url | +| tst13.js:83:22:83:24 | url | semmle.label | url | +| tst.js:2:19:2:69 | /.*redi ... n.href) | semmle.label | /.*redi ... n.href) | +| tst.js:2:19:2:72 | /.*redi ... ref)[1] | semmle.label | /.*redi ... ref)[1] | +| tst.js:2:47:2:68 | documen ... on.href | semmle.label | documen ... on.href | +| tst.js:6:20:6:56 | indirec ... n.href) | semmle.label | indirec ... n.href) | +| tst.js:6:20:6:59 | indirec ... ref)[1] | semmle.label | indirec ... ref)[1] | +| tst.js:6:34:6:55 | documen ... on.href | semmle.label | documen ... on.href | +| tst.js:10:19:10:81 | new Reg ... n.href) | semmle.label | new Reg ... n.href) | +| tst.js:10:19:10:84 | new Reg ... ref)[1] | semmle.label | new Reg ... ref)[1] | +| tst.js:10:59:10:80 | documen ... on.href | semmle.label | documen ... on.href | +| tst.js:14:20:14:56 | indirec ... n.href) | semmle.label | indirec ... n.href) | +| tst.js:14:20:14:59 | indirec ... ref)[1] | semmle.label | indirec ... ref)[1] | +| tst.js:14:34:14:55 | documen ... on.href | semmle.label | documen ... on.href | +| tst.js:18:19:18:81 | new Reg ... n.href) | semmle.label | new Reg ... n.href) | +| tst.js:18:19:18:84 | new Reg ... ref)[1] | semmle.label | new Reg ... ref)[1] | +| tst.js:18:59:18:80 | documen ... on.href | semmle.label | documen ... on.href | +| tst.js:22:20:22:56 | indirec ... n.href) | semmle.label | indirec ... n.href) | +| tst.js:22:20:22:59 | indirec ... ref)[1] | semmle.label | indirec ... ref)[1] | +| tst.js:22:34:22:55 | documen ... on.href | semmle.label | documen ... on.href | +| tst.js:26:22:26:79 | new Reg ... n.href) | semmle.label | new Reg ... n.href) | +| tst.js:26:22:26:82 | new Reg ... ref)[1] | semmle.label | new Reg ... ref)[1] | +| tst.js:26:62:26:78 | win.location.href | semmle.label | win.location.href | +| typed.ts:4:13:4:36 | params | semmle.label | params | +| typed.ts:4:22:4:36 | location.search | semmle.label | location.search | +| typed.ts:5:25:5:30 | params | semmle.label | params | +| typed.ts:7:24:7:34 | redirectUri | semmle.label | redirectUri | +| typed.ts:8:33:8:43 | redirectUri | semmle.label | redirectUri | +| typed.ts:25:25:25:34 | loc.search | semmle.label | loc.search | +| typed.ts:28:24:28:34 | redirectUri | semmle.label | redirectUri | +| typed.ts:29:33:29:43 | redirectUri | semmle.label | redirectUri | +| typed.ts:47:25:47:34 | loc.search | semmle.label | loc.search | +| typed.ts:48:26:48:36 | loc2.search | semmle.label | loc2.search | +| typed.ts:51:24:51:34 | redirectUri | semmle.label | redirectUri | +| typed.ts:52:33:52:43 | redirectUri | semmle.label | redirectUri | +| typed.ts:55:25:55:35 | redirectUri | semmle.label | redirectUri | +| typed.ts:56:33:56:43 | redirectUri | semmle.label | redirectUri | edges | electron.js:4:12:4:22 | window.name | electron.js:7:20:7:29 | getTaint() | -| electron.js:4:12:4:22 | window.name | electron.js:7:20:7:29 | getTaint() | -| electron.js:4:12:4:22 | window.name | electron.js:7:20:7:29 | getTaint() | -| electron.js:4:12:4:22 | window.name | electron.js:7:20:7:29 | getTaint() | -| react.js:10:60:10:81 | documen ... on.hash | react.js:10:60:10:81 | documen ... on.hash | -| react.js:21:24:21:45 | documen ... on.hash | react.js:21:24:21:45 | documen ... on.hash | -| react.js:28:43:28:64 | documen ... on.hash | react.js:28:43:28:74 | documen ... bstr(1) | -| react.js:28:43:28:64 | documen ... on.hash | react.js:28:43:28:74 | documen ... bstr(1) | -| react.js:28:43:28:64 | documen ... on.hash | react.js:28:43:28:74 | documen ... bstr(1) | | react.js:28:43:28:64 | documen ... on.hash | react.js:28:43:28:74 | documen ... bstr(1) | | react.js:34:43:34:64 | documen ... on.hash | react.js:34:43:34:74 | documen ... bstr(1) | -| react.js:34:43:34:64 | documen ... on.hash | react.js:34:43:34:74 | documen ... bstr(1) | -| react.js:34:43:34:64 | documen ... on.hash | react.js:34:43:34:74 | documen ... bstr(1) | -| react.js:34:43:34:64 | documen ... on.hash | react.js:34:43:34:74 | documen ... bstr(1) | -| react.js:40:19:40:40 | documen ... on.hash | react.js:40:19:40:50 | documen ... bstr(1) | -| react.js:40:19:40:40 | documen ... on.hash | react.js:40:19:40:50 | documen ... bstr(1) | -| react.js:40:19:40:40 | documen ... on.hash | react.js:40:19:40:50 | documen ... bstr(1) | | react.js:40:19:40:40 | documen ... on.hash | react.js:40:19:40:50 | documen ... bstr(1) | | sanitizer.js:2:9:2:25 | url | sanitizer.js:4:27:4:29 | url | -| sanitizer.js:2:9:2:25 | url | sanitizer.js:4:27:4:29 | url | -| sanitizer.js:2:9:2:25 | url | sanitizer.js:16:27:16:29 | url | | sanitizer.js:2:9:2:25 | url | sanitizer.js:16:27:16:29 | url | | sanitizer.js:2:9:2:25 | url | sanitizer.js:19:27:19:29 | url | -| sanitizer.js:2:9:2:25 | url | sanitizer.js:19:27:19:29 | url | -| sanitizer.js:2:9:2:25 | url | sanitizer.js:22:27:22:29 | url | | sanitizer.js:2:9:2:25 | url | sanitizer.js:22:27:22:29 | url | | sanitizer.js:2:9:2:25 | url | sanitizer.js:25:27:25:29 | url | -| sanitizer.js:2:9:2:25 | url | sanitizer.js:25:27:25:29 | url | -| sanitizer.js:2:9:2:25 | url | sanitizer.js:28:27:28:29 | url | | sanitizer.js:2:9:2:25 | url | sanitizer.js:28:27:28:29 | url | | sanitizer.js:2:9:2:25 | url | sanitizer.js:31:27:31:29 | url | -| sanitizer.js:2:9:2:25 | url | sanitizer.js:31:27:31:29 | url | | sanitizer.js:2:9:2:25 | url | sanitizer.js:37:27:37:29 | url | -| sanitizer.js:2:9:2:25 | url | sanitizer.js:37:27:37:29 | url | -| sanitizer.js:2:15:2:25 | window.name | sanitizer.js:2:9:2:25 | url | | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:2:9:2:25 | url | | tst2.js:2:7:2:33 | href | tst2.js:4:21:4:24 | href | -| tst2.js:2:14:2:28 | window.location | tst2.js:2:14:2:33 | window.location.href | -| tst2.js:2:14:2:28 | window.location | tst2.js:2:14:2:33 | window.location.href | -| tst2.js:2:14:2:33 | window.location.href | tst2.js:2:7:2:33 | href | | tst2.js:2:14:2:33 | window.location.href | tst2.js:2:7:2:33 | href | | tst2.js:4:21:4:24 | href | tst2.js:4:21:4:55 | href.su ... '?')+1) | -| tst2.js:4:21:4:24 | href | tst2.js:4:21:4:55 | href.su ... '?')+1) | -| tst6.js:2:7:2:45 | redirect | tst6.js:4:21:4:28 | redirect | | tst6.js:2:7:2:45 | redirect | tst6.js:4:21:4:28 | redirect | | tst6.js:2:7:2:45 | redirect | tst6.js:6:17:6:24 | redirect | -| tst6.js:2:7:2:45 | redirect | tst6.js:6:17:6:24 | redirect | -| tst6.js:2:18:2:45 | $locati ... irect') | tst6.js:2:7:2:45 | redirect | | tst6.js:2:18:2:45 | $locati ... irect') | tst6.js:2:7:2:45 | redirect | | tst6.js:8:21:8:48 | $locati ... irect') | tst6.js:8:21:8:56 | $locati ... + "foo" | -| tst6.js:8:21:8:48 | $locati ... irect') | tst6.js:8:21:8:56 | $locati ... + "foo" | -| tst6.js:8:21:8:48 | $locati ... irect') | tst6.js:8:21:8:56 | $locati ... + "foo" | -| tst6.js:8:21:8:48 | $locati ... irect') | tst6.js:8:21:8:56 | $locati ... + "foo" | -| tst7.js:2:12:2:35 | documen ... .search | tst7.js:2:12:2:35 | documen ... .search | -| tst7.js:5:27:5:50 | documen ... .search | tst7.js:5:27:5:50 | documen ... .search | -| tst9.js:2:21:2:42 | documen ... on.hash | tst9.js:2:21:2:55 | documen ... ring(1) | -| tst9.js:2:21:2:42 | documen ... on.hash | tst9.js:2:21:2:55 | documen ... ring(1) | -| tst9.js:2:21:2:42 | documen ... on.hash | tst9.js:2:21:2:55 | documen ... ring(1) | | tst9.js:2:21:2:42 | documen ... on.hash | tst9.js:2:21:2:55 | documen ... ring(1) | | tst10.js:5:23:5:46 | documen ... .search | tst10.js:5:17:5:46 | '/' + d ... .search | -| tst10.js:5:23:5:46 | documen ... .search | tst10.js:5:17:5:46 | '/' + d ... .search | -| tst10.js:5:23:5:46 | documen ... .search | tst10.js:5:17:5:46 | '/' + d ... .search | -| tst10.js:5:23:5:46 | documen ... .search | tst10.js:5:17:5:46 | '/' + d ... .search | -| tst10.js:8:24:8:47 | documen ... .search | tst10.js:8:17:8:47 | '//' + ... .search | -| tst10.js:8:24:8:47 | documen ... .search | tst10.js:8:17:8:47 | '//' + ... .search | -| tst10.js:8:24:8:47 | documen ... .search | tst10.js:8:17:8:47 | '//' + ... .search | | tst10.js:8:24:8:47 | documen ... .search | tst10.js:8:17:8:47 | '//' + ... .search | | tst10.js:11:27:11:50 | documen ... .search | tst10.js:11:17:11:50 | '//foo' ... .search | -| tst10.js:11:27:11:50 | documen ... .search | tst10.js:11:17:11:50 | '//foo' ... .search | -| tst10.js:11:27:11:50 | documen ... .search | tst10.js:11:17:11:50 | '//foo' ... .search | -| tst10.js:11:27:11:50 | documen ... .search | tst10.js:11:17:11:50 | '//foo' ... .search | -| tst10.js:14:33:14:56 | documen ... .search | tst10.js:14:17:14:56 | 'https: ... .search | -| tst10.js:14:33:14:56 | documen ... .search | tst10.js:14:17:14:56 | 'https: ... .search | -| tst10.js:14:33:14:56 | documen ... .search | tst10.js:14:17:14:56 | 'https: ... .search | | tst10.js:14:33:14:56 | documen ... .search | tst10.js:14:17:14:56 | 'https: ... .search | | tst12.js:3:9:3:50 | urlParts | tst12.js:4:15:4:22 | urlParts | | tst12.js:3:20:3:39 | window.location.hash | tst12.js:3:20:3:50 | window. ... it('?') | -| tst12.js:3:20:3:39 | window.location.hash | tst12.js:3:20:3:50 | window. ... it('?') | | tst12.js:3:20:3:50 | window. ... it('?') | tst12.js:3:9:3:50 | urlParts | | tst12.js:4:9:4:45 | loc | tst12.js:5:23:5:25 | loc | -| tst12.js:4:9:4:45 | loc | tst12.js:5:23:5:25 | loc | -| tst12.js:4:15:4:22 | urlParts | tst12.js:4:15:4:25 | urlParts[0] | -| tst12.js:4:15:4:25 | urlParts[0] | tst12.js:4:15:4:45 | urlPart ... s.value | -| tst12.js:4:15:4:45 | urlPart ... s.value | tst12.js:4:9:4:45 | loc | -| tst13.js:2:9:2:52 | payload | tst13.js:4:15:4:21 | payload | +| tst12.js:4:15:4:22 | urlParts | tst12.js:4:9:4:45 | loc | | tst13.js:2:9:2:52 | payload | tst13.js:4:15:4:21 | payload | | tst13.js:2:9:2:52 | payload | tst13.js:8:21:8:27 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:8:21:8:27 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:12:14:12:20 | payload | | tst13.js:2:9:2:52 | payload | tst13.js:12:14:12:20 | payload | | tst13.js:2:9:2:52 | payload | tst13.js:16:17:16:23 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:16:17:16:23 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:20:14:20:20 | payload | | tst13.js:2:9:2:52 | payload | tst13.js:20:14:20:20 | payload | | tst13.js:2:9:2:52 | payload | tst13.js:24:14:24:20 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:24:14:24:20 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:28:21:28:27 | payload | | tst13.js:2:9:2:52 | payload | tst13.js:28:21:28:27 | payload | | tst13.js:2:9:2:52 | payload | tst13.js:32:17:32:23 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:32:17:32:23 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:36:21:36:27 | payload | | tst13.js:2:9:2:52 | payload | tst13.js:36:21:36:27 | payload | | tst13.js:2:9:2:52 | payload | tst13.js:40:15:40:21 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:40:15:40:21 | payload | | tst13.js:2:9:2:52 | payload | tst13.js:44:14:44:20 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:44:14:44:20 | payload | -| tst13.js:2:19:2:42 | documen ... .search | tst13.js:2:19:2:52 | documen ... bstr(1) | | tst13.js:2:19:2:42 | documen ... .search | tst13.js:2:19:2:52 | documen ... bstr(1) | | tst13.js:2:19:2:52 | documen ... bstr(1) | tst13.js:2:9:2:52 | payload | | tst13.js:49:32:49:32 | e | tst13.js:50:23:50:23 | e | -| tst13.js:49:32:49:32 | e | tst13.js:50:23:50:23 | e | -| tst13.js:49:32:49:32 | e | tst13.js:50:23:50:23 | e | -| tst13.js:49:32:49:32 | e | tst13.js:50:23:50:23 | e | -| tst13.js:52:34:52:34 | e | tst13.js:53:28:53:28 | e | -| tst13.js:52:34:52:34 | e | tst13.js:53:28:53:28 | e | -| tst13.js:52:34:52:34 | e | tst13.js:53:28:53:28 | e | | tst13.js:52:34:52:34 | e | tst13.js:53:28:53:28 | e | | tst13.js:59:9:59:52 | payload | tst13.js:61:18:61:24 | payload | -| tst13.js:59:9:59:52 | payload | tst13.js:61:18:61:24 | payload | -| tst13.js:59:19:59:42 | documen ... .search | tst13.js:59:19:59:52 | documen ... bstr(1) | | tst13.js:59:19:59:42 | documen ... .search | tst13.js:59:19:59:52 | documen ... bstr(1) | | tst13.js:59:19:59:52 | documen ... bstr(1) | tst13.js:59:9:59:52 | payload | | tst13.js:65:9:65:49 | payload | tst13.js:67:21:67:27 | payload | -| tst13.js:65:9:65:49 | payload | tst13.js:67:21:67:27 | payload | -| tst13.js:65:19:65:39 | history ... on.hash | tst13.js:65:19:65:49 | history ... bstr(1) | | tst13.js:65:19:65:39 | history ... on.hash | tst13.js:65:19:65:49 | history ... bstr(1) | | tst13.js:65:19:65:49 | history ... bstr(1) | tst13.js:65:9:65:49 | payload | | tst13.js:72:9:72:49 | payload | tst13.js:74:21:74:27 | payload | -| tst13.js:72:9:72:49 | payload | tst13.js:74:21:74:27 | payload | -| tst13.js:72:19:72:39 | history ... on.hash | tst13.js:72:19:72:49 | history ... bstr(1) | | tst13.js:72:19:72:39 | history ... on.hash | tst13.js:72:19:72:49 | history ... bstr(1) | | tst13.js:72:19:72:49 | history ... bstr(1) | tst13.js:72:9:72:49 | payload | | tst13.js:78:9:78:48 | url | tst13.js:80:21:80:23 | url | -| tst13.js:78:9:78:48 | url | tst13.js:80:21:80:23 | url | -| tst13.js:78:9:78:48 | url | tst13.js:81:28:81:30 | url | | tst13.js:78:9:78:48 | url | tst13.js:81:28:81:30 | url | | tst13.js:78:9:78:48 | url | tst13.js:82:27:82:29 | url | -| tst13.js:78:9:78:48 | url | tst13.js:82:27:82:29 | url | | tst13.js:78:9:78:48 | url | tst13.js:83:22:83:24 | url | -| tst13.js:78:9:78:48 | url | tst13.js:83:22:83:24 | url | -| tst13.js:78:15:78:38 | documen ... .search | tst13.js:78:15:78:48 | documen ... bstr(1) | | tst13.js:78:15:78:38 | documen ... .search | tst13.js:78:15:78:48 | documen ... bstr(1) | | tst13.js:78:15:78:48 | documen ... bstr(1) | tst13.js:78:9:78:48 | url | | tst.js:2:19:2:69 | /.*redi ... n.href) | tst.js:2:19:2:72 | /.*redi ... ref)[1] | -| tst.js:2:19:2:69 | /.*redi ... n.href) | tst.js:2:19:2:72 | /.*redi ... ref)[1] | -| tst.js:2:47:2:63 | document.location | tst.js:2:47:2:68 | documen ... on.href | -| tst.js:2:47:2:63 | document.location | tst.js:2:47:2:68 | documen ... on.href | -| tst.js:2:47:2:68 | documen ... on.href | tst.js:2:19:2:69 | /.*redi ... n.href) | | tst.js:2:47:2:68 | documen ... on.href | tst.js:2:19:2:69 | /.*redi ... n.href) | | tst.js:6:20:6:56 | indirec ... n.href) | tst.js:6:20:6:59 | indirec ... ref)[1] | -| tst.js:6:20:6:56 | indirec ... n.href) | tst.js:6:20:6:59 | indirec ... ref)[1] | -| tst.js:6:34:6:50 | document.location | tst.js:6:34:6:55 | documen ... on.href | -| tst.js:6:34:6:50 | document.location | tst.js:6:34:6:55 | documen ... on.href | -| tst.js:6:34:6:55 | documen ... on.href | tst.js:6:20:6:56 | indirec ... n.href) | | tst.js:6:34:6:55 | documen ... on.href | tst.js:6:20:6:56 | indirec ... n.href) | | tst.js:10:19:10:81 | new Reg ... n.href) | tst.js:10:19:10:84 | new Reg ... ref)[1] | -| tst.js:10:19:10:81 | new Reg ... n.href) | tst.js:10:19:10:84 | new Reg ... ref)[1] | -| tst.js:10:59:10:75 | document.location | tst.js:10:59:10:80 | documen ... on.href | -| tst.js:10:59:10:75 | document.location | tst.js:10:59:10:80 | documen ... on.href | -| tst.js:10:59:10:80 | documen ... on.href | tst.js:10:19:10:81 | new Reg ... n.href) | | tst.js:10:59:10:80 | documen ... on.href | tst.js:10:19:10:81 | new Reg ... n.href) | | tst.js:14:20:14:56 | indirec ... n.href) | tst.js:14:20:14:59 | indirec ... ref)[1] | -| tst.js:14:20:14:56 | indirec ... n.href) | tst.js:14:20:14:59 | indirec ... ref)[1] | -| tst.js:14:34:14:50 | document.location | tst.js:14:34:14:55 | documen ... on.href | -| tst.js:14:34:14:50 | document.location | tst.js:14:34:14:55 | documen ... on.href | -| tst.js:14:34:14:55 | documen ... on.href | tst.js:14:20:14:56 | indirec ... n.href) | | tst.js:14:34:14:55 | documen ... on.href | tst.js:14:20:14:56 | indirec ... n.href) | | tst.js:18:19:18:81 | new Reg ... n.href) | tst.js:18:19:18:84 | new Reg ... ref)[1] | -| tst.js:18:19:18:81 | new Reg ... n.href) | tst.js:18:19:18:84 | new Reg ... ref)[1] | -| tst.js:18:59:18:75 | document.location | tst.js:18:59:18:80 | documen ... on.href | -| tst.js:18:59:18:75 | document.location | tst.js:18:59:18:80 | documen ... on.href | -| tst.js:18:59:18:80 | documen ... on.href | tst.js:18:19:18:81 | new Reg ... n.href) | | tst.js:18:59:18:80 | documen ... on.href | tst.js:18:19:18:81 | new Reg ... n.href) | | tst.js:22:20:22:56 | indirec ... n.href) | tst.js:22:20:22:59 | indirec ... ref)[1] | -| tst.js:22:20:22:56 | indirec ... n.href) | tst.js:22:20:22:59 | indirec ... ref)[1] | -| tst.js:22:34:22:50 | document.location | tst.js:22:34:22:55 | documen ... on.href | -| tst.js:22:34:22:50 | document.location | tst.js:22:34:22:55 | documen ... on.href | -| tst.js:22:34:22:55 | documen ... on.href | tst.js:22:20:22:56 | indirec ... n.href) | | tst.js:22:34:22:55 | documen ... on.href | tst.js:22:20:22:56 | indirec ... n.href) | | tst.js:26:22:26:79 | new Reg ... n.href) | tst.js:26:22:26:82 | new Reg ... ref)[1] | -| tst.js:26:22:26:79 | new Reg ... n.href) | tst.js:26:22:26:82 | new Reg ... ref)[1] | -| tst.js:26:62:26:78 | win.location.href | tst.js:26:22:26:79 | new Reg ... n.href) | | tst.js:26:62:26:78 | win.location.href | tst.js:26:22:26:79 | new Reg ... n.href) | | typed.ts:4:13:4:36 | params | typed.ts:5:25:5:30 | params | | typed.ts:4:22:4:36 | location.search | typed.ts:4:13:4:36 | params | -| typed.ts:4:22:4:36 | location.search | typed.ts:4:13:4:36 | params | | typed.ts:5:25:5:30 | params | typed.ts:7:24:7:34 | redirectUri | | typed.ts:7:24:7:34 | redirectUri | typed.ts:8:33:8:43 | redirectUri | -| typed.ts:7:24:7:34 | redirectUri | typed.ts:8:33:8:43 | redirectUri | -| typed.ts:25:25:25:34 | loc.search | typed.ts:28:24:28:34 | redirectUri | | typed.ts:25:25:25:34 | loc.search | typed.ts:28:24:28:34 | redirectUri | | typed.ts:28:24:28:34 | redirectUri | typed.ts:29:33:29:43 | redirectUri | -| typed.ts:28:24:28:34 | redirectUri | typed.ts:29:33:29:43 | redirectUri | -| typed.ts:47:25:47:34 | loc.search | typed.ts:51:24:51:34 | redirectUri | | typed.ts:47:25:47:34 | loc.search | typed.ts:51:24:51:34 | redirectUri | | typed.ts:48:26:48:36 | loc2.search | typed.ts:55:25:55:35 | redirectUri | -| typed.ts:48:26:48:36 | loc2.search | typed.ts:55:25:55:35 | redirectUri | -| typed.ts:51:24:51:34 | redirectUri | typed.ts:52:33:52:43 | redirectUri | | typed.ts:51:24:51:34 | redirectUri | typed.ts:52:33:52:43 | redirectUri | | typed.ts:55:25:55:35 | redirectUri | typed.ts:56:33:56:43 | redirectUri | -| typed.ts:55:25:55:35 | redirectUri | typed.ts:56:33:56:43 | redirectUri | +subpaths #select | electron.js:7:20:7:29 | getTaint() | electron.js:4:12:4:22 | window.name | electron.js:7:20:7:29 | getTaint() | Untrusted URL redirection depends on a $@. | electron.js:4:12:4:22 | window.name | user-provided value | | react.js:10:60:10:81 | documen ... on.hash | react.js:10:60:10:81 | documen ... on.hash | react.js:10:60:10:81 | documen ... on.hash | Untrusted URL redirection depends on a $@. | react.js:10:60:10:81 | documen ... on.hash | user-provided value | @@ -445,7 +220,6 @@ edges | sanitizer.js:28:27:28:29 | url | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:28:27:28:29 | url | Untrusted URL redirection depends on a $@. | sanitizer.js:2:15:2:25 | window.name | user-provided value | | sanitizer.js:31:27:31:29 | url | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:31:27:31:29 | url | Untrusted URL redirection depends on a $@. | sanitizer.js:2:15:2:25 | window.name | user-provided value | | sanitizer.js:37:27:37:29 | url | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:37:27:37:29 | url | Untrusted URL redirection depends on a $@. | sanitizer.js:2:15:2:25 | window.name | user-provided value | -| tst2.js:4:21:4:55 | href.su ... '?')+1) | tst2.js:2:14:2:28 | window.location | tst2.js:4:21:4:55 | href.su ... '?')+1) | Untrusted URL redirection depends on a $@. | tst2.js:2:14:2:28 | window.location | user-provided value | | tst2.js:4:21:4:55 | href.su ... '?')+1) | tst2.js:2:14:2:33 | window.location.href | tst2.js:4:21:4:55 | href.su ... '?')+1) | Untrusted URL redirection depends on a $@. | tst2.js:2:14:2:33 | window.location.href | user-provided value | | tst6.js:4:21:4:28 | redirect | tst6.js:2:18:2:45 | $locati ... irect') | tst6.js:4:21:4:28 | redirect | Untrusted URL redirection depends on a $@. | tst6.js:2:18:2:45 | $locati ... irect') | user-provided value | | tst6.js:6:17:6:24 | redirect | tst6.js:2:18:2:45 | $locati ... irect') | tst6.js:6:17:6:24 | redirect | Untrusted URL redirection depends on a $@. | tst6.js:2:18:2:45 | $locati ... irect') | user-provided value | @@ -478,17 +252,11 @@ edges | tst13.js:81:28:81:30 | url | tst13.js:78:15:78:38 | documen ... .search | tst13.js:81:28:81:30 | url | Untrusted URL redirection depends on a $@. | tst13.js:78:15:78:38 | documen ... .search | user-provided value | | tst13.js:82:27:82:29 | url | tst13.js:78:15:78:38 | documen ... .search | tst13.js:82:27:82:29 | url | Untrusted URL redirection depends on a $@. | tst13.js:78:15:78:38 | documen ... .search | user-provided value | | tst13.js:83:22:83:24 | url | tst13.js:78:15:78:38 | documen ... .search | tst13.js:83:22:83:24 | url | Untrusted URL redirection depends on a $@. | tst13.js:78:15:78:38 | documen ... .search | user-provided value | -| tst.js:2:19:2:72 | /.*redi ... ref)[1] | tst.js:2:47:2:63 | document.location | tst.js:2:19:2:72 | /.*redi ... ref)[1] | Untrusted URL redirection depends on a $@. | tst.js:2:47:2:63 | document.location | user-provided value | | tst.js:2:19:2:72 | /.*redi ... ref)[1] | tst.js:2:47:2:68 | documen ... on.href | tst.js:2:19:2:72 | /.*redi ... ref)[1] | Untrusted URL redirection depends on a $@. | tst.js:2:47:2:68 | documen ... on.href | user-provided value | -| tst.js:6:20:6:59 | indirec ... ref)[1] | tst.js:6:34:6:50 | document.location | tst.js:6:20:6:59 | indirec ... ref)[1] | Untrusted URL redirection depends on a $@. | tst.js:6:34:6:50 | document.location | user-provided value | | tst.js:6:20:6:59 | indirec ... ref)[1] | tst.js:6:34:6:55 | documen ... on.href | tst.js:6:20:6:59 | indirec ... ref)[1] | Untrusted URL redirection depends on a $@. | tst.js:6:34:6:55 | documen ... on.href | user-provided value | -| tst.js:10:19:10:84 | new Reg ... ref)[1] | tst.js:10:59:10:75 | document.location | tst.js:10:19:10:84 | new Reg ... ref)[1] | Untrusted URL redirection depends on a $@. | tst.js:10:59:10:75 | document.location | user-provided value | | tst.js:10:19:10:84 | new Reg ... ref)[1] | tst.js:10:59:10:80 | documen ... on.href | tst.js:10:19:10:84 | new Reg ... ref)[1] | Untrusted URL redirection depends on a $@. | tst.js:10:59:10:80 | documen ... on.href | user-provided value | -| tst.js:14:20:14:59 | indirec ... ref)[1] | tst.js:14:34:14:50 | document.location | tst.js:14:20:14:59 | indirec ... ref)[1] | Untrusted URL redirection depends on a $@. | tst.js:14:34:14:50 | document.location | user-provided value | | tst.js:14:20:14:59 | indirec ... ref)[1] | tst.js:14:34:14:55 | documen ... on.href | tst.js:14:20:14:59 | indirec ... ref)[1] | Untrusted URL redirection depends on a $@. | tst.js:14:34:14:55 | documen ... on.href | user-provided value | -| tst.js:18:19:18:84 | new Reg ... ref)[1] | tst.js:18:59:18:75 | document.location | tst.js:18:19:18:84 | new Reg ... ref)[1] | Untrusted URL redirection depends on a $@. | tst.js:18:59:18:75 | document.location | user-provided value | | tst.js:18:19:18:84 | new Reg ... ref)[1] | tst.js:18:59:18:80 | documen ... on.href | tst.js:18:19:18:84 | new Reg ... ref)[1] | Untrusted URL redirection depends on a $@. | tst.js:18:59:18:80 | documen ... on.href | user-provided value | -| tst.js:22:20:22:59 | indirec ... ref)[1] | tst.js:22:34:22:50 | document.location | tst.js:22:20:22:59 | indirec ... ref)[1] | Untrusted URL redirection depends on a $@. | tst.js:22:34:22:50 | document.location | user-provided value | | tst.js:22:20:22:59 | indirec ... ref)[1] | tst.js:22:34:22:55 | documen ... on.href | tst.js:22:20:22:59 | indirec ... ref)[1] | Untrusted URL redirection depends on a $@. | tst.js:22:34:22:55 | documen ... on.href | user-provided value | | tst.js:26:22:26:82 | new Reg ... ref)[1] | tst.js:26:62:26:78 | win.location.href | tst.js:26:22:26:82 | new Reg ... ref)[1] | Untrusted URL redirection depends on a $@. | tst.js:26:62:26:78 | win.location.href | user-provided value | | typed.ts:8:33:8:43 | redirectUri | typed.ts:4:22:4:36 | location.search | typed.ts:8:33:8:43 | redirectUri | Untrusted URL redirection depends on a $@. | typed.ts:4:22:4:36 | location.search | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst15.js b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst15.js new file mode 100644 index 00000000000..cb5345d5921 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst15.js @@ -0,0 +1,12 @@ +function foo() { + var url = document.location.toString(); + window.location = url.substring(0).substring(1); // OK + window.location = url.substring(0, 10).substring(1); // OK + window.location = url.substring(0, url.indexOf('/', 10)).substring(1); // OK +} + +function bar() { + var url = new URL(window.location); + window.location = url.origin; // OK + window.location = url.origin.substring(10); // OK +} From f1f45927b121fb858c5bfc3c8078c1915ae9731b Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:36:31 +0200 Subject: [PATCH 057/514] JS: Port PrototypePollutingAssignment --- ...otypePollutingAssignmentCustomizations.qll | 32 +- .../PrototypePollutingAssignmentQuery.qll | 138 ++++-- .../CWE-915/PrototypePollutingAssignment.ql | 9 +- .../Consistency.expected | 1 + .../Consistency.ql | 11 +- .../PrototypePollutingAssignment.expected | 402 ++++++------------ 6 files changed, 286 insertions(+), 307 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentCustomizations.qll index 656c7bb3849..4b0b954066a 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentCustomizations.qll @@ -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" } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll index 0ba2f26b24c..ca61ebf284d 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll @@ -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::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::getABarrierNode(lbl) + } +} + +/** Taint-tracking for reasoning about prototype-polluting assignments. */ +module PrototypePollutingAssignmentFlow = + DataFlow::GlobalWithState; + +/** + * 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() } diff --git a/javascript/ql/src/Security/CWE-915/PrototypePollutingAssignment.ql b/javascript/ql/src/Security/CWE-915/PrototypePollutingAssignment.ql index 2b916426169..b5f86910e9d 100644 --- a/javascript/ql/src/Security/CWE-915/PrototypePollutingAssignment.ql +++ b/javascript/ql/src/Security/CWE-915/PrototypePollutingAssignment.ql @@ -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() diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.expected index e69de29bb2d..8d013c40b5f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.expected @@ -0,0 +1 @@ +| query-tests/Security/CWE-915/PrototypePollutingAssignment/lib.js:70 | expected an alert, but found none | NOT OK | Config | diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.ql index 7a440ac58bb..636d6e3bbda 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.ql @@ -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) + ) + } } diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected index 891aeff4221..e3e20255490 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected @@ -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 | From adf7d5409dfffd39db78deee210c93bc8a32dc89 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:37:13 +0200 Subject: [PATCH 058/514] JS: Port PrototypePollutingFunction --- .../CWE-915/PrototypePollutingFunction.ql | 182 +- .../PrototypePollutingFunction.expected | 3690 ++++------------- .../PrototypePollutingFunction/tests.js | 21 +- 3 files changed, 874 insertions(+), 3019 deletions(-) diff --git a/javascript/ql/src/Security/CWE-915/PrototypePollutingFunction.ql b/javascript/ql/src/Security/CWE-915/PrototypePollutingFunction.ql index fa2fd3da021..161763d341e 100644 --- a/javascript/ql/src/Security/CWE-915/PrototypePollutingFunction.ql +++ b/javascript/ql/src/Security/CWE-915/PrototypePollutingFunction.ql @@ -17,11 +17,10 @@ */ import javascript -import DataFlow -import PathGraph import semmle.javascript.DynamicPropertyAccess private import semmle.javascript.dataflow.InferredTypes +// WIN: gained TP in Lucifier/r.js:2757, though not sure why it wasn't flagged to start with. /** * A call of form `x.split(".")` where `x` is a parameter. * @@ -30,14 +29,14 @@ private import semmle.javascript.dataflow.InferredTypes class SplitCall extends StringSplitCall { SplitCall() { this.getSeparator() = "." and - this.getBaseString().getALocalSource() instanceof ParameterNode + this.getBaseString().getALocalSource() instanceof DataFlow::ParameterNode } } /** * Holds if `pred -> succ` should preserve polluted property names. */ -predicate copyArrayStep(SourceNode pred, SourceNode succ) { +predicate copyArrayStep(DataFlow::SourceNode pred, DataFlow::SourceNode succ) { // x -> [...x] exists(SpreadElement spread | pred.flowsTo(spread.getOperand().flow()) and @@ -45,7 +44,7 @@ predicate copyArrayStep(SourceNode pred, SourceNode succ) { ) or // `x -> y` in `y.push( x[i] )` - exists(MethodCallNode push | + exists(DataFlow::MethodCallNode push | push = succ.getAMethodCall("push") and ( getAnEnumeratedArrayElement(pred).flowsTo(push.getAnArgument()) @@ -55,7 +54,7 @@ predicate copyArrayStep(SourceNode pred, SourceNode succ) { ) or // x -> x.concat(...) - exists(MethodCallNode concat_ | + exists(DataFlow::MethodCallNode concat_ | concat_.getMethodName() = "concat" and (pred = concat_.getReceiver() or pred = concat_.getAnArgument()) and succ = concat_ @@ -66,21 +65,21 @@ predicate copyArrayStep(SourceNode pred, SourceNode succ) { * Holds if `node` may refer to a `SplitCall` or a copy thereof, possibly * returned through a function call. */ -predicate isSplitArray(SourceNode node) { +predicate isSplitArray(DataFlow::SourceNode node) { node instanceof SplitCall or - exists(SourceNode pred | isSplitArray(pred) | + exists(DataFlow::SourceNode pred | isSplitArray(pred) | copyArrayStep(pred, node) or - pred.flowsToExpr(node.(CallNode).getACallee().getAReturnedExpr()) + pred.flowsToExpr(node.(DataFlow::CallNode).getACallee().getAReturnedExpr()) ) } /** * A property name originating from a `x.split(".")` call. */ -class SplitPropName extends SourceNode { - SourceNode array; +class SplitPropName extends DataFlow::SourceNode { + DataFlow::SourceNode array; SplitPropName() { isSplitArray(array) and @@ -90,7 +89,7 @@ class SplitPropName extends SourceNode { /** * Gets the array from which this property name was obtained (the result from `split`). */ - SourceNode getArray() { result = array } + DataFlow::SourceNode getArray() { result = array } /** Gets an element accessed on the same underlying array. */ SplitPropName getAnAlias() { result.getArray() = this.getArray() } @@ -117,18 +116,18 @@ predicate isPollutedPropNameSource(DataFlow::Node node) { * Holds if `node` may flow from a source of polluted propery names, possibly * into function calls (but not returns). */ -predicate isPollutedPropName(Node node) { +predicate isPollutedPropName(DataFlow::Node node) { isPollutedPropNameSource(node) or - exists(Node pred | isPollutedPropName(pred) | + exists(DataFlow::Node pred | isPollutedPropName(pred) | node = pred.getASuccessor() or - argumentPassingStep(_, pred, _, node) + DataFlow::argumentPassingStep(_, pred, _, node) or // Handle one level of callbacks - exists(FunctionNode function, ParameterNode callback, int i | + exists(DataFlow::FunctionNode function, DataFlow::ParameterNode callback, int i | pred = callback.getAnInvocation().getArgument(i) and - argumentPassingStep(_, function, _, callback) and + DataFlow::argumentPassingStep(_, function, _, callback) and node = function.getParameter(i) ) ) @@ -138,8 +137,8 @@ predicate isPollutedPropName(Node node) { * Holds if `node` may refer to `Object.prototype` obtained through dynamic property * read of a property obtained through property enumeration. */ -predicate isPotentiallyObjectPrototype(SourceNode node) { - exists(Node base, Node key | +predicate isPotentiallyObjectPrototype(DataFlow::SourceNode node) { + exists(DataFlow::Node base, DataFlow::Node key | dynamicPropReadStep(base, key, node) and isPollutedPropName(key) and // Ignore cases where the properties of `base` are enumerated, to avoid FPs @@ -149,8 +148,8 @@ predicate isPotentiallyObjectPrototype(SourceNode node) { not arePropertiesEnumerated(base.getALocalSource()) ) or - exists(Node use | isPotentiallyObjectPrototype(use.getALocalSource()) | - argumentPassingStep(_, use, _, node) + exists(DataFlow::Node use | isPotentiallyObjectPrototype(use.getALocalSource()) | + DataFlow::argumentPassingStep(_, use, _, node) ) } @@ -197,7 +196,7 @@ string unsafePropName() { * A flow label representing an unsafe property name, or an object obtained * by using such a property in a dynamic read. */ -class UnsafePropLabel extends FlowLabel { +class UnsafePropLabel extends DataFlow::FlowLabel { UnsafePropLabel() { this = unsafePropName() } } @@ -233,10 +232,10 @@ class UnsafePropLabel extends FlowLabel { * for coinciding paths afterwards. This means this configuration can't be used as * a standalone configuration like in most path queries. */ -class PropNameTracking extends DataFlow::Configuration { - PropNameTracking() { this = "PropNameTracking" } +module PropNameTrackingConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; - override predicate isSource(DataFlow::Node node, FlowLabel label) { + predicate isSource(DataFlow::Node node, DataFlow::FlowLabel label) { label instanceof UnsafePropLabel and ( isPollutedPropNameSource(node) @@ -245,7 +244,7 @@ class PropNameTracking extends DataFlow::Configuration { ) } - override predicate isSink(DataFlow::Node node, FlowLabel label) { + predicate isSink(DataFlow::Node node, DataFlow::FlowLabel label) { label instanceof UnsafePropLabel and ( dynamicPropWrite(node, _, _) or @@ -254,14 +253,19 @@ class PropNameTracking extends DataFlow::Configuration { ) } - override predicate isAdditionalFlowStep( - DataFlow::Node pred, DataFlow::Node succ, FlowLabel predlbl, FlowLabel succlbl + predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel label) { + node = DataFlow::MakeLabeledBarrierGuard::getABarrierNode(label) + } + + predicate isAdditionalFlowStep( + DataFlow::Node pred, DataFlow::FlowLabel predlbl, DataFlow::Node succ, + DataFlow::FlowLabel succlbl ) { predlbl instanceof UnsafePropLabel and succlbl = predlbl and ( // Step through `p -> x[p]` - exists(PropRead read | + exists(DataFlow::PropRead read | pred = read.getPropertyNameExpr().flow() and not read.(DynamicPropRead).hasDominatingAssignment() and succ = read @@ -276,29 +280,33 @@ class PropNameTracking extends DataFlow::Configuration { ) } - override predicate isBarrier(DataFlow::Node node) { - super.isBarrier(node) - or - node instanceof DataFlow::VarAccessBarrier + predicate isBarrier(DataFlow::Node node) { + node instanceof DataFlow::VarAccessBarrier or + node = DataFlow::MakeBarrierGuard::getABarrierNode() } +} - override predicate isBarrierGuard(DataFlow::BarrierGuardNode node) { - node instanceof DenyListEqualityGuard or - node instanceof AllowListEqualityGuard or - node instanceof HasOwnPropertyGuard or - node instanceof InExprGuard or - node instanceof InstanceOfGuard or - node instanceof TypeofGuard or - node instanceof DenyListInclusionGuard or - node instanceof AllowListInclusionGuard or - node instanceof IsPlainObjectGuard - } +module PropNameTracking = DataFlow::GlobalWithState; + +/** + * A barrier guard for prototype pollution. + */ +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 sanitizer guard of form `x === "__proto__"` or `x === "constructor"`. */ -class DenyListEqualityGuard extends DataFlow::LabeledBarrierGuardNode, ValueNode { +class DenyListEqualityGuard extends BarrierGuard, DataFlow::ValueNode { override EqualityTest astNode; string propName; @@ -307,7 +315,7 @@ class DenyListEqualityGuard extends DataFlow::LabeledBarrierGuardNode, ValueNode propName = unsafePropName() } - override predicate blocks(boolean outcome, Expr e, FlowLabel label) { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { e = astNode.getAnOperand() and outcome = astNode.getPolarity().booleanNot() and label = propName @@ -317,7 +325,7 @@ class DenyListEqualityGuard extends DataFlow::LabeledBarrierGuardNode, ValueNode /** * An equality test with something other than `__proto__` or `constructor`. */ -class AllowListEqualityGuard extends DataFlow::LabeledBarrierGuardNode, ValueNode { +class AllowListEqualityGuard extends BarrierGuard, DataFlow::ValueNode { override EqualityTest astNode; AllowListEqualityGuard() { @@ -325,7 +333,7 @@ class AllowListEqualityGuard extends DataFlow::LabeledBarrierGuardNode, ValueNod astNode.getAnOperand() instanceof Literal } - override predicate blocks(boolean outcome, Expr e, FlowLabel label) { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { e = astNode.getAnOperand() and outcome = astNode.getPolarity() and label instanceof UnsafePropLabel @@ -339,7 +347,7 @@ class AllowListEqualityGuard extends DataFlow::LabeledBarrierGuardNode, ValueNod * but the destination object generally doesn't. It is therefore only a sanitizer when * used on the destination object. */ -class HasOwnPropertyGuard extends DataFlow::BarrierGuardNode instanceof HasOwnPropertyCall { +class HasOwnPropertyGuard extends BarrierGuard instanceof HasOwnPropertyCall { HasOwnPropertyGuard() { // Try to avoid `src.hasOwnProperty` by requiring that the receiver // does not locally have its properties enumerated. Typically there is no @@ -347,7 +355,7 @@ class HasOwnPropertyGuard extends DataFlow::BarrierGuardNode instanceof HasOwnPr not arePropertiesEnumerated(super.getObject().getALocalSource()) } - override predicate blocks(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { e = super.getProperty().asExpr() and outcome = true } } @@ -358,7 +366,7 @@ class HasOwnPropertyGuard extends DataFlow::BarrierGuardNode instanceof HasOwnPr * Since `"__proto__" in obj` and `"constructor" in obj` is true for most objects, * this is seen as a sanitizer for `key` in the false outcome. */ -class InExprGuard extends DataFlow::BarrierGuardNode, DataFlow::ValueNode { +class InExprGuard extends BarrierGuard, DataFlow::ValueNode { override InExpr astNode; InExprGuard() { @@ -366,7 +374,7 @@ class InExprGuard extends DataFlow::BarrierGuardNode, DataFlow::ValueNode { not arePropertiesEnumerated(astNode.getRightOperand().flow().getALocalSource()) } - override predicate blocks(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { e = astNode.getLeftOperand() and outcome = false } } @@ -379,10 +387,10 @@ class InExprGuard extends DataFlow::BarrierGuardNode, DataFlow::ValueNode { * It is still possible to get to `Function.prototype` through `constructor.constructor.prototype` * so we do not block the `constructor` label. */ -class InstanceOfGuard extends DataFlow::LabeledBarrierGuardNode, DataFlow::ValueNode { +class InstanceOfGuard extends BarrierGuard, DataFlow::ValueNode { override InstanceOfExpr astNode; - override predicate blocks(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 = "__proto__" } } @@ -393,14 +401,14 @@ class InstanceOfGuard extends DataFlow::LabeledBarrierGuardNode, DataFlow::Value * The former blocks the `constructor` label as that payload must pass through a function, * and the latter blocks the `__proto__` label as that only passes through objects. */ -class TypeofGuard extends DataFlow::LabeledBarrierGuardNode, DataFlow::ValueNode { +class TypeofGuard extends BarrierGuard, DataFlow::ValueNode { override EqualityTest astNode; Expr operand; TypeofTag tag; TypeofGuard() { TaintTracking::isTypeofGuard(astNode, operand, tag) } - override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel label) { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { e = operand and outcome = astNode.getPolarity() and ( @@ -428,7 +436,7 @@ class TypeofGuard extends DataFlow::LabeledBarrierGuardNode, DataFlow::ValueNode /** * A check of form `["__proto__"].includes(x)` or similar. */ -class DenyListInclusionGuard extends DataFlow::LabeledBarrierGuardNode, InclusionTest { +class DenyListInclusionGuard extends BarrierGuard, InclusionTest { UnsafePropLabel label; DenyListInclusionGuard() { @@ -438,7 +446,7 @@ class DenyListInclusionGuard extends DataFlow::LabeledBarrierGuardNode, Inclusio ) } - override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { outcome = this.getPolarity().booleanNot() and e = this.getContainedNode().asExpr() and label = lbl @@ -448,7 +456,7 @@ class DenyListInclusionGuard extends DataFlow::LabeledBarrierGuardNode, Inclusio /** * A check of form `xs.includes(x)` or similar, which sanitizes `x` in the true case. */ -class AllowListInclusionGuard extends DataFlow::LabeledBarrierGuardNode { +class AllowListInclusionGuard extends BarrierGuard { AllowListInclusionGuard() { this instanceof TaintTracking::PositiveIndexOfSanitizer or @@ -456,7 +464,7 @@ class AllowListInclusionGuard extends DataFlow::LabeledBarrierGuardNode { not this = any(MembershipCandidate::ObjectPropertyNameMembershipCandidate c).getTest() // handled with more precision in `HasOwnPropertyGuard` } - override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { this.(TaintTracking::AdditionalSanitizerGuardNode).sanitizes(outcome, e) and lbl instanceof UnsafePropLabel } @@ -467,14 +475,14 @@ class AllowListInclusionGuard extends DataFlow::LabeledBarrierGuardNode { * payload in the true case, since it rejects objects with a non-standard `constructor` * property. */ -class IsPlainObjectGuard extends DataFlow::LabeledBarrierGuardNode, DataFlow::CallNode { +class IsPlainObjectGuard extends BarrierGuard, DataFlow::CallNode { IsPlainObjectGuard() { exists(string name | name = "is-plain-object" or name = "is-extendable" | - this = moduleImport(name).getACall() + this = DataFlow::moduleImport(name).getACall() ) } - override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { e = this.getArgument(0).asExpr() and outcome = true and lbl = "constructor" @@ -507,26 +515,26 @@ string deriveExprName(DataFlow::Node node) { * In most cases this will result in an alert, the exception being the case where * `base` does not have a prototype at all. */ -predicate isPrototypePollutingAssignment(Node base, Node prop, Node rhs, Node propNameSource) { +predicate isPrototypePollutingAssignment( + DataFlow::Node base, DataFlow::Node prop, DataFlow::Node rhs, DataFlow::Node propNameSource +) { dynamicPropWrite(base, prop, rhs) and isPollutedPropNameSource(propNameSource) and - exists(PropNameTracking cfg | - cfg.hasFlow(propNameSource, base) and - if propNameSource instanceof EnumeratedPropName - then - cfg.hasFlow(propNameSource, prop) and - cfg.hasFlow([propNameSource, AccessPath::getAnAliasedSourceNode(propNameSource)] - .(EnumeratedPropName) - .getASourceProp(), rhs) - else ( - cfg.hasFlow(propNameSource.(SplitPropName).getAnAlias(), prop) and - rhs.getALocalSource() instanceof ParameterNode - ) + PropNameTracking::flow(propNameSource, base) and + if propNameSource instanceof EnumeratedPropName + then + PropNameTracking::flow(propNameSource, prop) and + PropNameTracking::flow([propNameSource, AccessPath::getAnAliasedSourceNode(propNameSource)] + .(EnumeratedPropName) + .getASourceProp(), rhs) + else ( + PropNameTracking::flow(propNameSource.(SplitPropName).getAnAlias(), prop) and + rhs.getALocalSource() instanceof DataFlow::ParameterNode ) } /** Gets a data flow node leading to the base of a prototype-polluting assignment. */ -private DataFlow::SourceNode getANodeLeadingToBase(DataFlow::TypeBackTracker t, Node base) { +private DataFlow::SourceNode getANodeLeadingToBase(DataFlow::TypeBackTracker t, DataFlow::Node base) { t.start() and isPrototypePollutingAssignment(base, _, _, _) and result = base.getALocalSource() @@ -542,7 +550,9 @@ private DataFlow::SourceNode getANodeLeadingToBase(DataFlow::TypeBackTracker t, * This dynamic read is where the reference to a built-in prototype object is obtained, * and we need this to ensure that this object actually has a prototype. */ -private DataFlow::SourceNode getANodeLeadingToBaseBase(DataFlow::TypeBackTracker t, Node base) { +private DataFlow::SourceNode getANodeLeadingToBaseBase( + DataFlow::TypeBackTracker t, DataFlow::Node base +) { exists(DynamicPropRead read | read = getANodeLeadingToBase(t, base) and result = read.getBase().getALocalSource() @@ -553,29 +563,31 @@ private DataFlow::SourceNode getANodeLeadingToBaseBase(DataFlow::TypeBackTracker ) } -DataFlow::SourceNode getANodeLeadingToBaseBase(Node base) { +DataFlow::SourceNode getANodeLeadingToBaseBase(DataFlow::Node base) { result = getANodeLeadingToBaseBase(DataFlow::TypeBackTracker::end(), base) } /** A call to `Object.create(null)`. */ -class ObjectCreateNullCall extends CallNode { +class ObjectCreateNullCall extends DataFlow::CallNode { ObjectCreateNullCall() { - this = globalVarRef("Object").getAMemberCall("create") and + this = DataFlow::globalVarRef("Object").getAMemberCall("create") and this.getArgument(0).asExpr() instanceof NullLiteral } } +import DataFlow::DeduplicatePathGraph + from - PropNameTracking cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Node propNameSource, - Node base, string msg, Node col1, Node col2 + PathNode source, PathNode sink, DataFlow::Node propNameSource, DataFlow::Node base, string msg, + DataFlow::Node col1, DataFlow::Node col2 where isPollutedPropName(propNameSource) and - cfg.hasFlowPath(source, sink) and + PropNameTracking::flowPath(source.getAnOriginalPathNode(), sink.getAnOriginalPathNode()) and isPrototypePollutingAssignment(base, _, _, propNameSource) and sink.getNode() = base and source.getNode() = propNameSource and ( - getANodeLeadingToBaseBase(base) instanceof ObjectLiteralNode + getANodeLeadingToBaseBase(base) instanceof DataFlow::ObjectLiteralNode or not getANodeLeadingToBaseBase(base) instanceof ObjectCreateNullCall ) and diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/PrototypePollutingFunction.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/PrototypePollutingFunction.expected index 28a0fc8bd83..e9cf5fe90f6 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/PrototypePollutingFunction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/PrototypePollutingFunction.expected @@ -1,2838 +1,1088 @@ nodes -| examples/PrototypePollutingFunction.js:1:16:1:18 | dst | -| examples/PrototypePollutingFunction.js:1:16:1:18 | dst | -| examples/PrototypePollutingFunction.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | -| examples/PrototypePollutingFunction.js:5:19:5:21 | dst | -| examples/PrototypePollutingFunction.js:5:19:5:21 | dst | -| examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | -| examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | -| examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | -| examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | -| examples/PrototypePollutingFunction.js:5:23:5:25 | key | -| examples/PrototypePollutingFunction.js:5:23:5:25 | key | -| examples/PrototypePollutingFunction.js:5:29:5:31 | src | -| examples/PrototypePollutingFunction.js:5:29:5:31 | src | -| examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | -| examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | -| examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | -| examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | -| examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | -| examples/PrototypePollutingFunction.js:5:33:5:35 | key | -| examples/PrototypePollutingFunction.js:5:33:5:35 | key | -| examples/PrototypePollutingFunction.js:7:13:7:15 | dst | -| examples/PrototypePollutingFunction.js:7:13:7:15 | dst | -| examples/PrototypePollutingFunction.js:7:13:7:15 | dst | -| examples/PrototypePollutingFunction.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction.js:7:24:7:26 | src | -| examples/PrototypePollutingFunction.js:7:24:7:26 | src | -| examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction.js:7:28:7:30 | key | -| examples/PrototypePollutingFunction.js:7:28:7:30 | key | -| examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction_fixed2.js:6:29:6:31 | src | -| examples/PrototypePollutingFunction_fixed2.js:6:29:6:31 | src | -| examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:8:24:8:26 | src | -| examples/PrototypePollutingFunction_fixed2.js:8:24:8:26 | src | -| examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | -| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | -| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | -| examples/PrototypePollutingFunction_fixed.js:5:29:5:31 | src | -| examples/PrototypePollutingFunction_fixed.js:5:29:5:31 | src | -| examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction_fixed.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction_fixed.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction_fixed.js:7:24:7:26 | src | -| examples/PrototypePollutingFunction_fixed.js:7:24:7:26 | src | -| examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | -| examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | -| path-assignment.js:8:13:8:25 | key | -| path-assignment.js:8:13:8:25 | key | -| path-assignment.js:8:19:8:25 | keys[i] | -| path-assignment.js:8:19:8:25 | keys[i] | -| path-assignment.js:8:19:8:25 | keys[i] | -| path-assignment.js:13:13:13:32 | target | -| path-assignment.js:13:13:13:32 | target | -| path-assignment.js:13:22:13:27 | target | -| path-assignment.js:13:22:13:27 | target | -| path-assignment.js:13:22:13:32 | target[key] | -| path-assignment.js:13:22:13:32 | target[key] | -| path-assignment.js:13:29:13:31 | key | -| path-assignment.js:13:29:13:31 | key | -| path-assignment.js:15:13:15:18 | target | -| path-assignment.js:15:13:15:18 | target | -| path-assignment.js:15:13:15:18 | target | -| path-assignment.js:15:20:15:22 | key | -| path-assignment.js:15:20:15:22 | key | -| path-assignment.js:15:20:15:22 | key | -| path-assignment.js:41:13:41:25 | key | -| path-assignment.js:41:13:41:25 | key | -| path-assignment.js:41:19:41:25 | keys[i] | -| path-assignment.js:41:19:41:25 | keys[i] | -| path-assignment.js:41:19:41:25 | keys[i] | -| path-assignment.js:42:9:42:48 | target | -| path-assignment.js:42:9:42:48 | target | -| path-assignment.js:42:18:42:23 | target | -| path-assignment.js:42:18:42:23 | target | -| path-assignment.js:42:18:42:23 | target | -| path-assignment.js:42:18:42:48 | target[ ... ] \|\| {} | -| path-assignment.js:42:18:42:48 | target[ ... ] \|\| {} | -| path-assignment.js:42:25:42:27 | key | -| path-assignment.js:42:25:42:27 | key | -| path-assignment.js:42:25:42:27 | key | -| path-assignment.js:42:32:42:37 | target | -| path-assignment.js:42:32:42:37 | target | -| path-assignment.js:42:32:42:42 | target[key] | -| path-assignment.js:42:32:42:42 | target[key] | -| path-assignment.js:42:32:42:48 | target[key] \|\| {} | -| path-assignment.js:42:32:42:48 | target[key] \|\| {} | -| path-assignment.js:42:32:42:48 | target[key] \|\| {} | -| path-assignment.js:42:39:42:41 | key | -| path-assignment.js:42:39:42:41 | key | -| path-assignment.js:44:5:44:10 | target | -| path-assignment.js:44:5:44:10 | target | -| path-assignment.js:44:5:44:10 | target | -| path-assignment.js:44:12:44:18 | keys[i] | -| path-assignment.js:44:12:44:18 | keys[i] | -| path-assignment.js:44:12:44:18 | keys[i] | -| path-assignment.js:44:12:44:18 | keys[i] | -| path-assignment.js:58:13:58:25 | key | -| path-assignment.js:58:13:58:25 | key | -| path-assignment.js:58:19:58:25 | keys[i] | -| path-assignment.js:58:19:58:25 | keys[i] | -| path-assignment.js:58:19:58:25 | keys[i] | -| path-assignment.js:59:9:59:48 | target | -| path-assignment.js:59:9:59:48 | target | -| path-assignment.js:59:18:59:23 | target | -| path-assignment.js:59:18:59:23 | target | -| path-assignment.js:59:18:59:23 | target | -| path-assignment.js:59:18:59:48 | target[ ... ] \|\| {} | -| path-assignment.js:59:18:59:48 | target[ ... ] \|\| {} | -| path-assignment.js:59:25:59:27 | key | -| path-assignment.js:59:25:59:27 | key | -| path-assignment.js:59:25:59:27 | key | -| path-assignment.js:59:32:59:37 | target | -| path-assignment.js:59:32:59:37 | target | -| path-assignment.js:59:32:59:42 | target[key] | -| path-assignment.js:59:32:59:42 | target[key] | -| path-assignment.js:59:32:59:48 | target[key] \|\| {} | -| path-assignment.js:59:32:59:48 | target[key] \|\| {} | -| path-assignment.js:59:32:59:48 | target[key] \|\| {} | -| path-assignment.js:59:39:59:41 | key | -| path-assignment.js:59:39:59:41 | key | -| path-assignment.js:61:5:61:10 | target | -| path-assignment.js:61:5:61:10 | target | -| path-assignment.js:61:5:61:10 | target | -| path-assignment.js:61:12:61:18 | keys[i] | -| path-assignment.js:61:12:61:18 | keys[i] | -| path-assignment.js:61:12:61:18 | keys[i] | -| path-assignment.js:61:12:61:18 | keys[i] | -| path-assignment.js:68:13:68:25 | key | -| path-assignment.js:68:13:68:25 | key | -| path-assignment.js:68:19:68:25 | keys[i] | -| path-assignment.js:68:19:68:25 | keys[i] | -| path-assignment.js:68:19:68:25 | keys[i] | -| path-assignment.js:69:9:69:48 | target | -| path-assignment.js:69:9:69:48 | target | -| path-assignment.js:69:18:69:23 | target | -| path-assignment.js:69:18:69:23 | target | -| path-assignment.js:69:18:69:23 | target | -| path-assignment.js:69:18:69:48 | target[ ... ] \|\| {} | -| path-assignment.js:69:18:69:48 | target[ ... ] \|\| {} | -| path-assignment.js:69:25:69:27 | key | -| path-assignment.js:69:25:69:27 | key | -| path-assignment.js:69:25:69:27 | key | -| path-assignment.js:69:32:69:37 | target | -| path-assignment.js:69:32:69:37 | target | -| path-assignment.js:69:32:69:42 | target[key] | -| path-assignment.js:69:32:69:42 | target[key] | -| path-assignment.js:69:32:69:48 | target[key] \|\| {} | -| path-assignment.js:69:32:69:48 | target[key] \|\| {} | -| path-assignment.js:69:32:69:48 | target[key] \|\| {} | -| path-assignment.js:69:39:69:41 | key | -| path-assignment.js:69:39:69:41 | key | -| path-assignment.js:71:5:71:10 | target | -| path-assignment.js:71:5:71:10 | target | -| path-assignment.js:71:5:71:10 | target | -| path-assignment.js:71:12:71:18 | keys[i] | -| path-assignment.js:71:12:71:18 | keys[i] | -| path-assignment.js:71:12:71:18 | keys[i] | -| path-assignment.js:71:12:71:18 | keys[i] | -| tests.js:3:25:3:27 | dst | -| tests.js:3:25:3:27 | dst | -| tests.js:3:30:3:32 | src | -| tests.js:3:30:3:32 | src | -| tests.js:4:14:4:16 | key | -| tests.js:4:14:4:16 | key | -| tests.js:4:14:4:16 | key | -| tests.js:6:28:6:30 | dst | -| tests.js:6:28:6:30 | dst | -| tests.js:6:28:6:35 | dst[key] | -| tests.js:6:28:6:35 | dst[key] | -| tests.js:6:28:6:35 | dst[key] | -| tests.js:6:28:6:35 | dst[key] | -| tests.js:6:32:6:34 | key | -| tests.js:6:32:6:34 | key | -| tests.js:6:38:6:40 | src | -| tests.js:6:38:6:40 | src | -| tests.js:6:38:6:45 | src[key] | -| tests.js:6:38:6:45 | src[key] | -| tests.js:6:38:6:45 | src[key] | -| tests.js:6:38:6:45 | src[key] | -| tests.js:6:38:6:45 | src[key] | -| tests.js:6:42:6:44 | key | -| tests.js:6:42:6:44 | key | -| tests.js:8:13:8:15 | dst | -| tests.js:8:13:8:15 | dst | -| tests.js:8:13:8:15 | dst | -| tests.js:8:17:8:19 | key | -| tests.js:8:17:8:19 | key | -| tests.js:8:17:8:19 | key | -| tests.js:8:24:8:26 | src | -| tests.js:8:24:8:26 | src | -| tests.js:8:24:8:31 | src[key] | -| tests.js:8:24:8:31 | src[key] | -| tests.js:8:24:8:31 | src[key] | -| tests.js:8:24:8:31 | src[key] | -| tests.js:8:24:8:31 | src[key] | -| tests.js:8:24:8:31 | src[key] | -| tests.js:8:28:8:30 | key | -| tests.js:8:28:8:30 | key | -| tests.js:13:24:13:26 | dst | -| tests.js:13:24:13:26 | dst | -| tests.js:13:29:13:31 | src | -| tests.js:13:29:13:31 | src | -| tests.js:14:30:14:32 | key | -| tests.js:14:30:14:32 | key | -| tests.js:14:30:14:32 | key | -| tests.js:16:27:16:29 | dst | -| tests.js:16:27:16:29 | dst | -| tests.js:16:27:16:34 | dst[key] | -| tests.js:16:27:16:34 | dst[key] | -| tests.js:16:27:16:34 | dst[key] | -| tests.js:16:27:16:34 | dst[key] | -| tests.js:16:31:16:33 | key | -| tests.js:16:31:16:33 | key | -| tests.js:16:37:16:39 | src | -| tests.js:16:37:16:39 | src | -| tests.js:16:37:16:44 | src[key] | -| tests.js:16:37:16:44 | src[key] | -| tests.js:16:37:16:44 | src[key] | -| tests.js:16:37:16:44 | src[key] | -| tests.js:16:37:16:44 | src[key] | -| tests.js:16:41:16:43 | key | -| tests.js:16:41:16:43 | key | -| tests.js:18:13:18:15 | dst | -| tests.js:18:13:18:15 | dst | -| tests.js:18:13:18:15 | dst | -| tests.js:18:17:18:19 | key | -| tests.js:18:17:18:19 | key | -| tests.js:18:17:18:19 | key | -| tests.js:18:24:18:26 | src | -| tests.js:18:24:18:26 | src | -| tests.js:18:24:18:31 | src[key] | -| tests.js:18:24:18:31 | src[key] | -| tests.js:18:24:18:31 | src[key] | -| tests.js:18:24:18:31 | src[key] | -| tests.js:18:24:18:31 | src[key] | -| tests.js:18:24:18:31 | src[key] | -| tests.js:18:28:18:30 | key | -| tests.js:18:28:18:30 | key | -| tests.js:23:19:23:21 | dst | -| tests.js:23:19:23:21 | dst | -| tests.js:25:18:25:20 | key | -| tests.js:25:18:25:20 | key | -| tests.js:25:18:25:20 | key | -| tests.js:26:25:26:27 | dst | -| tests.js:26:25:26:27 | dst | -| tests.js:26:30:26:40 | source[key] | -| tests.js:26:30:26:40 | source[key] | -| tests.js:26:30:26:40 | source[key] | -| tests.js:26:37:26:39 | key | -| tests.js:26:37:26:39 | key | -| tests.js:26:43:26:45 | key | -| tests.js:26:43:26:45 | key | -| tests.js:31:22:31:24 | dst | -| tests.js:31:22:31:24 | dst | -| tests.js:31:27:31:31 | value | -| tests.js:31:27:31:31 | value | -| tests.js:31:34:31:36 | key | -| tests.js:31:34:31:36 | key | -| tests.js:32:9:32:27 | dstValue | -| tests.js:32:9:32:27 | dstValue | -| tests.js:32:20:32:22 | dst | -| tests.js:32:20:32:22 | dst | -| tests.js:32:20:32:27 | dst[key] | -| tests.js:32:20:32:27 | dst[key] | -| tests.js:32:24:32:26 | key | -| tests.js:32:24:32:26 | key | -| tests.js:34:18:34:25 | dstValue | -| tests.js:34:18:34:25 | dstValue | -| tests.js:36:9:36:11 | dst | -| tests.js:36:9:36:11 | dst | -| tests.js:36:9:36:11 | dst | -| tests.js:36:13:36:15 | key | -| tests.js:36:13:36:15 | key | -| tests.js:36:13:36:15 | key | -| tests.js:36:20:36:24 | value | -| tests.js:36:20:36:24 | value | -| tests.js:36:20:36:24 | value | -| tests.js:40:27:40:29 | dst | -| tests.js:40:32:40:34 | src | -| tests.js:40:32:40:34 | src | -| tests.js:41:14:41:16 | key | -| tests.js:41:14:41:16 | key | -| tests.js:44:30:44:32 | dst | -| tests.js:44:30:44:37 | dst[key] | -| tests.js:44:30:44:37 | dst[key] | -| tests.js:44:34:44:36 | key | -| tests.js:44:40:44:42 | src | -| tests.js:44:40:44:42 | src | -| tests.js:44:40:44:47 | src[key] | -| tests.js:44:40:44:47 | src[key] | -| tests.js:44:40:44:47 | src[key] | -| tests.js:44:40:44:47 | src[key] | -| tests.js:44:40:44:47 | src[key] | -| tests.js:44:44:44:46 | key | -| tests.js:46:13:46:15 | dst | -| tests.js:46:13:46:15 | dst | -| tests.js:46:17:46:19 | key | -| tests.js:46:17:46:19 | key | -| tests.js:46:24:46:26 | src | -| tests.js:46:24:46:26 | src | -| tests.js:46:24:46:31 | src[key] | -| tests.js:46:24:46:31 | src[key] | -| tests.js:46:24:46:31 | src[key] | -| tests.js:46:24:46:31 | src[key] | -| tests.js:46:24:46:31 | src[key] | -| tests.js:46:24:46:31 | src[key] | -| tests.js:46:28:46:30 | key | -| tests.js:51:26:51:28 | dst | -| tests.js:51:31:51:33 | src | -| tests.js:51:31:51:33 | src | -| tests.js:52:14:52:16 | key | -| tests.js:52:14:52:16 | key | -| tests.js:55:29:55:31 | dst | -| tests.js:55:29:55:36 | dst[key] | -| tests.js:55:29:55:36 | dst[key] | -| tests.js:55:33:55:35 | key | -| tests.js:55:39:55:41 | src | -| tests.js:55:39:55:41 | src | -| tests.js:55:39:55:46 | src[key] | -| tests.js:55:39:55:46 | src[key] | -| tests.js:55:39:55:46 | src[key] | -| tests.js:55:39:55:46 | src[key] | -| tests.js:55:39:55:46 | src[key] | -| tests.js:55:43:55:45 | key | -| tests.js:57:13:57:15 | dst | -| tests.js:57:13:57:15 | dst | -| tests.js:57:17:57:19 | key | -| tests.js:57:17:57:19 | key | -| tests.js:57:24:57:26 | src | -| tests.js:57:24:57:26 | src | -| tests.js:57:24:57:31 | src[key] | -| tests.js:57:24:57:31 | src[key] | -| tests.js:57:24:57:31 | src[key] | -| tests.js:57:24:57:31 | src[key] | -| tests.js:57:24:57:31 | src[key] | -| tests.js:57:24:57:31 | src[key] | -| tests.js:57:28:57:30 | key | -| tests.js:62:33:62:35 | src | -| tests.js:62:33:62:35 | src | -| tests.js:66:41:66:43 | src | -| tests.js:66:41:66:43 | src | -| tests.js:66:41:66:48 | src[key] | -| tests.js:66:41:66:48 | src[key] | -| tests.js:66:41:66:48 | src[key] | -| tests.js:66:41:66:48 | src[key] | -| tests.js:66:41:66:48 | src[key] | -| tests.js:68:24:68:26 | src | -| tests.js:68:24:68:26 | src | -| tests.js:68:24:68:31 | src[key] | -| tests.js:68:24:68:31 | src[key] | -| tests.js:68:24:68:31 | src[key] | -| tests.js:68:24:68:31 | src[key] | -| tests.js:68:24:68:31 | src[key] | -| tests.js:68:24:68:31 | src[key] | -| tests.js:77:27:77:29 | src | -| tests.js:77:27:77:29 | src | -| tests.js:81:39:81:41 | src | -| tests.js:81:39:81:41 | src | -| tests.js:81:39:81:46 | src[key] | -| tests.js:81:39:81:46 | src[key] | -| tests.js:81:39:81:46 | src[key] | -| tests.js:81:39:81:46 | src[key] | -| tests.js:81:39:81:46 | src[key] | -| tests.js:83:28:83:30 | src | -| tests.js:83:28:83:30 | src | -| tests.js:83:28:83:35 | src[key] | -| tests.js:83:28:83:35 | src[key] | -| tests.js:83:28:83:35 | src[key] | -| tests.js:83:28:83:35 | src[key] | -| tests.js:83:28:83:35 | src[key] | -| tests.js:83:28:83:35 | src[key] | -| tests.js:89:34:89:36 | src | -| tests.js:89:34:89:36 | src | -| tests.js:90:14:90:16 | key | -| tests.js:90:14:90:16 | key | -| tests.js:90:14:90:16 | key | -| tests.js:94:42:94:44 | src | -| tests.js:94:42:94:44 | src | -| tests.js:94:42:94:49 | src[key] | -| tests.js:94:42:94:49 | src[key] | -| tests.js:94:42:94:49 | src[key] | -| tests.js:94:42:94:49 | src[key] | -| tests.js:94:42:94:49 | src[key] | -| tests.js:96:17:96:19 | key | -| tests.js:96:17:96:19 | key | -| tests.js:96:17:96:19 | key | -| tests.js:96:24:96:26 | src | -| tests.js:96:24:96:26 | src | -| tests.js:96:24:96:31 | src[key] | -| tests.js:96:24:96:31 | src[key] | -| tests.js:96:24:96:31 | src[key] | -| tests.js:96:24:96:31 | src[key] | -| tests.js:96:24:96:31 | src[key] | -| tests.js:96:24:96:31 | src[key] | -| tests.js:96:28:96:30 | key | -| tests.js:96:28:96:30 | key | -| tests.js:101:32:101:34 | dst | -| tests.js:101:32:101:34 | dst | -| tests.js:101:37:101:39 | src | -| tests.js:101:37:101:39 | src | -| tests.js:102:14:102:16 | key | -| tests.js:102:14:102:16 | key | -| tests.js:102:14:102:16 | key | -| tests.js:107:35:107:37 | dst | -| tests.js:107:35:107:37 | dst | -| tests.js:107:35:107:42 | dst[key] | -| tests.js:107:35:107:42 | dst[key] | -| tests.js:107:35:107:42 | dst[key] | -| tests.js:107:35:107:42 | dst[key] | -| tests.js:107:39:107:41 | key | -| tests.js:107:39:107:41 | key | -| tests.js:107:45:107:47 | src | -| tests.js:107:45:107:47 | src | -| tests.js:107:45:107:52 | src[key] | -| tests.js:107:45:107:52 | src[key] | -| tests.js:107:45:107:52 | src[key] | -| tests.js:107:45:107:52 | src[key] | -| tests.js:107:45:107:52 | src[key] | -| tests.js:107:49:107:51 | key | -| tests.js:107:49:107:51 | key | -| tests.js:109:13:109:15 | dst | -| tests.js:109:13:109:15 | dst | -| tests.js:109:13:109:15 | dst | -| tests.js:109:17:109:19 | key | -| tests.js:109:17:109:19 | key | -| tests.js:109:17:109:19 | key | -| tests.js:109:24:109:26 | src | -| tests.js:109:24:109:26 | src | -| tests.js:109:24:109:31 | src[key] | -| tests.js:109:24:109:31 | src[key] | -| tests.js:109:24:109:31 | src[key] | -| tests.js:109:24:109:31 | src[key] | -| tests.js:109:24:109:31 | src[key] | -| tests.js:109:24:109:31 | src[key] | -| tests.js:109:28:109:30 | key | -| tests.js:109:28:109:30 | key | -| tests.js:116:41:116:43 | src | -| tests.js:116:41:116:43 | src | -| tests.js:117:14:117:16 | key | -| tests.js:117:14:117:16 | key | -| tests.js:117:14:117:16 | key | -| tests.js:119:49:119:51 | src | -| tests.js:119:49:119:51 | src | -| tests.js:119:49:119:56 | src[key] | -| tests.js:119:49:119:56 | src[key] | -| tests.js:119:49:119:56 | src[key] | -| tests.js:119:49:119:56 | src[key] | -| tests.js:119:49:119:56 | src[key] | -| tests.js:121:17:121:19 | key | -| tests.js:121:17:121:19 | key | -| tests.js:121:17:121:19 | key | -| tests.js:121:24:121:26 | src | -| tests.js:121:24:121:26 | src | -| tests.js:121:24:121:31 | src[key] | -| tests.js:121:24:121:31 | src[key] | -| tests.js:121:24:121:31 | src[key] | -| tests.js:121:24:121:31 | src[key] | -| tests.js:121:24:121:31 | src[key] | -| tests.js:121:24:121:31 | src[key] | -| tests.js:121:28:121:30 | key | -| tests.js:121:28:121:30 | key | -| tests.js:149:31:149:33 | dst | -| tests.js:149:31:149:33 | dst | -| tests.js:149:31:149:33 | dst | -| tests.js:149:31:149:33 | dst | -| tests.js:149:36:149:38 | src | -| tests.js:149:36:149:38 | src | -| tests.js:149:36:149:38 | src | -| tests.js:149:36:149:38 | src | -| tests.js:150:14:150:16 | key | -| tests.js:150:14:150:16 | key | -| tests.js:150:14:150:16 | key | -| tests.js:152:22:152:24 | dst | -| tests.js:152:22:152:24 | dst | -| tests.js:152:22:152:24 | dst | -| tests.js:152:22:152:24 | dst | -| tests.js:152:27:152:29 | src | -| tests.js:152:27:152:29 | src | -| tests.js:152:27:152:29 | src | -| tests.js:152:27:152:29 | src | -| tests.js:152:32:152:34 | key | -| tests.js:152:32:152:34 | key | -| tests.js:154:13:154:15 | dst | -| tests.js:154:13:154:15 | dst | -| tests.js:154:13:154:15 | dst | -| tests.js:154:13:154:15 | dst | -| tests.js:154:13:154:15 | dst | -| tests.js:154:17:154:19 | key | -| tests.js:154:17:154:19 | key | -| tests.js:154:17:154:19 | key | -| tests.js:154:24:154:26 | src | -| tests.js:154:24:154:26 | src | -| tests.js:154:24:154:26 | src | -| tests.js:154:24:154:26 | src | -| tests.js:154:24:154:31 | src[key] | -| tests.js:154:24:154:31 | src[key] | -| tests.js:154:24:154:31 | src[key] | -| tests.js:154:24:154:31 | src[key] | -| tests.js:154:24:154:31 | src[key] | -| tests.js:154:24:154:31 | src[key] | -| tests.js:154:24:154:31 | src[key] | -| tests.js:154:24:154:31 | src[key] | -| tests.js:154:28:154:30 | key | -| tests.js:154:28:154:30 | key | -| tests.js:159:36:159:38 | dst | -| tests.js:159:36:159:38 | dst | -| tests.js:159:36:159:38 | dst | -| tests.js:159:36:159:38 | dst | -| tests.js:159:41:159:43 | src | -| tests.js:159:41:159:43 | src | -| tests.js:159:41:159:43 | src | -| tests.js:159:41:159:43 | src | -| tests.js:160:26:160:28 | dst | -| tests.js:160:26:160:28 | dst | -| tests.js:160:26:160:28 | dst | -| tests.js:160:26:160:28 | dst | -| tests.js:160:31:160:33 | src | -| tests.js:160:31:160:33 | src | -| tests.js:160:31:160:33 | src | -| tests.js:160:31:160:33 | src | -| tests.js:160:37:160:39 | dst | -| tests.js:160:37:160:39 | dst | -| tests.js:160:37:160:39 | dst | -| tests.js:160:37:160:39 | dst | -| tests.js:160:42:160:44 | src | -| tests.js:160:42:160:44 | src | -| tests.js:160:42:160:44 | src | -| tests.js:160:42:160:44 | src | -| tests.js:160:47:160:49 | key | -| tests.js:160:47:160:49 | key | -| tests.js:160:47:160:49 | key | -| tests.js:160:47:160:49 | key | -| tests.js:161:35:161:37 | dst | -| tests.js:161:35:161:37 | dst | -| tests.js:161:35:161:37 | dst | -| tests.js:161:35:161:37 | dst | -| tests.js:161:35:161:42 | dst[key] | -| tests.js:161:35:161:42 | dst[key] | -| tests.js:161:35:161:42 | dst[key] | -| tests.js:161:35:161:42 | dst[key] | -| tests.js:161:39:161:41 | key | -| tests.js:161:39:161:41 | key | -| tests.js:161:39:161:41 | key | -| tests.js:161:39:161:41 | key | -| tests.js:161:45:161:47 | src | -| tests.js:161:45:161:47 | src | -| tests.js:161:45:161:47 | src | -| tests.js:161:45:161:47 | src | -| tests.js:161:45:161:52 | src[key] | -| tests.js:161:45:161:52 | src[key] | -| tests.js:161:45:161:52 | src[key] | -| tests.js:161:45:161:52 | src[key] | -| tests.js:161:49:161:51 | key | -| tests.js:161:49:161:51 | key | -| tests.js:161:49:161:51 | key | -| tests.js:161:49:161:51 | key | -| tests.js:165:37:165:39 | src | -| tests.js:165:37:165:39 | src | -| tests.js:166:14:166:16 | key | -| tests.js:166:14:166:16 | key | -| tests.js:166:14:166:16 | key | -| tests.js:169:45:169:47 | src | -| tests.js:169:45:169:47 | src | -| tests.js:169:45:169:52 | src[key] | -| tests.js:169:45:169:52 | src[key] | -| tests.js:169:45:169:52 | src[key] | -| tests.js:169:45:169:52 | src[key] | -| tests.js:169:45:169:52 | src[key] | -| tests.js:169:49:169:51 | key | -| tests.js:169:49:169:51 | key | -| tests.js:171:17:171:19 | key | -| tests.js:171:17:171:19 | key | -| tests.js:171:17:171:19 | key | -| tests.js:171:24:171:26 | src | -| tests.js:171:24:171:26 | src | -| tests.js:171:24:171:31 | src[key] | -| tests.js:171:24:171:31 | src[key] | -| tests.js:171:24:171:31 | src[key] | -| tests.js:171:24:171:31 | src[key] | -| tests.js:171:24:171:31 | src[key] | -| tests.js:171:24:171:31 | src[key] | -| tests.js:171:28:171:30 | key | -| tests.js:171:28:171:30 | key | -| tests.js:178:33:178:35 | src | -| tests.js:178:33:178:35 | src | -| tests.js:182:41:182:43 | src | -| tests.js:182:41:182:43 | src | -| tests.js:182:41:182:48 | src[key] | -| tests.js:182:41:182:48 | src[key] | -| tests.js:182:41:182:48 | src[key] | -| tests.js:182:41:182:48 | src[key] | -| tests.js:182:41:182:48 | src[key] | -| tests.js:184:24:184:26 | src | -| tests.js:184:24:184:26 | src | -| tests.js:184:24:184:31 | src[key] | -| tests.js:184:24:184:31 | src[key] | -| tests.js:184:24:184:31 | src[key] | -| tests.js:184:24:184:31 | src[key] | -| tests.js:184:24:184:31 | src[key] | -| tests.js:184:24:184:31 | src[key] | -| tests.js:189:32:189:34 | dst | -| tests.js:189:32:189:34 | dst | -| tests.js:189:37:189:39 | src | -| tests.js:189:37:189:39 | src | -| tests.js:192:13:192:25 | key | -| tests.js:192:13:192:25 | key | -| tests.js:192:19:192:25 | keys[i] | -| tests.js:192:19:192:25 | keys[i] | -| tests.js:192:19:192:25 | keys[i] | -| tests.js:194:35:194:37 | dst | -| tests.js:194:35:194:37 | dst | -| tests.js:194:35:194:42 | dst[key] | -| tests.js:194:35:194:42 | dst[key] | -| tests.js:194:35:194:42 | dst[key] | -| tests.js:194:35:194:42 | dst[key] | -| tests.js:194:39:194:41 | key | -| tests.js:194:39:194:41 | key | -| tests.js:194:45:194:47 | src | -| tests.js:194:45:194:47 | src | -| tests.js:194:45:194:52 | src[key] | -| tests.js:194:45:194:52 | src[key] | -| tests.js:194:45:194:52 | src[key] | -| tests.js:194:45:194:52 | src[key] | -| tests.js:194:45:194:52 | src[key] | -| tests.js:194:49:194:51 | key | -| tests.js:194:49:194:51 | key | -| tests.js:196:13:196:15 | dst | -| tests.js:196:13:196:15 | dst | -| tests.js:196:13:196:15 | dst | -| tests.js:196:17:196:19 | key | -| tests.js:196:17:196:19 | key | -| tests.js:196:17:196:19 | key | -| tests.js:196:24:196:26 | src | -| tests.js:196:24:196:26 | src | -| tests.js:196:24:196:31 | src[key] | -| tests.js:196:24:196:31 | src[key] | -| tests.js:196:24:196:31 | src[key] | -| tests.js:196:24:196:31 | src[key] | -| tests.js:196:24:196:31 | src[key] | -| tests.js:196:24:196:31 | src[key] | -| tests.js:196:28:196:30 | key | -| tests.js:196:28:196:30 | key | -| tests.js:201:39:201:41 | dst | -| tests.js:201:39:201:41 | dst | -| tests.js:201:44:201:46 | src | -| tests.js:201:44:201:46 | src | -| tests.js:206:42:206:44 | dst | -| tests.js:206:42:206:44 | dst | -| tests.js:206:42:206:53 | dst[keys[i]] | -| tests.js:206:42:206:53 | dst[keys[i]] | -| tests.js:206:42:206:53 | dst[keys[i]] | -| tests.js:206:42:206:53 | dst[keys[i]] | -| tests.js:206:46:206:52 | keys[i] | -| tests.js:206:46:206:52 | keys[i] | -| tests.js:206:46:206:52 | keys[i] | -| tests.js:206:56:206:58 | src | -| tests.js:206:56:206:58 | src | -| tests.js:206:56:206:67 | src[keys[i]] | -| tests.js:206:56:206:67 | src[keys[i]] | -| tests.js:206:56:206:67 | src[keys[i]] | -| tests.js:206:56:206:67 | src[keys[i]] | -| tests.js:206:56:206:67 | src[keys[i]] | -| tests.js:206:60:206:66 | keys[i] | -| tests.js:206:60:206:66 | keys[i] | -| tests.js:206:60:206:66 | keys[i] | -| tests.js:208:13:208:15 | dst | -| tests.js:208:13:208:15 | dst | -| tests.js:208:13:208:15 | dst | -| tests.js:208:17:208:23 | keys[i] | -| tests.js:208:17:208:23 | keys[i] | -| tests.js:208:17:208:23 | keys[i] | -| tests.js:208:17:208:23 | keys[i] | -| tests.js:208:28:208:30 | src | -| tests.js:208:28:208:30 | src | -| tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:32:208:38 | keys[i] | -| tests.js:208:32:208:38 | keys[i] | -| tests.js:208:32:208:38 | keys[i] | -| tests.js:213:23:213:26 | key1 | -| tests.js:213:23:213:26 | key1 | -| tests.js:213:29:213:32 | key2 | -| tests.js:213:29:213:32 | key2 | -| tests.js:213:35:213:39 | value | -| tests.js:213:35:213:39 | value | -| tests.js:217:5:217:13 | map[key1] | -| tests.js:217:5:217:13 | map[key1] | -| tests.js:217:5:217:13 | map[key1] | -| tests.js:217:9:217:12 | key1 | -| tests.js:217:9:217:12 | key1 | -| tests.js:217:15:217:18 | key2 | -| tests.js:217:15:217:18 | key2 | -| tests.js:217:15:217:18 | key2 | -| tests.js:217:23:217:27 | value | -| tests.js:217:23:217:27 | value | -| tests.js:217:23:217:27 | value | -| tests.js:223:14:223:16 | key | -| tests.js:223:14:223:16 | key | -| tests.js:223:14:223:16 | key | -| tests.js:224:23:224:25 | key | -| tests.js:224:23:224:25 | key | -| tests.js:224:33:224:41 | data[key] | -| tests.js:224:33:224:41 | data[key] | -| tests.js:224:33:224:41 | data[key] | -| tests.js:224:38:224:40 | key | -| tests.js:224:38:224:40 | key | -| tests.js:225:28:225:30 | key | -| tests.js:225:28:225:30 | key | -| tests.js:225:33:225:41 | data[key] | -| tests.js:225:33:225:41 | data[key] | -| tests.js:225:33:225:41 | data[key] | -| tests.js:225:38:225:40 | key | -| tests.js:225:38:225:40 | key | -| tests.js:229:26:229:29 | key1 | -| tests.js:229:26:229:29 | key1 | -| tests.js:229:32:229:35 | key2 | -| tests.js:229:32:229:35 | key2 | -| tests.js:229:38:229:42 | value | -| tests.js:229:38:229:42 | value | -| tests.js:233:5:233:13 | map[key1] | -| tests.js:233:5:233:13 | map[key1] | -| tests.js:233:5:233:13 | map[key1] | -| tests.js:233:9:233:12 | key1 | -| tests.js:233:9:233:12 | key1 | -| tests.js:233:15:233:18 | key2 | -| tests.js:233:15:233:18 | key2 | -| tests.js:233:15:233:18 | key2 | -| tests.js:233:23:233:27 | value | -| tests.js:233:23:233:27 | value | -| tests.js:233:23:233:27 | value | -| tests.js:238:14:238:16 | key | -| tests.js:238:14:238:16 | key | -| tests.js:238:14:238:16 | key | -| tests.js:239:24:239:26 | key | -| tests.js:239:24:239:26 | key | -| tests.js:239:34:239:42 | data[key] | -| tests.js:239:34:239:42 | data[key] | -| tests.js:239:34:239:42 | data[key] | -| tests.js:239:39:239:41 | key | -| tests.js:239:39:239:41 | key | -| tests.js:240:31:240:33 | key | -| tests.js:240:31:240:33 | key | -| tests.js:240:36:240:44 | data[key] | -| tests.js:240:36:240:44 | data[key] | -| tests.js:240:36:240:44 | data[key] | -| tests.js:240:41:240:43 | key | -| tests.js:240:41:240:43 | key | -| tests.js:263:27:263:29 | dst | -| tests.js:263:27:263:29 | dst | -| tests.js:265:13:265:26 | key | -| tests.js:265:13:265:26 | key | -| tests.js:265:19:265:26 | entry[0] | -| tests.js:265:19:265:26 | entry[0] | -| tests.js:265:19:265:26 | entry[0] | -| tests.js:266:13:266:28 | value | -| tests.js:266:13:266:28 | value | -| tests.js:266:21:266:28 | entry[1] | -| tests.js:266:21:266:28 | entry[1] | -| tests.js:266:21:266:28 | entry[1] | -| tests.js:268:30:268:32 | dst | -| tests.js:268:30:268:32 | dst | -| tests.js:268:30:268:37 | dst[key] | -| tests.js:268:30:268:37 | dst[key] | -| tests.js:268:30:268:37 | dst[key] | -| tests.js:268:30:268:37 | dst[key] | -| tests.js:268:34:268:36 | key | -| tests.js:268:34:268:36 | key | -| tests.js:270:13:270:15 | dst | -| tests.js:270:13:270:15 | dst | -| tests.js:270:13:270:15 | dst | -| tests.js:270:17:270:19 | key | -| tests.js:270:17:270:19 | key | -| tests.js:270:17:270:19 | key | -| tests.js:270:24:270:28 | value | -| tests.js:270:24:270:28 | value | -| tests.js:270:24:270:28 | value | -| tests.js:275:27:275:29 | dst | -| tests.js:275:27:275:29 | dst | -| tests.js:275:32:275:34 | src | -| tests.js:275:32:275:34 | src | -| tests.js:276:34:276:36 | key | -| tests.js:276:34:276:36 | key | -| tests.js:276:34:276:36 | key | -| tests.js:278:30:278:32 | dst | -| tests.js:278:30:278:32 | dst | -| tests.js:278:30:278:37 | dst[key] | -| tests.js:278:30:278:37 | dst[key] | -| tests.js:278:30:278:37 | dst[key] | -| tests.js:278:30:278:37 | dst[key] | -| tests.js:278:34:278:36 | key | -| tests.js:278:34:278:36 | key | -| tests.js:278:40:278:42 | src | -| tests.js:278:40:278:42 | src | -| tests.js:278:40:278:47 | src[key] | -| tests.js:278:40:278:47 | src[key] | -| tests.js:278:40:278:47 | src[key] | -| tests.js:278:40:278:47 | src[key] | -| tests.js:278:40:278:47 | src[key] | -| tests.js:278:44:278:46 | key | -| tests.js:278:44:278:46 | key | -| tests.js:280:13:280:15 | dst | -| tests.js:280:13:280:15 | dst | -| tests.js:280:13:280:15 | dst | -| tests.js:280:17:280:19 | key | -| tests.js:280:17:280:19 | key | -| tests.js:280:17:280:19 | key | -| tests.js:280:24:280:26 | src | -| tests.js:280:24:280:26 | src | -| tests.js:280:24:280:31 | src[key] | -| tests.js:280:24:280:31 | src[key] | -| tests.js:280:24:280:31 | src[key] | -| tests.js:280:24:280:31 | src[key] | -| tests.js:280:24:280:31 | src[key] | -| tests.js:280:24:280:31 | src[key] | -| tests.js:280:28:280:30 | key | -| tests.js:280:28:280:30 | key | -| tests.js:301:27:301:29 | dst | -| tests.js:301:27:301:29 | dst | -| tests.js:301:32:301:34 | src | -| tests.js:302:14:302:16 | key | -| tests.js:302:14:302:16 | key | -| tests.js:302:14:302:16 | key | -| tests.js:304:17:304:32 | value | -| tests.js:304:17:304:32 | value | -| tests.js:304:17:304:32 | value | -| tests.js:304:25:304:27 | src | -| tests.js:304:25:304:32 | src[key] | -| tests.js:304:25:304:32 | src[key] | -| tests.js:304:25:304:32 | src[key] | -| tests.js:304:25:304:32 | src[key] | -| tests.js:304:29:304:31 | key | -| tests.js:304:29:304:31 | key | -| tests.js:306:34:306:36 | dst | -| tests.js:306:34:306:36 | dst | -| tests.js:306:34:306:41 | dst[key] | -| tests.js:306:34:306:41 | dst[key] | -| tests.js:306:34:306:41 | dst[key] | -| tests.js:306:34:306:41 | dst[key] | -| tests.js:306:38:306:40 | key | -| tests.js:306:38:306:40 | key | -| tests.js:306:44:306:48 | value | -| tests.js:306:44:306:48 | value | -| tests.js:308:17:308:19 | dst | -| tests.js:308:17:308:19 | dst | -| tests.js:308:17:308:19 | dst | -| tests.js:308:21:308:23 | key | -| tests.js:308:21:308:23 | key | -| tests.js:308:21:308:23 | key | -| tests.js:308:28:308:32 | value | -| tests.js:308:28:308:32 | value | -| tests.js:308:28:308:32 | value | -| tests.js:308:28:308:32 | value | -| tests.js:314:31:314:33 | dst | -| tests.js:314:31:314:33 | dst | -| tests.js:314:36:314:38 | src | -| tests.js:315:14:315:16 | key | -| tests.js:315:14:315:16 | key | -| tests.js:315:14:315:16 | key | -| tests.js:318:17:318:32 | value | -| tests.js:318:17:318:32 | value | -| tests.js:318:17:318:32 | value | -| tests.js:318:25:318:27 | src | -| tests.js:318:25:318:32 | src[key] | -| tests.js:318:25:318:32 | src[key] | -| tests.js:318:25:318:32 | src[key] | -| tests.js:318:25:318:32 | src[key] | -| tests.js:318:29:318:31 | key | -| tests.js:318:29:318:31 | key | -| tests.js:320:38:320:40 | dst | -| tests.js:320:38:320:40 | dst | -| tests.js:320:38:320:45 | dst[key] | -| tests.js:320:38:320:45 | dst[key] | -| tests.js:320:38:320:45 | dst[key] | -| tests.js:320:38:320:45 | dst[key] | -| tests.js:320:42:320:44 | key | -| tests.js:320:42:320:44 | key | -| tests.js:320:48:320:52 | value | -| tests.js:320:48:320:52 | value | -| tests.js:322:17:322:19 | dst | -| tests.js:322:17:322:19 | dst | -| tests.js:322:17:322:19 | dst | -| tests.js:322:21:322:23 | key | -| tests.js:322:21:322:23 | key | -| tests.js:322:21:322:23 | key | -| tests.js:322:28:322:32 | value | -| tests.js:322:28:322:32 | value | -| tests.js:322:28:322:32 | value | -| tests.js:322:28:322:32 | value | -| tests.js:328:30:328:32 | src | -| tests.js:328:30:328:32 | src | -| tests.js:336:42:336:44 | src | -| tests.js:336:42:336:44 | src | -| tests.js:336:42:336:49 | src[key] | -| tests.js:336:42:336:49 | src[key] | -| tests.js:336:42:336:49 | src[key] | -| tests.js:336:42:336:49 | src[key] | -| tests.js:336:42:336:49 | src[key] | -| tests.js:338:28:338:30 | src | -| tests.js:338:28:338:30 | src | -| tests.js:338:28:338:35 | src[key] | -| tests.js:338:28:338:35 | src[key] | -| tests.js:338:28:338:35 | src[key] | -| tests.js:338:28:338:35 | src[key] | -| tests.js:338:28:338:35 | src[key] | -| tests.js:338:28:338:35 | src[key] | -| tests.js:348:32:348:37 | target | -| tests.js:348:40:348:45 | source | -| tests.js:350:37:350:39 | key | -| tests.js:350:37:350:39 | key | -| tests.js:355:17:355:22 | target | -| tests.js:355:17:355:22 | target | -| tests.js:355:24:355:26 | key | -| tests.js:355:24:355:26 | key | -| tests.js:355:31:355:86 | mergePl ... ptions) | -| tests.js:355:31:355:86 | mergePl ... ptions) | -| tests.js:355:31:355:86 | mergePl ... ptions) | -| tests.js:355:53:355:58 | target | -| tests.js:355:53:355:63 | target[key] | -| tests.js:355:53:355:63 | target[key] | -| tests.js:355:60:355:62 | key | -| tests.js:355:66:355:71 | source | -| tests.js:355:66:355:76 | source[key] | -| tests.js:355:66:355:76 | source[key] | -| tests.js:355:66:355:76 | source[key] | -| tests.js:357:17:357:22 | target | -| tests.js:357:17:357:22 | target | -| tests.js:357:24:357:26 | key | -| tests.js:357:24:357:26 | key | -| tests.js:357:31:357:36 | source | -| tests.js:357:31:357:41 | source[key] | -| tests.js:357:31:357:41 | source[key] | -| tests.js:357:31:357:41 | source[key] | -| tests.js:357:31:357:41 | source[key] | -| tests.js:357:31:357:41 | source[key] | -| tests.js:357:38:357:40 | key | -| tests.js:364:49:364:54 | source | -| tests.js:366:18:366:20 | key | -| tests.js:366:18:366:20 | key | -| tests.js:371:24:371:26 | key | -| tests.js:371:24:371:26 | key | -| tests.js:371:31:371:95 | mergePl ... ptions) | -| tests.js:371:31:371:95 | mergePl ... ptions) | -| tests.js:371:62:371:72 | target[key] | -| tests.js:371:69:371:71 | key | -| tests.js:371:75:371:80 | source | -| tests.js:371:75:371:85 | source[key] | -| tests.js:371:75:371:85 | source[key] | -| tests.js:371:75:371:85 | source[key] | -| tests.js:373:24:373:26 | key | -| tests.js:373:24:373:26 | key | -| tests.js:373:31:373:36 | source | -| tests.js:373:31:373:41 | source[key] | -| tests.js:373:31:373:41 | source[key] | -| tests.js:373:31:373:41 | source[key] | -| tests.js:373:31:373:41 | source[key] | -| tests.js:373:31:373:41 | source[key] | -| tests.js:373:38:373:40 | key | -| tests.js:381:14:381:16 | key | -| tests.js:381:14:381:16 | key | -| tests.js:381:14:381:16 | key | -| tests.js:383:22:383:24 | key | -| tests.js:383:22:383:24 | key | -| tests.js:383:27:383:34 | obj[key] | -| tests.js:383:27:383:34 | obj[key] | -| tests.js:383:27:383:34 | obj[key] | -| tests.js:383:31:383:33 | key | -| tests.js:383:31:383:33 | key | -| tests.js:388:29:388:31 | dst | -| tests.js:388:29:388:31 | dst | -| tests.js:388:34:388:36 | src | -| tests.js:388:34:388:36 | src | -| tests.js:389:22:389:24 | key | -| tests.js:389:22:389:24 | key | -| tests.js:391:32:391:34 | dst | -| tests.js:391:32:391:34 | dst | -| tests.js:391:32:391:39 | dst[key] | -| tests.js:391:32:391:39 | dst[key] | -| tests.js:391:36:391:38 | key | -| tests.js:391:36:391:38 | key | -| tests.js:391:42:391:44 | src | -| tests.js:391:42:391:44 | src | -| tests.js:391:42:391:49 | src[key] | -| tests.js:391:42:391:49 | src[key] | -| tests.js:391:46:391:48 | key | -| tests.js:391:46:391:48 | key | -| tests.js:393:13:393:15 | dst | -| tests.js:393:13:393:15 | dst | -| tests.js:393:13:393:15 | dst | -| tests.js:393:17:393:19 | key | -| tests.js:393:17:393:19 | key | -| tests.js:393:17:393:19 | key | -| tests.js:393:24:393:26 | src | -| tests.js:393:24:393:26 | src | -| tests.js:393:24:393:31 | src[key] | -| tests.js:393:24:393:31 | src[key] | -| tests.js:393:24:393:31 | src[key] | -| tests.js:393:28:393:30 | key | -| tests.js:393:28:393:30 | key | -| tests.js:398:30:398:32 | dst | -| tests.js:398:30:398:32 | dst | -| tests.js:398:35:398:37 | src | -| tests.js:398:35:398:37 | src | -| tests.js:399:17:399:19 | src | -| tests.js:399:17:399:19 | src | -| tests.js:399:23:399:25 | key | -| tests.js:399:23:399:25 | key | -| tests.js:399:28:399:32 | value | -| tests.js:399:28:399:32 | value | -| tests.js:401:33:401:35 | dst | -| tests.js:401:33:401:35 | dst | -| tests.js:401:33:401:40 | dst[key] | -| tests.js:401:33:401:40 | dst[key] | -| tests.js:401:37:401:39 | key | -| tests.js:401:37:401:39 | key | -| tests.js:401:43:401:47 | value | -| tests.js:401:43:401:47 | value | -| tests.js:403:13:403:15 | dst | -| tests.js:403:13:403:15 | dst | -| tests.js:403:13:403:15 | dst | -| tests.js:403:17:403:19 | key | -| tests.js:403:17:403:19 | key | -| tests.js:403:17:403:19 | key | -| tests.js:403:24:403:28 | value | -| tests.js:403:24:403:28 | value | -| tests.js:403:24:403:28 | value | -| tests.js:412:31:412:33 | dst | -| tests.js:412:31:412:33 | dst | -| tests.js:412:36:412:38 | src | -| tests.js:412:36:412:38 | src | -| tests.js:413:14:413:16 | key | -| tests.js:413:14:413:16 | key | -| tests.js:413:14:413:16 | key | -| tests.js:414:13:414:41 | value | -| tests.js:414:13:414:41 | value | -| tests.js:414:13:414:41 | value | -| tests.js:414:13:414:41 | value | -| tests.js:414:21:414:41 | wrapped ... c, key) | -| tests.js:414:21:414:41 | wrapped ... c, key) | -| tests.js:414:21:414:41 | wrapped ... c, key) | -| tests.js:414:21:414:41 | wrapped ... c, key) | -| tests.js:414:21:414:41 | wrapped ... c, key) | -| tests.js:414:33:414:35 | src | -| tests.js:414:33:414:35 | src | -| tests.js:414:38:414:40 | key | -| tests.js:414:38:414:40 | key | -| tests.js:415:13:415:42 | target | -| tests.js:415:13:415:42 | target | -| tests.js:415:13:415:42 | target | -| tests.js:415:13:415:42 | target | -| tests.js:415:22:415:42 | wrapped ... t, key) | -| tests.js:415:22:415:42 | wrapped ... t, key) | -| tests.js:415:22:415:42 | wrapped ... t, key) | -| tests.js:415:22:415:42 | wrapped ... t, key) | -| tests.js:415:34:415:36 | dst | -| tests.js:415:34:415:36 | dst | -| tests.js:415:39:415:41 | key | -| tests.js:415:39:415:41 | key | -| tests.js:417:34:417:39 | target | -| tests.js:417:34:417:39 | target | -| tests.js:417:34:417:39 | target | -| tests.js:417:34:417:39 | target | -| tests.js:417:42:417:46 | value | -| tests.js:417:42:417:46 | value | -| tests.js:417:42:417:46 | value | -| tests.js:417:42:417:46 | value | -| tests.js:419:13:419:15 | dst | -| tests.js:419:13:419:15 | dst | -| tests.js:419:13:419:15 | dst | -| tests.js:419:17:419:19 | key | -| tests.js:419:17:419:19 | key | -| tests.js:419:17:419:19 | key | -| tests.js:419:24:419:28 | value | -| tests.js:419:24:419:28 | value | -| tests.js:419:24:419:28 | value | -| tests.js:419:24:419:28 | value | -| tests.js:419:24:419:28 | value | -| tests.js:429:34:429:36 | dst | -| tests.js:429:39:429:41 | src | -| tests.js:429:39:429:41 | src | -| tests.js:430:14:430:16 | key | -| tests.js:430:14:430:16 | key | -| tests.js:430:14:430:16 | key | -| tests.js:431:13:431:44 | value | -| tests.js:431:13:431:44 | value | -| tests.js:431:13:431:44 | value | -| tests.js:431:13:431:44 | value | -| tests.js:431:21:431:44 | almostS ... c, key) | -| tests.js:431:21:431:44 | almostS ... c, key) | -| tests.js:431:21:431:44 | almostS ... c, key) | -| tests.js:431:21:431:44 | almostS ... c, key) | -| tests.js:431:21:431:44 | almostS ... c, key) | -| tests.js:431:36:431:38 | src | -| tests.js:431:36:431:38 | src | -| tests.js:431:41:431:43 | key | -| tests.js:432:13:432:45 | target | -| tests.js:432:13:432:45 | target | -| tests.js:432:22:432:45 | almostS ... t, key) | -| tests.js:432:22:432:45 | almostS ... t, key) | -| tests.js:432:37:432:39 | dst | -| tests.js:432:42:432:44 | key | -| tests.js:434:37:434:42 | target | -| tests.js:434:37:434:42 | target | -| tests.js:434:45:434:49 | value | -| tests.js:434:45:434:49 | value | -| tests.js:434:45:434:49 | value | -| tests.js:434:45:434:49 | value | -| tests.js:436:13:436:15 | dst | -| tests.js:436:13:436:15 | dst | -| tests.js:436:17:436:19 | key | -| tests.js:436:17:436:19 | key | -| tests.js:436:17:436:19 | key | -| tests.js:436:24:436:28 | value | -| tests.js:436:24:436:28 | value | -| tests.js:436:24:436:28 | value | -| tests.js:436:24:436:28 | value | -| tests.js:436:24:436:28 | value | -| tests.js:446:33:446:35 | src | -| tests.js:446:33:446:35 | src | -| tests.js:447:14:447:16 | key | -| tests.js:447:14:447:16 | key | -| tests.js:447:14:447:16 | key | -| tests.js:448:13:448:38 | value | -| tests.js:448:13:448:38 | value | -| tests.js:448:13:448:38 | value | -| tests.js:448:13:448:38 | value | -| tests.js:448:21:448:38 | safeRead(src, key) | -| tests.js:448:21:448:38 | safeRead(src, key) | -| tests.js:448:21:448:38 | safeRead(src, key) | -| tests.js:448:21:448:38 | safeRead(src, key) | -| tests.js:448:21:448:38 | safeRead(src, key) | -| tests.js:448:30:448:32 | src | -| tests.js:448:30:448:32 | src | -| tests.js:451:39:451:43 | value | -| tests.js:451:39:451:43 | value | -| tests.js:451:39:451:43 | value | -| tests.js:451:39:451:43 | value | -| tests.js:453:17:453:19 | key | -| tests.js:453:17:453:19 | key | -| tests.js:453:17:453:19 | key | -| tests.js:453:24:453:28 | value | -| tests.js:453:24:453:28 | value | -| tests.js:453:24:453:28 | value | -| tests.js:453:24:453:28 | value | -| tests.js:453:24:453:28 | value | -| tests.js:458:26:458:28 | dst | -| tests.js:458:26:458:28 | dst | -| tests.js:458:31:458:33 | src | -| tests.js:458:31:458:33 | src | -| tests.js:460:18:460:22 | value | -| tests.js:460:18:460:22 | value | -| tests.js:460:18:460:22 | value | -| tests.js:460:25:460:27 | key | -| tests.js:460:25:460:27 | key | -| tests.js:460:25:460:27 | key | -| tests.js:462:29:462:31 | dst | -| tests.js:462:29:462:31 | dst | -| tests.js:462:29:462:36 | dst[key] | -| tests.js:462:29:462:36 | dst[key] | -| tests.js:462:29:462:36 | dst[key] | -| tests.js:462:29:462:36 | dst[key] | -| tests.js:462:33:462:35 | key | -| tests.js:462:33:462:35 | key | -| tests.js:462:39:462:41 | src | -| tests.js:462:39:462:41 | src | -| tests.js:462:39:462:46 | src[key] | -| tests.js:462:39:462:46 | src[key] | -| tests.js:462:39:462:46 | src[key] | -| tests.js:462:39:462:46 | src[key] | -| tests.js:462:39:462:46 | src[key] | -| tests.js:462:43:462:45 | key | -| tests.js:462:43:462:45 | key | -| tests.js:465:30:465:32 | dst | -| tests.js:465:30:465:32 | dst | -| tests.js:465:30:465:32 | dst | -| tests.js:465:34:465:36 | key | -| tests.js:465:34:465:36 | key | -| tests.js:465:34:465:36 | key | -| tests.js:465:41:465:43 | src | -| tests.js:465:41:465:43 | src | -| tests.js:465:41:465:48 | src[key] | -| tests.js:465:41:465:48 | src[key] | -| tests.js:465:41:465:48 | src[key] | -| tests.js:465:41:465:48 | src[key] | -| tests.js:465:41:465:48 | src[key] | -| tests.js:465:41:465:48 | src[key] | -| tests.js:465:45:465:47 | key | -| tests.js:465:45:465:47 | key | -| tests.js:466:30:466:32 | dst | -| tests.js:466:30:466:32 | dst | -| tests.js:466:30:466:32 | dst | -| tests.js:466:34:466:36 | key | -| tests.js:466:34:466:36 | key | -| tests.js:466:34:466:36 | key | -| tests.js:466:41:466:46 | o[key] | -| tests.js:466:41:466:46 | o[key] | -| tests.js:466:41:466:46 | o[key] | -| tests.js:466:41:466:46 | o[key] | -| tests.js:466:43:466:45 | key | -| tests.js:466:43:466:45 | key | -| tests.js:467:30:467:32 | dst | -| tests.js:467:30:467:32 | dst | -| tests.js:467:30:467:32 | dst | -| tests.js:467:34:467:36 | key | -| tests.js:467:34:467:36 | key | -| tests.js:467:34:467:36 | key | -| tests.js:467:41:467:45 | value | -| tests.js:467:41:467:45 | value | -| tests.js:467:41:467:45 | value | -| tests.js:472:38:472:40 | dst | -| tests.js:472:38:472:40 | dst | -| tests.js:473:18:473:22 | value | -| tests.js:473:18:473:22 | value | -| tests.js:473:18:473:22 | value | -| tests.js:473:25:473:27 | key | -| tests.js:473:25:473:27 | key | -| tests.js:473:25:473:27 | key | -| tests.js:475:41:475:43 | dst | -| tests.js:475:41:475:43 | dst | -| tests.js:475:41:475:48 | dst[key] | -| tests.js:475:41:475:48 | dst[key] | -| tests.js:475:41:475:48 | dst[key] | -| tests.js:475:41:475:48 | dst[key] | -| tests.js:475:45:475:47 | key | -| tests.js:475:45:475:47 | key | -| tests.js:477:13:477:15 | dst | -| tests.js:477:13:477:15 | dst | -| tests.js:477:13:477:15 | dst | -| tests.js:477:17:477:19 | key | -| tests.js:477:17:477:19 | key | -| tests.js:477:17:477:19 | key | -| tests.js:477:24:477:28 | value | -| tests.js:477:24:477:28 | value | -| tests.js:477:24:477:28 | value | -| tests.js:483:26:483:28 | dst | -| tests.js:483:31:483:33 | src | -| tests.js:483:31:483:33 | src | -| tests.js:484:14:484:16 | key | -| tests.js:484:14:484:16 | key | -| tests.js:487:29:487:31 | dst | -| tests.js:487:29:487:36 | dst[key] | -| tests.js:487:29:487:36 | dst[key] | -| tests.js:487:33:487:35 | key | -| tests.js:487:39:487:41 | src | -| tests.js:487:39:487:46 | src[key] | -| tests.js:487:39:487:46 | src[key] | -| tests.js:487:39:487:46 | src[key] | -| tests.js:487:39:487:46 | src[key] | -| tests.js:487:43:487:45 | key | -| tests.js:489:13:489:15 | dst | -| tests.js:489:13:489:15 | dst | -| tests.js:489:17:489:19 | key | -| tests.js:489:17:489:19 | key | -| tests.js:489:24:489:26 | src | -| tests.js:489:24:489:26 | src | -| tests.js:489:24:489:31 | src[key] | -| tests.js:489:24:489:31 | src[key] | -| tests.js:489:24:489:31 | src[key] | -| tests.js:489:24:489:31 | src[key] | -| tests.js:489:24:489:31 | src[key] | -| tests.js:489:24:489:31 | src[key] | -| tests.js:489:28:489:30 | key | -| tests.js:494:32:494:34 | src | -| tests.js:495:14:495:16 | key | -| tests.js:495:14:495:16 | key | -| tests.js:498:13:498:28 | value | -| tests.js:498:13:498:28 | value | -| tests.js:498:13:498:28 | value | -| tests.js:498:21:498:23 | src | -| tests.js:498:21:498:28 | src[key] | -| tests.js:498:21:498:28 | src[key] | -| tests.js:498:21:498:28 | src[key] | -| tests.js:498:21:498:28 | src[key] | -| tests.js:498:25:498:27 | key | -| tests.js:500:38:500:42 | value | -| tests.js:500:38:500:42 | value | -| tests.js:502:17:502:19 | key | -| tests.js:502:17:502:19 | key | -| tests.js:502:24:502:28 | value | -| tests.js:502:24:502:28 | value | -| tests.js:502:24:502:28 | value | -| tests.js:502:24:502:28 | value | -| tests.js:508:30:508:32 | dst | -| tests.js:508:30:508:32 | dst | -| tests.js:508:35:508:37 | src | -| tests.js:508:35:508:37 | src | -| tests.js:511:13:511:25 | key | -| tests.js:511:13:511:25 | key | -| tests.js:511:19:511:25 | keys[i] | -| tests.js:511:19:511:25 | keys[i] | -| tests.js:511:19:511:25 | keys[i] | -| tests.js:513:33:513:35 | dst | -| tests.js:513:33:513:35 | dst | -| tests.js:513:33:513:40 | dst[key] | -| tests.js:513:33:513:40 | dst[key] | -| tests.js:513:33:513:40 | dst[key] | -| tests.js:513:33:513:40 | dst[key] | -| tests.js:513:37:513:39 | key | -| tests.js:513:37:513:39 | key | -| tests.js:513:43:513:45 | src | -| tests.js:513:43:513:45 | src | -| tests.js:513:43:513:50 | src[key] | -| tests.js:513:43:513:50 | src[key] | -| tests.js:513:43:513:50 | src[key] | -| tests.js:513:43:513:50 | src[key] | -| tests.js:513:43:513:50 | src[key] | -| tests.js:513:47:513:49 | key | -| tests.js:513:47:513:49 | key | -| tests.js:516:32:516:34 | src | -| tests.js:516:32:516:34 | src | -| tests.js:516:32:516:39 | src[key] | -| tests.js:516:32:516:39 | src[key] | -| tests.js:516:32:516:39 | src[key] | -| tests.js:516:32:516:39 | src[key] | -| tests.js:516:32:516:39 | src[key] | -| tests.js:516:32:516:39 | src[key] | -| tests.js:516:36:516:38 | key | -| tests.js:516:36:516:38 | key | -| tests.js:517:35:517:37 | dst | -| tests.js:517:35:517:37 | dst | -| tests.js:517:35:517:37 | dst | -| tests.js:517:40:517:42 | key | -| tests.js:517:40:517:42 | key | -| tests.js:517:40:517:42 | key | -| tests.js:523:11:523:23 | dst | -| tests.js:523:11:523:23 | dst | -| tests.js:523:17:523:23 | args[0] | -| tests.js:523:17:523:23 | args[0] | -| tests.js:524:11:524:23 | src | -| tests.js:524:11:524:23 | src | -| tests.js:524:17:524:23 | args[1] | -| tests.js:524:17:524:23 | args[1] | -| tests.js:525:14:525:16 | key | -| tests.js:525:14:525:16 | key | -| tests.js:525:14:525:16 | key | -| tests.js:527:35:527:37 | dst | -| tests.js:527:35:527:37 | dst | -| tests.js:527:35:527:42 | dst[key] | -| tests.js:527:35:527:42 | dst[key] | -| tests.js:527:35:527:42 | dst[key] | -| tests.js:527:35:527:42 | dst[key] | -| tests.js:527:39:527:41 | key | -| tests.js:527:39:527:41 | key | -| tests.js:527:45:527:47 | src | -| tests.js:527:45:527:47 | src | -| tests.js:527:45:527:52 | src[key] | -| tests.js:527:45:527:52 | src[key] | -| tests.js:527:45:527:52 | src[key] | -| tests.js:527:45:527:52 | src[key] | -| tests.js:527:45:527:52 | src[key] | -| tests.js:527:49:527:51 | key | -| tests.js:527:49:527:51 | key | -| tests.js:529:13:529:15 | dst | -| tests.js:529:13:529:15 | dst | -| tests.js:529:13:529:15 | dst | -| tests.js:529:17:529:19 | key | -| tests.js:529:17:529:19 | key | -| tests.js:529:17:529:19 | key | -| tests.js:529:24:529:26 | src | -| tests.js:529:24:529:26 | src | -| tests.js:529:24:529:31 | src[key] | -| tests.js:529:24:529:31 | src[key] | -| tests.js:529:24:529:31 | src[key] | -| tests.js:529:24:529:31 | src[key] | -| tests.js:529:24:529:31 | src[key] | -| tests.js:529:24:529:31 | src[key] | -| tests.js:529:28:529:30 | key | -| tests.js:529:28:529:30 | key | -| tests.js:534:31:534:33 | obj | -| tests.js:534:31:534:33 | obj | -| tests.js:534:31:534:33 | obj | -| tests.js:534:31:534:33 | obj | -| tests.js:538:18:538:24 | keys[i] | -| tests.js:538:18:538:24 | keys[i] | -| tests.js:538:18:538:24 | keys[i] | -| tests.js:538:27:538:29 | obj | -| tests.js:538:27:538:29 | obj | -| tests.js:538:27:538:29 | obj | -| tests.js:538:27:538:29 | obj | -| tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:538:31:538:37 | keys[i] | -| tests.js:538:31:538:37 | keys[i] | -| tests.js:538:31:538:37 | keys[i] | -| tests.js:542:30:542:32 | dst | -| tests.js:542:30:542:32 | dst | -| tests.js:542:30:542:32 | dst | -| tests.js:542:30:542:32 | dst | -| tests.js:542:35:542:37 | src | -| tests.js:542:35:542:37 | src | -| tests.js:542:35:542:37 | src | -| tests.js:542:35:542:37 | src | -| tests.js:543:26:543:28 | src | -| tests.js:543:26:543:28 | src | -| tests.js:543:26:543:28 | src | -| tests.js:543:26:543:28 | src | -| tests.js:543:32:543:34 | key | -| tests.js:543:32:543:34 | key | -| tests.js:543:32:543:34 | key | -| tests.js:543:32:543:34 | key | -| tests.js:543:37:543:41 | value | -| tests.js:543:37:543:41 | value | -| tests.js:543:37:543:41 | value | -| tests.js:543:37:543:41 | value | -| tests.js:545:33:545:35 | dst | -| tests.js:545:33:545:35 | dst | -| tests.js:545:33:545:35 | dst | -| tests.js:545:33:545:35 | dst | -| tests.js:545:33:545:40 | dst[key] | -| tests.js:545:33:545:40 | dst[key] | -| tests.js:545:33:545:40 | dst[key] | -| tests.js:545:33:545:40 | dst[key] | -| tests.js:545:37:545:39 | key | -| tests.js:545:37:545:39 | key | -| tests.js:545:37:545:39 | key | -| tests.js:545:37:545:39 | key | -| tests.js:545:43:545:47 | value | -| tests.js:545:43:545:47 | value | -| tests.js:545:43:545:47 | value | -| tests.js:545:43:545:47 | value | -| tests.js:547:13:547:15 | dst | -| tests.js:547:13:547:15 | dst | -| tests.js:547:13:547:15 | dst | -| tests.js:547:13:547:15 | dst | -| tests.js:547:13:547:15 | dst | -| tests.js:547:17:547:19 | key | -| tests.js:547:17:547:19 | key | -| tests.js:547:17:547:19 | key | -| tests.js:547:17:547:19 | key | -| tests.js:547:17:547:19 | key | -| tests.js:547:24:547:28 | value | -| tests.js:547:24:547:28 | value | -| tests.js:547:24:547:28 | value | -| tests.js:547:24:547:28 | value | -| tests.js:547:24:547:28 | value | -| tests.js:552:35:552:37 | src | -| tests.js:552:35:552:37 | src | -| tests.js:553:14:553:16 | key | -| tests.js:553:14:553:16 | key | -| tests.js:553:14:553:16 | key | -| tests.js:557:43:557:45 | src | -| tests.js:557:43:557:45 | src | -| tests.js:557:43:557:50 | src[key] | -| tests.js:557:43:557:50 | src[key] | -| tests.js:557:43:557:50 | src[key] | -| tests.js:557:43:557:50 | src[key] | -| tests.js:557:43:557:50 | src[key] | -| tests.js:559:17:559:19 | key | -| tests.js:559:17:559:19 | key | -| tests.js:559:17:559:19 | key | -| tests.js:559:24:559:26 | src | -| tests.js:559:24:559:26 | src | -| tests.js:559:24:559:31 | src[key] | -| tests.js:559:24:559:31 | src[key] | -| tests.js:559:24:559:31 | src[key] | -| tests.js:559:24:559:31 | src[key] | -| tests.js:559:24:559:31 | src[key] | -| tests.js:559:24:559:31 | src[key] | -| tests.js:559:28:559:30 | key | -| tests.js:559:28:559:30 | key | -| tests.js:564:35:564:37 | src | -| tests.js:564:35:564:37 | src | -| tests.js:565:14:565:16 | key | -| tests.js:565:14:565:16 | key | -| tests.js:565:14:565:16 | key | -| tests.js:569:43:569:45 | src | -| tests.js:569:43:569:45 | src | -| tests.js:569:43:569:50 | src[key] | -| tests.js:569:43:569:50 | src[key] | -| tests.js:569:43:569:50 | src[key] | -| tests.js:569:43:569:50 | src[key] | -| tests.js:569:43:569:50 | src[key] | -| tests.js:571:17:571:19 | key | -| tests.js:571:17:571:19 | key | -| tests.js:571:17:571:19 | key | -| tests.js:571:24:571:26 | src | -| tests.js:571:24:571:26 | src | -| tests.js:571:24:571:31 | src[key] | -| tests.js:571:24:571:31 | src[key] | -| tests.js:571:24:571:31 | src[key] | -| tests.js:571:24:571:31 | src[key] | -| tests.js:571:24:571:31 | src[key] | -| tests.js:571:24:571:31 | src[key] | -| tests.js:571:28:571:30 | key | -| tests.js:571:28:571:30 | key | -| tests.js:576:30:576:32 | src | -| tests.js:576:30:576:32 | src | -| tests.js:577:14:577:16 | key | -| tests.js:577:14:577:16 | key | -| tests.js:577:14:577:16 | key | -| tests.js:580:38:580:40 | src | -| tests.js:580:38:580:40 | src | -| tests.js:580:38:580:45 | src[key] | -| tests.js:580:38:580:45 | src[key] | -| tests.js:580:38:580:45 | src[key] | -| tests.js:580:38:580:45 | src[key] | -| tests.js:580:38:580:45 | src[key] | -| tests.js:582:17:582:19 | key | -| tests.js:582:17:582:19 | key | -| tests.js:582:17:582:19 | key | -| tests.js:582:24:582:26 | src | -| tests.js:582:24:582:26 | src | -| tests.js:582:24:582:31 | src[key] | -| tests.js:582:24:582:31 | src[key] | -| tests.js:582:24:582:31 | src[key] | -| tests.js:582:24:582:31 | src[key] | -| tests.js:582:24:582:31 | src[key] | -| tests.js:582:24:582:31 | src[key] | -| tests.js:582:28:582:30 | key | -| tests.js:582:28:582:30 | key | +| examples/PrototypePollutingFunction.js:1:16:1:18 | dst | semmle.label | dst | +| examples/PrototypePollutingFunction.js:1:21:1:23 | src | semmle.label | src | +| examples/PrototypePollutingFunction.js:2:14:2:16 | key | semmle.label | key | +| examples/PrototypePollutingFunction.js:5:19:5:21 | dst | semmle.label | dst | +| examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | semmle.label | dst[key] | +| examples/PrototypePollutingFunction.js:5:23:5:25 | key | semmle.label | key | +| examples/PrototypePollutingFunction.js:5:29:5:31 | src | semmle.label | src | +| examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | semmle.label | src[key] | +| examples/PrototypePollutingFunction.js:5:33:5:35 | key | semmle.label | key | +| examples/PrototypePollutingFunction.js:7:13:7:15 | dst | semmle.label | dst | +| examples/PrototypePollutingFunction.js:7:17:7:19 | key | semmle.label | key | +| examples/PrototypePollutingFunction.js:7:24:7:26 | src | semmle.label | src | +| examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | semmle.label | src[key] | +| examples/PrototypePollutingFunction.js:7:28:7:30 | key | semmle.label | key | +| examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | semmle.label | src | +| examples/PrototypePollutingFunction_fixed2.js:6:29:6:31 | src | semmle.label | src | +| examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | semmle.label | src[key] | +| examples/PrototypePollutingFunction_fixed2.js:8:24:8:26 | src | semmle.label | src | +| examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | semmle.label | src[key] | +| examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | semmle.label | src | +| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | semmle.label | key | +| examples/PrototypePollutingFunction_fixed.js:5:29:5:31 | src | semmle.label | src | +| examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | semmle.label | src[key] | +| examples/PrototypePollutingFunction_fixed.js:7:17:7:19 | key | semmle.label | key | +| examples/PrototypePollutingFunction_fixed.js:7:24:7:26 | src | semmle.label | src | +| examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | semmle.label | src[key] | +| examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | semmle.label | key | +| path-assignment.js:8:13:8:25 | key | semmle.label | key | +| path-assignment.js:8:19:8:25 | keys[i] | semmle.label | keys[i] | +| path-assignment.js:13:13:13:32 | target | semmle.label | target | +| path-assignment.js:13:22:13:27 | target | semmle.label | target | +| path-assignment.js:13:22:13:32 | target[key] | semmle.label | target[key] | +| path-assignment.js:13:29:13:31 | key | semmle.label | key | +| path-assignment.js:15:13:15:18 | target | semmle.label | target | +| path-assignment.js:15:20:15:22 | key | semmle.label | key | +| path-assignment.js:41:13:41:25 | key | semmle.label | key | +| path-assignment.js:41:19:41:25 | keys[i] | semmle.label | keys[i] | +| path-assignment.js:42:9:42:48 | target | semmle.label | target | +| path-assignment.js:42:18:42:23 | target | semmle.label | target | +| path-assignment.js:42:25:42:27 | key | semmle.label | key | +| path-assignment.js:42:32:42:37 | target | semmle.label | target | +| path-assignment.js:42:32:42:42 | target[key] | semmle.label | target[key] | +| path-assignment.js:42:32:42:48 | target[key] \|\| {} | semmle.label | target[key] \|\| {} | +| path-assignment.js:42:39:42:41 | key | semmle.label | key | +| path-assignment.js:44:5:44:10 | target | semmle.label | target | +| path-assignment.js:44:12:44:18 | keys[i] | semmle.label | keys[i] | +| path-assignment.js:58:13:58:25 | key | semmle.label | key | +| path-assignment.js:58:19:58:25 | keys[i] | semmle.label | keys[i] | +| path-assignment.js:59:9:59:48 | target | semmle.label | target | +| path-assignment.js:59:18:59:23 | target | semmle.label | target | +| path-assignment.js:59:25:59:27 | key | semmle.label | key | +| path-assignment.js:59:32:59:37 | target | semmle.label | target | +| path-assignment.js:59:32:59:42 | target[key] | semmle.label | target[key] | +| path-assignment.js:59:32:59:48 | target[key] \|\| {} | semmle.label | target[key] \|\| {} | +| path-assignment.js:59:39:59:41 | key | semmle.label | key | +| path-assignment.js:61:5:61:10 | target | semmle.label | target | +| path-assignment.js:61:12:61:18 | keys[i] | semmle.label | keys[i] | +| path-assignment.js:68:13:68:25 | key | semmle.label | key | +| path-assignment.js:68:19:68:25 | keys[i] | semmle.label | keys[i] | +| path-assignment.js:69:9:69:48 | target | semmle.label | target | +| path-assignment.js:69:18:69:23 | target | semmle.label | target | +| path-assignment.js:69:25:69:27 | key | semmle.label | key | +| path-assignment.js:69:32:69:37 | target | semmle.label | target | +| path-assignment.js:69:32:69:42 | target[key] | semmle.label | target[key] | +| path-assignment.js:69:32:69:48 | target[key] \|\| {} | semmle.label | target[key] \|\| {} | +| path-assignment.js:69:39:69:41 | key | semmle.label | key | +| path-assignment.js:71:5:71:10 | target | semmle.label | target | +| path-assignment.js:71:12:71:18 | keys[i] | semmle.label | keys[i] | +| tests.js:3:25:3:27 | dst | semmle.label | dst | +| tests.js:3:30:3:32 | src | semmle.label | src | +| tests.js:4:14:4:16 | key | semmle.label | key | +| tests.js:6:28:6:30 | dst | semmle.label | dst | +| tests.js:6:28:6:35 | dst[key] | semmle.label | dst[key] | +| tests.js:6:32:6:34 | key | semmle.label | key | +| tests.js:6:38:6:40 | src | semmle.label | src | +| tests.js:6:38:6:45 | src[key] | semmle.label | src[key] | +| tests.js:6:42:6:44 | key | semmle.label | key | +| tests.js:8:13:8:15 | dst | semmle.label | dst | +| tests.js:8:17:8:19 | key | semmle.label | key | +| tests.js:8:24:8:26 | src | semmle.label | src | +| tests.js:8:24:8:31 | src[key] | semmle.label | src[key] | +| tests.js:8:28:8:30 | key | semmle.label | key | +| tests.js:13:24:13:26 | dst | semmle.label | dst | +| tests.js:13:29:13:31 | src | semmle.label | src | +| tests.js:14:17:14:19 | src | semmle.label | src | +| tests.js:14:30:14:32 | key | semmle.label | key | +| tests.js:16:27:16:29 | dst | semmle.label | dst | +| tests.js:16:27:16:34 | dst[key] | semmle.label | dst[key] | +| tests.js:16:31:16:33 | key | semmle.label | key | +| tests.js:16:37:16:39 | src | semmle.label | src | +| tests.js:16:37:16:44 | src[key] | semmle.label | src[key] | +| tests.js:16:41:16:43 | key | semmle.label | key | +| tests.js:18:13:18:15 | dst | semmle.label | dst | +| tests.js:18:17:18:19 | key | semmle.label | key | +| tests.js:18:24:18:26 | src | semmle.label | src | +| tests.js:18:24:18:31 | src[key] | semmle.label | src[key] | +| tests.js:18:28:18:30 | key | semmle.label | key | +| tests.js:23:19:23:21 | dst | semmle.label | dst | +| tests.js:25:18:25:20 | key | semmle.label | key | +| tests.js:26:25:26:27 | dst | semmle.label | dst | +| tests.js:26:30:26:40 | source[key] | semmle.label | source[key] | +| tests.js:26:37:26:39 | key | semmle.label | key | +| tests.js:26:43:26:45 | key | semmle.label | key | +| tests.js:31:22:31:24 | dst | semmle.label | dst | +| tests.js:31:27:31:31 | value | semmle.label | value | +| tests.js:31:34:31:36 | key | semmle.label | key | +| tests.js:32:9:32:27 | dstValue | semmle.label | dstValue | +| tests.js:32:20:32:22 | dst | semmle.label | dst | +| tests.js:32:20:32:27 | dst[key] | semmle.label | dst[key] | +| tests.js:32:24:32:26 | key | semmle.label | key | +| tests.js:34:18:34:25 | dstValue | semmle.label | dstValue | +| tests.js:36:9:36:11 | dst | semmle.label | dst | +| tests.js:36:13:36:15 | key | semmle.label | key | +| tests.js:36:20:36:24 | value | semmle.label | value | +| tests.js:40:27:40:29 | dst | semmle.label | dst | +| tests.js:40:32:40:34 | src | semmle.label | src | +| tests.js:41:14:41:16 | key | semmle.label | key | +| tests.js:44:30:44:32 | dst | semmle.label | dst | +| tests.js:44:30:44:37 | dst[key] | semmle.label | dst[key] | +| tests.js:44:34:44:36 | key | semmle.label | key | +| tests.js:44:40:44:42 | src | semmle.label | src | +| tests.js:44:40:44:47 | src[key] | semmle.label | src[key] | +| tests.js:44:44:44:46 | key | semmle.label | key | +| tests.js:46:13:46:15 | dst | semmle.label | dst | +| tests.js:46:17:46:19 | key | semmle.label | key | +| tests.js:46:24:46:26 | src | semmle.label | src | +| tests.js:46:24:46:31 | src[key] | semmle.label | src[key] | +| tests.js:46:28:46:30 | key | semmle.label | key | +| tests.js:51:26:51:28 | dst | semmle.label | dst | +| tests.js:51:31:51:33 | src | semmle.label | src | +| tests.js:52:14:52:16 | key | semmle.label | key | +| tests.js:55:29:55:31 | dst | semmle.label | dst | +| tests.js:55:29:55:36 | dst[key] | semmle.label | dst[key] | +| tests.js:55:33:55:35 | key | semmle.label | key | +| tests.js:55:39:55:41 | src | semmle.label | src | +| tests.js:55:39:55:46 | src[key] | semmle.label | src[key] | +| tests.js:55:43:55:45 | key | semmle.label | key | +| tests.js:57:13:57:15 | dst | semmle.label | dst | +| tests.js:57:17:57:19 | key | semmle.label | key | +| tests.js:57:24:57:26 | src | semmle.label | src | +| tests.js:57:24:57:31 | src[key] | semmle.label | src[key] | +| tests.js:57:28:57:30 | key | semmle.label | key | +| tests.js:62:33:62:35 | src | semmle.label | src | +| tests.js:66:41:66:43 | src | semmle.label | src | +| tests.js:66:41:66:48 | src[key] | semmle.label | src[key] | +| tests.js:68:24:68:26 | src | semmle.label | src | +| tests.js:68:24:68:31 | src[key] | semmle.label | src[key] | +| tests.js:77:27:77:29 | src | semmle.label | src | +| tests.js:81:39:81:41 | src | semmle.label | src | +| tests.js:81:39:81:46 | src[key] | semmle.label | src[key] | +| tests.js:83:28:83:30 | src | semmle.label | src | +| tests.js:83:28:83:35 | src[key] | semmle.label | src[key] | +| tests.js:89:34:89:36 | src | semmle.label | src | +| tests.js:90:14:90:16 | key | semmle.label | key | +| tests.js:94:42:94:44 | src | semmle.label | src | +| tests.js:94:42:94:49 | src[key] | semmle.label | src[key] | +| tests.js:96:17:96:19 | key | semmle.label | key | +| tests.js:96:24:96:26 | src | semmle.label | src | +| tests.js:96:24:96:31 | src[key] | semmle.label | src[key] | +| tests.js:96:28:96:30 | key | semmle.label | key | +| tests.js:101:32:101:34 | dst | semmle.label | dst | +| tests.js:101:37:101:39 | src | semmle.label | src | +| tests.js:102:14:102:16 | key | semmle.label | key | +| tests.js:107:35:107:37 | dst | semmle.label | dst | +| tests.js:107:35:107:42 | dst[key] | semmle.label | dst[key] | +| tests.js:107:39:107:41 | key | semmle.label | key | +| tests.js:107:45:107:47 | src | semmle.label | src | +| tests.js:107:45:107:52 | src[key] | semmle.label | src[key] | +| tests.js:107:49:107:51 | key | semmle.label | key | +| tests.js:109:13:109:15 | dst | semmle.label | dst | +| tests.js:109:17:109:19 | key | semmle.label | key | +| tests.js:109:24:109:26 | src | semmle.label | src | +| tests.js:109:24:109:31 | src[key] | semmle.label | src[key] | +| tests.js:109:28:109:30 | key | semmle.label | key | +| tests.js:116:41:116:43 | src | semmle.label | src | +| tests.js:117:14:117:16 | key | semmle.label | key | +| tests.js:119:49:119:51 | src | semmle.label | src | +| tests.js:119:49:119:56 | src[key] | semmle.label | src[key] | +| tests.js:121:17:121:19 | key | semmle.label | key | +| tests.js:121:24:121:26 | src | semmle.label | src | +| tests.js:121:24:121:31 | src[key] | semmle.label | src[key] | +| tests.js:121:28:121:30 | key | semmle.label | key | +| tests.js:149:31:149:33 | dst | semmle.label | dst | +| tests.js:149:36:149:38 | src | semmle.label | src | +| tests.js:150:14:150:16 | key | semmle.label | key | +| tests.js:152:22:152:24 | dst | semmle.label | dst | +| tests.js:152:27:152:29 | src | semmle.label | src | +| tests.js:152:32:152:34 | key | semmle.label | key | +| tests.js:154:13:154:15 | dst | semmle.label | dst | +| tests.js:154:17:154:19 | key | semmle.label | key | +| tests.js:154:24:154:26 | src | semmle.label | src | +| tests.js:154:24:154:31 | src[key] | semmle.label | src[key] | +| tests.js:154:28:154:30 | key | semmle.label | key | +| tests.js:159:36:159:38 | dst | semmle.label | dst | +| tests.js:159:41:159:43 | src | semmle.label | src | +| tests.js:160:26:160:28 | dst | semmle.label | dst | +| tests.js:160:31:160:33 | src | semmle.label | src | +| tests.js:160:37:160:39 | dst | semmle.label | dst | +| tests.js:160:42:160:44 | src | semmle.label | src | +| tests.js:160:47:160:49 | key | semmle.label | key | +| tests.js:161:35:161:37 | dst | semmle.label | dst | +| tests.js:161:35:161:42 | dst[key] | semmle.label | dst[key] | +| tests.js:161:39:161:41 | key | semmle.label | key | +| tests.js:161:45:161:47 | src | semmle.label | src | +| tests.js:161:45:161:52 | src[key] | semmle.label | src[key] | +| tests.js:161:49:161:51 | key | semmle.label | key | +| tests.js:165:37:165:39 | src | semmle.label | src | +| tests.js:166:14:166:16 | key | semmle.label | key | +| tests.js:169:45:169:47 | src | semmle.label | src | +| tests.js:169:45:169:52 | src[key] | semmle.label | src[key] | +| tests.js:169:49:169:51 | key | semmle.label | key | +| tests.js:171:17:171:19 | key | semmle.label | key | +| tests.js:171:24:171:26 | src | semmle.label | src | +| tests.js:171:24:171:31 | src[key] | semmle.label | src[key] | +| tests.js:171:28:171:30 | key | semmle.label | key | +| tests.js:178:33:178:35 | src | semmle.label | src | +| tests.js:182:41:182:43 | src | semmle.label | src | +| tests.js:182:41:182:48 | src[key] | semmle.label | src[key] | +| tests.js:184:24:184:26 | src | semmle.label | src | +| tests.js:184:24:184:31 | src[key] | semmle.label | src[key] | +| tests.js:189:32:189:34 | dst | semmle.label | dst | +| tests.js:189:37:189:39 | src | semmle.label | src | +| tests.js:192:13:192:25 | key | semmle.label | key | +| tests.js:192:19:192:25 | keys[i] | semmle.label | keys[i] | +| tests.js:194:35:194:37 | dst | semmle.label | dst | +| tests.js:194:35:194:42 | dst[key] | semmle.label | dst[key] | +| tests.js:194:39:194:41 | key | semmle.label | key | +| tests.js:194:45:194:47 | src | semmle.label | src | +| tests.js:194:45:194:52 | src[key] | semmle.label | src[key] | +| tests.js:194:49:194:51 | key | semmle.label | key | +| tests.js:196:13:196:15 | dst | semmle.label | dst | +| tests.js:196:17:196:19 | key | semmle.label | key | +| tests.js:196:24:196:26 | src | semmle.label | src | +| tests.js:196:24:196:31 | src[key] | semmle.label | src[key] | +| tests.js:196:28:196:30 | key | semmle.label | key | +| tests.js:201:39:201:41 | dst | semmle.label | dst | +| tests.js:201:44:201:46 | src | semmle.label | src | +| tests.js:206:42:206:44 | dst | semmle.label | dst | +| tests.js:206:42:206:53 | dst[keys[i]] | semmle.label | dst[keys[i]] | +| tests.js:206:46:206:52 | keys[i] | semmle.label | keys[i] | +| tests.js:206:56:206:58 | src | semmle.label | src | +| tests.js:206:56:206:67 | src[keys[i]] | semmle.label | src[keys[i]] | +| tests.js:206:60:206:66 | keys[i] | semmle.label | keys[i] | +| tests.js:208:13:208:15 | dst | semmle.label | dst | +| tests.js:208:17:208:23 | keys[i] | semmle.label | keys[i] | +| tests.js:208:28:208:30 | src | semmle.label | src | +| tests.js:208:28:208:39 | src[keys[i]] | semmle.label | src[keys[i]] | +| tests.js:208:32:208:38 | keys[i] | semmle.label | keys[i] | +| tests.js:213:23:213:26 | key1 | semmle.label | key1 | +| tests.js:213:29:213:32 | key2 | semmle.label | key2 | +| tests.js:213:35:213:39 | value | semmle.label | value | +| tests.js:217:5:217:13 | map[key1] | semmle.label | map[key1] | +| tests.js:217:9:217:12 | key1 | semmle.label | key1 | +| tests.js:217:15:217:18 | key2 | semmle.label | key2 | +| tests.js:217:23:217:27 | value | semmle.label | value | +| tests.js:223:14:223:16 | key | semmle.label | key | +| tests.js:224:23:224:25 | key | semmle.label | key | +| tests.js:224:33:224:41 | data[key] | semmle.label | data[key] | +| tests.js:224:38:224:40 | key | semmle.label | key | +| tests.js:225:28:225:30 | key | semmle.label | key | +| tests.js:225:33:225:41 | data[key] | semmle.label | data[key] | +| tests.js:225:38:225:40 | key | semmle.label | key | +| tests.js:229:26:229:29 | key1 | semmle.label | key1 | +| tests.js:229:32:229:35 | key2 | semmle.label | key2 | +| tests.js:229:38:229:42 | value | semmle.label | value | +| tests.js:233:5:233:13 | map[key1] | semmle.label | map[key1] | +| tests.js:233:9:233:12 | key1 | semmle.label | key1 | +| tests.js:233:15:233:18 | key2 | semmle.label | key2 | +| tests.js:233:23:233:27 | value | semmle.label | value | +| tests.js:238:14:238:16 | key | semmle.label | key | +| tests.js:239:24:239:26 | key | semmle.label | key | +| tests.js:239:34:239:42 | data[key] | semmle.label | data[key] | +| tests.js:239:39:239:41 | key | semmle.label | key | +| tests.js:240:31:240:33 | key | semmle.label | key | +| tests.js:240:36:240:44 | data[key] | semmle.label | data[key] | +| tests.js:240:41:240:43 | key | semmle.label | key | +| tests.js:263:27:263:29 | dst | semmle.label | dst | +| tests.js:265:13:265:26 | key | semmle.label | key | +| tests.js:265:19:265:26 | entry[0] | semmle.label | entry[0] | +| tests.js:266:13:266:28 | value | semmle.label | value | +| tests.js:266:21:266:28 | entry[1] | semmle.label | entry[1] | +| tests.js:268:30:268:32 | dst | semmle.label | dst | +| tests.js:268:30:268:37 | dst[key] | semmle.label | dst[key] | +| tests.js:268:34:268:36 | key | semmle.label | key | +| tests.js:270:13:270:15 | dst | semmle.label | dst | +| tests.js:270:17:270:19 | key | semmle.label | key | +| tests.js:270:24:270:28 | value | semmle.label | value | +| tests.js:275:27:275:29 | dst | semmle.label | dst | +| tests.js:275:32:275:34 | src | semmle.label | src | +| tests.js:276:21:276:23 | src | semmle.label | src | +| tests.js:276:34:276:36 | key | semmle.label | key | +| tests.js:278:30:278:32 | dst | semmle.label | dst | +| tests.js:278:30:278:37 | dst[key] | semmle.label | dst[key] | +| tests.js:278:34:278:36 | key | semmle.label | key | +| tests.js:278:40:278:42 | src | semmle.label | src | +| tests.js:278:40:278:47 | src[key] | semmle.label | src[key] | +| tests.js:278:44:278:46 | key | semmle.label | key | +| tests.js:280:13:280:15 | dst | semmle.label | dst | +| tests.js:280:17:280:19 | key | semmle.label | key | +| tests.js:280:24:280:26 | src | semmle.label | src | +| tests.js:280:24:280:31 | src[key] | semmle.label | src[key] | +| tests.js:280:28:280:30 | key | semmle.label | key | +| tests.js:301:27:301:29 | dst | semmle.label | dst | +| tests.js:301:32:301:34 | src | semmle.label | src | +| tests.js:302:14:302:16 | key | semmle.label | key | +| tests.js:304:17:304:32 | value | semmle.label | value | +| tests.js:304:17:304:32 | value | semmle.label | value | +| tests.js:304:17:304:32 | value | semmle.label | value | +| tests.js:304:25:304:27 | src | semmle.label | src | +| tests.js:304:25:304:32 | src[key] | semmle.label | src[key] | +| tests.js:304:25:304:32 | src[key] | semmle.label | src[key] | +| tests.js:304:25:304:32 | src[key] | semmle.label | src[key] | +| tests.js:304:29:304:31 | key | semmle.label | key | +| tests.js:306:34:306:36 | dst | semmle.label | dst | +| tests.js:306:34:306:41 | dst[key] | semmle.label | dst[key] | +| tests.js:306:38:306:40 | key | semmle.label | key | +| tests.js:306:44:306:48 | value | semmle.label | value | +| tests.js:306:44:306:48 | value | semmle.label | value | +| tests.js:308:17:308:19 | dst | semmle.label | dst | +| tests.js:308:21:308:23 | key | semmle.label | key | +| tests.js:308:28:308:32 | value | semmle.label | value | +| tests.js:314:31:314:33 | dst | semmle.label | dst | +| tests.js:314:36:314:38 | src | semmle.label | src | +| tests.js:315:14:315:16 | key | semmle.label | key | +| tests.js:318:17:318:32 | value | semmle.label | value | +| tests.js:318:17:318:32 | value | semmle.label | value | +| tests.js:318:17:318:32 | value | semmle.label | value | +| tests.js:318:25:318:27 | src | semmle.label | src | +| tests.js:318:25:318:32 | src[key] | semmle.label | src[key] | +| tests.js:318:25:318:32 | src[key] | semmle.label | src[key] | +| tests.js:318:25:318:32 | src[key] | semmle.label | src[key] | +| tests.js:318:29:318:31 | key | semmle.label | key | +| tests.js:320:38:320:40 | dst | semmle.label | dst | +| tests.js:320:38:320:45 | dst[key] | semmle.label | dst[key] | +| tests.js:320:42:320:44 | key | semmle.label | key | +| tests.js:320:48:320:52 | value | semmle.label | value | +| tests.js:320:48:320:52 | value | semmle.label | value | +| tests.js:322:17:322:19 | dst | semmle.label | dst | +| tests.js:322:21:322:23 | key | semmle.label | key | +| tests.js:322:28:322:32 | value | semmle.label | value | +| tests.js:328:25:328:27 | dst | semmle.label | dst | +| tests.js:328:30:328:32 | src | semmle.label | src | +| tests.js:329:14:329:16 | key | semmle.label | key | +| tests.js:336:32:336:34 | dst | semmle.label | dst | +| tests.js:336:32:336:39 | dst[key] | semmle.label | dst[key] | +| tests.js:336:36:336:38 | key | semmle.label | key | +| tests.js:336:42:336:44 | src | semmle.label | src | +| tests.js:336:42:336:49 | src[key] | semmle.label | src[key] | +| tests.js:336:46:336:48 | key | semmle.label | key | +| tests.js:338:17:338:19 | dst | semmle.label | dst | +| tests.js:338:21:338:23 | key | semmle.label | key | +| tests.js:338:28:338:30 | src | semmle.label | src | +| tests.js:338:28:338:35 | src[key] | semmle.label | src[key] | +| tests.js:338:32:338:34 | key | semmle.label | key | +| tests.js:348:32:348:37 | target | semmle.label | target | +| tests.js:348:40:348:45 | source | semmle.label | source | +| tests.js:349:26:349:31 | target | semmle.label | target | +| tests.js:349:54:349:59 | source | semmle.label | source | +| tests.js:350:21:350:26 | source | semmle.label | source | +| tests.js:350:37:350:39 | key | semmle.label | key | +| tests.js:355:17:355:22 | target | semmle.label | target | +| tests.js:355:24:355:26 | key | semmle.label | key | +| tests.js:355:31:355:86 | mergePl ... ptions) | semmle.label | mergePl ... ptions) | +| tests.js:355:53:355:58 | target | semmle.label | target | +| tests.js:355:53:355:63 | target[key] | semmle.label | target[key] | +| tests.js:355:60:355:62 | key | semmle.label | key | +| tests.js:355:66:355:71 | source | semmle.label | source | +| tests.js:355:66:355:76 | source[key] | semmle.label | source[key] | +| tests.js:357:17:357:22 | target | semmle.label | target | +| tests.js:357:24:357:26 | key | semmle.label | key | +| tests.js:357:31:357:36 | source | semmle.label | source | +| tests.js:357:31:357:41 | source[key] | semmle.label | source[key] | +| tests.js:357:38:357:40 | key | semmle.label | key | +| tests.js:361:12:361:17 | target | semmle.label | target | +| tests.js:364:41:364:46 | target | semmle.label | target | +| tests.js:364:49:364:54 | source | semmle.label | source | +| tests.js:366:18:366:20 | key | semmle.label | key | +| tests.js:371:24:371:26 | key | semmle.label | key | +| tests.js:371:31:371:95 | mergePl ... ptions) | semmle.label | mergePl ... ptions) | +| tests.js:371:62:371:72 | target[key] | semmle.label | target[key] | +| tests.js:371:69:371:71 | key | semmle.label | key | +| tests.js:371:75:371:80 | source | semmle.label | source | +| tests.js:371:75:371:85 | source[key] | semmle.label | source[key] | +| tests.js:373:24:373:26 | key | semmle.label | key | +| tests.js:373:31:373:36 | source | semmle.label | source | +| tests.js:373:31:373:41 | source[key] | semmle.label | source[key] | +| tests.js:373:38:373:40 | key | semmle.label | key | +| tests.js:377:12:377:17 | target | semmle.label | target | +| tests.js:380:22:380:24 | obj | semmle.label | obj | +| tests.js:380:27:380:34 | callback [dst] | semmle.label | callback [dst] | +| tests.js:380:27:380:34 | callback [dst] | semmle.label | callback [dst] | +| tests.js:380:27:380:34 | callback [dst] | semmle.label | callback [dst] | +| tests.js:380:27:380:34 | callback [dst] | semmle.label | callback [dst] | +| tests.js:380:27:380:34 | callback [src] | semmle.label | callback [src] | +| tests.js:381:14:381:16 | key | semmle.label | key | +| tests.js:383:13:383:20 | callback [dst] | semmle.label | callback [dst] | +| tests.js:383:13:383:20 | callback [dst] | semmle.label | callback [dst] | +| tests.js:383:13:383:20 | callback [dst] | semmle.label | callback [dst] | +| tests.js:383:13:383:20 | callback [dst] | semmle.label | callback [dst] | +| tests.js:383:13:383:20 | callback [src] | semmle.label | callback [src] | +| tests.js:383:22:383:24 | key | semmle.label | key | +| tests.js:383:27:383:29 | obj | semmle.label | obj | +| tests.js:383:27:383:34 | obj[key] | semmle.label | obj[key] | +| tests.js:383:31:383:33 | key | semmle.label | key | +| tests.js:388:29:388:31 | dst | semmle.label | dst | +| tests.js:388:29:388:31 | dst | semmle.label | dst | +| tests.js:388:34:388:36 | src | semmle.label | src | +| tests.js:389:17:389:19 | src | semmle.label | src | +| tests.js:389:22:389:24 | key | semmle.label | key | +| tests.js:391:32:391:34 | dst | semmle.label | dst | +| tests.js:391:32:391:34 | dst | semmle.label | dst | +| tests.js:391:32:391:39 | dst[key] | semmle.label | dst[key] | +| tests.js:391:32:391:39 | dst[key] | semmle.label | dst[key] | +| tests.js:391:36:391:38 | key | semmle.label | key | +| tests.js:391:42:391:44 | src | semmle.label | src | +| tests.js:391:42:391:49 | src[key] | semmle.label | src[key] | +| tests.js:391:46:391:48 | key | semmle.label | key | +| tests.js:393:13:393:15 | dst | semmle.label | dst | +| tests.js:393:17:393:19 | key | semmle.label | key | +| tests.js:393:24:393:26 | src | semmle.label | src | +| tests.js:393:24:393:31 | src[key] | semmle.label | src[key] | +| tests.js:393:28:393:30 | key | semmle.label | key | +| tests.js:398:30:398:32 | dst | semmle.label | dst | +| tests.js:398:30:398:32 | dst | semmle.label | dst | +| tests.js:398:35:398:37 | src | semmle.label | src | +| tests.js:399:17:399:19 | src | semmle.label | src | +| tests.js:399:23:399:25 | key | semmle.label | key | +| tests.js:399:28:399:32 | value | semmle.label | value | +| tests.js:401:33:401:35 | dst | semmle.label | dst | +| tests.js:401:33:401:35 | dst | semmle.label | dst | +| tests.js:401:33:401:40 | dst[key] | semmle.label | dst[key] | +| tests.js:401:33:401:40 | dst[key] | semmle.label | dst[key] | +| tests.js:401:37:401:39 | key | semmle.label | key | +| tests.js:401:43:401:47 | value | semmle.label | value | +| tests.js:403:13:403:15 | dst | semmle.label | dst | +| tests.js:403:17:403:19 | key | semmle.label | key | +| tests.js:403:24:403:28 | value | semmle.label | value | +| tests.js:408:22:408:24 | obj | semmle.label | obj | +| tests.js:408:27:408:29 | key | semmle.label | key | +| tests.js:409:12:409:14 | obj | semmle.label | obj | +| tests.js:409:12:409:19 | obj[key] | semmle.label | obj[key] | +| tests.js:409:16:409:18 | key | semmle.label | key | +| tests.js:412:31:412:33 | dst | semmle.label | dst | +| tests.js:412:36:412:38 | src | semmle.label | src | +| tests.js:413:14:413:16 | key | semmle.label | key | +| tests.js:414:13:414:41 | value | semmle.label | value | +| tests.js:414:21:414:41 | wrapped ... c, key) | semmle.label | wrapped ... c, key) | +| tests.js:414:33:414:35 | src | semmle.label | src | +| tests.js:414:38:414:40 | key | semmle.label | key | +| tests.js:415:13:415:42 | target | semmle.label | target | +| tests.js:415:22:415:42 | wrapped ... t, key) | semmle.label | wrapped ... t, key) | +| tests.js:415:34:415:36 | dst | semmle.label | dst | +| tests.js:415:39:415:41 | key | semmle.label | key | +| tests.js:417:34:417:39 | target | semmle.label | target | +| tests.js:417:42:417:46 | value | semmle.label | value | +| tests.js:419:13:419:15 | dst | semmle.label | dst | +| tests.js:419:17:419:19 | key | semmle.label | key | +| tests.js:419:24:419:28 | value | semmle.label | value | +| tests.js:424:25:424:27 | obj | semmle.label | obj | +| tests.js:424:30:424:32 | key | semmle.label | key | +| tests.js:426:12:426:14 | obj | semmle.label | obj | +| tests.js:426:12:426:19 | obj[key] | semmle.label | obj[key] | +| tests.js:426:16:426:18 | key | semmle.label | key | +| tests.js:429:34:429:36 | dst | semmle.label | dst | +| tests.js:429:39:429:41 | src | semmle.label | src | +| tests.js:430:14:430:16 | key | semmle.label | key | +| tests.js:431:13:431:44 | value | semmle.label | value | +| tests.js:431:21:431:44 | almostS ... c, key) | semmle.label | almostS ... c, key) | +| tests.js:431:36:431:38 | src | semmle.label | src | +| tests.js:431:41:431:43 | key | semmle.label | key | +| tests.js:432:13:432:45 | target | semmle.label | target | +| tests.js:432:22:432:45 | almostS ... t, key) | semmle.label | almostS ... t, key) | +| tests.js:432:37:432:39 | dst | semmle.label | dst | +| tests.js:432:42:432:44 | key | semmle.label | key | +| tests.js:434:37:434:42 | target | semmle.label | target | +| tests.js:434:45:434:49 | value | semmle.label | value | +| tests.js:436:13:436:15 | dst | semmle.label | dst | +| tests.js:436:17:436:19 | key | semmle.label | key | +| tests.js:436:24:436:28 | value | semmle.label | value | +| tests.js:441:19:441:21 | obj | semmle.label | obj | +| tests.js:443:12:443:14 | obj | semmle.label | obj | +| tests.js:443:12:443:19 | obj[key] | semmle.label | obj[key] | +| tests.js:446:33:446:35 | src | semmle.label | src | +| tests.js:447:14:447:16 | key | semmle.label | key | +| tests.js:448:13:448:38 | value | semmle.label | value | +| tests.js:448:21:448:38 | safeRead(src, key) | semmle.label | safeRead(src, key) | +| tests.js:448:30:448:32 | src | semmle.label | src | +| tests.js:451:39:451:43 | value | semmle.label | value | +| tests.js:453:17:453:19 | key | semmle.label | key | +| tests.js:453:24:453:28 | value | semmle.label | value | +| tests.js:458:26:458:28 | dst | semmle.label | dst | +| tests.js:458:31:458:33 | src | semmle.label | src | +| tests.js:460:12:460:14 | src | semmle.label | src | +| tests.js:460:18:460:22 | value | semmle.label | value | +| tests.js:460:25:460:27 | key | semmle.label | key | +| tests.js:462:29:462:31 | dst | semmle.label | dst | +| tests.js:462:29:462:36 | dst[key] | semmle.label | dst[key] | +| tests.js:462:33:462:35 | key | semmle.label | key | +| tests.js:462:39:462:41 | src | semmle.label | src | +| tests.js:462:39:462:46 | src[key] | semmle.label | src[key] | +| tests.js:462:43:462:45 | key | semmle.label | key | +| tests.js:465:30:465:32 | dst | semmle.label | dst | +| tests.js:465:34:465:36 | key | semmle.label | key | +| tests.js:465:41:465:43 | src | semmle.label | src | +| tests.js:465:41:465:48 | src[key] | semmle.label | src[key] | +| tests.js:465:45:465:47 | key | semmle.label | key | +| tests.js:466:30:466:32 | dst | semmle.label | dst | +| tests.js:466:34:466:36 | key | semmle.label | key | +| tests.js:466:41:466:46 | o[key] | semmle.label | o[key] | +| tests.js:466:43:466:45 | key | semmle.label | key | +| tests.js:467:30:467:32 | dst | semmle.label | dst | +| tests.js:467:34:467:36 | key | semmle.label | key | +| tests.js:467:41:467:45 | value | semmle.label | value | +| tests.js:472:38:472:40 | dst | semmle.label | dst | +| tests.js:473:18:473:22 | value | semmle.label | value | +| tests.js:473:25:473:27 | key | semmle.label | key | +| tests.js:475:41:475:43 | dst | semmle.label | dst | +| tests.js:475:41:475:48 | dst[key] | semmle.label | dst[key] | +| tests.js:475:45:475:47 | key | semmle.label | key | +| tests.js:477:13:477:15 | dst | semmle.label | dst | +| tests.js:477:17:477:19 | key | semmle.label | key | +| tests.js:477:24:477:28 | value | semmle.label | value | +| tests.js:483:26:483:28 | dst | semmle.label | dst | +| tests.js:483:31:483:33 | src | semmle.label | src | +| tests.js:483:31:483:33 | src | semmle.label | src | +| tests.js:484:14:484:16 | key | semmle.label | key | +| tests.js:487:29:487:31 | dst | semmle.label | dst | +| tests.js:487:29:487:36 | dst[key] | semmle.label | dst[key] | +| tests.js:487:33:487:35 | key | semmle.label | key | +| tests.js:487:39:487:41 | src | semmle.label | src | +| tests.js:487:39:487:46 | src[key] | semmle.label | src[key] | +| tests.js:487:39:487:46 | src[key] | semmle.label | src[key] | +| tests.js:487:39:487:46 | src[key] | semmle.label | src[key] | +| tests.js:487:43:487:45 | key | semmle.label | key | +| tests.js:489:13:489:15 | dst | semmle.label | dst | +| tests.js:489:17:489:19 | key | semmle.label | key | +| tests.js:489:24:489:26 | src | semmle.label | src | +| tests.js:489:24:489:31 | src[key] | semmle.label | src[key] | +| tests.js:489:28:489:30 | key | semmle.label | key | +| tests.js:494:32:494:34 | src | semmle.label | src | +| tests.js:495:14:495:16 | key | semmle.label | key | +| tests.js:498:13:498:28 | value | semmle.label | value | +| tests.js:498:13:498:28 | value | semmle.label | value | +| tests.js:498:13:498:28 | value | semmle.label | value | +| tests.js:498:21:498:23 | src | semmle.label | src | +| tests.js:498:21:498:28 | src[key] | semmle.label | src[key] | +| tests.js:498:21:498:28 | src[key] | semmle.label | src[key] | +| tests.js:498:21:498:28 | src[key] | semmle.label | src[key] | +| tests.js:498:25:498:27 | key | semmle.label | key | +| tests.js:500:38:500:42 | value | semmle.label | value | +| tests.js:500:38:500:42 | value | semmle.label | value | +| tests.js:502:17:502:19 | key | semmle.label | key | +| tests.js:502:24:502:28 | value | semmle.label | value | +| tests.js:508:30:508:32 | dst | semmle.label | dst | +| tests.js:508:35:508:37 | src | semmle.label | src | +| tests.js:511:13:511:25 | key | semmle.label | key | +| tests.js:511:19:511:25 | keys[i] | semmle.label | keys[i] | +| tests.js:513:33:513:35 | dst | semmle.label | dst | +| tests.js:513:33:513:40 | dst[key] | semmle.label | dst[key] | +| tests.js:513:37:513:39 | key | semmle.label | key | +| tests.js:513:43:513:45 | src | semmle.label | src | +| tests.js:513:43:513:50 | src[key] | semmle.label | src[key] | +| tests.js:513:47:513:49 | key | semmle.label | key | +| tests.js:516:32:516:34 | src | semmle.label | src | +| tests.js:516:32:516:39 | src[key] | semmle.label | src[key] | +| tests.js:516:36:516:38 | key | semmle.label | key | +| tests.js:517:35:517:37 | dst | semmle.label | dst | +| tests.js:517:40:517:42 | key | semmle.label | key | +| tests.js:525:14:525:16 | key | semmle.label | key | +| tests.js:529:17:529:19 | key | semmle.label | key | +| tests.js:529:24:529:31 | src[key] | semmle.label | src[key] | +| tests.js:529:28:529:30 | key | semmle.label | key | +| tests.js:534:31:534:33 | obj | semmle.label | obj | +| tests.js:534:36:534:43 | callback [dst] | semmle.label | callback [dst] | +| tests.js:538:9:538:16 | callback [dst] | semmle.label | callback [dst] | +| tests.js:538:18:538:24 | keys[i] | semmle.label | keys[i] | +| tests.js:538:27:538:29 | obj | semmle.label | obj | +| tests.js:538:27:538:38 | obj[keys[i]] | semmle.label | obj[keys[i]] | +| tests.js:538:31:538:37 | keys[i] | semmle.label | keys[i] | +| tests.js:542:30:542:32 | dst | semmle.label | dst | +| tests.js:542:35:542:37 | src | semmle.label | src | +| tests.js:543:26:543:28 | src | semmle.label | src | +| tests.js:543:32:543:34 | key | semmle.label | key | +| tests.js:543:37:543:41 | value | semmle.label | value | +| tests.js:545:33:545:35 | dst | semmle.label | dst | +| tests.js:545:33:545:40 | dst[key] | semmle.label | dst[key] | +| tests.js:545:37:545:39 | key | semmle.label | key | +| tests.js:545:43:545:47 | value | semmle.label | value | +| tests.js:547:13:547:15 | dst | semmle.label | dst | +| tests.js:547:17:547:19 | key | semmle.label | key | +| tests.js:547:24:547:28 | value | semmle.label | value | +| tests.js:552:35:552:37 | src | semmle.label | src | +| tests.js:553:14:553:16 | key | semmle.label | key | +| tests.js:557:43:557:45 | src | semmle.label | src | +| tests.js:557:43:557:50 | src[key] | semmle.label | src[key] | +| tests.js:559:17:559:19 | key | semmle.label | key | +| tests.js:559:24:559:26 | src | semmle.label | src | +| tests.js:559:24:559:31 | src[key] | semmle.label | src[key] | +| tests.js:559:28:559:30 | key | semmle.label | key | +| tests.js:564:35:564:37 | src | semmle.label | src | +| tests.js:565:14:565:16 | key | semmle.label | key | +| tests.js:569:43:569:45 | src | semmle.label | src | +| tests.js:569:43:569:50 | src[key] | semmle.label | src[key] | +| tests.js:571:17:571:19 | key | semmle.label | key | +| tests.js:571:24:571:26 | src | semmle.label | src | +| tests.js:571:24:571:31 | src[key] | semmle.label | src[key] | +| tests.js:571:28:571:30 | key | semmle.label | key | +| tests.js:576:30:576:32 | src | semmle.label | src | +| tests.js:577:14:577:16 | key | semmle.label | key | +| tests.js:580:38:580:40 | src | semmle.label | src | +| tests.js:580:38:580:45 | src[key] | semmle.label | src[key] | +| tests.js:582:17:582:19 | key | semmle.label | key | +| tests.js:582:24:582:26 | src | semmle.label | src | +| tests.js:582:24:582:31 | src[key] | semmle.label | src[key] | +| tests.js:582:28:582:30 | key | semmle.label | key | +| tests.js:591:25:591:27 | obj | semmle.label | obj | +| tests.js:592:7:592:9 | obj | semmle.label | obj | +| tests.js:592:21:592:23 | obj | semmle.label | obj | +| tests.js:593:10:593:12 | obj | semmle.label | obj | +| tests.js:600:31:600:34 | dest | semmle.label | dest | +| tests.js:600:37:600:42 | source | semmle.label | source | +| tests.js:601:16:601:18 | key | semmle.label | key | +| tests.js:603:34:603:37 | dest | semmle.label | dest | +| tests.js:603:34:603:42 | dest[key] | semmle.label | dest[key] | +| tests.js:603:39:603:41 | key | semmle.label | key | +| tests.js:603:45:603:50 | source | semmle.label | source | +| tests.js:603:45:603:55 | source[key] | semmle.label | source[key] | +| tests.js:603:52:603:54 | key | semmle.label | key | +| tests.js:605:13:605:16 | dest | semmle.label | dest | +| tests.js:605:18:605:20 | key | semmle.label | key | +| tests.js:605:25:605:51 | capture ... e[key]) | semmle.label | capture ... e[key]) | +| tests.js:605:40:605:45 | source | semmle.label | source | +| tests.js:605:40:605:50 | source[key] | semmle.label | source[key] | +| tests.js:605:47:605:49 | key | semmle.label | key | edges | examples/PrototypePollutingFunction.js:1:16:1:18 | dst | examples/PrototypePollutingFunction.js:5:19:5:21 | dst | -| examples/PrototypePollutingFunction.js:1:16:1:18 | dst | examples/PrototypePollutingFunction.js:5:19:5:21 | dst | -| examples/PrototypePollutingFunction.js:1:16:1:18 | dst | examples/PrototypePollutingFunction.js:7:13:7:15 | dst | -| examples/PrototypePollutingFunction.js:1:16:1:18 | dst | examples/PrototypePollutingFunction.js:7:13:7:15 | dst | -| examples/PrototypePollutingFunction.js:1:16:1:18 | dst | examples/PrototypePollutingFunction.js:7:13:7:15 | dst | | examples/PrototypePollutingFunction.js:1:16:1:18 | dst | examples/PrototypePollutingFunction.js:7:13:7:15 | dst | | examples/PrototypePollutingFunction.js:1:21:1:23 | src | examples/PrototypePollutingFunction.js:5:29:5:31 | src | -| examples/PrototypePollutingFunction.js:1:21:1:23 | src | examples/PrototypePollutingFunction.js:5:29:5:31 | src | -| examples/PrototypePollutingFunction.js:1:21:1:23 | src | examples/PrototypePollutingFunction.js:7:24:7:26 | src | | examples/PrototypePollutingFunction.js:1:21:1:23 | src | examples/PrototypePollutingFunction.js:7:24:7:26 | src | | examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:5:23:5:25 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:5:23:5:25 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:5:23:5:25 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:5:23:5:25 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:5:33:5:35 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:5:33:5:35 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:5:33:5:35 | key | | examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:5:33:5:35 | key | | examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:28:7:30 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:28:7:30 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:28:7:30 | key | | examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:28:7:30 | key | | examples/PrototypePollutingFunction.js:5:19:5:21 | dst | examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | -| examples/PrototypePollutingFunction.js:5:19:5:21 | dst | examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | -| examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | examples/PrototypePollutingFunction.js:1:16:1:18 | dst | -| examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | examples/PrototypePollutingFunction.js:1:16:1:18 | dst | -| examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | examples/PrototypePollutingFunction.js:1:16:1:18 | dst | | examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | examples/PrototypePollutingFunction.js:1:16:1:18 | dst | | examples/PrototypePollutingFunction.js:5:23:5:25 | key | examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | -| examples/PrototypePollutingFunction.js:5:23:5:25 | key | examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | -| examples/PrototypePollutingFunction.js:5:29:5:31 | src | examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | | examples/PrototypePollutingFunction.js:5:29:5:31 | src | examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | | examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction.js:5:33:5:35 | key | examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | | examples/PrototypePollutingFunction.js:5:33:5:35 | key | examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | | examples/PrototypePollutingFunction.js:7:24:7:26 | src | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction.js:7:24:7:26 | src | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction.js:7:24:7:26 | src | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction.js:7:24:7:26 | src | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction.js:7:28:7:30 | key | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction.js:7:28:7:30 | key | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction.js:7:28:7:30 | key | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | | examples/PrototypePollutingFunction.js:7:28:7:30 | key | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | | examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed2.js:6:29:6:31 | src | -| examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed2.js:6:29:6:31 | src | -| examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed2.js:8:24:8:26 | src | | examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed2.js:8:24:8:26 | src | | examples/PrototypePollutingFunction_fixed2.js:6:29:6:31 | src | examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:6:29:6:31 | src | examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | | examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | | examples/PrototypePollutingFunction_fixed2.js:8:24:8:26 | src | examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:8:24:8:26 | src | examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:8:24:8:26 | src | examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:8:24:8:26 | src | examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed.js:5:29:5:31 | src | | examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed.js:5:29:5:31 | src | | examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed.js:7:24:7:26 | src | -| examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed.js:7:24:7:26 | src | | examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | -| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | -| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | | examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | | examples/PrototypePollutingFunction_fixed.js:5:29:5:31 | src | examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:5:29:5:31 | src | examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | | examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | | examples/PrototypePollutingFunction_fixed.js:7:24:7:26 | src | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:7:24:7:26 | src | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:7:24:7:26 | src | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:7:24:7:26 | src | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | | examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | | path-assignment.js:8:13:8:25 | key | path-assignment.js:13:29:13:31 | key | -| path-assignment.js:8:13:8:25 | key | path-assignment.js:13:29:13:31 | key | | path-assignment.js:8:13:8:25 | key | path-assignment.js:15:20:15:22 | key | -| path-assignment.js:8:13:8:25 | key | path-assignment.js:15:20:15:22 | key | -| path-assignment.js:8:13:8:25 | key | path-assignment.js:15:20:15:22 | key | -| path-assignment.js:8:13:8:25 | key | path-assignment.js:15:20:15:22 | key | -| path-assignment.js:8:19:8:25 | keys[i] | path-assignment.js:8:13:8:25 | key | -| path-assignment.js:8:19:8:25 | keys[i] | path-assignment.js:8:13:8:25 | key | -| path-assignment.js:8:19:8:25 | keys[i] | path-assignment.js:8:13:8:25 | key | | path-assignment.js:8:19:8:25 | keys[i] | path-assignment.js:8:13:8:25 | key | | path-assignment.js:13:13:13:32 | target | path-assignment.js:13:22:13:27 | target | -| path-assignment.js:13:13:13:32 | target | path-assignment.js:13:22:13:27 | target | -| path-assignment.js:13:13:13:32 | target | path-assignment.js:15:13:15:18 | target | -| path-assignment.js:13:13:13:32 | target | path-assignment.js:15:13:15:18 | target | -| path-assignment.js:13:13:13:32 | target | path-assignment.js:15:13:15:18 | target | | path-assignment.js:13:13:13:32 | target | path-assignment.js:15:13:15:18 | target | | path-assignment.js:13:22:13:27 | target | path-assignment.js:13:22:13:32 | target[key] | -| path-assignment.js:13:22:13:27 | target | path-assignment.js:13:22:13:32 | target[key] | -| path-assignment.js:13:22:13:32 | target[key] | path-assignment.js:13:13:13:32 | target | | path-assignment.js:13:22:13:32 | target[key] | path-assignment.js:13:13:13:32 | target | | path-assignment.js:13:29:13:31 | key | path-assignment.js:13:22:13:32 | target[key] | -| path-assignment.js:13:29:13:31 | key | path-assignment.js:13:22:13:32 | target[key] | -| path-assignment.js:41:13:41:25 | key | path-assignment.js:42:25:42:27 | key | -| path-assignment.js:41:13:41:25 | key | path-assignment.js:42:25:42:27 | key | -| path-assignment.js:41:13:41:25 | key | path-assignment.js:42:25:42:27 | key | | path-assignment.js:41:13:41:25 | key | path-assignment.js:42:25:42:27 | key | | path-assignment.js:41:13:41:25 | key | path-assignment.js:42:39:42:41 | key | -| path-assignment.js:41:13:41:25 | key | path-assignment.js:42:39:42:41 | key | | path-assignment.js:41:19:41:25 | keys[i] | path-assignment.js:41:13:41:25 | key | -| path-assignment.js:41:19:41:25 | keys[i] | path-assignment.js:41:13:41:25 | key | -| path-assignment.js:41:19:41:25 | keys[i] | path-assignment.js:41:13:41:25 | key | -| path-assignment.js:41:19:41:25 | keys[i] | path-assignment.js:41:13:41:25 | key | -| path-assignment.js:42:9:42:48 | target | path-assignment.js:42:18:42:23 | target | -| path-assignment.js:42:9:42:48 | target | path-assignment.js:42:18:42:23 | target | -| path-assignment.js:42:9:42:48 | target | path-assignment.js:42:18:42:23 | target | | path-assignment.js:42:9:42:48 | target | path-assignment.js:42:18:42:23 | target | | path-assignment.js:42:9:42:48 | target | path-assignment.js:42:32:42:37 | target | -| path-assignment.js:42:9:42:48 | target | path-assignment.js:42:32:42:37 | target | | path-assignment.js:42:9:42:48 | target | path-assignment.js:44:5:44:10 | target | -| path-assignment.js:42:9:42:48 | target | path-assignment.js:44:5:44:10 | target | -| path-assignment.js:42:9:42:48 | target | path-assignment.js:44:5:44:10 | target | -| path-assignment.js:42:9:42:48 | target | path-assignment.js:44:5:44:10 | target | -| path-assignment.js:42:18:42:48 | target[ ... ] \|\| {} | path-assignment.js:42:9:42:48 | target | -| path-assignment.js:42:18:42:48 | target[ ... ] \|\| {} | path-assignment.js:42:9:42:48 | target | -| path-assignment.js:42:32:42:37 | target | path-assignment.js:42:32:42:42 | target[key] | | path-assignment.js:42:32:42:37 | target | path-assignment.js:42:32:42:42 | target[key] | +| path-assignment.js:42:32:42:42 | target[key] | path-assignment.js:42:9:42:48 | target | | path-assignment.js:42:32:42:42 | target[key] | path-assignment.js:42:32:42:48 | target[key] \|\| {} | -| path-assignment.js:42:32:42:42 | target[key] | path-assignment.js:42:32:42:48 | target[key] \|\| {} | -| path-assignment.js:42:32:42:42 | target[key] | path-assignment.js:42:32:42:48 | target[key] \|\| {} | -| path-assignment.js:42:32:42:42 | target[key] | path-assignment.js:42:32:42:48 | target[key] \|\| {} | -| path-assignment.js:42:32:42:48 | target[key] \|\| {} | path-assignment.js:42:18:42:48 | target[ ... ] \|\| {} | -| path-assignment.js:42:32:42:48 | target[key] \|\| {} | path-assignment.js:42:18:42:48 | target[ ... ] \|\| {} | | path-assignment.js:42:39:42:41 | key | path-assignment.js:42:32:42:42 | target[key] | -| path-assignment.js:42:39:42:41 | key | path-assignment.js:42:32:42:42 | target[key] | -| path-assignment.js:44:12:44:18 | keys[i] | path-assignment.js:44:12:44:18 | keys[i] | -| path-assignment.js:58:13:58:25 | key | path-assignment.js:59:25:59:27 | key | -| path-assignment.js:58:13:58:25 | key | path-assignment.js:59:25:59:27 | key | -| path-assignment.js:58:13:58:25 | key | path-assignment.js:59:25:59:27 | key | | path-assignment.js:58:13:58:25 | key | path-assignment.js:59:25:59:27 | key | | path-assignment.js:58:13:58:25 | key | path-assignment.js:59:39:59:41 | key | -| path-assignment.js:58:13:58:25 | key | path-assignment.js:59:39:59:41 | key | | path-assignment.js:58:19:58:25 | keys[i] | path-assignment.js:58:13:58:25 | key | -| path-assignment.js:58:19:58:25 | keys[i] | path-assignment.js:58:13:58:25 | key | -| path-assignment.js:58:19:58:25 | keys[i] | path-assignment.js:58:13:58:25 | key | -| path-assignment.js:58:19:58:25 | keys[i] | path-assignment.js:58:13:58:25 | key | -| path-assignment.js:59:9:59:48 | target | path-assignment.js:59:18:59:23 | target | -| path-assignment.js:59:9:59:48 | target | path-assignment.js:59:18:59:23 | target | -| path-assignment.js:59:9:59:48 | target | path-assignment.js:59:18:59:23 | target | | path-assignment.js:59:9:59:48 | target | path-assignment.js:59:18:59:23 | target | | path-assignment.js:59:9:59:48 | target | path-assignment.js:59:32:59:37 | target | -| path-assignment.js:59:9:59:48 | target | path-assignment.js:59:32:59:37 | target | | path-assignment.js:59:9:59:48 | target | path-assignment.js:61:5:61:10 | target | -| path-assignment.js:59:9:59:48 | target | path-assignment.js:61:5:61:10 | target | -| path-assignment.js:59:9:59:48 | target | path-assignment.js:61:5:61:10 | target | -| path-assignment.js:59:9:59:48 | target | path-assignment.js:61:5:61:10 | target | -| path-assignment.js:59:18:59:48 | target[ ... ] \|\| {} | path-assignment.js:59:9:59:48 | target | -| path-assignment.js:59:18:59:48 | target[ ... ] \|\| {} | path-assignment.js:59:9:59:48 | target | -| path-assignment.js:59:32:59:37 | target | path-assignment.js:59:32:59:42 | target[key] | | path-assignment.js:59:32:59:37 | target | path-assignment.js:59:32:59:42 | target[key] | +| path-assignment.js:59:32:59:42 | target[key] | path-assignment.js:59:9:59:48 | target | | path-assignment.js:59:32:59:42 | target[key] | path-assignment.js:59:32:59:48 | target[key] \|\| {} | -| path-assignment.js:59:32:59:42 | target[key] | path-assignment.js:59:32:59:48 | target[key] \|\| {} | -| path-assignment.js:59:32:59:42 | target[key] | path-assignment.js:59:32:59:48 | target[key] \|\| {} | -| path-assignment.js:59:32:59:42 | target[key] | path-assignment.js:59:32:59:48 | target[key] \|\| {} | -| path-assignment.js:59:32:59:48 | target[key] \|\| {} | path-assignment.js:59:18:59:48 | target[ ... ] \|\| {} | -| path-assignment.js:59:32:59:48 | target[key] \|\| {} | path-assignment.js:59:18:59:48 | target[ ... ] \|\| {} | | path-assignment.js:59:39:59:41 | key | path-assignment.js:59:32:59:42 | target[key] | -| path-assignment.js:59:39:59:41 | key | path-assignment.js:59:32:59:42 | target[key] | -| path-assignment.js:61:12:61:18 | keys[i] | path-assignment.js:61:12:61:18 | keys[i] | -| path-assignment.js:68:13:68:25 | key | path-assignment.js:69:25:69:27 | key | -| path-assignment.js:68:13:68:25 | key | path-assignment.js:69:25:69:27 | key | -| path-assignment.js:68:13:68:25 | key | path-assignment.js:69:25:69:27 | key | | path-assignment.js:68:13:68:25 | key | path-assignment.js:69:25:69:27 | key | | path-assignment.js:68:13:68:25 | key | path-assignment.js:69:39:69:41 | key | -| path-assignment.js:68:13:68:25 | key | path-assignment.js:69:39:69:41 | key | | path-assignment.js:68:19:68:25 | keys[i] | path-assignment.js:68:13:68:25 | key | -| path-assignment.js:68:19:68:25 | keys[i] | path-assignment.js:68:13:68:25 | key | -| path-assignment.js:68:19:68:25 | keys[i] | path-assignment.js:68:13:68:25 | key | -| path-assignment.js:68:19:68:25 | keys[i] | path-assignment.js:68:13:68:25 | key | -| path-assignment.js:69:9:69:48 | target | path-assignment.js:69:18:69:23 | target | -| path-assignment.js:69:9:69:48 | target | path-assignment.js:69:18:69:23 | target | -| path-assignment.js:69:9:69:48 | target | path-assignment.js:69:18:69:23 | target | | path-assignment.js:69:9:69:48 | target | path-assignment.js:69:18:69:23 | target | | path-assignment.js:69:9:69:48 | target | path-assignment.js:69:32:69:37 | target | -| path-assignment.js:69:9:69:48 | target | path-assignment.js:69:32:69:37 | target | | path-assignment.js:69:9:69:48 | target | path-assignment.js:71:5:71:10 | target | -| path-assignment.js:69:9:69:48 | target | path-assignment.js:71:5:71:10 | target | -| path-assignment.js:69:9:69:48 | target | path-assignment.js:71:5:71:10 | target | -| path-assignment.js:69:9:69:48 | target | path-assignment.js:71:5:71:10 | target | -| path-assignment.js:69:18:69:48 | target[ ... ] \|\| {} | path-assignment.js:69:9:69:48 | target | -| path-assignment.js:69:18:69:48 | target[ ... ] \|\| {} | path-assignment.js:69:9:69:48 | target | -| path-assignment.js:69:32:69:37 | target | path-assignment.js:69:32:69:42 | target[key] | | path-assignment.js:69:32:69:37 | target | path-assignment.js:69:32:69:42 | target[key] | +| path-assignment.js:69:32:69:42 | target[key] | path-assignment.js:69:9:69:48 | target | | path-assignment.js:69:32:69:42 | target[key] | path-assignment.js:69:32:69:48 | target[key] \|\| {} | -| path-assignment.js:69:32:69:42 | target[key] | path-assignment.js:69:32:69:48 | target[key] \|\| {} | -| path-assignment.js:69:32:69:42 | target[key] | path-assignment.js:69:32:69:48 | target[key] \|\| {} | -| path-assignment.js:69:32:69:42 | target[key] | path-assignment.js:69:32:69:48 | target[key] \|\| {} | -| path-assignment.js:69:32:69:48 | target[key] \|\| {} | path-assignment.js:69:18:69:48 | target[ ... ] \|\| {} | -| path-assignment.js:69:32:69:48 | target[key] \|\| {} | path-assignment.js:69:18:69:48 | target[ ... ] \|\| {} | | path-assignment.js:69:39:69:41 | key | path-assignment.js:69:32:69:42 | target[key] | -| path-assignment.js:69:39:69:41 | key | path-assignment.js:69:32:69:42 | target[key] | -| path-assignment.js:71:12:71:18 | keys[i] | path-assignment.js:71:12:71:18 | keys[i] | -| tests.js:3:25:3:27 | dst | tests.js:6:28:6:30 | dst | | tests.js:3:25:3:27 | dst | tests.js:6:28:6:30 | dst | | tests.js:3:25:3:27 | dst | tests.js:8:13:8:15 | dst | -| tests.js:3:25:3:27 | dst | tests.js:8:13:8:15 | dst | -| tests.js:3:25:3:27 | dst | tests.js:8:13:8:15 | dst | -| tests.js:3:25:3:27 | dst | tests.js:8:13:8:15 | dst | -| tests.js:3:30:3:32 | src | tests.js:6:38:6:40 | src | | tests.js:3:30:3:32 | src | tests.js:6:38:6:40 | src | | tests.js:3:30:3:32 | src | tests.js:8:24:8:26 | src | -| tests.js:3:30:3:32 | src | tests.js:8:24:8:26 | src | -| tests.js:4:14:4:16 | key | tests.js:6:32:6:34 | key | -| tests.js:4:14:4:16 | key | tests.js:6:32:6:34 | key | -| tests.js:4:14:4:16 | key | tests.js:6:32:6:34 | key | | tests.js:4:14:4:16 | key | tests.js:6:32:6:34 | key | | tests.js:4:14:4:16 | key | tests.js:6:42:6:44 | key | -| tests.js:4:14:4:16 | key | tests.js:6:42:6:44 | key | -| tests.js:4:14:4:16 | key | tests.js:6:42:6:44 | key | -| tests.js:4:14:4:16 | key | tests.js:6:42:6:44 | key | | tests.js:4:14:4:16 | key | tests.js:8:17:8:19 | key | -| tests.js:4:14:4:16 | key | tests.js:8:17:8:19 | key | -| tests.js:4:14:4:16 | key | tests.js:8:17:8:19 | key | -| tests.js:4:14:4:16 | key | tests.js:8:17:8:19 | key | -| tests.js:4:14:4:16 | key | tests.js:8:17:8:19 | key | -| tests.js:4:14:4:16 | key | tests.js:8:17:8:19 | key | -| tests.js:4:14:4:16 | key | tests.js:8:17:8:19 | key | -| tests.js:4:14:4:16 | key | tests.js:8:28:8:30 | key | -| tests.js:4:14:4:16 | key | tests.js:8:28:8:30 | key | -| tests.js:4:14:4:16 | key | tests.js:8:28:8:30 | key | | tests.js:4:14:4:16 | key | tests.js:8:28:8:30 | key | | tests.js:6:28:6:30 | dst | tests.js:6:28:6:35 | dst[key] | -| tests.js:6:28:6:30 | dst | tests.js:6:28:6:35 | dst[key] | -| tests.js:6:28:6:35 | dst[key] | tests.js:3:25:3:27 | dst | -| tests.js:6:28:6:35 | dst[key] | tests.js:3:25:3:27 | dst | -| tests.js:6:28:6:35 | dst[key] | tests.js:3:25:3:27 | dst | | tests.js:6:28:6:35 | dst[key] | tests.js:3:25:3:27 | dst | | tests.js:6:32:6:34 | key | tests.js:6:28:6:35 | dst[key] | -| tests.js:6:32:6:34 | key | tests.js:6:28:6:35 | dst[key] | -| tests.js:6:38:6:40 | src | tests.js:6:38:6:45 | src[key] | | tests.js:6:38:6:40 | src | tests.js:6:38:6:45 | src[key] | | tests.js:6:38:6:45 | src[key] | tests.js:3:30:3:32 | src | -| tests.js:6:38:6:45 | src[key] | tests.js:3:30:3:32 | src | -| tests.js:6:38:6:45 | src[key] | tests.js:3:30:3:32 | src | -| tests.js:6:38:6:45 | src[key] | tests.js:3:30:3:32 | src | -| tests.js:6:38:6:45 | src[key] | tests.js:3:30:3:32 | src | -| tests.js:6:38:6:45 | src[key] | tests.js:3:30:3:32 | src | -| tests.js:6:42:6:44 | key | tests.js:6:38:6:45 | src[key] | | tests.js:6:42:6:44 | key | tests.js:6:38:6:45 | src[key] | | tests.js:8:24:8:26 | src | tests.js:8:24:8:31 | src[key] | -| tests.js:8:24:8:26 | src | tests.js:8:24:8:31 | src[key] | -| tests.js:8:24:8:26 | src | tests.js:8:24:8:31 | src[key] | -| tests.js:8:24:8:26 | src | tests.js:8:24:8:31 | src[key] | -| tests.js:8:24:8:31 | src[key] | tests.js:8:24:8:31 | src[key] | -| tests.js:8:28:8:30 | key | tests.js:8:24:8:31 | src[key] | -| tests.js:8:28:8:30 | key | tests.js:8:24:8:31 | src[key] | -| tests.js:8:28:8:30 | key | tests.js:8:24:8:31 | src[key] | | tests.js:8:28:8:30 | key | tests.js:8:24:8:31 | src[key] | | tests.js:13:24:13:26 | dst | tests.js:16:27:16:29 | dst | -| tests.js:13:24:13:26 | dst | tests.js:16:27:16:29 | dst | | tests.js:13:24:13:26 | dst | tests.js:18:13:18:15 | dst | -| tests.js:13:24:13:26 | dst | tests.js:18:13:18:15 | dst | -| tests.js:13:24:13:26 | dst | tests.js:18:13:18:15 | dst | -| tests.js:13:24:13:26 | dst | tests.js:18:13:18:15 | dst | -| tests.js:13:29:13:31 | src | tests.js:16:37:16:39 | src | -| tests.js:13:29:13:31 | src | tests.js:16:37:16:39 | src | -| tests.js:13:29:13:31 | src | tests.js:18:24:18:26 | src | -| tests.js:13:29:13:31 | src | tests.js:18:24:18:26 | src | -| tests.js:14:30:14:32 | key | tests.js:16:31:16:33 | key | -| tests.js:14:30:14:32 | key | tests.js:16:31:16:33 | key | -| tests.js:14:30:14:32 | key | tests.js:16:31:16:33 | key | +| tests.js:13:29:13:31 | src | tests.js:14:17:14:19 | src | +| tests.js:14:17:14:19 | src | tests.js:16:37:16:39 | src | +| tests.js:14:17:14:19 | src | tests.js:18:24:18:26 | src | | tests.js:14:30:14:32 | key | tests.js:16:31:16:33 | key | | tests.js:14:30:14:32 | key | tests.js:16:41:16:43 | key | -| tests.js:14:30:14:32 | key | tests.js:16:41:16:43 | key | -| tests.js:14:30:14:32 | key | tests.js:16:41:16:43 | key | -| tests.js:14:30:14:32 | key | tests.js:16:41:16:43 | key | | tests.js:14:30:14:32 | key | tests.js:18:17:18:19 | key | -| tests.js:14:30:14:32 | key | tests.js:18:17:18:19 | key | -| tests.js:14:30:14:32 | key | tests.js:18:17:18:19 | key | -| tests.js:14:30:14:32 | key | tests.js:18:17:18:19 | key | -| tests.js:14:30:14:32 | key | tests.js:18:17:18:19 | key | -| tests.js:14:30:14:32 | key | tests.js:18:17:18:19 | key | -| tests.js:14:30:14:32 | key | tests.js:18:17:18:19 | key | -| tests.js:14:30:14:32 | key | tests.js:18:28:18:30 | key | -| tests.js:14:30:14:32 | key | tests.js:18:28:18:30 | key | -| tests.js:14:30:14:32 | key | tests.js:18:28:18:30 | key | | tests.js:14:30:14:32 | key | tests.js:18:28:18:30 | key | | tests.js:16:27:16:29 | dst | tests.js:16:27:16:34 | dst[key] | -| tests.js:16:27:16:29 | dst | tests.js:16:27:16:34 | dst[key] | -| tests.js:16:27:16:34 | dst[key] | tests.js:13:24:13:26 | dst | -| tests.js:16:27:16:34 | dst[key] | tests.js:13:24:13:26 | dst | -| tests.js:16:27:16:34 | dst[key] | tests.js:13:24:13:26 | dst | | tests.js:16:27:16:34 | dst[key] | tests.js:13:24:13:26 | dst | | tests.js:16:31:16:33 | key | tests.js:16:27:16:34 | dst[key] | -| tests.js:16:31:16:33 | key | tests.js:16:27:16:34 | dst[key] | -| tests.js:16:37:16:39 | src | tests.js:16:37:16:44 | src[key] | | tests.js:16:37:16:39 | src | tests.js:16:37:16:44 | src[key] | | tests.js:16:37:16:44 | src[key] | tests.js:13:29:13:31 | src | -| tests.js:16:37:16:44 | src[key] | tests.js:13:29:13:31 | src | -| tests.js:16:37:16:44 | src[key] | tests.js:13:29:13:31 | src | -| tests.js:16:37:16:44 | src[key] | tests.js:13:29:13:31 | src | -| tests.js:16:37:16:44 | src[key] | tests.js:13:29:13:31 | src | -| tests.js:16:37:16:44 | src[key] | tests.js:13:29:13:31 | src | -| tests.js:16:41:16:43 | key | tests.js:16:37:16:44 | src[key] | | tests.js:16:41:16:43 | key | tests.js:16:37:16:44 | src[key] | | tests.js:18:24:18:26 | src | tests.js:18:24:18:31 | src[key] | -| tests.js:18:24:18:26 | src | tests.js:18:24:18:31 | src[key] | -| tests.js:18:24:18:26 | src | tests.js:18:24:18:31 | src[key] | -| tests.js:18:24:18:26 | src | tests.js:18:24:18:31 | src[key] | -| tests.js:18:24:18:31 | src[key] | tests.js:18:24:18:31 | src[key] | -| tests.js:18:28:18:30 | key | tests.js:18:24:18:31 | src[key] | -| tests.js:18:28:18:30 | key | tests.js:18:24:18:31 | src[key] | -| tests.js:18:28:18:30 | key | tests.js:18:24:18:31 | src[key] | | tests.js:18:28:18:30 | key | tests.js:18:24:18:31 | src[key] | | tests.js:23:19:23:21 | dst | tests.js:26:25:26:27 | dst | -| tests.js:23:19:23:21 | dst | tests.js:26:25:26:27 | dst | | tests.js:25:18:25:20 | key | tests.js:26:37:26:39 | key | -| tests.js:25:18:25:20 | key | tests.js:26:37:26:39 | key | -| tests.js:25:18:25:20 | key | tests.js:26:37:26:39 | key | -| tests.js:25:18:25:20 | key | tests.js:26:37:26:39 | key | -| tests.js:25:18:25:20 | key | tests.js:26:43:26:45 | key | -| tests.js:25:18:25:20 | key | tests.js:26:43:26:45 | key | -| tests.js:25:18:25:20 | key | tests.js:26:43:26:45 | key | | tests.js:25:18:25:20 | key | tests.js:26:43:26:45 | key | | tests.js:26:25:26:27 | dst | tests.js:31:22:31:24 | dst | -| tests.js:26:25:26:27 | dst | tests.js:31:22:31:24 | dst | -| tests.js:26:30:26:40 | source[key] | tests.js:31:27:31:31 | value | -| tests.js:26:30:26:40 | source[key] | tests.js:31:27:31:31 | value | -| tests.js:26:30:26:40 | source[key] | tests.js:31:27:31:31 | value | | tests.js:26:30:26:40 | source[key] | tests.js:31:27:31:31 | value | | tests.js:26:37:26:39 | key | tests.js:26:30:26:40 | source[key] | -| tests.js:26:37:26:39 | key | tests.js:26:30:26:40 | source[key] | -| tests.js:26:43:26:45 | key | tests.js:31:34:31:36 | key | | tests.js:26:43:26:45 | key | tests.js:31:34:31:36 | key | | tests.js:31:22:31:24 | dst | tests.js:32:20:32:22 | dst | -| tests.js:31:22:31:24 | dst | tests.js:32:20:32:22 | dst | | tests.js:31:22:31:24 | dst | tests.js:36:9:36:11 | dst | -| tests.js:31:22:31:24 | dst | tests.js:36:9:36:11 | dst | -| tests.js:31:22:31:24 | dst | tests.js:36:9:36:11 | dst | -| tests.js:31:22:31:24 | dst | tests.js:36:9:36:11 | dst | -| tests.js:31:27:31:31 | value | tests.js:36:20:36:24 | value | -| tests.js:31:27:31:31 | value | tests.js:36:20:36:24 | value | -| tests.js:31:27:31:31 | value | tests.js:36:20:36:24 | value | | tests.js:31:27:31:31 | value | tests.js:36:20:36:24 | value | | tests.js:31:34:31:36 | key | tests.js:32:24:32:26 | key | -| tests.js:31:34:31:36 | key | tests.js:32:24:32:26 | key | -| tests.js:31:34:31:36 | key | tests.js:36:13:36:15 | key | -| tests.js:31:34:31:36 | key | tests.js:36:13:36:15 | key | -| tests.js:31:34:31:36 | key | tests.js:36:13:36:15 | key | | tests.js:31:34:31:36 | key | tests.js:36:13:36:15 | key | | tests.js:32:9:32:27 | dstValue | tests.js:34:18:34:25 | dstValue | -| tests.js:32:9:32:27 | dstValue | tests.js:34:18:34:25 | dstValue | -| tests.js:32:20:32:22 | dst | tests.js:32:20:32:27 | dst[key] | | tests.js:32:20:32:22 | dst | tests.js:32:20:32:27 | dst[key] | | tests.js:32:20:32:27 | dst[key] | tests.js:32:9:32:27 | dstValue | -| tests.js:32:20:32:27 | dst[key] | tests.js:32:9:32:27 | dstValue | | tests.js:32:24:32:26 | key | tests.js:32:20:32:27 | dst[key] | -| tests.js:32:24:32:26 | key | tests.js:32:20:32:27 | dst[key] | -| tests.js:34:18:34:25 | dstValue | tests.js:23:19:23:21 | dst | | tests.js:34:18:34:25 | dstValue | tests.js:23:19:23:21 | dst | | tests.js:40:27:40:29 | dst | tests.js:44:30:44:32 | dst | | tests.js:40:27:40:29 | dst | tests.js:46:13:46:15 | dst | -| tests.js:40:27:40:29 | dst | tests.js:46:13:46:15 | dst | -| tests.js:40:32:40:34 | src | tests.js:44:40:44:42 | src | | tests.js:40:32:40:34 | src | tests.js:44:40:44:42 | src | | tests.js:40:32:40:34 | src | tests.js:46:24:46:26 | src | -| tests.js:40:32:40:34 | src | tests.js:46:24:46:26 | src | -| tests.js:41:14:41:16 | key | tests.js:44:34:44:36 | key | | tests.js:41:14:41:16 | key | tests.js:44:34:44:36 | key | | tests.js:41:14:41:16 | key | tests.js:44:44:44:46 | key | -| tests.js:41:14:41:16 | key | tests.js:44:44:44:46 | key | | tests.js:41:14:41:16 | key | tests.js:46:17:46:19 | key | -| tests.js:41:14:41:16 | key | tests.js:46:17:46:19 | key | -| tests.js:41:14:41:16 | key | tests.js:46:17:46:19 | key | -| tests.js:41:14:41:16 | key | tests.js:46:17:46:19 | key | -| tests.js:41:14:41:16 | key | tests.js:46:28:46:30 | key | | tests.js:41:14:41:16 | key | tests.js:46:28:46:30 | key | | tests.js:44:30:44:32 | dst | tests.js:44:30:44:37 | dst[key] | | tests.js:44:30:44:37 | dst[key] | tests.js:40:27:40:29 | dst | -| tests.js:44:30:44:37 | dst[key] | tests.js:40:27:40:29 | dst | | tests.js:44:34:44:36 | key | tests.js:44:30:44:37 | dst[key] | | tests.js:44:40:44:42 | src | tests.js:44:40:44:47 | src[key] | -| tests.js:44:40:44:42 | src | tests.js:44:40:44:47 | src[key] | -| tests.js:44:40:44:47 | src[key] | tests.js:40:32:40:34 | src | -| tests.js:44:40:44:47 | src[key] | tests.js:40:32:40:34 | src | -| tests.js:44:40:44:47 | src[key] | tests.js:40:32:40:34 | src | -| tests.js:44:40:44:47 | src[key] | tests.js:40:32:40:34 | src | -| tests.js:44:40:44:47 | src[key] | tests.js:40:32:40:34 | src | | tests.js:44:40:44:47 | src[key] | tests.js:40:32:40:34 | src | | tests.js:44:44:44:46 | key | tests.js:44:40:44:47 | src[key] | | tests.js:46:24:46:26 | src | tests.js:46:24:46:31 | src[key] | -| tests.js:46:24:46:26 | src | tests.js:46:24:46:31 | src[key] | -| tests.js:46:24:46:26 | src | tests.js:46:24:46:31 | src[key] | -| tests.js:46:24:46:26 | src | tests.js:46:24:46:31 | src[key] | -| tests.js:46:24:46:31 | src[key] | tests.js:46:24:46:31 | src[key] | -| tests.js:46:28:46:30 | key | tests.js:46:24:46:31 | src[key] | | tests.js:46:28:46:30 | key | tests.js:46:24:46:31 | src[key] | | tests.js:51:26:51:28 | dst | tests.js:55:29:55:31 | dst | | tests.js:51:26:51:28 | dst | tests.js:57:13:57:15 | dst | -| tests.js:51:26:51:28 | dst | tests.js:57:13:57:15 | dst | -| tests.js:51:31:51:33 | src | tests.js:55:39:55:41 | src | | tests.js:51:31:51:33 | src | tests.js:55:39:55:41 | src | | tests.js:51:31:51:33 | src | tests.js:57:24:57:26 | src | -| tests.js:51:31:51:33 | src | tests.js:57:24:57:26 | src | -| tests.js:52:14:52:16 | key | tests.js:55:33:55:35 | key | | tests.js:52:14:52:16 | key | tests.js:55:33:55:35 | key | | tests.js:52:14:52:16 | key | tests.js:55:43:55:45 | key | -| tests.js:52:14:52:16 | key | tests.js:55:43:55:45 | key | | tests.js:52:14:52:16 | key | tests.js:57:17:57:19 | key | -| tests.js:52:14:52:16 | key | tests.js:57:17:57:19 | key | -| tests.js:52:14:52:16 | key | tests.js:57:17:57:19 | key | -| tests.js:52:14:52:16 | key | tests.js:57:17:57:19 | key | -| tests.js:52:14:52:16 | key | tests.js:57:28:57:30 | key | | tests.js:52:14:52:16 | key | tests.js:57:28:57:30 | key | | tests.js:55:29:55:31 | dst | tests.js:55:29:55:36 | dst[key] | | tests.js:55:29:55:36 | dst[key] | tests.js:51:26:51:28 | dst | -| tests.js:55:29:55:36 | dst[key] | tests.js:51:26:51:28 | dst | | tests.js:55:33:55:35 | key | tests.js:55:29:55:36 | dst[key] | | tests.js:55:39:55:41 | src | tests.js:55:39:55:46 | src[key] | -| tests.js:55:39:55:41 | src | tests.js:55:39:55:46 | src[key] | -| tests.js:55:39:55:46 | src[key] | tests.js:51:31:51:33 | src | -| tests.js:55:39:55:46 | src[key] | tests.js:51:31:51:33 | src | -| tests.js:55:39:55:46 | src[key] | tests.js:51:31:51:33 | src | -| tests.js:55:39:55:46 | src[key] | tests.js:51:31:51:33 | src | -| tests.js:55:39:55:46 | src[key] | tests.js:51:31:51:33 | src | | tests.js:55:39:55:46 | src[key] | tests.js:51:31:51:33 | src | | tests.js:55:43:55:45 | key | tests.js:55:39:55:46 | src[key] | | tests.js:57:24:57:26 | src | tests.js:57:24:57:31 | src[key] | -| tests.js:57:24:57:26 | src | tests.js:57:24:57:31 | src[key] | -| tests.js:57:24:57:26 | src | tests.js:57:24:57:31 | src[key] | -| tests.js:57:24:57:26 | src | tests.js:57:24:57:31 | src[key] | -| tests.js:57:24:57:31 | src[key] | tests.js:57:24:57:31 | src[key] | -| tests.js:57:28:57:30 | key | tests.js:57:24:57:31 | src[key] | | tests.js:57:28:57:30 | key | tests.js:57:24:57:31 | src[key] | | tests.js:62:33:62:35 | src | tests.js:66:41:66:43 | src | -| tests.js:62:33:62:35 | src | tests.js:66:41:66:43 | src | -| tests.js:62:33:62:35 | src | tests.js:68:24:68:26 | src | | tests.js:62:33:62:35 | src | tests.js:68:24:68:26 | src | | tests.js:66:41:66:43 | src | tests.js:66:41:66:48 | src[key] | -| tests.js:66:41:66:43 | src | tests.js:66:41:66:48 | src[key] | -| tests.js:66:41:66:48 | src[key] | tests.js:62:33:62:35 | src | -| tests.js:66:41:66:48 | src[key] | tests.js:62:33:62:35 | src | -| tests.js:66:41:66:48 | src[key] | tests.js:62:33:62:35 | src | -| tests.js:66:41:66:48 | src[key] | tests.js:62:33:62:35 | src | -| tests.js:66:41:66:48 | src[key] | tests.js:62:33:62:35 | src | | tests.js:66:41:66:48 | src[key] | tests.js:62:33:62:35 | src | | tests.js:68:24:68:26 | src | tests.js:68:24:68:31 | src[key] | -| tests.js:68:24:68:26 | src | tests.js:68:24:68:31 | src[key] | -| tests.js:68:24:68:26 | src | tests.js:68:24:68:31 | src[key] | -| tests.js:68:24:68:26 | src | tests.js:68:24:68:31 | src[key] | -| tests.js:68:24:68:31 | src[key] | tests.js:68:24:68:31 | src[key] | -| tests.js:77:27:77:29 | src | tests.js:81:39:81:41 | src | | tests.js:77:27:77:29 | src | tests.js:81:39:81:41 | src | | tests.js:77:27:77:29 | src | tests.js:83:28:83:30 | src | -| tests.js:77:27:77:29 | src | tests.js:83:28:83:30 | src | -| tests.js:81:39:81:41 | src | tests.js:81:39:81:46 | src[key] | | tests.js:81:39:81:41 | src | tests.js:81:39:81:46 | src[key] | | tests.js:81:39:81:46 | src[key] | tests.js:77:27:77:29 | src | -| tests.js:81:39:81:46 | src[key] | tests.js:77:27:77:29 | src | -| tests.js:81:39:81:46 | src[key] | tests.js:77:27:77:29 | src | -| tests.js:81:39:81:46 | src[key] | tests.js:77:27:77:29 | src | -| tests.js:81:39:81:46 | src[key] | tests.js:77:27:77:29 | src | -| tests.js:81:39:81:46 | src[key] | tests.js:77:27:77:29 | src | | tests.js:83:28:83:30 | src | tests.js:83:28:83:35 | src[key] | -| tests.js:83:28:83:30 | src | tests.js:83:28:83:35 | src[key] | -| tests.js:83:28:83:30 | src | tests.js:83:28:83:35 | src[key] | -| tests.js:83:28:83:30 | src | tests.js:83:28:83:35 | src[key] | -| tests.js:83:28:83:35 | src[key] | tests.js:83:28:83:35 | src[key] | -| tests.js:89:34:89:36 | src | tests.js:94:42:94:44 | src | | tests.js:89:34:89:36 | src | tests.js:94:42:94:44 | src | | tests.js:89:34:89:36 | src | tests.js:96:24:96:26 | src | -| tests.js:89:34:89:36 | src | tests.js:96:24:96:26 | src | | tests.js:90:14:90:16 | key | tests.js:96:17:96:19 | key | -| tests.js:90:14:90:16 | key | tests.js:96:17:96:19 | key | -| tests.js:90:14:90:16 | key | tests.js:96:17:96:19 | key | -| tests.js:90:14:90:16 | key | tests.js:96:17:96:19 | key | -| tests.js:90:14:90:16 | key | tests.js:96:17:96:19 | key | -| tests.js:90:14:90:16 | key | tests.js:96:17:96:19 | key | -| tests.js:90:14:90:16 | key | tests.js:96:17:96:19 | key | -| tests.js:90:14:90:16 | key | tests.js:96:28:96:30 | key | -| tests.js:90:14:90:16 | key | tests.js:96:28:96:30 | key | -| tests.js:90:14:90:16 | key | tests.js:96:28:96:30 | key | | tests.js:90:14:90:16 | key | tests.js:96:28:96:30 | key | | tests.js:94:42:94:44 | src | tests.js:94:42:94:49 | src[key] | -| tests.js:94:42:94:44 | src | tests.js:94:42:94:49 | src[key] | -| tests.js:94:42:94:49 | src[key] | tests.js:89:34:89:36 | src | -| tests.js:94:42:94:49 | src[key] | tests.js:89:34:89:36 | src | -| tests.js:94:42:94:49 | src[key] | tests.js:89:34:89:36 | src | -| tests.js:94:42:94:49 | src[key] | tests.js:89:34:89:36 | src | -| tests.js:94:42:94:49 | src[key] | tests.js:89:34:89:36 | src | | tests.js:94:42:94:49 | src[key] | tests.js:89:34:89:36 | src | | tests.js:96:24:96:26 | src | tests.js:96:24:96:31 | src[key] | -| tests.js:96:24:96:26 | src | tests.js:96:24:96:31 | src[key] | -| tests.js:96:24:96:26 | src | tests.js:96:24:96:31 | src[key] | -| tests.js:96:24:96:26 | src | tests.js:96:24:96:31 | src[key] | -| tests.js:96:24:96:31 | src[key] | tests.js:96:24:96:31 | src[key] | -| tests.js:96:28:96:30 | key | tests.js:96:24:96:31 | src[key] | -| tests.js:96:28:96:30 | key | tests.js:96:24:96:31 | src[key] | -| tests.js:96:28:96:30 | key | tests.js:96:24:96:31 | src[key] | | tests.js:96:28:96:30 | key | tests.js:96:24:96:31 | src[key] | | tests.js:101:32:101:34 | dst | tests.js:107:35:107:37 | dst | -| tests.js:101:32:101:34 | dst | tests.js:107:35:107:37 | dst | -| tests.js:101:32:101:34 | dst | tests.js:109:13:109:15 | dst | -| tests.js:101:32:101:34 | dst | tests.js:109:13:109:15 | dst | -| tests.js:101:32:101:34 | dst | tests.js:109:13:109:15 | dst | | tests.js:101:32:101:34 | dst | tests.js:109:13:109:15 | dst | | tests.js:101:37:101:39 | src | tests.js:107:45:107:47 | src | -| tests.js:101:37:101:39 | src | tests.js:107:45:107:47 | src | -| tests.js:101:37:101:39 | src | tests.js:109:24:109:26 | src | | tests.js:101:37:101:39 | src | tests.js:109:24:109:26 | src | | tests.js:102:14:102:16 | key | tests.js:107:39:107:41 | key | -| tests.js:102:14:102:16 | key | tests.js:107:39:107:41 | key | -| tests.js:102:14:102:16 | key | tests.js:107:39:107:41 | key | -| tests.js:102:14:102:16 | key | tests.js:107:39:107:41 | key | -| tests.js:102:14:102:16 | key | tests.js:107:49:107:51 | key | -| tests.js:102:14:102:16 | key | tests.js:107:49:107:51 | key | -| tests.js:102:14:102:16 | key | tests.js:107:49:107:51 | key | | tests.js:102:14:102:16 | key | tests.js:107:49:107:51 | key | | tests.js:102:14:102:16 | key | tests.js:109:17:109:19 | key | -| tests.js:102:14:102:16 | key | tests.js:109:17:109:19 | key | -| tests.js:102:14:102:16 | key | tests.js:109:17:109:19 | key | -| tests.js:102:14:102:16 | key | tests.js:109:17:109:19 | key | -| tests.js:102:14:102:16 | key | tests.js:109:17:109:19 | key | -| tests.js:102:14:102:16 | key | tests.js:109:17:109:19 | key | -| tests.js:102:14:102:16 | key | tests.js:109:17:109:19 | key | -| tests.js:102:14:102:16 | key | tests.js:109:28:109:30 | key | -| tests.js:102:14:102:16 | key | tests.js:109:28:109:30 | key | -| tests.js:102:14:102:16 | key | tests.js:109:28:109:30 | key | | tests.js:102:14:102:16 | key | tests.js:109:28:109:30 | key | | tests.js:107:35:107:37 | dst | tests.js:107:35:107:42 | dst[key] | -| tests.js:107:35:107:37 | dst | tests.js:107:35:107:42 | dst[key] | -| tests.js:107:35:107:42 | dst[key] | tests.js:101:32:101:34 | dst | -| tests.js:107:35:107:42 | dst[key] | tests.js:101:32:101:34 | dst | -| tests.js:107:35:107:42 | dst[key] | tests.js:101:32:101:34 | dst | | tests.js:107:35:107:42 | dst[key] | tests.js:101:32:101:34 | dst | | tests.js:107:39:107:41 | key | tests.js:107:35:107:42 | dst[key] | -| tests.js:107:39:107:41 | key | tests.js:107:35:107:42 | dst[key] | -| tests.js:107:45:107:47 | src | tests.js:107:45:107:52 | src[key] | | tests.js:107:45:107:47 | src | tests.js:107:45:107:52 | src[key] | | tests.js:107:45:107:52 | src[key] | tests.js:101:37:101:39 | src | -| tests.js:107:45:107:52 | src[key] | tests.js:101:37:101:39 | src | -| tests.js:107:45:107:52 | src[key] | tests.js:101:37:101:39 | src | -| tests.js:107:45:107:52 | src[key] | tests.js:101:37:101:39 | src | -| tests.js:107:45:107:52 | src[key] | tests.js:101:37:101:39 | src | -| tests.js:107:45:107:52 | src[key] | tests.js:101:37:101:39 | src | -| tests.js:107:49:107:51 | key | tests.js:107:45:107:52 | src[key] | | tests.js:107:49:107:51 | key | tests.js:107:45:107:52 | src[key] | | tests.js:109:24:109:26 | src | tests.js:109:24:109:31 | src[key] | -| tests.js:109:24:109:26 | src | tests.js:109:24:109:31 | src[key] | -| tests.js:109:24:109:26 | src | tests.js:109:24:109:31 | src[key] | -| tests.js:109:24:109:26 | src | tests.js:109:24:109:31 | src[key] | -| tests.js:109:24:109:31 | src[key] | tests.js:109:24:109:31 | src[key] | -| tests.js:109:28:109:30 | key | tests.js:109:24:109:31 | src[key] | -| tests.js:109:28:109:30 | key | tests.js:109:24:109:31 | src[key] | -| tests.js:109:28:109:30 | key | tests.js:109:24:109:31 | src[key] | | tests.js:109:28:109:30 | key | tests.js:109:24:109:31 | src[key] | | tests.js:116:41:116:43 | src | tests.js:119:49:119:51 | src | -| tests.js:116:41:116:43 | src | tests.js:119:49:119:51 | src | -| tests.js:116:41:116:43 | src | tests.js:121:24:121:26 | src | | tests.js:116:41:116:43 | src | tests.js:121:24:121:26 | src | | tests.js:117:14:117:16 | key | tests.js:121:17:121:19 | key | -| tests.js:117:14:117:16 | key | tests.js:121:17:121:19 | key | -| tests.js:117:14:117:16 | key | tests.js:121:17:121:19 | key | -| tests.js:117:14:117:16 | key | tests.js:121:17:121:19 | key | -| tests.js:117:14:117:16 | key | tests.js:121:17:121:19 | key | -| tests.js:117:14:117:16 | key | tests.js:121:17:121:19 | key | -| tests.js:117:14:117:16 | key | tests.js:121:17:121:19 | key | -| tests.js:117:14:117:16 | key | tests.js:121:28:121:30 | key | -| tests.js:117:14:117:16 | key | tests.js:121:28:121:30 | key | -| tests.js:117:14:117:16 | key | tests.js:121:28:121:30 | key | | tests.js:117:14:117:16 | key | tests.js:121:28:121:30 | key | | tests.js:119:49:119:51 | src | tests.js:119:49:119:56 | src[key] | -| tests.js:119:49:119:51 | src | tests.js:119:49:119:56 | src[key] | -| tests.js:119:49:119:56 | src[key] | tests.js:116:41:116:43 | src | -| tests.js:119:49:119:56 | src[key] | tests.js:116:41:116:43 | src | -| tests.js:119:49:119:56 | src[key] | tests.js:116:41:116:43 | src | -| tests.js:119:49:119:56 | src[key] | tests.js:116:41:116:43 | src | -| tests.js:119:49:119:56 | src[key] | tests.js:116:41:116:43 | src | | tests.js:119:49:119:56 | src[key] | tests.js:116:41:116:43 | src | | tests.js:121:24:121:26 | src | tests.js:121:24:121:31 | src[key] | -| tests.js:121:24:121:26 | src | tests.js:121:24:121:31 | src[key] | -| tests.js:121:24:121:26 | src | tests.js:121:24:121:31 | src[key] | -| tests.js:121:24:121:26 | src | tests.js:121:24:121:31 | src[key] | -| tests.js:121:24:121:31 | src[key] | tests.js:121:24:121:31 | src[key] | -| tests.js:121:28:121:30 | key | tests.js:121:24:121:31 | src[key] | -| tests.js:121:28:121:30 | key | tests.js:121:24:121:31 | src[key] | -| tests.js:121:28:121:30 | key | tests.js:121:24:121:31 | src[key] | | tests.js:121:28:121:30 | key | tests.js:121:24:121:31 | src[key] | | tests.js:149:31:149:33 | dst | tests.js:152:22:152:24 | dst | -| tests.js:149:31:149:33 | dst | tests.js:152:22:152:24 | dst | -| tests.js:149:31:149:33 | dst | tests.js:152:22:152:24 | dst | -| tests.js:149:31:149:33 | dst | tests.js:152:22:152:24 | dst | -| tests.js:149:31:149:33 | dst | tests.js:154:13:154:15 | dst | -| tests.js:149:31:149:33 | dst | tests.js:154:13:154:15 | dst | -| tests.js:149:31:149:33 | dst | tests.js:154:13:154:15 | dst | -| tests.js:149:31:149:33 | dst | tests.js:154:13:154:15 | dst | -| tests.js:149:31:149:33 | dst | tests.js:154:13:154:15 | dst | -| tests.js:149:31:149:33 | dst | tests.js:154:13:154:15 | dst | -| tests.js:149:31:149:33 | dst | tests.js:154:13:154:15 | dst | | tests.js:149:31:149:33 | dst | tests.js:154:13:154:15 | dst | | tests.js:149:36:149:38 | src | tests.js:152:27:152:29 | src | -| tests.js:149:36:149:38 | src | tests.js:152:27:152:29 | src | -| tests.js:149:36:149:38 | src | tests.js:152:27:152:29 | src | -| tests.js:149:36:149:38 | src | tests.js:152:27:152:29 | src | -| tests.js:149:36:149:38 | src | tests.js:154:24:154:26 | src | -| tests.js:149:36:149:38 | src | tests.js:154:24:154:26 | src | -| tests.js:149:36:149:38 | src | tests.js:154:24:154:26 | src | | tests.js:149:36:149:38 | src | tests.js:154:24:154:26 | src | | tests.js:150:14:150:16 | key | tests.js:152:32:152:34 | key | -| tests.js:150:14:150:16 | key | tests.js:152:32:152:34 | key | -| tests.js:150:14:150:16 | key | tests.js:152:32:152:34 | key | -| tests.js:150:14:150:16 | key | tests.js:152:32:152:34 | key | -| tests.js:150:14:150:16 | key | tests.js:154:17:154:19 | key | -| tests.js:150:14:150:16 | key | tests.js:154:17:154:19 | key | -| tests.js:150:14:150:16 | key | tests.js:154:17:154:19 | key | -| tests.js:150:14:150:16 | key | tests.js:154:17:154:19 | key | -| tests.js:150:14:150:16 | key | tests.js:154:17:154:19 | key | -| tests.js:150:14:150:16 | key | tests.js:154:17:154:19 | key | | tests.js:150:14:150:16 | key | tests.js:154:17:154:19 | key | | tests.js:150:14:150:16 | key | tests.js:154:28:154:30 | key | -| tests.js:150:14:150:16 | key | tests.js:154:28:154:30 | key | -| tests.js:150:14:150:16 | key | tests.js:154:28:154:30 | key | -| tests.js:150:14:150:16 | key | tests.js:154:28:154:30 | key | -| tests.js:152:22:152:24 | dst | tests.js:160:37:160:39 | dst | -| tests.js:152:22:152:24 | dst | tests.js:160:37:160:39 | dst | -| tests.js:152:22:152:24 | dst | tests.js:160:37:160:39 | dst | | tests.js:152:22:152:24 | dst | tests.js:160:37:160:39 | dst | | tests.js:152:27:152:29 | src | tests.js:160:42:160:44 | src | -| tests.js:152:27:152:29 | src | tests.js:160:42:160:44 | src | -| tests.js:152:27:152:29 | src | tests.js:160:42:160:44 | src | -| tests.js:152:27:152:29 | src | tests.js:160:42:160:44 | src | -| tests.js:152:32:152:34 | key | tests.js:160:47:160:49 | key | -| tests.js:152:32:152:34 | key | tests.js:160:47:160:49 | key | -| tests.js:152:32:152:34 | key | tests.js:160:47:160:49 | key | | tests.js:152:32:152:34 | key | tests.js:160:47:160:49 | key | | tests.js:154:24:154:26 | src | tests.js:154:24:154:31 | src[key] | -| tests.js:154:24:154:26 | src | tests.js:154:24:154:31 | src[key] | -| tests.js:154:24:154:26 | src | tests.js:154:24:154:31 | src[key] | -| tests.js:154:24:154:26 | src | tests.js:154:24:154:31 | src[key] | -| tests.js:154:24:154:26 | src | tests.js:154:24:154:31 | src[key] | -| tests.js:154:24:154:26 | src | tests.js:154:24:154:31 | src[key] | -| tests.js:154:24:154:26 | src | tests.js:154:24:154:31 | src[key] | -| tests.js:154:24:154:26 | src | tests.js:154:24:154:31 | src[key] | -| tests.js:154:24:154:31 | src[key] | tests.js:154:24:154:31 | src[key] | -| tests.js:154:28:154:30 | key | tests.js:154:24:154:31 | src[key] | -| tests.js:154:28:154:30 | key | tests.js:154:24:154:31 | src[key] | -| tests.js:154:28:154:30 | key | tests.js:154:24:154:31 | src[key] | | tests.js:154:28:154:30 | key | tests.js:154:24:154:31 | src[key] | | tests.js:159:36:159:38 | dst | tests.js:160:26:160:28 | dst | -| tests.js:159:36:159:38 | dst | tests.js:160:26:160:28 | dst | -| tests.js:159:36:159:38 | dst | tests.js:160:26:160:28 | dst | -| tests.js:159:36:159:38 | dst | tests.js:160:26:160:28 | dst | -| tests.js:159:41:159:43 | src | tests.js:160:31:160:33 | src | -| tests.js:159:41:159:43 | src | tests.js:160:31:160:33 | src | -| tests.js:159:41:159:43 | src | tests.js:160:31:160:33 | src | | tests.js:159:41:159:43 | src | tests.js:160:31:160:33 | src | | tests.js:160:26:160:28 | dst | tests.js:149:31:149:33 | dst | -| tests.js:160:26:160:28 | dst | tests.js:149:31:149:33 | dst | -| tests.js:160:26:160:28 | dst | tests.js:149:31:149:33 | dst | -| tests.js:160:26:160:28 | dst | tests.js:149:31:149:33 | dst | -| tests.js:160:26:160:28 | dst | tests.js:160:37:160:39 | dst | -| tests.js:160:26:160:28 | dst | tests.js:160:37:160:39 | dst | -| tests.js:160:26:160:28 | dst | tests.js:160:37:160:39 | dst | -| tests.js:160:26:160:28 | dst | tests.js:160:37:160:39 | dst | | tests.js:160:31:160:33 | src | tests.js:149:36:149:38 | src | -| tests.js:160:31:160:33 | src | tests.js:149:36:149:38 | src | -| tests.js:160:31:160:33 | src | tests.js:149:36:149:38 | src | -| tests.js:160:31:160:33 | src | tests.js:149:36:149:38 | src | -| tests.js:160:31:160:33 | src | tests.js:160:42:160:44 | src | -| tests.js:160:31:160:33 | src | tests.js:160:42:160:44 | src | -| tests.js:160:31:160:33 | src | tests.js:160:42:160:44 | src | -| tests.js:160:31:160:33 | src | tests.js:160:42:160:44 | src | -| tests.js:160:37:160:39 | dst | tests.js:161:35:161:37 | dst | -| tests.js:160:37:160:39 | dst | tests.js:161:35:161:37 | dst | -| tests.js:160:37:160:39 | dst | tests.js:161:35:161:37 | dst | | tests.js:160:37:160:39 | dst | tests.js:161:35:161:37 | dst | | tests.js:160:42:160:44 | src | tests.js:161:45:161:47 | src | -| tests.js:160:42:160:44 | src | tests.js:161:45:161:47 | src | -| tests.js:160:42:160:44 | src | tests.js:161:45:161:47 | src | -| tests.js:160:42:160:44 | src | tests.js:161:45:161:47 | src | -| tests.js:160:47:160:49 | key | tests.js:161:39:161:41 | key | -| tests.js:160:47:160:49 | key | tests.js:161:39:161:41 | key | -| tests.js:160:47:160:49 | key | tests.js:161:39:161:41 | key | | tests.js:160:47:160:49 | key | tests.js:161:39:161:41 | key | | tests.js:160:47:160:49 | key | tests.js:161:49:161:51 | key | -| tests.js:160:47:160:49 | key | tests.js:161:49:161:51 | key | -| tests.js:160:47:160:49 | key | tests.js:161:49:161:51 | key | -| tests.js:160:47:160:49 | key | tests.js:161:49:161:51 | key | -| tests.js:161:35:161:37 | dst | tests.js:161:35:161:42 | dst[key] | -| tests.js:161:35:161:37 | dst | tests.js:161:35:161:42 | dst[key] | -| tests.js:161:35:161:37 | dst | tests.js:161:35:161:42 | dst[key] | | tests.js:161:35:161:37 | dst | tests.js:161:35:161:42 | dst[key] | | tests.js:161:35:161:42 | dst[key] | tests.js:159:36:159:38 | dst | -| tests.js:161:35:161:42 | dst[key] | tests.js:159:36:159:38 | dst | -| tests.js:161:35:161:42 | dst[key] | tests.js:159:36:159:38 | dst | -| tests.js:161:35:161:42 | dst[key] | tests.js:159:36:159:38 | dst | -| tests.js:161:39:161:41 | key | tests.js:161:35:161:42 | dst[key] | -| tests.js:161:39:161:41 | key | tests.js:161:35:161:42 | dst[key] | -| tests.js:161:39:161:41 | key | tests.js:161:35:161:42 | dst[key] | | tests.js:161:39:161:41 | key | tests.js:161:35:161:42 | dst[key] | | tests.js:161:45:161:47 | src | tests.js:161:45:161:52 | src[key] | -| tests.js:161:45:161:47 | src | tests.js:161:45:161:52 | src[key] | -| tests.js:161:45:161:47 | src | tests.js:161:45:161:52 | src[key] | -| tests.js:161:45:161:47 | src | tests.js:161:45:161:52 | src[key] | | tests.js:161:45:161:52 | src[key] | tests.js:159:41:159:43 | src | -| tests.js:161:45:161:52 | src[key] | tests.js:159:41:159:43 | src | -| tests.js:161:45:161:52 | src[key] | tests.js:159:41:159:43 | src | -| tests.js:161:45:161:52 | src[key] | tests.js:159:41:159:43 | src | -| tests.js:161:49:161:51 | key | tests.js:161:45:161:52 | src[key] | -| tests.js:161:49:161:51 | key | tests.js:161:45:161:52 | src[key] | -| tests.js:161:49:161:51 | key | tests.js:161:45:161:52 | src[key] | | tests.js:161:49:161:51 | key | tests.js:161:45:161:52 | src[key] | | tests.js:165:37:165:39 | src | tests.js:169:45:169:47 | src | -| tests.js:165:37:165:39 | src | tests.js:169:45:169:47 | src | -| tests.js:165:37:165:39 | src | tests.js:171:24:171:26 | src | | tests.js:165:37:165:39 | src | tests.js:171:24:171:26 | src | | tests.js:166:14:166:16 | key | tests.js:169:49:169:51 | key | -| tests.js:166:14:166:16 | key | tests.js:169:49:169:51 | key | -| tests.js:166:14:166:16 | key | tests.js:169:49:169:51 | key | -| tests.js:166:14:166:16 | key | tests.js:169:49:169:51 | key | | tests.js:166:14:166:16 | key | tests.js:171:17:171:19 | key | -| tests.js:166:14:166:16 | key | tests.js:171:17:171:19 | key | -| tests.js:166:14:166:16 | key | tests.js:171:17:171:19 | key | -| tests.js:166:14:166:16 | key | tests.js:171:17:171:19 | key | -| tests.js:166:14:166:16 | key | tests.js:171:17:171:19 | key | -| tests.js:166:14:166:16 | key | tests.js:171:17:171:19 | key | -| tests.js:166:14:166:16 | key | tests.js:171:17:171:19 | key | -| tests.js:166:14:166:16 | key | tests.js:171:28:171:30 | key | -| tests.js:166:14:166:16 | key | tests.js:171:28:171:30 | key | -| tests.js:166:14:166:16 | key | tests.js:171:28:171:30 | key | | tests.js:166:14:166:16 | key | tests.js:171:28:171:30 | key | | tests.js:169:45:169:47 | src | tests.js:169:45:169:52 | src[key] | -| tests.js:169:45:169:47 | src | tests.js:169:45:169:52 | src[key] | -| tests.js:169:45:169:52 | src[key] | tests.js:165:37:165:39 | src | -| tests.js:169:45:169:52 | src[key] | tests.js:165:37:165:39 | src | -| tests.js:169:45:169:52 | src[key] | tests.js:165:37:165:39 | src | -| tests.js:169:45:169:52 | src[key] | tests.js:165:37:165:39 | src | -| tests.js:169:45:169:52 | src[key] | tests.js:165:37:165:39 | src | | tests.js:169:45:169:52 | src[key] | tests.js:165:37:165:39 | src | | tests.js:169:49:169:51 | key | tests.js:169:45:169:52 | src[key] | -| tests.js:169:49:169:51 | key | tests.js:169:45:169:52 | src[key] | | tests.js:171:24:171:26 | src | tests.js:171:24:171:31 | src[key] | -| tests.js:171:24:171:26 | src | tests.js:171:24:171:31 | src[key] | -| tests.js:171:24:171:26 | src | tests.js:171:24:171:31 | src[key] | -| tests.js:171:24:171:26 | src | tests.js:171:24:171:31 | src[key] | -| tests.js:171:24:171:31 | src[key] | tests.js:171:24:171:31 | src[key] | -| tests.js:171:28:171:30 | key | tests.js:171:24:171:31 | src[key] | -| tests.js:171:28:171:30 | key | tests.js:171:24:171:31 | src[key] | -| tests.js:171:28:171:30 | key | tests.js:171:24:171:31 | src[key] | | tests.js:171:28:171:30 | key | tests.js:171:24:171:31 | src[key] | | tests.js:178:33:178:35 | src | tests.js:182:41:182:43 | src | -| tests.js:178:33:178:35 | src | tests.js:182:41:182:43 | src | -| tests.js:178:33:178:35 | src | tests.js:184:24:184:26 | src | | tests.js:178:33:178:35 | src | tests.js:184:24:184:26 | src | | tests.js:182:41:182:43 | src | tests.js:182:41:182:48 | src[key] | -| tests.js:182:41:182:43 | src | tests.js:182:41:182:48 | src[key] | -| tests.js:182:41:182:48 | src[key] | tests.js:178:33:178:35 | src | -| tests.js:182:41:182:48 | src[key] | tests.js:178:33:178:35 | src | -| tests.js:182:41:182:48 | src[key] | tests.js:178:33:178:35 | src | -| tests.js:182:41:182:48 | src[key] | tests.js:178:33:178:35 | src | -| tests.js:182:41:182:48 | src[key] | tests.js:178:33:178:35 | src | | tests.js:182:41:182:48 | src[key] | tests.js:178:33:178:35 | src | | tests.js:184:24:184:26 | src | tests.js:184:24:184:31 | src[key] | -| tests.js:184:24:184:26 | src | tests.js:184:24:184:31 | src[key] | -| tests.js:184:24:184:26 | src | tests.js:184:24:184:31 | src[key] | -| tests.js:184:24:184:26 | src | tests.js:184:24:184:31 | src[key] | -| tests.js:184:24:184:31 | src[key] | tests.js:184:24:184:31 | src[key] | -| tests.js:189:32:189:34 | dst | tests.js:194:35:194:37 | dst | | tests.js:189:32:189:34 | dst | tests.js:194:35:194:37 | dst | | tests.js:189:32:189:34 | dst | tests.js:196:13:196:15 | dst | -| tests.js:189:32:189:34 | dst | tests.js:196:13:196:15 | dst | -| tests.js:189:32:189:34 | dst | tests.js:196:13:196:15 | dst | -| tests.js:189:32:189:34 | dst | tests.js:196:13:196:15 | dst | -| tests.js:189:37:189:39 | src | tests.js:194:45:194:47 | src | | tests.js:189:37:189:39 | src | tests.js:194:45:194:47 | src | | tests.js:189:37:189:39 | src | tests.js:196:24:196:26 | src | -| tests.js:189:37:189:39 | src | tests.js:196:24:196:26 | src | -| tests.js:192:13:192:25 | key | tests.js:194:39:194:41 | key | | tests.js:192:13:192:25 | key | tests.js:194:39:194:41 | key | | tests.js:192:13:192:25 | key | tests.js:194:49:194:51 | key | -| tests.js:192:13:192:25 | key | tests.js:194:49:194:51 | key | -| tests.js:192:13:192:25 | key | tests.js:196:17:196:19 | key | -| tests.js:192:13:192:25 | key | tests.js:196:17:196:19 | key | -| tests.js:192:13:192:25 | key | tests.js:196:17:196:19 | key | | tests.js:192:13:192:25 | key | tests.js:196:17:196:19 | key | | tests.js:192:13:192:25 | key | tests.js:196:28:196:30 | key | -| tests.js:192:13:192:25 | key | tests.js:196:28:196:30 | key | -| tests.js:192:19:192:25 | keys[i] | tests.js:192:13:192:25 | key | -| tests.js:192:19:192:25 | keys[i] | tests.js:192:13:192:25 | key | -| tests.js:192:19:192:25 | keys[i] | tests.js:192:13:192:25 | key | | tests.js:192:19:192:25 | keys[i] | tests.js:192:13:192:25 | key | | tests.js:194:35:194:37 | dst | tests.js:194:35:194:42 | dst[key] | -| tests.js:194:35:194:37 | dst | tests.js:194:35:194:42 | dst[key] | -| tests.js:194:35:194:42 | dst[key] | tests.js:189:32:189:34 | dst | -| tests.js:194:35:194:42 | dst[key] | tests.js:189:32:189:34 | dst | -| tests.js:194:35:194:42 | dst[key] | tests.js:189:32:189:34 | dst | | tests.js:194:35:194:42 | dst[key] | tests.js:189:32:189:34 | dst | | tests.js:194:39:194:41 | key | tests.js:194:35:194:42 | dst[key] | -| tests.js:194:39:194:41 | key | tests.js:194:35:194:42 | dst[key] | -| tests.js:194:45:194:47 | src | tests.js:194:45:194:52 | src[key] | | tests.js:194:45:194:47 | src | tests.js:194:45:194:52 | src[key] | | tests.js:194:45:194:52 | src[key] | tests.js:189:37:189:39 | src | -| tests.js:194:45:194:52 | src[key] | tests.js:189:37:189:39 | src | -| tests.js:194:45:194:52 | src[key] | tests.js:189:37:189:39 | src | -| tests.js:194:45:194:52 | src[key] | tests.js:189:37:189:39 | src | -| tests.js:194:45:194:52 | src[key] | tests.js:189:37:189:39 | src | -| tests.js:194:45:194:52 | src[key] | tests.js:189:37:189:39 | src | -| tests.js:194:49:194:51 | key | tests.js:194:45:194:52 | src[key] | | tests.js:194:49:194:51 | key | tests.js:194:45:194:52 | src[key] | | tests.js:196:24:196:26 | src | tests.js:196:24:196:31 | src[key] | -| tests.js:196:24:196:26 | src | tests.js:196:24:196:31 | src[key] | -| tests.js:196:24:196:26 | src | tests.js:196:24:196:31 | src[key] | -| tests.js:196:24:196:26 | src | tests.js:196:24:196:31 | src[key] | -| tests.js:196:24:196:31 | src[key] | tests.js:196:24:196:31 | src[key] | -| tests.js:196:28:196:30 | key | tests.js:196:24:196:31 | src[key] | -| tests.js:196:28:196:30 | key | tests.js:196:24:196:31 | src[key] | -| tests.js:196:28:196:30 | key | tests.js:196:24:196:31 | src[key] | | tests.js:196:28:196:30 | key | tests.js:196:24:196:31 | src[key] | | tests.js:201:39:201:41 | dst | tests.js:206:42:206:44 | dst | -| tests.js:201:39:201:41 | dst | tests.js:206:42:206:44 | dst | -| tests.js:201:39:201:41 | dst | tests.js:208:13:208:15 | dst | -| tests.js:201:39:201:41 | dst | tests.js:208:13:208:15 | dst | -| tests.js:201:39:201:41 | dst | tests.js:208:13:208:15 | dst | | tests.js:201:39:201:41 | dst | tests.js:208:13:208:15 | dst | | tests.js:201:44:201:46 | src | tests.js:206:56:206:58 | src | -| tests.js:201:44:201:46 | src | tests.js:206:56:206:58 | src | -| tests.js:201:44:201:46 | src | tests.js:208:28:208:30 | src | | tests.js:201:44:201:46 | src | tests.js:208:28:208:30 | src | | tests.js:206:42:206:44 | dst | tests.js:206:42:206:53 | dst[keys[i]] | -| tests.js:206:42:206:44 | dst | tests.js:206:42:206:53 | dst[keys[i]] | | tests.js:206:42:206:53 | dst[keys[i]] | tests.js:201:39:201:41 | dst | -| tests.js:206:42:206:53 | dst[keys[i]] | tests.js:201:39:201:41 | dst | -| tests.js:206:42:206:53 | dst[keys[i]] | tests.js:201:39:201:41 | dst | -| tests.js:206:42:206:53 | dst[keys[i]] | tests.js:201:39:201:41 | dst | -| tests.js:206:46:206:52 | keys[i] | tests.js:206:42:206:53 | dst[keys[i]] | -| tests.js:206:46:206:52 | keys[i] | tests.js:206:42:206:53 | dst[keys[i]] | -| tests.js:206:46:206:52 | keys[i] | tests.js:206:42:206:53 | dst[keys[i]] | | tests.js:206:46:206:52 | keys[i] | tests.js:206:42:206:53 | dst[keys[i]] | | tests.js:206:56:206:58 | src | tests.js:206:56:206:67 | src[keys[i]] | -| tests.js:206:56:206:58 | src | tests.js:206:56:206:67 | src[keys[i]] | -| tests.js:206:56:206:67 | src[keys[i]] | tests.js:201:44:201:46 | src | -| tests.js:206:56:206:67 | src[keys[i]] | tests.js:201:44:201:46 | src | -| tests.js:206:56:206:67 | src[keys[i]] | tests.js:201:44:201:46 | src | -| tests.js:206:56:206:67 | src[keys[i]] | tests.js:201:44:201:46 | src | -| tests.js:206:56:206:67 | src[keys[i]] | tests.js:201:44:201:46 | src | | tests.js:206:56:206:67 | src[keys[i]] | tests.js:201:44:201:46 | src | | tests.js:206:60:206:66 | keys[i] | tests.js:206:56:206:67 | src[keys[i]] | -| tests.js:206:60:206:66 | keys[i] | tests.js:206:56:206:67 | src[keys[i]] | -| tests.js:206:60:206:66 | keys[i] | tests.js:206:56:206:67 | src[keys[i]] | -| tests.js:206:60:206:66 | keys[i] | tests.js:206:56:206:67 | src[keys[i]] | -| tests.js:208:17:208:23 | keys[i] | tests.js:208:17:208:23 | keys[i] | | tests.js:208:28:208:30 | src | tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:28:208:30 | src | tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:28:208:30 | src | tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:28:208:30 | src | tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:28:208:39 | src[keys[i]] | tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:32:208:38 | keys[i] | tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:32:208:38 | keys[i] | tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:32:208:38 | keys[i] | tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:32:208:38 | keys[i] | tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:32:208:38 | keys[i] | tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:32:208:38 | keys[i] | tests.js:208:28:208:39 | src[keys[i]] | | tests.js:208:32:208:38 | keys[i] | tests.js:208:28:208:39 | src[keys[i]] | | tests.js:213:23:213:26 | key1 | tests.js:217:9:217:12 | key1 | -| tests.js:213:23:213:26 | key1 | tests.js:217:9:217:12 | key1 | -| tests.js:213:29:213:32 | key2 | tests.js:217:15:217:18 | key2 | -| tests.js:213:29:213:32 | key2 | tests.js:217:15:217:18 | key2 | -| tests.js:213:29:213:32 | key2 | tests.js:217:15:217:18 | key2 | | tests.js:213:29:213:32 | key2 | tests.js:217:15:217:18 | key2 | | tests.js:213:35:213:39 | value | tests.js:217:23:217:27 | value | -| tests.js:213:35:213:39 | value | tests.js:217:23:217:27 | value | -| tests.js:213:35:213:39 | value | tests.js:217:23:217:27 | value | -| tests.js:213:35:213:39 | value | tests.js:217:23:217:27 | value | -| tests.js:217:9:217:12 | key1 | tests.js:217:5:217:13 | map[key1] | -| tests.js:217:9:217:12 | key1 | tests.js:217:5:217:13 | map[key1] | -| tests.js:217:9:217:12 | key1 | tests.js:217:5:217:13 | map[key1] | | tests.js:217:9:217:12 | key1 | tests.js:217:5:217:13 | map[key1] | | tests.js:223:14:223:16 | key | tests.js:224:23:224:25 | key | -| tests.js:223:14:223:16 | key | tests.js:224:23:224:25 | key | -| tests.js:223:14:223:16 | key | tests.js:224:23:224:25 | key | -| tests.js:223:14:223:16 | key | tests.js:224:23:224:25 | key | -| tests.js:223:14:223:16 | key | tests.js:224:38:224:40 | key | -| tests.js:223:14:223:16 | key | tests.js:224:38:224:40 | key | -| tests.js:223:14:223:16 | key | tests.js:224:38:224:40 | key | | tests.js:223:14:223:16 | key | tests.js:224:38:224:40 | key | | tests.js:223:14:223:16 | key | tests.js:225:28:225:30 | key | -| tests.js:223:14:223:16 | key | tests.js:225:28:225:30 | key | -| tests.js:223:14:223:16 | key | tests.js:225:28:225:30 | key | -| tests.js:223:14:223:16 | key | tests.js:225:28:225:30 | key | -| tests.js:223:14:223:16 | key | tests.js:225:38:225:40 | key | -| tests.js:223:14:223:16 | key | tests.js:225:38:225:40 | key | -| tests.js:223:14:223:16 | key | tests.js:225:38:225:40 | key | | tests.js:223:14:223:16 | key | tests.js:225:38:225:40 | key | | tests.js:224:23:224:25 | key | tests.js:213:23:213:26 | key1 | -| tests.js:224:23:224:25 | key | tests.js:213:23:213:26 | key1 | -| tests.js:224:33:224:41 | data[key] | tests.js:213:35:213:39 | value | -| tests.js:224:33:224:41 | data[key] | tests.js:213:35:213:39 | value | -| tests.js:224:33:224:41 | data[key] | tests.js:213:35:213:39 | value | | tests.js:224:33:224:41 | data[key] | tests.js:213:35:213:39 | value | | tests.js:224:38:224:40 | key | tests.js:224:33:224:41 | data[key] | -| tests.js:224:38:224:40 | key | tests.js:224:33:224:41 | data[key] | -| tests.js:225:28:225:30 | key | tests.js:213:29:213:32 | key2 | | tests.js:225:28:225:30 | key | tests.js:213:29:213:32 | key2 | | tests.js:225:33:225:41 | data[key] | tests.js:213:35:213:39 | value | -| tests.js:225:33:225:41 | data[key] | tests.js:213:35:213:39 | value | -| tests.js:225:33:225:41 | data[key] | tests.js:213:35:213:39 | value | -| tests.js:225:33:225:41 | data[key] | tests.js:213:35:213:39 | value | -| tests.js:225:38:225:40 | key | tests.js:225:33:225:41 | data[key] | | tests.js:225:38:225:40 | key | tests.js:225:33:225:41 | data[key] | | tests.js:229:26:229:29 | key1 | tests.js:233:9:233:12 | key1 | -| tests.js:229:26:229:29 | key1 | tests.js:233:9:233:12 | key1 | -| tests.js:229:32:229:35 | key2 | tests.js:233:15:233:18 | key2 | -| tests.js:229:32:229:35 | key2 | tests.js:233:15:233:18 | key2 | -| tests.js:229:32:229:35 | key2 | tests.js:233:15:233:18 | key2 | | tests.js:229:32:229:35 | key2 | tests.js:233:15:233:18 | key2 | | tests.js:229:38:229:42 | value | tests.js:233:23:233:27 | value | -| tests.js:229:38:229:42 | value | tests.js:233:23:233:27 | value | -| tests.js:229:38:229:42 | value | tests.js:233:23:233:27 | value | -| tests.js:229:38:229:42 | value | tests.js:233:23:233:27 | value | -| tests.js:233:9:233:12 | key1 | tests.js:233:5:233:13 | map[key1] | -| tests.js:233:9:233:12 | key1 | tests.js:233:5:233:13 | map[key1] | -| tests.js:233:9:233:12 | key1 | tests.js:233:5:233:13 | map[key1] | | tests.js:233:9:233:12 | key1 | tests.js:233:5:233:13 | map[key1] | | tests.js:238:14:238:16 | key | tests.js:239:24:239:26 | key | -| tests.js:238:14:238:16 | key | tests.js:239:24:239:26 | key | -| tests.js:238:14:238:16 | key | tests.js:239:24:239:26 | key | -| tests.js:238:14:238:16 | key | tests.js:239:24:239:26 | key | -| tests.js:238:14:238:16 | key | tests.js:239:39:239:41 | key | -| tests.js:238:14:238:16 | key | tests.js:239:39:239:41 | key | -| tests.js:238:14:238:16 | key | tests.js:239:39:239:41 | key | | tests.js:238:14:238:16 | key | tests.js:239:39:239:41 | key | | tests.js:238:14:238:16 | key | tests.js:240:31:240:33 | key | -| tests.js:238:14:238:16 | key | tests.js:240:31:240:33 | key | -| tests.js:238:14:238:16 | key | tests.js:240:31:240:33 | key | -| tests.js:238:14:238:16 | key | tests.js:240:31:240:33 | key | -| tests.js:238:14:238:16 | key | tests.js:240:41:240:43 | key | -| tests.js:238:14:238:16 | key | tests.js:240:41:240:43 | key | -| tests.js:238:14:238:16 | key | tests.js:240:41:240:43 | key | | tests.js:238:14:238:16 | key | tests.js:240:41:240:43 | key | | tests.js:239:24:239:26 | key | tests.js:229:26:229:29 | key1 | -| tests.js:239:24:239:26 | key | tests.js:229:26:229:29 | key1 | -| tests.js:239:34:239:42 | data[key] | tests.js:229:38:229:42 | value | -| tests.js:239:34:239:42 | data[key] | tests.js:229:38:229:42 | value | -| tests.js:239:34:239:42 | data[key] | tests.js:229:38:229:42 | value | | tests.js:239:34:239:42 | data[key] | tests.js:229:38:229:42 | value | | tests.js:239:39:239:41 | key | tests.js:239:34:239:42 | data[key] | -| tests.js:239:39:239:41 | key | tests.js:239:34:239:42 | data[key] | -| tests.js:240:31:240:33 | key | tests.js:229:32:229:35 | key2 | | tests.js:240:31:240:33 | key | tests.js:229:32:229:35 | key2 | | tests.js:240:36:240:44 | data[key] | tests.js:229:38:229:42 | value | -| tests.js:240:36:240:44 | data[key] | tests.js:229:38:229:42 | value | -| tests.js:240:36:240:44 | data[key] | tests.js:229:38:229:42 | value | -| tests.js:240:36:240:44 | data[key] | tests.js:229:38:229:42 | value | -| tests.js:240:41:240:43 | key | tests.js:240:36:240:44 | data[key] | | tests.js:240:41:240:43 | key | tests.js:240:36:240:44 | data[key] | | tests.js:263:27:263:29 | dst | tests.js:268:30:268:32 | dst | -| tests.js:263:27:263:29 | dst | tests.js:268:30:268:32 | dst | -| tests.js:263:27:263:29 | dst | tests.js:270:13:270:15 | dst | -| tests.js:263:27:263:29 | dst | tests.js:270:13:270:15 | dst | -| tests.js:263:27:263:29 | dst | tests.js:270:13:270:15 | dst | | tests.js:263:27:263:29 | dst | tests.js:270:13:270:15 | dst | | tests.js:265:13:265:26 | key | tests.js:268:34:268:36 | key | -| tests.js:265:13:265:26 | key | tests.js:268:34:268:36 | key | -| tests.js:265:13:265:26 | key | tests.js:270:17:270:19 | key | -| tests.js:265:13:265:26 | key | tests.js:270:17:270:19 | key | -| tests.js:265:13:265:26 | key | tests.js:270:17:270:19 | key | | tests.js:265:13:265:26 | key | tests.js:270:17:270:19 | key | | tests.js:265:19:265:26 | entry[0] | tests.js:265:13:265:26 | key | -| tests.js:265:19:265:26 | entry[0] | tests.js:265:13:265:26 | key | -| tests.js:265:19:265:26 | entry[0] | tests.js:265:13:265:26 | key | -| tests.js:265:19:265:26 | entry[0] | tests.js:265:13:265:26 | key | | tests.js:266:13:266:28 | value | tests.js:270:24:270:28 | value | -| tests.js:266:13:266:28 | value | tests.js:270:24:270:28 | value | -| tests.js:266:13:266:28 | value | tests.js:270:24:270:28 | value | -| tests.js:266:13:266:28 | value | tests.js:270:24:270:28 | value | -| tests.js:266:21:266:28 | entry[1] | tests.js:266:13:266:28 | value | -| tests.js:266:21:266:28 | entry[1] | tests.js:266:13:266:28 | value | -| tests.js:266:21:266:28 | entry[1] | tests.js:266:13:266:28 | value | | tests.js:266:21:266:28 | entry[1] | tests.js:266:13:266:28 | value | | tests.js:268:30:268:32 | dst | tests.js:268:30:268:37 | dst[key] | -| tests.js:268:30:268:32 | dst | tests.js:268:30:268:37 | dst[key] | -| tests.js:268:30:268:37 | dst[key] | tests.js:263:27:263:29 | dst | -| tests.js:268:30:268:37 | dst[key] | tests.js:263:27:263:29 | dst | -| tests.js:268:30:268:37 | dst[key] | tests.js:263:27:263:29 | dst | | tests.js:268:30:268:37 | dst[key] | tests.js:263:27:263:29 | dst | | tests.js:268:34:268:36 | key | tests.js:268:30:268:37 | dst[key] | -| tests.js:268:34:268:36 | key | tests.js:268:30:268:37 | dst[key] | -| tests.js:275:27:275:29 | dst | tests.js:278:30:278:32 | dst | | tests.js:275:27:275:29 | dst | tests.js:278:30:278:32 | dst | | tests.js:275:27:275:29 | dst | tests.js:280:13:280:15 | dst | -| tests.js:275:27:275:29 | dst | tests.js:280:13:280:15 | dst | -| tests.js:275:27:275:29 | dst | tests.js:280:13:280:15 | dst | -| tests.js:275:27:275:29 | dst | tests.js:280:13:280:15 | dst | -| tests.js:275:32:275:34 | src | tests.js:278:40:278:42 | src | -| tests.js:275:32:275:34 | src | tests.js:278:40:278:42 | src | -| tests.js:275:32:275:34 | src | tests.js:280:24:280:26 | src | -| tests.js:275:32:275:34 | src | tests.js:280:24:280:26 | src | -| tests.js:276:34:276:36 | key | tests.js:278:34:278:36 | key | -| tests.js:276:34:276:36 | key | tests.js:278:34:278:36 | key | -| tests.js:276:34:276:36 | key | tests.js:278:34:278:36 | key | +| tests.js:275:32:275:34 | src | tests.js:276:21:276:23 | src | +| tests.js:276:21:276:23 | src | tests.js:278:40:278:42 | src | +| tests.js:276:21:276:23 | src | tests.js:280:24:280:26 | src | | tests.js:276:34:276:36 | key | tests.js:278:34:278:36 | key | | tests.js:276:34:276:36 | key | tests.js:278:44:278:46 | key | -| tests.js:276:34:276:36 | key | tests.js:278:44:278:46 | key | -| tests.js:276:34:276:36 | key | tests.js:278:44:278:46 | key | -| tests.js:276:34:276:36 | key | tests.js:278:44:278:46 | key | | tests.js:276:34:276:36 | key | tests.js:280:17:280:19 | key | -| tests.js:276:34:276:36 | key | tests.js:280:17:280:19 | key | -| tests.js:276:34:276:36 | key | tests.js:280:17:280:19 | key | -| tests.js:276:34:276:36 | key | tests.js:280:17:280:19 | key | -| tests.js:276:34:276:36 | key | tests.js:280:17:280:19 | key | -| tests.js:276:34:276:36 | key | tests.js:280:17:280:19 | key | -| tests.js:276:34:276:36 | key | tests.js:280:17:280:19 | key | -| tests.js:276:34:276:36 | key | tests.js:280:28:280:30 | key | -| tests.js:276:34:276:36 | key | tests.js:280:28:280:30 | key | -| tests.js:276:34:276:36 | key | tests.js:280:28:280:30 | key | | tests.js:276:34:276:36 | key | tests.js:280:28:280:30 | key | | tests.js:278:30:278:32 | dst | tests.js:278:30:278:37 | dst[key] | -| tests.js:278:30:278:32 | dst | tests.js:278:30:278:37 | dst[key] | -| tests.js:278:30:278:37 | dst[key] | tests.js:275:27:275:29 | dst | -| tests.js:278:30:278:37 | dst[key] | tests.js:275:27:275:29 | dst | -| tests.js:278:30:278:37 | dst[key] | tests.js:275:27:275:29 | dst | | tests.js:278:30:278:37 | dst[key] | tests.js:275:27:275:29 | dst | | tests.js:278:34:278:36 | key | tests.js:278:30:278:37 | dst[key] | -| tests.js:278:34:278:36 | key | tests.js:278:30:278:37 | dst[key] | -| tests.js:278:40:278:42 | src | tests.js:278:40:278:47 | src[key] | | tests.js:278:40:278:42 | src | tests.js:278:40:278:47 | src[key] | | tests.js:278:40:278:47 | src[key] | tests.js:275:32:275:34 | src | -| tests.js:278:40:278:47 | src[key] | tests.js:275:32:275:34 | src | -| tests.js:278:40:278:47 | src[key] | tests.js:275:32:275:34 | src | -| tests.js:278:40:278:47 | src[key] | tests.js:275:32:275:34 | src | -| tests.js:278:40:278:47 | src[key] | tests.js:275:32:275:34 | src | -| tests.js:278:40:278:47 | src[key] | tests.js:275:32:275:34 | src | -| tests.js:278:44:278:46 | key | tests.js:278:40:278:47 | src[key] | | tests.js:278:44:278:46 | key | tests.js:278:40:278:47 | src[key] | | tests.js:280:24:280:26 | src | tests.js:280:24:280:31 | src[key] | -| tests.js:280:24:280:26 | src | tests.js:280:24:280:31 | src[key] | -| tests.js:280:24:280:26 | src | tests.js:280:24:280:31 | src[key] | -| tests.js:280:24:280:26 | src | tests.js:280:24:280:31 | src[key] | -| tests.js:280:24:280:31 | src[key] | tests.js:280:24:280:31 | src[key] | -| tests.js:280:28:280:30 | key | tests.js:280:24:280:31 | src[key] | -| tests.js:280:28:280:30 | key | tests.js:280:24:280:31 | src[key] | -| tests.js:280:28:280:30 | key | tests.js:280:24:280:31 | src[key] | | tests.js:280:28:280:30 | key | tests.js:280:24:280:31 | src[key] | | tests.js:301:27:301:29 | dst | tests.js:306:34:306:36 | dst | -| tests.js:301:27:301:29 | dst | tests.js:306:34:306:36 | dst | -| tests.js:301:27:301:29 | dst | tests.js:308:17:308:19 | dst | -| tests.js:301:27:301:29 | dst | tests.js:308:17:308:19 | dst | -| tests.js:301:27:301:29 | dst | tests.js:308:17:308:19 | dst | | tests.js:301:27:301:29 | dst | tests.js:308:17:308:19 | dst | | tests.js:301:32:301:34 | src | tests.js:304:25:304:27 | src | | tests.js:302:14:302:16 | key | tests.js:304:29:304:31 | key | -| tests.js:302:14:302:16 | key | tests.js:304:29:304:31 | key | -| tests.js:302:14:302:16 | key | tests.js:304:29:304:31 | key | -| tests.js:302:14:302:16 | key | tests.js:304:29:304:31 | key | | tests.js:302:14:302:16 | key | tests.js:306:38:306:40 | key | -| tests.js:302:14:302:16 | key | tests.js:306:38:306:40 | key | -| tests.js:302:14:302:16 | key | tests.js:306:38:306:40 | key | -| tests.js:302:14:302:16 | key | tests.js:306:38:306:40 | key | -| tests.js:302:14:302:16 | key | tests.js:308:21:308:23 | key | -| tests.js:302:14:302:16 | key | tests.js:308:21:308:23 | key | -| tests.js:302:14:302:16 | key | tests.js:308:21:308:23 | key | -| tests.js:302:14:302:16 | key | tests.js:308:21:308:23 | key | -| tests.js:302:14:302:16 | key | tests.js:308:21:308:23 | key | -| tests.js:302:14:302:16 | key | tests.js:308:21:308:23 | key | | tests.js:302:14:302:16 | key | tests.js:308:21:308:23 | key | | tests.js:304:17:304:32 | value | tests.js:306:44:306:48 | value | | tests.js:304:17:304:32 | value | tests.js:306:44:306:48 | value | | tests.js:304:17:304:32 | value | tests.js:308:28:308:32 | value | | tests.js:304:17:304:32 | value | tests.js:308:28:308:32 | value | | tests.js:304:17:304:32 | value | tests.js:308:28:308:32 | value | -| tests.js:304:17:304:32 | value | tests.js:308:28:308:32 | value | -| tests.js:304:17:304:32 | value | tests.js:308:28:308:32 | value | -| tests.js:304:17:304:32 | value | tests.js:308:28:308:32 | value | | tests.js:304:25:304:27 | src | tests.js:304:25:304:32 | src[key] | | tests.js:304:25:304:32 | src[key] | tests.js:304:17:304:32 | value | | tests.js:304:25:304:32 | src[key] | tests.js:304:17:304:32 | value | | tests.js:304:25:304:32 | src[key] | tests.js:304:17:304:32 | value | -| tests.js:304:25:304:32 | src[key] | tests.js:304:17:304:32 | value | -| tests.js:304:25:304:32 | src[key] | tests.js:304:17:304:32 | value | | tests.js:304:29:304:31 | key | tests.js:304:25:304:32 | src[key] | | tests.js:304:29:304:31 | key | tests.js:304:25:304:32 | src[key] | | tests.js:306:34:306:36 | dst | tests.js:306:34:306:41 | dst[key] | -| tests.js:306:34:306:36 | dst | tests.js:306:34:306:41 | dst[key] | | tests.js:306:34:306:41 | dst[key] | tests.js:301:27:301:29 | dst | -| tests.js:306:34:306:41 | dst[key] | tests.js:301:27:301:29 | dst | -| tests.js:306:34:306:41 | dst[key] | tests.js:301:27:301:29 | dst | -| tests.js:306:34:306:41 | dst[key] | tests.js:301:27:301:29 | dst | -| tests.js:306:38:306:40 | key | tests.js:306:34:306:41 | dst[key] | | tests.js:306:38:306:40 | key | tests.js:306:34:306:41 | dst[key] | | tests.js:306:44:306:48 | value | tests.js:301:32:301:34 | src | | tests.js:306:44:306:48 | value | tests.js:301:32:301:34 | src | | tests.js:314:31:314:33 | dst | tests.js:320:38:320:40 | dst | -| tests.js:314:31:314:33 | dst | tests.js:320:38:320:40 | dst | -| tests.js:314:31:314:33 | dst | tests.js:322:17:322:19 | dst | -| tests.js:314:31:314:33 | dst | tests.js:322:17:322:19 | dst | -| tests.js:314:31:314:33 | dst | tests.js:322:17:322:19 | dst | | tests.js:314:31:314:33 | dst | tests.js:322:17:322:19 | dst | | tests.js:314:36:314:38 | src | tests.js:318:25:318:27 | src | | tests.js:315:14:315:16 | key | tests.js:318:29:318:31 | key | -| tests.js:315:14:315:16 | key | tests.js:318:29:318:31 | key | -| tests.js:315:14:315:16 | key | tests.js:318:29:318:31 | key | -| tests.js:315:14:315:16 | key | tests.js:318:29:318:31 | key | | tests.js:315:14:315:16 | key | tests.js:320:42:320:44 | key | -| tests.js:315:14:315:16 | key | tests.js:320:42:320:44 | key | -| tests.js:315:14:315:16 | key | tests.js:320:42:320:44 | key | -| tests.js:315:14:315:16 | key | tests.js:320:42:320:44 | key | -| tests.js:315:14:315:16 | key | tests.js:322:21:322:23 | key | -| tests.js:315:14:315:16 | key | tests.js:322:21:322:23 | key | -| tests.js:315:14:315:16 | key | tests.js:322:21:322:23 | key | -| tests.js:315:14:315:16 | key | tests.js:322:21:322:23 | key | -| tests.js:315:14:315:16 | key | tests.js:322:21:322:23 | key | -| tests.js:315:14:315:16 | key | tests.js:322:21:322:23 | key | | tests.js:315:14:315:16 | key | tests.js:322:21:322:23 | key | | tests.js:318:17:318:32 | value | tests.js:320:48:320:52 | value | | tests.js:318:17:318:32 | value | tests.js:320:48:320:52 | value | | tests.js:318:17:318:32 | value | tests.js:322:28:322:32 | value | | tests.js:318:17:318:32 | value | tests.js:322:28:322:32 | value | | tests.js:318:17:318:32 | value | tests.js:322:28:322:32 | value | -| tests.js:318:17:318:32 | value | tests.js:322:28:322:32 | value | -| tests.js:318:17:318:32 | value | tests.js:322:28:322:32 | value | -| tests.js:318:17:318:32 | value | tests.js:322:28:322:32 | value | | tests.js:318:25:318:27 | src | tests.js:318:25:318:32 | src[key] | | tests.js:318:25:318:32 | src[key] | tests.js:318:17:318:32 | value | | tests.js:318:25:318:32 | src[key] | tests.js:318:17:318:32 | value | | tests.js:318:25:318:32 | src[key] | tests.js:318:17:318:32 | value | -| tests.js:318:25:318:32 | src[key] | tests.js:318:17:318:32 | value | -| tests.js:318:25:318:32 | src[key] | tests.js:318:17:318:32 | value | | tests.js:318:29:318:31 | key | tests.js:318:25:318:32 | src[key] | | tests.js:318:29:318:31 | key | tests.js:318:25:318:32 | src[key] | | tests.js:320:38:320:40 | dst | tests.js:320:38:320:45 | dst[key] | -| tests.js:320:38:320:40 | dst | tests.js:320:38:320:45 | dst[key] | | tests.js:320:38:320:45 | dst[key] | tests.js:314:31:314:33 | dst | -| tests.js:320:38:320:45 | dst[key] | tests.js:314:31:314:33 | dst | -| tests.js:320:38:320:45 | dst[key] | tests.js:314:31:314:33 | dst | -| tests.js:320:38:320:45 | dst[key] | tests.js:314:31:314:33 | dst | -| tests.js:320:42:320:44 | key | tests.js:320:38:320:45 | dst[key] | | tests.js:320:42:320:44 | key | tests.js:320:38:320:45 | dst[key] | | tests.js:320:48:320:52 | value | tests.js:314:36:314:38 | src | | tests.js:320:48:320:52 | value | tests.js:314:36:314:38 | src | -| tests.js:328:30:328:32 | src | tests.js:336:42:336:44 | src | +| tests.js:328:25:328:27 | dst | tests.js:336:32:336:34 | dst | +| tests.js:328:25:328:27 | dst | tests.js:338:17:338:19 | dst | | tests.js:328:30:328:32 | src | tests.js:336:42:336:44 | src | | tests.js:328:30:328:32 | src | tests.js:338:28:338:30 | src | -| tests.js:328:30:328:32 | src | tests.js:338:28:338:30 | src | -| tests.js:336:42:336:44 | src | tests.js:336:42:336:49 | src[key] | +| tests.js:329:14:329:16 | key | tests.js:336:36:336:38 | key | +| tests.js:329:14:329:16 | key | tests.js:336:46:336:48 | key | +| tests.js:329:14:329:16 | key | tests.js:338:21:338:23 | key | +| tests.js:329:14:329:16 | key | tests.js:338:32:338:34 | key | +| tests.js:336:32:336:34 | dst | tests.js:336:32:336:39 | dst[key] | +| tests.js:336:32:336:39 | dst[key] | tests.js:328:25:328:27 | dst | +| tests.js:336:36:336:38 | key | tests.js:336:32:336:39 | dst[key] | | tests.js:336:42:336:44 | src | tests.js:336:42:336:49 | src[key] | | tests.js:336:42:336:49 | src[key] | tests.js:328:30:328:32 | src | -| tests.js:336:42:336:49 | src[key] | tests.js:328:30:328:32 | src | -| tests.js:336:42:336:49 | src[key] | tests.js:328:30:328:32 | src | -| tests.js:336:42:336:49 | src[key] | tests.js:328:30:328:32 | src | -| tests.js:336:42:336:49 | src[key] | tests.js:328:30:328:32 | src | -| tests.js:336:42:336:49 | src[key] | tests.js:328:30:328:32 | src | +| tests.js:336:46:336:48 | key | tests.js:336:42:336:49 | src[key] | | tests.js:338:28:338:30 | src | tests.js:338:28:338:35 | src[key] | -| tests.js:338:28:338:30 | src | tests.js:338:28:338:35 | src[key] | -| tests.js:338:28:338:30 | src | tests.js:338:28:338:35 | src[key] | -| tests.js:338:28:338:30 | src | tests.js:338:28:338:35 | src[key] | -| tests.js:338:28:338:35 | src[key] | tests.js:338:28:338:35 | src[key] | -| tests.js:348:32:348:37 | target | tests.js:355:17:355:22 | target | -| tests.js:348:32:348:37 | target | tests.js:355:17:355:22 | target | -| tests.js:348:32:348:37 | target | tests.js:355:53:355:58 | target | -| tests.js:348:32:348:37 | target | tests.js:357:17:357:22 | target | -| tests.js:348:32:348:37 | target | tests.js:357:17:357:22 | target | -| tests.js:348:40:348:45 | source | tests.js:355:66:355:71 | source | -| tests.js:348:40:348:45 | source | tests.js:357:31:357:36 | source | -| tests.js:350:37:350:39 | key | tests.js:355:24:355:26 | key | -| tests.js:350:37:350:39 | key | tests.js:355:24:355:26 | key | -| tests.js:350:37:350:39 | key | tests.js:355:24:355:26 | key | +| tests.js:338:32:338:34 | key | tests.js:338:28:338:35 | src[key] | +| tests.js:348:32:348:37 | target | tests.js:349:26:349:31 | target | +| tests.js:348:32:348:37 | target | tests.js:361:12:361:17 | target | +| tests.js:348:40:348:45 | source | tests.js:349:54:349:59 | source | +| tests.js:348:40:348:45 | source | tests.js:350:21:350:26 | source | +| tests.js:349:26:349:31 | target | tests.js:355:17:355:22 | target | +| tests.js:349:26:349:31 | target | tests.js:355:53:355:58 | target | +| tests.js:349:26:349:31 | target | tests.js:357:17:357:22 | target | +| tests.js:349:26:349:31 | target | tests.js:361:12:361:17 | target | +| tests.js:349:54:349:59 | source | tests.js:350:21:350:26 | source | +| tests.js:350:21:350:26 | source | tests.js:355:66:355:71 | source | +| tests.js:350:21:350:26 | source | tests.js:357:31:357:36 | source | | tests.js:350:37:350:39 | key | tests.js:355:24:355:26 | key | | tests.js:350:37:350:39 | key | tests.js:355:60:355:62 | key | -| tests.js:350:37:350:39 | key | tests.js:355:60:355:62 | key | | tests.js:350:37:350:39 | key | tests.js:357:24:357:26 | key | -| tests.js:350:37:350:39 | key | tests.js:357:24:357:26 | key | -| tests.js:350:37:350:39 | key | tests.js:357:24:357:26 | key | -| tests.js:350:37:350:39 | key | tests.js:357:24:357:26 | key | -| tests.js:350:37:350:39 | key | tests.js:357:38:357:40 | key | | tests.js:350:37:350:39 | key | tests.js:357:38:357:40 | key | | tests.js:355:53:355:58 | target | tests.js:355:53:355:63 | target[key] | | tests.js:355:53:355:63 | target[key] | tests.js:348:32:348:37 | target | -| tests.js:355:53:355:63 | target[key] | tests.js:348:32:348:37 | target | -| tests.js:355:53:355:63 | target[key] | tests.js:355:31:355:86 | mergePl ... ptions) | -| tests.js:355:53:355:63 | target[key] | tests.js:355:31:355:86 | mergePl ... ptions) | -| tests.js:355:53:355:63 | target[key] | tests.js:355:31:355:86 | mergePl ... ptions) | | tests.js:355:53:355:63 | target[key] | tests.js:355:31:355:86 | mergePl ... ptions) | | tests.js:355:60:355:62 | key | tests.js:355:53:355:63 | target[key] | | tests.js:355:66:355:71 | source | tests.js:355:66:355:76 | source[key] | | tests.js:355:66:355:76 | source[key] | tests.js:348:40:348:45 | source | -| tests.js:355:66:355:76 | source[key] | tests.js:348:40:348:45 | source | -| tests.js:355:66:355:76 | source[key] | tests.js:348:40:348:45 | source | | tests.js:357:31:357:36 | source | tests.js:357:31:357:41 | source[key] | -| tests.js:357:31:357:36 | source | tests.js:357:31:357:41 | source[key] | -| tests.js:357:31:357:41 | source[key] | tests.js:357:31:357:41 | source[key] | -| tests.js:357:38:357:40 | key | tests.js:357:31:357:41 | source[key] | | tests.js:357:38:357:40 | key | tests.js:357:31:357:41 | source[key] | +| tests.js:364:41:364:46 | target | tests.js:377:12:377:17 | target | | tests.js:364:49:364:54 | source | tests.js:371:75:371:80 | source | | tests.js:364:49:364:54 | source | tests.js:373:31:373:36 | source | | tests.js:366:18:366:20 | key | tests.js:371:24:371:26 | key | -| tests.js:366:18:366:20 | key | tests.js:371:24:371:26 | key | -| tests.js:366:18:366:20 | key | tests.js:371:24:371:26 | key | -| tests.js:366:18:366:20 | key | tests.js:371:24:371:26 | key | -| tests.js:366:18:366:20 | key | tests.js:371:69:371:71 | key | | tests.js:366:18:366:20 | key | tests.js:371:69:371:71 | key | | tests.js:366:18:366:20 | key | tests.js:373:24:373:26 | key | -| tests.js:366:18:366:20 | key | tests.js:373:24:373:26 | key | -| tests.js:366:18:366:20 | key | tests.js:373:24:373:26 | key | -| tests.js:366:18:366:20 | key | tests.js:373:24:373:26 | key | | tests.js:366:18:366:20 | key | tests.js:373:38:373:40 | key | -| tests.js:366:18:366:20 | key | tests.js:373:38:373:40 | key | -| tests.js:371:62:371:72 | target[key] | tests.js:371:31:371:95 | mergePl ... ptions) | +| tests.js:371:62:371:72 | target[key] | tests.js:364:41:364:46 | target | | tests.js:371:62:371:72 | target[key] | tests.js:371:31:371:95 | mergePl ... ptions) | | tests.js:371:69:371:71 | key | tests.js:371:62:371:72 | target[key] | | tests.js:371:75:371:80 | source | tests.js:371:75:371:85 | source[key] | | tests.js:371:75:371:85 | source[key] | tests.js:364:49:364:54 | source | -| tests.js:371:75:371:85 | source[key] | tests.js:364:49:364:54 | source | -| tests.js:371:75:371:85 | source[key] | tests.js:364:49:364:54 | source | | tests.js:373:31:373:36 | source | tests.js:373:31:373:41 | source[key] | -| tests.js:373:31:373:36 | source | tests.js:373:31:373:41 | source[key] | -| tests.js:373:31:373:41 | source[key] | tests.js:373:31:373:41 | source[key] | | tests.js:373:38:373:40 | key | tests.js:373:31:373:41 | source[key] | -| tests.js:373:38:373:40 | key | tests.js:373:31:373:41 | source[key] | -| tests.js:381:14:381:16 | key | tests.js:383:22:383:24 | key | -| tests.js:381:14:381:16 | key | tests.js:383:22:383:24 | key | -| tests.js:381:14:381:16 | key | tests.js:383:22:383:24 | key | +| tests.js:380:22:380:24 | obj | tests.js:383:27:383:29 | obj | +| tests.js:380:27:380:34 | callback [dst] | tests.js:383:13:383:20 | callback [dst] | +| tests.js:380:27:380:34 | callback [dst] | tests.js:383:13:383:20 | callback [dst] | +| tests.js:380:27:380:34 | callback [dst] | tests.js:383:13:383:20 | callback [dst] | +| tests.js:380:27:380:34 | callback [dst] | tests.js:383:13:383:20 | callback [dst] | +| tests.js:380:27:380:34 | callback [src] | tests.js:383:13:383:20 | callback [src] | | tests.js:381:14:381:16 | key | tests.js:383:22:383:24 | key | | tests.js:381:14:381:16 | key | tests.js:383:31:383:33 | key | -| tests.js:381:14:381:16 | key | tests.js:383:31:383:33 | key | -| tests.js:381:14:381:16 | key | tests.js:383:31:383:33 | key | -| tests.js:381:14:381:16 | key | tests.js:383:31:383:33 | key | -| tests.js:383:22:383:24 | key | tests.js:389:22:389:24 | key | +| tests.js:383:13:383:20 | callback [dst] | tests.js:391:32:391:34 | dst | +| tests.js:383:13:383:20 | callback [dst] | tests.js:391:32:391:34 | dst | +| tests.js:383:13:383:20 | callback [dst] | tests.js:393:13:393:15 | dst | +| tests.js:383:13:383:20 | callback [dst] | tests.js:393:13:393:15 | dst | +| tests.js:383:13:383:20 | callback [dst] | tests.js:401:33:401:35 | dst | +| tests.js:383:13:383:20 | callback [dst] | tests.js:401:33:401:35 | dst | +| tests.js:383:13:383:20 | callback [dst] | tests.js:403:13:403:15 | dst | +| tests.js:383:13:383:20 | callback [dst] | tests.js:403:13:403:15 | dst | +| tests.js:383:13:383:20 | callback [src] | tests.js:391:42:391:44 | src | +| tests.js:383:13:383:20 | callback [src] | tests.js:393:24:393:26 | src | | tests.js:383:22:383:24 | key | tests.js:389:22:389:24 | key | | tests.js:383:22:383:24 | key | tests.js:399:23:399:25 | key | -| tests.js:383:22:383:24 | key | tests.js:399:23:399:25 | key | -| tests.js:383:27:383:34 | obj[key] | tests.js:399:28:399:32 | value | -| tests.js:383:27:383:34 | obj[key] | tests.js:399:28:399:32 | value | -| tests.js:383:27:383:34 | obj[key] | tests.js:399:28:399:32 | value | +| tests.js:383:27:383:29 | obj | tests.js:383:27:383:34 | obj[key] | | tests.js:383:27:383:34 | obj[key] | tests.js:399:28:399:32 | value | | tests.js:383:31:383:33 | key | tests.js:383:27:383:34 | obj[key] | -| tests.js:383:31:383:33 | key | tests.js:383:27:383:34 | obj[key] | +| tests.js:388:29:388:31 | dst | tests.js:380:27:380:34 | callback [dst] | +| tests.js:388:29:388:31 | dst | tests.js:380:27:380:34 | callback [dst] | | tests.js:388:29:388:31 | dst | tests.js:391:32:391:34 | dst | | tests.js:388:29:388:31 | dst | tests.js:391:32:391:34 | dst | | tests.js:388:29:388:31 | dst | tests.js:393:13:393:15 | dst | | tests.js:388:29:388:31 | dst | tests.js:393:13:393:15 | dst | -| tests.js:388:29:388:31 | dst | tests.js:393:13:393:15 | dst | -| tests.js:388:29:388:31 | dst | tests.js:393:13:393:15 | dst | -| tests.js:388:34:388:36 | src | tests.js:391:42:391:44 | src | -| tests.js:388:34:388:36 | src | tests.js:391:42:391:44 | src | -| tests.js:388:34:388:36 | src | tests.js:393:24:393:26 | src | -| tests.js:388:34:388:36 | src | tests.js:393:24:393:26 | src | -| tests.js:389:22:389:24 | key | tests.js:391:36:391:38 | key | +| tests.js:388:34:388:36 | src | tests.js:389:17:389:19 | src | +| tests.js:389:17:389:19 | src | tests.js:380:27:380:34 | callback [src] | +| tests.js:389:17:389:19 | src | tests.js:391:42:391:44 | src | +| tests.js:389:17:389:19 | src | tests.js:393:24:393:26 | src | | tests.js:389:22:389:24 | key | tests.js:391:36:391:38 | key | | tests.js:389:22:389:24 | key | tests.js:391:46:391:48 | key | -| tests.js:389:22:389:24 | key | tests.js:391:46:391:48 | key | | tests.js:389:22:389:24 | key | tests.js:393:17:393:19 | key | -| tests.js:389:22:389:24 | key | tests.js:393:17:393:19 | key | -| tests.js:389:22:389:24 | key | tests.js:393:17:393:19 | key | -| tests.js:389:22:389:24 | key | tests.js:393:17:393:19 | key | -| tests.js:389:22:389:24 | key | tests.js:393:28:393:30 | key | | tests.js:389:22:389:24 | key | tests.js:393:28:393:30 | key | | tests.js:391:32:391:34 | dst | tests.js:391:32:391:39 | dst[key] | | tests.js:391:32:391:34 | dst | tests.js:391:32:391:39 | dst[key] | @@ -2841,40 +1091,21 @@ edges | tests.js:391:36:391:38 | key | tests.js:391:32:391:39 | dst[key] | | tests.js:391:36:391:38 | key | tests.js:391:32:391:39 | dst[key] | | tests.js:391:42:391:44 | src | tests.js:391:42:391:49 | src[key] | -| tests.js:391:42:391:44 | src | tests.js:391:42:391:49 | src[key] | -| tests.js:391:42:391:49 | src[key] | tests.js:388:34:388:36 | src | | tests.js:391:42:391:49 | src[key] | tests.js:388:34:388:36 | src | | tests.js:391:46:391:48 | key | tests.js:391:42:391:49 | src[key] | -| tests.js:391:46:391:48 | key | tests.js:391:42:391:49 | src[key] | -| tests.js:393:24:393:26 | src | tests.js:393:24:393:31 | src[key] | -| tests.js:393:24:393:26 | src | tests.js:393:24:393:31 | src[key] | -| tests.js:393:24:393:26 | src | tests.js:393:24:393:31 | src[key] | | tests.js:393:24:393:26 | src | tests.js:393:24:393:31 | src[key] | | tests.js:393:28:393:30 | key | tests.js:393:24:393:31 | src[key] | -| tests.js:393:28:393:30 | key | tests.js:393:24:393:31 | src[key] | -| tests.js:393:28:393:30 | key | tests.js:393:24:393:31 | src[key] | -| tests.js:393:28:393:30 | key | tests.js:393:24:393:31 | src[key] | +| tests.js:398:30:398:32 | dst | tests.js:380:27:380:34 | callback [dst] | +| tests.js:398:30:398:32 | dst | tests.js:380:27:380:34 | callback [dst] | | tests.js:398:30:398:32 | dst | tests.js:401:33:401:35 | dst | | tests.js:398:30:398:32 | dst | tests.js:401:33:401:35 | dst | | tests.js:398:30:398:32 | dst | tests.js:403:13:403:15 | dst | | tests.js:398:30:398:32 | dst | tests.js:403:13:403:15 | dst | -| tests.js:398:30:398:32 | dst | tests.js:403:13:403:15 | dst | -| tests.js:398:30:398:32 | dst | tests.js:403:13:403:15 | dst | | tests.js:398:35:398:37 | src | tests.js:399:17:399:19 | src | -| tests.js:398:35:398:37 | src | tests.js:399:17:399:19 | src | -| tests.js:399:17:399:19 | src | tests.js:399:28:399:32 | value | -| tests.js:399:17:399:19 | src | tests.js:399:28:399:32 | value | -| tests.js:399:23:399:25 | key | tests.js:401:37:401:39 | key | +| tests.js:399:17:399:19 | src | tests.js:380:22:380:24 | obj | | tests.js:399:23:399:25 | key | tests.js:401:37:401:39 | key | | tests.js:399:23:399:25 | key | tests.js:403:17:403:19 | key | -| tests.js:399:23:399:25 | key | tests.js:403:17:403:19 | key | -| tests.js:399:23:399:25 | key | tests.js:403:17:403:19 | key | -| tests.js:399:23:399:25 | key | tests.js:403:17:403:19 | key | | tests.js:399:28:399:32 | value | tests.js:401:43:401:47 | value | -| tests.js:399:28:399:32 | value | tests.js:401:43:401:47 | value | -| tests.js:399:28:399:32 | value | tests.js:403:24:403:28 | value | -| tests.js:399:28:399:32 | value | tests.js:403:24:403:28 | value | -| tests.js:399:28:399:32 | value | tests.js:403:24:403:28 | value | | tests.js:399:28:399:32 | value | tests.js:403:24:403:28 | value | | tests.js:401:33:401:35 | dst | tests.js:401:33:401:40 | dst[key] | | tests.js:401:33:401:35 | dst | tests.js:401:33:401:40 | dst[key] | @@ -2883,641 +1114,233 @@ edges | tests.js:401:37:401:39 | key | tests.js:401:33:401:40 | dst[key] | | tests.js:401:37:401:39 | key | tests.js:401:33:401:40 | dst[key] | | tests.js:401:43:401:47 | value | tests.js:398:35:398:37 | src | -| tests.js:401:43:401:47 | value | tests.js:398:35:398:37 | src | -| tests.js:412:31:412:33 | dst | tests.js:415:34:415:36 | dst | +| tests.js:408:22:408:24 | obj | tests.js:409:12:409:14 | obj | +| tests.js:408:27:408:29 | key | tests.js:409:16:409:18 | key | +| tests.js:409:12:409:14 | obj | tests.js:409:12:409:19 | obj[key] | +| tests.js:409:16:409:18 | key | tests.js:409:12:409:19 | obj[key] | | tests.js:412:31:412:33 | dst | tests.js:415:34:415:36 | dst | | tests.js:412:31:412:33 | dst | tests.js:419:13:419:15 | dst | -| tests.js:412:31:412:33 | dst | tests.js:419:13:419:15 | dst | -| tests.js:412:31:412:33 | dst | tests.js:419:13:419:15 | dst | -| tests.js:412:31:412:33 | dst | tests.js:419:13:419:15 | dst | -| tests.js:412:36:412:38 | src | tests.js:414:33:414:35 | src | | tests.js:412:36:412:38 | src | tests.js:414:33:414:35 | src | | tests.js:413:14:413:16 | key | tests.js:414:38:414:40 | key | -| tests.js:413:14:413:16 | key | tests.js:414:38:414:40 | key | -| tests.js:413:14:413:16 | key | tests.js:414:38:414:40 | key | -| tests.js:413:14:413:16 | key | tests.js:414:38:414:40 | key | -| tests.js:413:14:413:16 | key | tests.js:415:39:415:41 | key | -| tests.js:413:14:413:16 | key | tests.js:415:39:415:41 | key | -| tests.js:413:14:413:16 | key | tests.js:415:39:415:41 | key | | tests.js:413:14:413:16 | key | tests.js:415:39:415:41 | key | | tests.js:413:14:413:16 | key | tests.js:419:17:419:19 | key | -| tests.js:413:14:413:16 | key | tests.js:419:17:419:19 | key | -| tests.js:413:14:413:16 | key | tests.js:419:17:419:19 | key | -| tests.js:413:14:413:16 | key | tests.js:419:17:419:19 | key | -| tests.js:413:14:413:16 | key | tests.js:419:17:419:19 | key | -| tests.js:413:14:413:16 | key | tests.js:419:17:419:19 | key | -| tests.js:413:14:413:16 | key | tests.js:419:17:419:19 | key | -| tests.js:414:13:414:41 | value | tests.js:417:42:417:46 | value | -| tests.js:414:13:414:41 | value | tests.js:417:42:417:46 | value | -| tests.js:414:13:414:41 | value | tests.js:417:42:417:46 | value | | tests.js:414:13:414:41 | value | tests.js:417:42:417:46 | value | | tests.js:414:13:414:41 | value | tests.js:419:24:419:28 | value | -| tests.js:414:13:414:41 | value | tests.js:419:24:419:28 | value | -| tests.js:414:13:414:41 | value | tests.js:419:24:419:28 | value | -| tests.js:414:13:414:41 | value | tests.js:419:24:419:28 | value | -| tests.js:414:13:414:41 | value | tests.js:419:24:419:28 | value | -| tests.js:414:13:414:41 | value | tests.js:419:24:419:28 | value | -| tests.js:414:13:414:41 | value | tests.js:419:24:419:28 | value | -| tests.js:414:13:414:41 | value | tests.js:419:24:419:28 | value | -| tests.js:414:21:414:41 | wrapped ... c, key) | tests.js:414:13:414:41 | value | -| tests.js:414:21:414:41 | wrapped ... c, key) | tests.js:414:13:414:41 | value | -| tests.js:414:21:414:41 | wrapped ... c, key) | tests.js:414:13:414:41 | value | -| tests.js:414:21:414:41 | wrapped ... c, key) | tests.js:414:13:414:41 | value | -| tests.js:414:21:414:41 | wrapped ... c, key) | tests.js:414:13:414:41 | value | | tests.js:414:21:414:41 | wrapped ... c, key) | tests.js:414:13:414:41 | value | +| tests.js:414:33:414:35 | src | tests.js:408:22:408:24 | obj | | tests.js:414:33:414:35 | src | tests.js:414:21:414:41 | wrapped ... c, key) | -| tests.js:414:33:414:35 | src | tests.js:414:21:414:41 | wrapped ... c, key) | -| tests.js:414:38:414:40 | key | tests.js:414:21:414:41 | wrapped ... c, key) | +| tests.js:414:38:414:40 | key | tests.js:408:27:408:29 | key | | tests.js:414:38:414:40 | key | tests.js:414:21:414:41 | wrapped ... c, key) | | tests.js:415:13:415:42 | target | tests.js:417:34:417:39 | target | -| tests.js:415:13:415:42 | target | tests.js:417:34:417:39 | target | -| tests.js:415:13:415:42 | target | tests.js:417:34:417:39 | target | -| tests.js:415:13:415:42 | target | tests.js:417:34:417:39 | target | -| tests.js:415:22:415:42 | wrapped ... t, key) | tests.js:415:13:415:42 | target | -| tests.js:415:22:415:42 | wrapped ... t, key) | tests.js:415:13:415:42 | target | -| tests.js:415:22:415:42 | wrapped ... t, key) | tests.js:415:13:415:42 | target | | tests.js:415:22:415:42 | wrapped ... t, key) | tests.js:415:13:415:42 | target | +| tests.js:415:34:415:36 | dst | tests.js:408:22:408:24 | obj | | tests.js:415:34:415:36 | dst | tests.js:415:22:415:42 | wrapped ... t, key) | -| tests.js:415:34:415:36 | dst | tests.js:415:22:415:42 | wrapped ... t, key) | -| tests.js:415:39:415:41 | key | tests.js:415:22:415:42 | wrapped ... t, key) | +| tests.js:415:39:415:41 | key | tests.js:408:27:408:29 | key | | tests.js:415:39:415:41 | key | tests.js:415:22:415:42 | wrapped ... t, key) | | tests.js:417:34:417:39 | target | tests.js:412:31:412:33 | dst | -| tests.js:417:34:417:39 | target | tests.js:412:31:412:33 | dst | -| tests.js:417:34:417:39 | target | tests.js:412:31:412:33 | dst | -| tests.js:417:34:417:39 | target | tests.js:412:31:412:33 | dst | -| tests.js:417:42:417:46 | value | tests.js:412:36:412:38 | src | -| tests.js:417:42:417:46 | value | tests.js:412:36:412:38 | src | -| tests.js:417:42:417:46 | value | tests.js:412:36:412:38 | src | | tests.js:417:42:417:46 | value | tests.js:412:36:412:38 | src | +| tests.js:424:25:424:27 | obj | tests.js:426:12:426:14 | obj | +| tests.js:424:30:424:32 | key | tests.js:426:16:426:18 | key | +| tests.js:426:12:426:14 | obj | tests.js:426:12:426:19 | obj[key] | +| tests.js:426:16:426:18 | key | tests.js:426:12:426:19 | obj[key] | | tests.js:429:34:429:36 | dst | tests.js:432:37:432:39 | dst | | tests.js:429:34:429:36 | dst | tests.js:436:13:436:15 | dst | -| tests.js:429:34:429:36 | dst | tests.js:436:13:436:15 | dst | -| tests.js:429:39:429:41 | src | tests.js:431:36:431:38 | src | | tests.js:429:39:429:41 | src | tests.js:431:36:431:38 | src | | tests.js:430:14:430:16 | key | tests.js:431:41:431:43 | key | -| tests.js:430:14:430:16 | key | tests.js:431:41:431:43 | key | -| tests.js:430:14:430:16 | key | tests.js:432:42:432:44 | key | | tests.js:430:14:430:16 | key | tests.js:432:42:432:44 | key | | tests.js:430:14:430:16 | key | tests.js:436:17:436:19 | key | -| tests.js:430:14:430:16 | key | tests.js:436:17:436:19 | key | -| tests.js:430:14:430:16 | key | tests.js:436:17:436:19 | key | -| tests.js:430:14:430:16 | key | tests.js:436:17:436:19 | key | -| tests.js:430:14:430:16 | key | tests.js:436:17:436:19 | key | -| tests.js:430:14:430:16 | key | tests.js:436:17:436:19 | key | -| tests.js:430:14:430:16 | key | tests.js:436:17:436:19 | key | -| tests.js:431:13:431:44 | value | tests.js:434:45:434:49 | value | -| tests.js:431:13:431:44 | value | tests.js:434:45:434:49 | value | -| tests.js:431:13:431:44 | value | tests.js:434:45:434:49 | value | | tests.js:431:13:431:44 | value | tests.js:434:45:434:49 | value | | tests.js:431:13:431:44 | value | tests.js:436:24:436:28 | value | -| tests.js:431:13:431:44 | value | tests.js:436:24:436:28 | value | -| tests.js:431:13:431:44 | value | tests.js:436:24:436:28 | value | -| tests.js:431:13:431:44 | value | tests.js:436:24:436:28 | value | -| tests.js:431:13:431:44 | value | tests.js:436:24:436:28 | value | -| tests.js:431:13:431:44 | value | tests.js:436:24:436:28 | value | -| tests.js:431:13:431:44 | value | tests.js:436:24:436:28 | value | -| tests.js:431:13:431:44 | value | tests.js:436:24:436:28 | value | -| tests.js:431:21:431:44 | almostS ... c, key) | tests.js:431:13:431:44 | value | -| tests.js:431:21:431:44 | almostS ... c, key) | tests.js:431:13:431:44 | value | -| tests.js:431:21:431:44 | almostS ... c, key) | tests.js:431:13:431:44 | value | -| tests.js:431:21:431:44 | almostS ... c, key) | tests.js:431:13:431:44 | value | -| tests.js:431:21:431:44 | almostS ... c, key) | tests.js:431:13:431:44 | value | | tests.js:431:21:431:44 | almostS ... c, key) | tests.js:431:13:431:44 | value | +| tests.js:431:36:431:38 | src | tests.js:424:25:424:27 | obj | | tests.js:431:36:431:38 | src | tests.js:431:21:431:44 | almostS ... c, key) | -| tests.js:431:36:431:38 | src | tests.js:431:21:431:44 | almostS ... c, key) | +| tests.js:431:41:431:43 | key | tests.js:424:30:424:32 | key | | tests.js:431:41:431:43 | key | tests.js:431:21:431:44 | almostS ... c, key) | | tests.js:432:13:432:45 | target | tests.js:434:37:434:42 | target | -| tests.js:432:13:432:45 | target | tests.js:434:37:434:42 | target | -| tests.js:432:22:432:45 | almostS ... t, key) | tests.js:432:13:432:45 | target | | tests.js:432:22:432:45 | almostS ... t, key) | tests.js:432:13:432:45 | target | +| tests.js:432:37:432:39 | dst | tests.js:424:25:424:27 | obj | | tests.js:432:37:432:39 | dst | tests.js:432:22:432:45 | almostS ... t, key) | +| tests.js:432:42:432:44 | key | tests.js:424:30:424:32 | key | | tests.js:432:42:432:44 | key | tests.js:432:22:432:45 | almostS ... t, key) | | tests.js:434:37:434:42 | target | tests.js:429:34:429:36 | dst | -| tests.js:434:37:434:42 | target | tests.js:429:34:429:36 | dst | | tests.js:434:45:434:49 | value | tests.js:429:39:429:41 | src | -| tests.js:434:45:434:49 | value | tests.js:429:39:429:41 | src | -| tests.js:434:45:434:49 | value | tests.js:429:39:429:41 | src | -| tests.js:434:45:434:49 | value | tests.js:429:39:429:41 | src | -| tests.js:446:33:446:35 | src | tests.js:448:30:448:32 | src | +| tests.js:441:19:441:21 | obj | tests.js:443:12:443:14 | obj | +| tests.js:443:12:443:14 | obj | tests.js:443:12:443:19 | obj[key] | | tests.js:446:33:446:35 | src | tests.js:448:30:448:32 | src | | tests.js:447:14:447:16 | key | tests.js:453:17:453:19 | key | -| tests.js:447:14:447:16 | key | tests.js:453:17:453:19 | key | -| tests.js:447:14:447:16 | key | tests.js:453:17:453:19 | key | -| tests.js:447:14:447:16 | key | tests.js:453:17:453:19 | key | -| tests.js:447:14:447:16 | key | tests.js:453:17:453:19 | key | -| tests.js:447:14:447:16 | key | tests.js:453:17:453:19 | key | -| tests.js:447:14:447:16 | key | tests.js:453:17:453:19 | key | -| tests.js:448:13:448:38 | value | tests.js:451:39:451:43 | value | -| tests.js:448:13:448:38 | value | tests.js:451:39:451:43 | value | -| tests.js:448:13:448:38 | value | tests.js:451:39:451:43 | value | | tests.js:448:13:448:38 | value | tests.js:451:39:451:43 | value | | tests.js:448:13:448:38 | value | tests.js:453:24:453:28 | value | -| tests.js:448:13:448:38 | value | tests.js:453:24:453:28 | value | -| tests.js:448:13:448:38 | value | tests.js:453:24:453:28 | value | -| tests.js:448:13:448:38 | value | tests.js:453:24:453:28 | value | -| tests.js:448:13:448:38 | value | tests.js:453:24:453:28 | value | -| tests.js:448:13:448:38 | value | tests.js:453:24:453:28 | value | -| tests.js:448:13:448:38 | value | tests.js:453:24:453:28 | value | -| tests.js:448:13:448:38 | value | tests.js:453:24:453:28 | value | | tests.js:448:21:448:38 | safeRead(src, key) | tests.js:448:13:448:38 | value | -| tests.js:448:21:448:38 | safeRead(src, key) | tests.js:448:13:448:38 | value | -| tests.js:448:21:448:38 | safeRead(src, key) | tests.js:448:13:448:38 | value | -| tests.js:448:21:448:38 | safeRead(src, key) | tests.js:448:13:448:38 | value | -| tests.js:448:21:448:38 | safeRead(src, key) | tests.js:448:13:448:38 | value | -| tests.js:448:21:448:38 | safeRead(src, key) | tests.js:448:13:448:38 | value | -| tests.js:448:30:448:32 | src | tests.js:448:21:448:38 | safeRead(src, key) | +| tests.js:448:30:448:32 | src | tests.js:441:19:441:21 | obj | | tests.js:448:30:448:32 | src | tests.js:448:21:448:38 | safeRead(src, key) | | tests.js:451:39:451:43 | value | tests.js:446:33:446:35 | src | -| tests.js:451:39:451:43 | value | tests.js:446:33:446:35 | src | -| tests.js:451:39:451:43 | value | tests.js:446:33:446:35 | src | -| tests.js:451:39:451:43 | value | tests.js:446:33:446:35 | src | -| tests.js:458:26:458:28 | dst | tests.js:462:29:462:31 | dst | | tests.js:458:26:458:28 | dst | tests.js:462:29:462:31 | dst | | tests.js:458:26:458:28 | dst | tests.js:465:30:465:32 | dst | -| tests.js:458:26:458:28 | dst | tests.js:465:30:465:32 | dst | -| tests.js:458:26:458:28 | dst | tests.js:465:30:465:32 | dst | -| tests.js:458:26:458:28 | dst | tests.js:465:30:465:32 | dst | -| tests.js:458:26:458:28 | dst | tests.js:466:30:466:32 | dst | -| tests.js:458:26:458:28 | dst | tests.js:466:30:466:32 | dst | -| tests.js:458:26:458:28 | dst | tests.js:466:30:466:32 | dst | | tests.js:458:26:458:28 | dst | tests.js:466:30:466:32 | dst | | tests.js:458:26:458:28 | dst | tests.js:467:30:467:32 | dst | -| tests.js:458:26:458:28 | dst | tests.js:467:30:467:32 | dst | -| tests.js:458:26:458:28 | dst | tests.js:467:30:467:32 | dst | -| tests.js:458:26:458:28 | dst | tests.js:467:30:467:32 | dst | -| tests.js:458:31:458:33 | src | tests.js:462:39:462:41 | src | -| tests.js:458:31:458:33 | src | tests.js:462:39:462:41 | src | -| tests.js:458:31:458:33 | src | tests.js:465:41:465:43 | src | -| tests.js:458:31:458:33 | src | tests.js:465:41:465:43 | src | -| tests.js:460:18:460:22 | value | tests.js:467:41:467:45 | value | -| tests.js:460:18:460:22 | value | tests.js:467:41:467:45 | value | -| tests.js:460:18:460:22 | value | tests.js:467:41:467:45 | value | -| tests.js:460:18:460:22 | value | tests.js:467:41:467:45 | value | -| tests.js:460:18:460:22 | value | tests.js:467:41:467:45 | value | -| tests.js:460:18:460:22 | value | tests.js:467:41:467:45 | value | +| tests.js:458:31:458:33 | src | tests.js:460:12:460:14 | src | +| tests.js:460:12:460:14 | src | tests.js:462:39:462:41 | src | +| tests.js:460:12:460:14 | src | tests.js:465:41:465:43 | src | | tests.js:460:18:460:22 | value | tests.js:467:41:467:45 | value | | tests.js:460:25:460:27 | key | tests.js:462:33:462:35 | key | -| tests.js:460:25:460:27 | key | tests.js:462:33:462:35 | key | -| tests.js:460:25:460:27 | key | tests.js:462:33:462:35 | key | -| tests.js:460:25:460:27 | key | tests.js:462:33:462:35 | key | -| tests.js:460:25:460:27 | key | tests.js:462:43:462:45 | key | -| tests.js:460:25:460:27 | key | tests.js:462:43:462:45 | key | -| tests.js:460:25:460:27 | key | tests.js:462:43:462:45 | key | | tests.js:460:25:460:27 | key | tests.js:462:43:462:45 | key | | tests.js:460:25:460:27 | key | tests.js:465:34:465:36 | key | -| tests.js:460:25:460:27 | key | tests.js:465:34:465:36 | key | -| tests.js:460:25:460:27 | key | tests.js:465:34:465:36 | key | -| tests.js:460:25:460:27 | key | tests.js:465:34:465:36 | key | -| tests.js:460:25:460:27 | key | tests.js:465:34:465:36 | key | -| tests.js:460:25:460:27 | key | tests.js:465:34:465:36 | key | -| tests.js:460:25:460:27 | key | tests.js:465:34:465:36 | key | -| tests.js:460:25:460:27 | key | tests.js:465:45:465:47 | key | -| tests.js:460:25:460:27 | key | tests.js:465:45:465:47 | key | -| tests.js:460:25:460:27 | key | tests.js:465:45:465:47 | key | | tests.js:460:25:460:27 | key | tests.js:465:45:465:47 | key | | tests.js:460:25:460:27 | key | tests.js:466:34:466:36 | key | -| tests.js:460:25:460:27 | key | tests.js:466:34:466:36 | key | -| tests.js:460:25:460:27 | key | tests.js:466:34:466:36 | key | -| tests.js:460:25:460:27 | key | tests.js:466:34:466:36 | key | -| tests.js:460:25:460:27 | key | tests.js:466:34:466:36 | key | -| tests.js:460:25:460:27 | key | tests.js:466:34:466:36 | key | -| tests.js:460:25:460:27 | key | tests.js:466:34:466:36 | key | | tests.js:460:25:460:27 | key | tests.js:466:43:466:45 | key | -| tests.js:460:25:460:27 | key | tests.js:466:43:466:45 | key | -| tests.js:460:25:460:27 | key | tests.js:466:43:466:45 | key | -| tests.js:460:25:460:27 | key | tests.js:466:43:466:45 | key | -| tests.js:460:25:460:27 | key | tests.js:467:34:467:36 | key | -| tests.js:460:25:460:27 | key | tests.js:467:34:467:36 | key | -| tests.js:460:25:460:27 | key | tests.js:467:34:467:36 | key | -| tests.js:460:25:460:27 | key | tests.js:467:34:467:36 | key | -| tests.js:460:25:460:27 | key | tests.js:467:34:467:36 | key | -| tests.js:460:25:460:27 | key | tests.js:467:34:467:36 | key | | tests.js:460:25:460:27 | key | tests.js:467:34:467:36 | key | | tests.js:462:29:462:31 | dst | tests.js:462:29:462:36 | dst[key] | -| tests.js:462:29:462:31 | dst | tests.js:462:29:462:36 | dst[key] | -| tests.js:462:29:462:36 | dst[key] | tests.js:458:26:458:28 | dst | -| tests.js:462:29:462:36 | dst[key] | tests.js:458:26:458:28 | dst | -| tests.js:462:29:462:36 | dst[key] | tests.js:458:26:458:28 | dst | | tests.js:462:29:462:36 | dst[key] | tests.js:458:26:458:28 | dst | | tests.js:462:33:462:35 | key | tests.js:462:29:462:36 | dst[key] | -| tests.js:462:33:462:35 | key | tests.js:462:29:462:36 | dst[key] | -| tests.js:462:39:462:41 | src | tests.js:462:39:462:46 | src[key] | | tests.js:462:39:462:41 | src | tests.js:462:39:462:46 | src[key] | | tests.js:462:39:462:46 | src[key] | tests.js:458:31:458:33 | src | -| tests.js:462:39:462:46 | src[key] | tests.js:458:31:458:33 | src | -| tests.js:462:39:462:46 | src[key] | tests.js:458:31:458:33 | src | -| tests.js:462:39:462:46 | src[key] | tests.js:458:31:458:33 | src | -| tests.js:462:39:462:46 | src[key] | tests.js:458:31:458:33 | src | -| tests.js:462:39:462:46 | src[key] | tests.js:458:31:458:33 | src | -| tests.js:462:43:462:45 | key | tests.js:462:39:462:46 | src[key] | | tests.js:462:43:462:45 | key | tests.js:462:39:462:46 | src[key] | | tests.js:465:41:465:43 | src | tests.js:465:41:465:48 | src[key] | -| tests.js:465:41:465:43 | src | tests.js:465:41:465:48 | src[key] | -| tests.js:465:41:465:43 | src | tests.js:465:41:465:48 | src[key] | -| tests.js:465:41:465:43 | src | tests.js:465:41:465:48 | src[key] | -| tests.js:465:41:465:48 | src[key] | tests.js:465:41:465:48 | src[key] | | tests.js:465:45:465:47 | key | tests.js:465:41:465:48 | src[key] | -| tests.js:465:45:465:47 | key | tests.js:465:41:465:48 | src[key] | -| tests.js:465:45:465:47 | key | tests.js:465:41:465:48 | src[key] | -| tests.js:465:45:465:47 | key | tests.js:465:41:465:48 | src[key] | -| tests.js:466:41:466:46 | o[key] | tests.js:466:41:466:46 | o[key] | -| tests.js:466:43:466:45 | key | tests.js:466:41:466:46 | o[key] | -| tests.js:466:43:466:45 | key | tests.js:466:41:466:46 | o[key] | -| tests.js:466:43:466:45 | key | tests.js:466:41:466:46 | o[key] | | tests.js:466:43:466:45 | key | tests.js:466:41:466:46 | o[key] | | tests.js:472:38:472:40 | dst | tests.js:475:41:475:43 | dst | -| tests.js:472:38:472:40 | dst | tests.js:475:41:475:43 | dst | -| tests.js:472:38:472:40 | dst | tests.js:477:13:477:15 | dst | -| tests.js:472:38:472:40 | dst | tests.js:477:13:477:15 | dst | -| tests.js:472:38:472:40 | dst | tests.js:477:13:477:15 | dst | | tests.js:472:38:472:40 | dst | tests.js:477:13:477:15 | dst | | tests.js:473:18:473:22 | value | tests.js:477:24:477:28 | value | -| tests.js:473:18:473:22 | value | tests.js:477:24:477:28 | value | -| tests.js:473:18:473:22 | value | tests.js:477:24:477:28 | value | -| tests.js:473:18:473:22 | value | tests.js:477:24:477:28 | value | -| tests.js:473:18:473:22 | value | tests.js:477:24:477:28 | value | -| tests.js:473:18:473:22 | value | tests.js:477:24:477:28 | value | -| tests.js:473:18:473:22 | value | tests.js:477:24:477:28 | value | | tests.js:473:25:473:27 | key | tests.js:475:45:475:47 | key | -| tests.js:473:25:473:27 | key | tests.js:475:45:475:47 | key | -| tests.js:473:25:473:27 | key | tests.js:475:45:475:47 | key | -| tests.js:473:25:473:27 | key | tests.js:475:45:475:47 | key | -| tests.js:473:25:473:27 | key | tests.js:477:17:477:19 | key | -| tests.js:473:25:473:27 | key | tests.js:477:17:477:19 | key | -| tests.js:473:25:473:27 | key | tests.js:477:17:477:19 | key | -| tests.js:473:25:473:27 | key | tests.js:477:17:477:19 | key | -| tests.js:473:25:473:27 | key | tests.js:477:17:477:19 | key | -| tests.js:473:25:473:27 | key | tests.js:477:17:477:19 | key | | tests.js:473:25:473:27 | key | tests.js:477:17:477:19 | key | | tests.js:475:41:475:43 | dst | tests.js:475:41:475:48 | dst[key] | -| tests.js:475:41:475:43 | dst | tests.js:475:41:475:48 | dst[key] | | tests.js:475:41:475:48 | dst[key] | tests.js:472:38:472:40 | dst | -| tests.js:475:41:475:48 | dst[key] | tests.js:472:38:472:40 | dst | -| tests.js:475:41:475:48 | dst[key] | tests.js:472:38:472:40 | dst | -| tests.js:475:41:475:48 | dst[key] | tests.js:472:38:472:40 | dst | -| tests.js:475:45:475:47 | key | tests.js:475:41:475:48 | dst[key] | | tests.js:475:45:475:47 | key | tests.js:475:41:475:48 | dst[key] | | tests.js:483:26:483:28 | dst | tests.js:487:29:487:31 | dst | | tests.js:483:26:483:28 | dst | tests.js:489:13:489:15 | dst | -| tests.js:483:26:483:28 | dst | tests.js:489:13:489:15 | dst | | tests.js:483:31:483:33 | src | tests.js:487:39:487:41 | src | | tests.js:483:31:483:33 | src | tests.js:489:24:489:26 | src | | tests.js:483:31:483:33 | src | tests.js:489:24:489:26 | src | | tests.js:484:14:484:16 | key | tests.js:487:33:487:35 | key | -| tests.js:484:14:484:16 | key | tests.js:487:33:487:35 | key | -| tests.js:484:14:484:16 | key | tests.js:487:43:487:45 | key | | tests.js:484:14:484:16 | key | tests.js:487:43:487:45 | key | | tests.js:484:14:484:16 | key | tests.js:489:17:489:19 | key | -| tests.js:484:14:484:16 | key | tests.js:489:17:489:19 | key | -| tests.js:484:14:484:16 | key | tests.js:489:17:489:19 | key | -| tests.js:484:14:484:16 | key | tests.js:489:17:489:19 | key | -| tests.js:484:14:484:16 | key | tests.js:489:28:489:30 | key | | tests.js:484:14:484:16 | key | tests.js:489:28:489:30 | key | | tests.js:487:29:487:31 | dst | tests.js:487:29:487:36 | dst[key] | | tests.js:487:29:487:36 | dst[key] | tests.js:483:26:483:28 | dst | -| tests.js:487:29:487:36 | dst[key] | tests.js:483:26:483:28 | dst | | tests.js:487:33:487:35 | key | tests.js:487:29:487:36 | dst[key] | | tests.js:487:39:487:41 | src | tests.js:487:39:487:46 | src[key] | | tests.js:487:39:487:46 | src[key] | tests.js:483:31:483:33 | src | | tests.js:487:39:487:46 | src[key] | tests.js:483:31:483:33 | src | | tests.js:487:39:487:46 | src[key] | tests.js:483:31:483:33 | src | -| tests.js:487:39:487:46 | src[key] | tests.js:483:31:483:33 | src | -| tests.js:487:39:487:46 | src[key] | tests.js:483:31:483:33 | src | | tests.js:487:43:487:45 | key | tests.js:487:39:487:46 | src[key] | | tests.js:489:24:489:26 | src | tests.js:489:24:489:31 | src[key] | -| tests.js:489:24:489:26 | src | tests.js:489:24:489:31 | src[key] | -| tests.js:489:24:489:26 | src | tests.js:489:24:489:31 | src[key] | -| tests.js:489:24:489:26 | src | tests.js:489:24:489:31 | src[key] | -| tests.js:489:24:489:31 | src[key] | tests.js:489:24:489:31 | src[key] | -| tests.js:489:28:489:30 | key | tests.js:489:24:489:31 | src[key] | | tests.js:489:28:489:30 | key | tests.js:489:24:489:31 | src[key] | | tests.js:494:32:494:34 | src | tests.js:498:21:498:23 | src | | tests.js:495:14:495:16 | key | tests.js:498:25:498:27 | key | -| tests.js:495:14:495:16 | key | tests.js:498:25:498:27 | key | -| tests.js:495:14:495:16 | key | tests.js:502:17:502:19 | key | -| tests.js:495:14:495:16 | key | tests.js:502:17:502:19 | key | -| tests.js:495:14:495:16 | key | tests.js:502:17:502:19 | key | | tests.js:495:14:495:16 | key | tests.js:502:17:502:19 | key | | tests.js:498:13:498:28 | value | tests.js:500:38:500:42 | value | | tests.js:498:13:498:28 | value | tests.js:500:38:500:42 | value | | tests.js:498:13:498:28 | value | tests.js:502:24:502:28 | value | | tests.js:498:13:498:28 | value | tests.js:502:24:502:28 | value | | tests.js:498:13:498:28 | value | tests.js:502:24:502:28 | value | -| tests.js:498:13:498:28 | value | tests.js:502:24:502:28 | value | -| tests.js:498:13:498:28 | value | tests.js:502:24:502:28 | value | -| tests.js:498:13:498:28 | value | tests.js:502:24:502:28 | value | | tests.js:498:21:498:23 | src | tests.js:498:21:498:28 | src[key] | | tests.js:498:21:498:28 | src[key] | tests.js:498:13:498:28 | value | | tests.js:498:21:498:28 | src[key] | tests.js:498:13:498:28 | value | | tests.js:498:21:498:28 | src[key] | tests.js:498:13:498:28 | value | -| tests.js:498:21:498:28 | src[key] | tests.js:498:13:498:28 | value | -| tests.js:498:21:498:28 | src[key] | tests.js:498:13:498:28 | value | | tests.js:498:25:498:27 | key | tests.js:498:21:498:28 | src[key] | | tests.js:500:38:500:42 | value | tests.js:494:32:494:34 | src | | tests.js:500:38:500:42 | value | tests.js:494:32:494:34 | src | | tests.js:508:30:508:32 | dst | tests.js:513:33:513:35 | dst | -| tests.js:508:30:508:32 | dst | tests.js:513:33:513:35 | dst | -| tests.js:508:30:508:32 | dst | tests.js:517:35:517:37 | dst | -| tests.js:508:30:508:32 | dst | tests.js:517:35:517:37 | dst | -| tests.js:508:30:508:32 | dst | tests.js:517:35:517:37 | dst | | tests.js:508:30:508:32 | dst | tests.js:517:35:517:37 | dst | | tests.js:508:35:508:37 | src | tests.js:513:43:513:45 | src | -| tests.js:508:35:508:37 | src | tests.js:513:43:513:45 | src | -| tests.js:508:35:508:37 | src | tests.js:516:32:516:34 | src | | tests.js:508:35:508:37 | src | tests.js:516:32:516:34 | src | | tests.js:511:13:511:25 | key | tests.js:513:37:513:39 | key | -| tests.js:511:13:511:25 | key | tests.js:513:37:513:39 | key | -| tests.js:511:13:511:25 | key | tests.js:513:47:513:49 | key | | tests.js:511:13:511:25 | key | tests.js:513:47:513:49 | key | | tests.js:511:13:511:25 | key | tests.js:516:36:516:38 | key | -| tests.js:511:13:511:25 | key | tests.js:516:36:516:38 | key | | tests.js:511:13:511:25 | key | tests.js:517:40:517:42 | key | -| tests.js:511:13:511:25 | key | tests.js:517:40:517:42 | key | -| tests.js:511:13:511:25 | key | tests.js:517:40:517:42 | key | -| tests.js:511:13:511:25 | key | tests.js:517:40:517:42 | key | -| tests.js:511:19:511:25 | keys[i] | tests.js:511:13:511:25 | key | -| tests.js:511:19:511:25 | keys[i] | tests.js:511:13:511:25 | key | -| tests.js:511:19:511:25 | keys[i] | tests.js:511:13:511:25 | key | | tests.js:511:19:511:25 | keys[i] | tests.js:511:13:511:25 | key | | tests.js:513:33:513:35 | dst | tests.js:513:33:513:40 | dst[key] | -| tests.js:513:33:513:35 | dst | tests.js:513:33:513:40 | dst[key] | -| tests.js:513:33:513:40 | dst[key] | tests.js:508:30:508:32 | dst | -| tests.js:513:33:513:40 | dst[key] | tests.js:508:30:508:32 | dst | -| tests.js:513:33:513:40 | dst[key] | tests.js:508:30:508:32 | dst | | tests.js:513:33:513:40 | dst[key] | tests.js:508:30:508:32 | dst | | tests.js:513:37:513:39 | key | tests.js:513:33:513:40 | dst[key] | -| tests.js:513:37:513:39 | key | tests.js:513:33:513:40 | dst[key] | -| tests.js:513:43:513:45 | src | tests.js:513:43:513:50 | src[key] | | tests.js:513:43:513:45 | src | tests.js:513:43:513:50 | src[key] | | tests.js:513:43:513:50 | src[key] | tests.js:508:35:508:37 | src | -| tests.js:513:43:513:50 | src[key] | tests.js:508:35:508:37 | src | -| tests.js:513:43:513:50 | src[key] | tests.js:508:35:508:37 | src | -| tests.js:513:43:513:50 | src[key] | tests.js:508:35:508:37 | src | -| tests.js:513:43:513:50 | src[key] | tests.js:508:35:508:37 | src | -| tests.js:513:43:513:50 | src[key] | tests.js:508:35:508:37 | src | -| tests.js:513:47:513:49 | key | tests.js:513:43:513:50 | src[key] | | tests.js:513:47:513:49 | key | tests.js:513:43:513:50 | src[key] | | tests.js:516:32:516:34 | src | tests.js:516:32:516:39 | src[key] | -| tests.js:516:32:516:34 | src | tests.js:516:32:516:39 | src[key] | -| tests.js:516:32:516:34 | src | tests.js:516:32:516:39 | src[key] | -| tests.js:516:32:516:34 | src | tests.js:516:32:516:39 | src[key] | -| tests.js:516:32:516:39 | src[key] | tests.js:516:32:516:39 | src[key] | | tests.js:516:36:516:38 | key | tests.js:516:32:516:39 | src[key] | -| tests.js:516:36:516:38 | key | tests.js:516:32:516:39 | src[key] | -| tests.js:516:36:516:38 | key | tests.js:516:32:516:39 | src[key] | -| tests.js:516:36:516:38 | key | tests.js:516:32:516:39 | src[key] | -| tests.js:523:11:523:23 | dst | tests.js:527:35:527:37 | dst | -| tests.js:523:11:523:23 | dst | tests.js:527:35:527:37 | dst | -| tests.js:523:11:523:23 | dst | tests.js:529:13:529:15 | dst | -| tests.js:523:11:523:23 | dst | tests.js:529:13:529:15 | dst | -| tests.js:523:11:523:23 | dst | tests.js:529:13:529:15 | dst | -| tests.js:523:11:523:23 | dst | tests.js:529:13:529:15 | dst | -| tests.js:523:17:523:23 | args[0] | tests.js:523:11:523:23 | dst | -| tests.js:523:17:523:23 | args[0] | tests.js:523:11:523:23 | dst | -| tests.js:524:11:524:23 | src | tests.js:527:45:527:47 | src | -| tests.js:524:11:524:23 | src | tests.js:527:45:527:47 | src | -| tests.js:524:11:524:23 | src | tests.js:529:24:529:26 | src | -| tests.js:524:11:524:23 | src | tests.js:529:24:529:26 | src | -| tests.js:524:17:524:23 | args[1] | tests.js:524:11:524:23 | src | -| tests.js:524:17:524:23 | args[1] | tests.js:524:11:524:23 | src | -| tests.js:525:14:525:16 | key | tests.js:527:39:527:41 | key | -| tests.js:525:14:525:16 | key | tests.js:527:39:527:41 | key | -| tests.js:525:14:525:16 | key | tests.js:527:39:527:41 | key | -| tests.js:525:14:525:16 | key | tests.js:527:39:527:41 | key | -| tests.js:525:14:525:16 | key | tests.js:527:49:527:51 | key | -| tests.js:525:14:525:16 | key | tests.js:527:49:527:51 | key | -| tests.js:525:14:525:16 | key | tests.js:527:49:527:51 | key | -| tests.js:525:14:525:16 | key | tests.js:527:49:527:51 | key | -| tests.js:525:14:525:16 | key | tests.js:529:17:529:19 | key | -| tests.js:525:14:525:16 | key | tests.js:529:17:529:19 | key | -| tests.js:525:14:525:16 | key | tests.js:529:17:529:19 | key | -| tests.js:525:14:525:16 | key | tests.js:529:17:529:19 | key | -| tests.js:525:14:525:16 | key | tests.js:529:17:529:19 | key | -| tests.js:525:14:525:16 | key | tests.js:529:17:529:19 | key | | tests.js:525:14:525:16 | key | tests.js:529:17:529:19 | key | | tests.js:525:14:525:16 | key | tests.js:529:28:529:30 | key | -| tests.js:525:14:525:16 | key | tests.js:529:28:529:30 | key | -| tests.js:525:14:525:16 | key | tests.js:529:28:529:30 | key | -| tests.js:525:14:525:16 | key | tests.js:529:28:529:30 | key | -| tests.js:527:35:527:37 | dst | tests.js:527:35:527:42 | dst[key] | -| tests.js:527:35:527:37 | dst | tests.js:527:35:527:42 | dst[key] | -| tests.js:527:35:527:42 | dst[key] | tests.js:523:17:523:23 | args[0] | -| tests.js:527:35:527:42 | dst[key] | tests.js:523:17:523:23 | args[0] | -| tests.js:527:35:527:42 | dst[key] | tests.js:523:17:523:23 | args[0] | -| tests.js:527:35:527:42 | dst[key] | tests.js:523:17:523:23 | args[0] | -| tests.js:527:39:527:41 | key | tests.js:527:35:527:42 | dst[key] | -| tests.js:527:39:527:41 | key | tests.js:527:35:527:42 | dst[key] | -| tests.js:527:45:527:47 | src | tests.js:527:45:527:52 | src[key] | -| tests.js:527:45:527:47 | src | tests.js:527:45:527:52 | src[key] | -| tests.js:527:45:527:52 | src[key] | tests.js:524:17:524:23 | args[1] | -| tests.js:527:45:527:52 | src[key] | tests.js:524:17:524:23 | args[1] | -| tests.js:527:45:527:52 | src[key] | tests.js:524:17:524:23 | args[1] | -| tests.js:527:45:527:52 | src[key] | tests.js:524:17:524:23 | args[1] | -| tests.js:527:45:527:52 | src[key] | tests.js:524:17:524:23 | args[1] | -| tests.js:527:45:527:52 | src[key] | tests.js:524:17:524:23 | args[1] | -| tests.js:527:49:527:51 | key | tests.js:527:45:527:52 | src[key] | -| tests.js:527:49:527:51 | key | tests.js:527:45:527:52 | src[key] | -| tests.js:529:24:529:26 | src | tests.js:529:24:529:31 | src[key] | -| tests.js:529:24:529:26 | src | tests.js:529:24:529:31 | src[key] | -| tests.js:529:24:529:26 | src | tests.js:529:24:529:31 | src[key] | -| tests.js:529:24:529:26 | src | tests.js:529:24:529:31 | src[key] | -| tests.js:529:24:529:31 | src[key] | tests.js:529:24:529:31 | src[key] | -| tests.js:529:28:529:30 | key | tests.js:529:24:529:31 | src[key] | -| tests.js:529:28:529:30 | key | tests.js:529:24:529:31 | src[key] | -| tests.js:529:28:529:30 | key | tests.js:529:24:529:31 | src[key] | | tests.js:529:28:529:30 | key | tests.js:529:24:529:31 | src[key] | | tests.js:534:31:534:33 | obj | tests.js:538:27:538:29 | obj | -| tests.js:534:31:534:33 | obj | tests.js:538:27:538:29 | obj | -| tests.js:534:31:534:33 | obj | tests.js:538:27:538:29 | obj | -| tests.js:534:31:534:33 | obj | tests.js:538:27:538:29 | obj | -| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key | -| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key | -| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key | -| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key | -| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key | -| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key | -| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key | +| tests.js:534:36:534:43 | callback [dst] | tests.js:538:9:538:16 | callback [dst] | +| tests.js:538:9:538:16 | callback [dst] | tests.js:545:33:545:35 | dst | +| tests.js:538:9:538:16 | callback [dst] | tests.js:547:13:547:15 | dst | | tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key | | tests.js:538:27:538:29 | obj | tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:538:27:538:29 | obj | tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:538:27:538:29 | obj | tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:538:27:538:29 | obj | tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value | -| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value | -| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value | -| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value | -| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value | -| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value | -| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value | -| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value | -| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value | -| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value | -| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value | | tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value | | tests.js:538:31:538:37 | keys[i] | tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:538:31:538:37 | keys[i] | tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:538:31:538:37 | keys[i] | tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:538:31:538:37 | keys[i] | tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:542:30:542:32 | dst | tests.js:545:33:545:35 | dst | -| tests.js:542:30:542:32 | dst | tests.js:545:33:545:35 | dst | -| tests.js:542:30:542:32 | dst | tests.js:545:33:545:35 | dst | +| tests.js:542:30:542:32 | dst | tests.js:534:36:534:43 | callback [dst] | | tests.js:542:30:542:32 | dst | tests.js:545:33:545:35 | dst | | tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst | -| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst | -| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst | -| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst | -| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst | -| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst | -| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst | -| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst | -| tests.js:542:35:542:37 | src | tests.js:543:26:543:28 | src | -| tests.js:542:35:542:37 | src | tests.js:543:26:543:28 | src | -| tests.js:542:35:542:37 | src | tests.js:543:26:543:28 | src | | tests.js:542:35:542:37 | src | tests.js:543:26:543:28 | src | | tests.js:543:26:543:28 | src | tests.js:534:31:534:33 | obj | -| tests.js:543:26:543:28 | src | tests.js:534:31:534:33 | obj | -| tests.js:543:26:543:28 | src | tests.js:534:31:534:33 | obj | -| tests.js:543:26:543:28 | src | tests.js:534:31:534:33 | obj | -| tests.js:543:26:543:28 | src | tests.js:543:37:543:41 | value | -| tests.js:543:26:543:28 | src | tests.js:543:37:543:41 | value | -| tests.js:543:26:543:28 | src | tests.js:543:37:543:41 | value | -| tests.js:543:26:543:28 | src | tests.js:543:37:543:41 | value | -| tests.js:543:32:543:34 | key | tests.js:545:37:545:39 | key | -| tests.js:543:32:543:34 | key | tests.js:545:37:545:39 | key | -| tests.js:543:32:543:34 | key | tests.js:545:37:545:39 | key | | tests.js:543:32:543:34 | key | tests.js:545:37:545:39 | key | | tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key | -| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key | -| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key | -| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key | -| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key | -| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key | -| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key | -| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key | -| tests.js:543:37:543:41 | value | tests.js:545:43:545:47 | value | -| tests.js:543:37:543:41 | value | tests.js:545:43:545:47 | value | -| tests.js:543:37:543:41 | value | tests.js:545:43:545:47 | value | | tests.js:543:37:543:41 | value | tests.js:545:43:545:47 | value | | tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value | -| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value | -| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value | -| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value | -| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value | -| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value | -| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value | -| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value | -| tests.js:545:33:545:35 | dst | tests.js:545:33:545:40 | dst[key] | -| tests.js:545:33:545:35 | dst | tests.js:545:33:545:40 | dst[key] | -| tests.js:545:33:545:35 | dst | tests.js:545:33:545:40 | dst[key] | | tests.js:545:33:545:35 | dst | tests.js:545:33:545:40 | dst[key] | | tests.js:545:33:545:40 | dst[key] | tests.js:542:30:542:32 | dst | -| tests.js:545:33:545:40 | dst[key] | tests.js:542:30:542:32 | dst | -| tests.js:545:33:545:40 | dst[key] | tests.js:542:30:542:32 | dst | -| tests.js:545:33:545:40 | dst[key] | tests.js:542:30:542:32 | dst | | tests.js:545:37:545:39 | key | tests.js:545:33:545:40 | dst[key] | -| tests.js:545:37:545:39 | key | tests.js:545:33:545:40 | dst[key] | -| tests.js:545:37:545:39 | key | tests.js:545:33:545:40 | dst[key] | -| tests.js:545:37:545:39 | key | tests.js:545:33:545:40 | dst[key] | -| tests.js:545:43:545:47 | value | tests.js:542:35:542:37 | src | -| tests.js:545:43:545:47 | value | tests.js:542:35:542:37 | src | -| tests.js:545:43:545:47 | value | tests.js:542:35:542:37 | src | | tests.js:545:43:545:47 | value | tests.js:542:35:542:37 | src | | tests.js:552:35:552:37 | src | tests.js:557:43:557:45 | src | -| tests.js:552:35:552:37 | src | tests.js:557:43:557:45 | src | -| tests.js:552:35:552:37 | src | tests.js:559:24:559:26 | src | | tests.js:552:35:552:37 | src | tests.js:559:24:559:26 | src | | tests.js:553:14:553:16 | key | tests.js:559:17:559:19 | key | -| tests.js:553:14:553:16 | key | tests.js:559:17:559:19 | key | -| tests.js:553:14:553:16 | key | tests.js:559:17:559:19 | key | -| tests.js:553:14:553:16 | key | tests.js:559:17:559:19 | key | -| tests.js:553:14:553:16 | key | tests.js:559:17:559:19 | key | -| tests.js:553:14:553:16 | key | tests.js:559:17:559:19 | key | -| tests.js:553:14:553:16 | key | tests.js:559:17:559:19 | key | -| tests.js:553:14:553:16 | key | tests.js:559:28:559:30 | key | -| tests.js:553:14:553:16 | key | tests.js:559:28:559:30 | key | -| tests.js:553:14:553:16 | key | tests.js:559:28:559:30 | key | | tests.js:553:14:553:16 | key | tests.js:559:28:559:30 | key | | tests.js:557:43:557:45 | src | tests.js:557:43:557:50 | src[key] | -| tests.js:557:43:557:45 | src | tests.js:557:43:557:50 | src[key] | -| tests.js:557:43:557:50 | src[key] | tests.js:552:35:552:37 | src | -| tests.js:557:43:557:50 | src[key] | tests.js:552:35:552:37 | src | -| tests.js:557:43:557:50 | src[key] | tests.js:552:35:552:37 | src | -| tests.js:557:43:557:50 | src[key] | tests.js:552:35:552:37 | src | -| tests.js:557:43:557:50 | src[key] | tests.js:552:35:552:37 | src | | tests.js:557:43:557:50 | src[key] | tests.js:552:35:552:37 | src | | tests.js:559:24:559:26 | src | tests.js:559:24:559:31 | src[key] | -| tests.js:559:24:559:26 | src | tests.js:559:24:559:31 | src[key] | -| tests.js:559:24:559:26 | src | tests.js:559:24:559:31 | src[key] | -| tests.js:559:24:559:26 | src | tests.js:559:24:559:31 | src[key] | -| tests.js:559:24:559:31 | src[key] | tests.js:559:24:559:31 | src[key] | -| tests.js:559:28:559:30 | key | tests.js:559:24:559:31 | src[key] | -| tests.js:559:28:559:30 | key | tests.js:559:24:559:31 | src[key] | -| tests.js:559:28:559:30 | key | tests.js:559:24:559:31 | src[key] | | tests.js:559:28:559:30 | key | tests.js:559:24:559:31 | src[key] | | tests.js:564:35:564:37 | src | tests.js:569:43:569:45 | src | -| tests.js:564:35:564:37 | src | tests.js:569:43:569:45 | src | -| tests.js:564:35:564:37 | src | tests.js:571:24:571:26 | src | | tests.js:564:35:564:37 | src | tests.js:571:24:571:26 | src | | tests.js:565:14:565:16 | key | tests.js:571:17:571:19 | key | -| tests.js:565:14:565:16 | key | tests.js:571:17:571:19 | key | -| tests.js:565:14:565:16 | key | tests.js:571:17:571:19 | key | -| tests.js:565:14:565:16 | key | tests.js:571:17:571:19 | key | -| tests.js:565:14:565:16 | key | tests.js:571:17:571:19 | key | -| tests.js:565:14:565:16 | key | tests.js:571:17:571:19 | key | -| tests.js:565:14:565:16 | key | tests.js:571:17:571:19 | key | -| tests.js:565:14:565:16 | key | tests.js:571:28:571:30 | key | -| tests.js:565:14:565:16 | key | tests.js:571:28:571:30 | key | -| tests.js:565:14:565:16 | key | tests.js:571:28:571:30 | key | | tests.js:565:14:565:16 | key | tests.js:571:28:571:30 | key | | tests.js:569:43:569:45 | src | tests.js:569:43:569:50 | src[key] | -| tests.js:569:43:569:45 | src | tests.js:569:43:569:50 | src[key] | -| tests.js:569:43:569:50 | src[key] | tests.js:564:35:564:37 | src | -| tests.js:569:43:569:50 | src[key] | tests.js:564:35:564:37 | src | -| tests.js:569:43:569:50 | src[key] | tests.js:564:35:564:37 | src | -| tests.js:569:43:569:50 | src[key] | tests.js:564:35:564:37 | src | -| tests.js:569:43:569:50 | src[key] | tests.js:564:35:564:37 | src | | tests.js:569:43:569:50 | src[key] | tests.js:564:35:564:37 | src | | tests.js:571:24:571:26 | src | tests.js:571:24:571:31 | src[key] | -| tests.js:571:24:571:26 | src | tests.js:571:24:571:31 | src[key] | -| tests.js:571:24:571:26 | src | tests.js:571:24:571:31 | src[key] | -| tests.js:571:24:571:26 | src | tests.js:571:24:571:31 | src[key] | -| tests.js:571:24:571:31 | src[key] | tests.js:571:24:571:31 | src[key] | -| tests.js:571:28:571:30 | key | tests.js:571:24:571:31 | src[key] | -| tests.js:571:28:571:30 | key | tests.js:571:24:571:31 | src[key] | -| tests.js:571:28:571:30 | key | tests.js:571:24:571:31 | src[key] | | tests.js:571:28:571:30 | key | tests.js:571:24:571:31 | src[key] | | tests.js:576:30:576:32 | src | tests.js:580:38:580:40 | src | -| tests.js:576:30:576:32 | src | tests.js:580:38:580:40 | src | -| tests.js:576:30:576:32 | src | tests.js:582:24:582:26 | src | | tests.js:576:30:576:32 | src | tests.js:582:24:582:26 | src | | tests.js:577:14:577:16 | key | tests.js:582:17:582:19 | key | -| tests.js:577:14:577:16 | key | tests.js:582:17:582:19 | key | -| tests.js:577:14:577:16 | key | tests.js:582:17:582:19 | key | -| tests.js:577:14:577:16 | key | tests.js:582:17:582:19 | key | -| tests.js:577:14:577:16 | key | tests.js:582:17:582:19 | key | -| tests.js:577:14:577:16 | key | tests.js:582:17:582:19 | key | -| tests.js:577:14:577:16 | key | tests.js:582:17:582:19 | key | -| tests.js:577:14:577:16 | key | tests.js:582:28:582:30 | key | -| tests.js:577:14:577:16 | key | tests.js:582:28:582:30 | key | -| tests.js:577:14:577:16 | key | tests.js:582:28:582:30 | key | | tests.js:577:14:577:16 | key | tests.js:582:28:582:30 | key | | tests.js:580:38:580:40 | src | tests.js:580:38:580:45 | src[key] | -| tests.js:580:38:580:40 | src | tests.js:580:38:580:45 | src[key] | -| tests.js:580:38:580:45 | src[key] | tests.js:576:30:576:32 | src | -| tests.js:580:38:580:45 | src[key] | tests.js:576:30:576:32 | src | -| tests.js:580:38:580:45 | src[key] | tests.js:576:30:576:32 | src | -| tests.js:580:38:580:45 | src[key] | tests.js:576:30:576:32 | src | -| tests.js:580:38:580:45 | src[key] | tests.js:576:30:576:32 | src | | tests.js:580:38:580:45 | src[key] | tests.js:576:30:576:32 | src | | tests.js:582:24:582:26 | src | tests.js:582:24:582:31 | src[key] | -| tests.js:582:24:582:26 | src | tests.js:582:24:582:31 | src[key] | -| tests.js:582:24:582:26 | src | tests.js:582:24:582:31 | src[key] | -| tests.js:582:24:582:26 | src | tests.js:582:24:582:31 | src[key] | -| tests.js:582:24:582:31 | src[key] | tests.js:582:24:582:31 | src[key] | -| tests.js:582:28:582:30 | key | tests.js:582:24:582:31 | src[key] | -| tests.js:582:28:582:30 | key | tests.js:582:24:582:31 | src[key] | -| tests.js:582:28:582:30 | key | tests.js:582:24:582:31 | src[key] | | tests.js:582:28:582:30 | key | tests.js:582:24:582:31 | src[key] | +| tests.js:591:25:591:27 | obj | tests.js:592:7:592:9 | obj | +| tests.js:591:25:591:27 | obj | tests.js:592:21:592:23 | obj | +| tests.js:592:7:592:9 | obj | tests.js:592:21:592:23 | obj | +| tests.js:592:7:592:9 | obj | tests.js:593:10:593:12 | obj | +| tests.js:592:21:592:23 | obj | tests.js:593:10:593:12 | obj | +| tests.js:600:31:600:34 | dest | tests.js:603:34:603:37 | dest | +| tests.js:600:31:600:34 | dest | tests.js:605:13:605:16 | dest | +| tests.js:600:37:600:42 | source | tests.js:603:45:603:50 | source | +| tests.js:600:37:600:42 | source | tests.js:605:40:605:45 | source | +| tests.js:601:16:601:18 | key | tests.js:603:39:603:41 | key | +| tests.js:601:16:601:18 | key | tests.js:603:52:603:54 | key | +| tests.js:601:16:601:18 | key | tests.js:605:18:605:20 | key | +| tests.js:601:16:601:18 | key | tests.js:605:47:605:49 | key | +| tests.js:603:34:603:37 | dest | tests.js:603:34:603:42 | dest[key] | +| tests.js:603:34:603:42 | dest[key] | tests.js:600:31:600:34 | dest | +| tests.js:603:39:603:41 | key | tests.js:603:34:603:42 | dest[key] | +| tests.js:603:45:603:50 | source | tests.js:603:45:603:55 | source[key] | +| tests.js:603:45:603:55 | source[key] | tests.js:600:37:600:42 | source | +| tests.js:603:52:603:54 | key | tests.js:603:45:603:55 | source[key] | +| tests.js:605:40:605:45 | source | tests.js:605:40:605:50 | source[key] | +| tests.js:605:40:605:50 | source[key] | tests.js:591:25:591:27 | obj | +| tests.js:605:40:605:50 | source[key] | tests.js:605:25:605:51 | capture ... e[key]) | +| tests.js:605:47:605:49 | key | tests.js:605:40:605:50 | source[key] | +subpaths +| tests.js:355:53:355:63 | target[key] | tests.js:348:32:348:37 | target | tests.js:361:12:361:17 | target | tests.js:355:31:355:86 | mergePl ... ptions) | +| tests.js:371:62:371:72 | target[key] | tests.js:364:41:364:46 | target | tests.js:377:12:377:17 | target | tests.js:371:31:371:95 | mergePl ... ptions) | +| tests.js:414:33:414:35 | src | tests.js:408:22:408:24 | obj | tests.js:409:12:409:19 | obj[key] | tests.js:414:21:414:41 | wrapped ... c, key) | +| tests.js:414:38:414:40 | key | tests.js:408:27:408:29 | key | tests.js:409:12:409:19 | obj[key] | tests.js:414:21:414:41 | wrapped ... c, key) | +| tests.js:415:34:415:36 | dst | tests.js:408:22:408:24 | obj | tests.js:409:12:409:19 | obj[key] | tests.js:415:22:415:42 | wrapped ... t, key) | +| tests.js:415:39:415:41 | key | tests.js:408:27:408:29 | key | tests.js:409:12:409:19 | obj[key] | tests.js:415:22:415:42 | wrapped ... t, key) | +| tests.js:431:36:431:38 | src | tests.js:424:25:424:27 | obj | tests.js:426:12:426:19 | obj[key] | tests.js:431:21:431:44 | almostS ... c, key) | +| tests.js:431:41:431:43 | key | tests.js:424:30:424:32 | key | tests.js:426:12:426:19 | obj[key] | tests.js:431:21:431:44 | almostS ... c, key) | +| tests.js:432:37:432:39 | dst | tests.js:424:25:424:27 | obj | tests.js:426:12:426:19 | obj[key] | tests.js:432:22:432:45 | almostS ... t, key) | +| tests.js:432:42:432:44 | key | tests.js:424:30:424:32 | key | tests.js:426:12:426:19 | obj[key] | tests.js:432:22:432:45 | almostS ... t, key) | +| tests.js:448:30:448:32 | src | tests.js:441:19:441:21 | obj | tests.js:443:12:443:19 | obj[key] | tests.js:448:21:448:38 | safeRead(src, key) | +| tests.js:605:40:605:50 | source[key] | tests.js:591:25:591:27 | obj | tests.js:593:10:593:12 | obj | tests.js:605:25:605:51 | capture ... e[key]) | #select | examples/PrototypePollutingFunction.js:7:13:7:15 | dst | examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:13:7:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | examples/PrototypePollutingFunction.js:2:21:2:23 | src | src | examples/PrototypePollutingFunction.js:7:13:7:15 | dst | dst | | path-assignment.js:15:13:15:18 | target | path-assignment.js:8:19:8:25 | keys[i] | path-assignment.js:15:13:15:18 | target | The property chain $@ is recursively assigned to $@ without guarding against prototype pollution. | path-assignment.js:8:19:8:25 | keys[i] | here | path-assignment.js:15:13:15:18 | target | target | @@ -3537,6 +1360,7 @@ edges | tests.js:280:13:280:15 | dst | tests.js:276:34:276:36 | key | tests.js:280:13:280:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:276:21:276:23 | src | src | tests.js:280:13:280:15 | dst | dst | | tests.js:308:17:308:19 | dst | tests.js:302:14:302:16 | key | tests.js:308:17:308:19 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:302:21:302:23 | src | src | tests.js:308:17:308:19 | dst | dst | | tests.js:322:17:322:19 | dst | tests.js:315:14:315:16 | key | tests.js:322:17:322:19 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:315:21:315:23 | src | src | tests.js:322:17:322:19 | dst | dst | +| tests.js:338:17:338:19 | dst | tests.js:329:14:329:16 | key | tests.js:338:17:338:19 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:329:21:329:23 | src | src | tests.js:338:17:338:19 | dst | dst | | tests.js:357:17:357:22 | target | tests.js:350:37:350:39 | key | tests.js:357:17:357:22 | target | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:350:21:350:26 | source | source | tests.js:357:17:357:22 | target | target | | tests.js:403:13:403:15 | dst | tests.js:381:14:381:16 | key | tests.js:403:13:403:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:381:21:381:23 | obj | obj | tests.js:403:13:403:15 | dst | dst | | tests.js:419:13:419:15 | dst | tests.js:413:14:413:16 | key | tests.js:419:13:419:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:413:21:413:23 | src | src | tests.js:419:13:419:15 | dst | dst | @@ -3547,5 +1371,5 @@ edges | tests.js:477:13:477:15 | dst | tests.js:473:25:473:27 | key | tests.js:477:13:477:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:473:12:473:14 | src | src | tests.js:477:13:477:15 | dst | dst | | tests.js:489:13:489:15 | dst | tests.js:484:14:484:16 | key | tests.js:489:13:489:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:484:21:484:23 | src | src | tests.js:489:13:489:15 | dst | dst | | tests.js:517:35:517:37 | dst | tests.js:511:19:511:25 | keys[i] | tests.js:517:35:517:37 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:509:28:509:30 | src | src | tests.js:517:35:517:37 | dst | dst | -| tests.js:529:13:529:15 | dst | tests.js:525:14:525:16 | key | tests.js:529:13:529:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:525:21:525:23 | src | src | tests.js:529:13:529:15 | dst | dst | | tests.js:547:13:547:15 | dst | tests.js:538:18:538:24 | keys[i] | tests.js:547:13:547:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:535:30:535:32 | obj | obj | tests.js:547:13:547:15 | dst | dst | +| tests.js:605:13:605:16 | dest | tests.js:601:16:601:18 | key | tests.js:605:13:605:16 | dest | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:601:35:601:40 | source | source | tests.js:605:13:605:16 | dest | dest | diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/tests.js b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/tests.js index 2efba5e773e..14a0a19fb62 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/tests.js +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/tests.js @@ -513,7 +513,7 @@ function usingDefineProperty(dst, src) { usingDefineProperty(dst[key], src[key]); } else { var descriptor = {}; - descriptor.value = src[key]; + descriptor.value = src[key]; Object.defineProperty(dst, key, descriptor); // NOT OK } } @@ -587,3 +587,22 @@ function indirectHasOwn(dst, src) { function hasOwn(obj, key) { return obj.hasOwnProperty(key) } + +function captureBarrier(obj) { + if (!obj || typeof obj !== 'object') { + return obj; // 'obj' is captured but should not propagate through here + } + const fn = () => obj; + fn(); + return "safe"; +} + +function merge_captureBarrier(dest, source) { + for (const key of Object.keys(source)) { + if (dest[key]) { + merge_captureBarrier(dest[key], source[key]); + } else { + dest[key] = captureBarrier(source[key]); // OK - but currently flagged anyway + } + } +} From a5c221fcfc819a54319784ded9474437b626c3c7 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:42:40 +0200 Subject: [PATCH 059/514] JS: Port PrototypePollutingMergeCall --- .../dataflow/PrototypePollutionQuery.qll | 45 ++++++++- .../CWE-915/PrototypePollutingMergeCall.ql | 8 +- .../PrototypePollutingMergeCall.expected | 99 ++++++++----------- 3 files changed, 88 insertions(+), 64 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionQuery.qll index 165b3ffc07b..3e5b360b21e 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionQuery.qll @@ -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; + +/** + * DEPRECATED. Use the `PrototypePollutionFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "PrototypePollution" } override predicate isSource(DataFlow::Node node, DataFlow::FlowLabel label) { diff --git a/javascript/ql/src/Security/CWE-915/PrototypePollutingMergeCall.ql b/javascript/ql/src/Security/CWE-915/PrototypePollutingMergeCall.ql index 0bc84b82d45..b23d7caa8d8 100644 --- a/javascript/ql/src/Security/CWE-915/PrototypePollutingMergeCall.ql +++ b/javascript/ql/src/Security/CWE-915/PrototypePollutingMergeCall.ql @@ -19,13 +19,11 @@ import javascript import semmle.javascript.security.dataflow.PrototypePollutionQuery -import DataFlow::PathGraph +import DataFlow::DeduplicatePathGraph -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, diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected index a697bd24760..29d49ed71a4 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected @@ -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 | From b8a6f8166925f49c296392c22c31422396937185 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:43:14 +0200 Subject: [PATCH 060/514] JS: Port CleartextLogging --- .../CleartextLoggingCustomizations.qll | 69 +-- .../dataflow/CleartextLoggingQuery.qll | 33 +- .../src/Security/CWE-312/CleartextLogging.ql | 6 +- .../CWE-312/CleartextLogging.expected | 411 ++++++------------ 4 files changed, 215 insertions(+), 304 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLoggingCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLoggingCustomizations.qll index c783a9c3cfc..77e8b5f92bc 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLoggingCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLoggingCustomizations.qll @@ -16,14 +16,20 @@ module CleartextLogging { /** Gets a string that describes the type of this data flow source. */ abstract string describe(); - abstract DataFlow::FlowLabel getLabel(); + /** + * DEPRECATED. Overriding this predicate no longer has any effect. + */ + deprecated DataFlow::FlowLabel getLabel() { result.isTaint() } } /** * A data flow sink for clear-text logging of sensitive information. */ abstract class Sink extends DataFlow::Node { - DataFlow::FlowLabel getLabel() { result.isTaint() } + /** + * DEPRECATED. Overriding this predicate no longer has any effect. + */ + deprecated DataFlow::FlowLabel getLabel() { result.isTaint() } } /** @@ -103,29 +109,28 @@ module CleartextLogging { abstract private class NonCleartextPassword extends DataFlow::Node { } /** - * An object with a property that may contain password information - * - * This is a source since `console.log(obj)` will show the properties of `obj`. + * A value stored in a property that may contain password information */ private class ObjectPasswordPropertySource extends DataFlow::ValueNode, Source { string name; ObjectPasswordPropertySource() { exists(DataFlow::PropWrite write | + write.getPropertyName() = name and name.regexpMatch(maybePassword()) and not name.regexpMatch(notSensitiveRegexp()) and - write = this.(DataFlow::SourceNode).getAPropertyWrite(name) and + this = write.getRhs() and // avoid safe values assigned to presumably unsafe names - not write.getRhs() instanceof NonCleartextPassword + not this instanceof NonCleartextPassword ) } override string describe() { result = "an access to " + name } - - override DataFlow::FlowLabel getLabel() { result.isTaint() } } - /** An access to a variable or property that might contain a password. */ + /** + * An access to a variable or property that might contain a password. + */ private class ReadPasswordSource extends DataFlow::ValueNode, Source { string name; @@ -147,8 +152,6 @@ module CleartextLogging { } override string describe() { result = "an access to " + name } - - override DataFlow::FlowLabel getLabel() { result.isTaint() } } /** A call that might return a password. */ @@ -161,8 +164,6 @@ module CleartextLogging { } override string describe() { result = "a call to " + name } - - override DataFlow::FlowLabel getLabel() { result.isTaint() } } /** An access to the sensitive object `process.env`. */ @@ -170,8 +171,28 @@ module CleartextLogging { ProcessEnvSource() { this = NodeJSLib::process().getAPropertyRead("env") } override string describe() { result = "process environment" } + } - override DataFlow::FlowLabel getLabel() { result.isTaint() } + /** Gets a data flow node referring to `process.env`. */ + private DataFlow::SourceNode processEnv(DataFlow::TypeTracker t) { + t.start() and + result instanceof ProcessEnvSource + or + exists(DataFlow::TypeTracker t2 | result = processEnv(t2).track(t2, t)) + } + + /** Gets a data flow node referring to `process.env`. */ + DataFlow::SourceNode processEnv() { result = processEnv(DataFlow::TypeTracker::end()) } + + /** + * A property access on `process.env`, seen as a barrier. + */ + private class SafeEnvironmentVariableBarrier extends Barrier instanceof DataFlow::PropRead { + SafeEnvironmentVariableBarrier() { + this = processEnv().getAPropertyRead() and + // If the name is known, it should not be sensitive + not nameIndicatesSensitiveData(this.getPropertyName(), _) + } } /** @@ -183,26 +204,10 @@ module CleartextLogging { succ.(DataFlow::PropRead).getBase() = pred } - private class PropReadAsBarrier extends Barrier { - PropReadAsBarrier() { - this = any(DataFlow::PropRead read).getBase() and - // the 'foo' in 'foo.bar()' may have flow, we only want to suppress plain property reads - not this = any(DataFlow::MethodCallNode call).getReceiver() and - // do not block custom taint steps from this node - not isAdditionalTaintStep(this, _) - } - } - /** * Holds if the edge `src` -> `trg` is an additional taint-step for clear-text logging of sensitive information. */ predicate isAdditionalTaintStep(DataFlow::Node src, DataFlow::Node trg) { - // A taint propagating data flow edge through objects: a tainted write taints the entire object. - exists(DataFlow::PropWrite write | - write.getRhs() = src and - trg.(DataFlow::SourceNode).flowsTo(write.getBase()) - ) - or // A property-copy step, // dst[x] = src[x] // dst[x] = JSON.stringify(src[x]) @@ -218,7 +223,7 @@ module CleartextLogging { not exists(read.getPropertyName()) and not isFilteredPropertyName(read.getPropertyNameExpr().flow().getALocalSource()) and src = read.getBase() and - trg = write.getBase().getALocalSource() + trg = write.getBase().getPostUpdateNode() ) or // Taint through the arguments object. diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLoggingQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLoggingQuery.qll index fe0a1073e08..2d222be1214 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLoggingQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLoggingQuery.qll @@ -20,7 +20,38 @@ private import CleartextLoggingCustomizations::CleartextLogging as CleartextLogg * added either by extending the relevant class, or by subclassing this configuration itself, * and amending the sources and sinks. */ -class Configuration extends TaintTracking::Configuration { +module CleartextLoggingConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Barrier } + + predicate isBarrierIn(DataFlow::Node node) { + // We rely on heuristic sources, which tends to cause sources to overlap + isSource(node) + } + + predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg) { + CleartextLogging::isAdditionalTaintStep(src, trg) + } + + predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet contents) { + // Assume all properties of a logged object are themselves logged. + contents = DataFlow::ContentSet::anyProperty() and + isSink(node) + } +} + +/** + * Taint tracking flow for clear-text logging of sensitive information. + */ +module CleartextLoggingFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `CleartextLoggingFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "CleartextLogging" } override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel lbl) { diff --git a/javascript/ql/src/Security/CWE-312/CleartextLogging.ql b/javascript/ql/src/Security/CWE-312/CleartextLogging.ql index 02779fa2e05..dbc791cbaaa 100644 --- a/javascript/ql/src/Security/CWE-312/CleartextLogging.ql +++ b/javascript/ql/src/Security/CWE-312/CleartextLogging.ql @@ -15,7 +15,7 @@ import javascript import semmle.javascript.security.dataflow.CleartextLoggingQuery -import DataFlow::PathGraph +import CleartextLoggingFlow::PathGraph /** * Holds if `tl` is used in a browser environment. @@ -33,9 +33,9 @@ predicate inBrowserEnvironment(TopLevel tl) { ) } -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink +from CleartextLoggingFlow::PathNode source, CleartextLoggingFlow::PathNode sink where - cfg.hasFlowPath(source, sink) and + CleartextLoggingFlow::flowPath(source, sink) and // ignore logging to the browser console (even though it is not a good practice) not inBrowserEnvironment(sink.getNode().asExpr().getTopLevel()) select sink.getNode(), source, sink, "This logs sensitive data returned by $@ as clear text.", diff --git a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index 01df8b2b672..181408ccdaa 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -1,300 +1,175 @@ -nodes -| passwords.js:2:17:2:24 | password | -| passwords.js:2:17:2:24 | password | -| passwords.js:2:17:2:24 | password | -| passwords.js:3:17:3:26 | o.password | -| passwords.js:3:17:3:26 | o.password | -| passwords.js:3:17:3:26 | o.password | -| passwords.js:4:17:4:29 | getPassword() | -| passwords.js:4:17:4:29 | getPassword() | -| passwords.js:4:17:4:29 | getPassword() | -| passwords.js:5:17:5:31 | o.getPassword() | -| passwords.js:5:17:5:31 | o.getPassword() | -| passwords.js:5:17:5:31 | o.getPassword() | -| passwords.js:7:20:7:20 | x | -| passwords.js:8:21:8:21 | x | -| passwords.js:8:21:8:21 | x | -| passwords.js:10:11:10:18 | password | -| passwords.js:10:11:10:18 | password | -| passwords.js:12:18:12:25 | password | -| passwords.js:12:18:12:25 | password | -| passwords.js:12:18:12:25 | password | -| passwords.js:14:17:14:38 | name + ... assword | -| passwords.js:14:17:14:38 | name + ... assword | -| passwords.js:14:31:14:38 | password | -| passwords.js:14:31:14:38 | password | -| passwords.js:16:17:16:38 | `${name ... sword}` | -| passwords.js:16:17:16:38 | `${name ... sword}` | -| passwords.js:16:29:16:36 | password | -| passwords.js:16:29:16:36 | password | -| passwords.js:18:9:20:5 | obj1 | -| passwords.js:18:16:20:5 | {\\n ... x\\n } | -| passwords.js:18:16:20:5 | {\\n ... x\\n } | -| passwords.js:21:17:21:20 | obj1 | -| passwords.js:21:17:21:20 | obj1 | -| passwords.js:23:9:25:5 | obj2 | -| passwords.js:23:16:25:5 | {\\n ... d\\n } | -| passwords.js:24:12:24:19 | password | -| passwords.js:24:12:24:19 | password | -| passwords.js:26:17:26:20 | obj2 | -| passwords.js:26:17:26:20 | obj2 | -| passwords.js:28:9:28:17 | obj3 | -| passwords.js:28:16:28:17 | {} | -| passwords.js:29:17:29:20 | obj3 | -| passwords.js:29:17:29:20 | obj3 | -| passwords.js:30:14:30:21 | password | -| passwords.js:30:14:30:21 | password | -| passwords.js:77:37:77:53 | req.body.password | -| passwords.js:77:37:77:53 | req.body.password | -| passwords.js:78:17:78:38 | temp.en ... assword | -| passwords.js:78:17:78:38 | temp.en ... assword | -| passwords.js:80:9:80:25 | secret | -| passwords.js:80:18:80:25 | password | -| passwords.js:80:18:80:25 | password | -| passwords.js:81:17:81:31 | `pw: ${secret}` | -| passwords.js:81:17:81:31 | `pw: ${secret}` | -| passwords.js:81:24:81:29 | secret | -| passwords.js:93:21:93:46 | "Passwo ... assword | -| passwords.js:93:21:93:46 | "Passwo ... assword | -| passwords.js:93:39:93:46 | password | -| passwords.js:93:39:93:46 | password | -| passwords.js:98:21:98:46 | "Passwo ... assword | -| passwords.js:98:21:98:46 | "Passwo ... assword | -| passwords.js:98:39:98:46 | password | -| passwords.js:98:39:98:46 | password | -| passwords.js:105:21:105:46 | "Passwo ... assword | -| passwords.js:105:21:105:46 | "Passwo ... assword | -| passwords.js:105:39:105:46 | password | -| passwords.js:105:39:105:46 | password | -| passwords.js:110:21:110:46 | "Passwo ... assword | -| passwords.js:110:21:110:46 | "Passwo ... assword | -| passwords.js:110:39:110:46 | password | -| passwords.js:110:39:110:46 | password | -| passwords.js:114:25:114:50 | "Passwo ... assword | -| passwords.js:114:25:114:50 | "Passwo ... assword | -| passwords.js:114:43:114:50 | password | -| passwords.js:114:43:114:50 | password | -| passwords.js:119:21:119:46 | "Passwo ... assword | -| passwords.js:119:21:119:46 | "Passwo ... assword | -| passwords.js:119:39:119:46 | password | -| passwords.js:119:39:119:46 | password | -| passwords.js:122:17:122:49 | name + ... tring() | -| passwords.js:122:17:122:49 | name + ... tring() | -| passwords.js:122:31:122:38 | password | -| passwords.js:122:31:122:38 | password | -| passwords.js:122:31:122:49 | password.toString() | -| passwords.js:123:17:123:48 | name + ... lueOf() | -| passwords.js:123:17:123:48 | name + ... lueOf() | -| passwords.js:123:31:123:38 | password | -| passwords.js:123:31:123:38 | password | -| passwords.js:123:31:123:48 | password.valueOf() | -| passwords.js:127:9:132:5 | config | -| passwords.js:127:18:132:5 | {\\n ... )\\n } | -| passwords.js:127:18:132:5 | {\\n ... )\\n } | -| passwords.js:130:12:130:19 | password | -| passwords.js:130:12:130:19 | password | -| passwords.js:131:12:131:24 | getPassword() | -| passwords.js:131:12:131:24 | getPassword() | -| passwords.js:135:17:135:22 | config | -| passwords.js:135:17:135:22 | config | -| passwords.js:136:17:136:24 | config.x | -| passwords.js:136:17:136:24 | config.x | -| passwords.js:137:17:137:24 | config.y | -| passwords.js:137:17:137:24 | config.y | -| passwords.js:142:26:142:34 | arguments | -| passwords.js:142:26:142:34 | arguments | -| passwords.js:147:12:147:19 | password | -| passwords.js:147:12:147:19 | password | -| passwords.js:149:21:149:28 | config.x | -| passwords.js:150:21:150:31 | process.env | -| passwords.js:150:21:150:31 | process.env | -| passwords.js:152:9:152:63 | procdesc | -| passwords.js:152:20:152:44 | Util.in ... ss.env) | -| passwords.js:152:20:152:63 | Util.in ... /g, '') | -| passwords.js:152:33:152:43 | process.env | -| passwords.js:152:33:152:43 | process.env | -| passwords.js:154:21:154:28 | procdesc | -| passwords.js:156:17:156:27 | process.env | -| passwords.js:156:17:156:27 | process.env | -| passwords.js:156:17:156:27 | process.env | -| passwords.js:163:14:163:21 | password | -| passwords.js:163:14:163:21 | password | -| passwords.js:163:14:163:41 | passwor ... g, "*") | -| passwords.js:163:14:163:41 | passwor ... g, "*") | -| passwords.js:164:14:164:21 | password | -| passwords.js:164:14:164:21 | password | -| passwords.js:164:14:164:42 | passwor ... g, "*") | -| passwords.js:164:14:164:42 | passwor ... g, "*") | -| passwords.js:169:17:169:24 | password | -| passwords.js:169:17:169:24 | password | -| passwords.js:169:17:169:45 | passwor ... g, "*") | -| passwords.js:169:17:169:45 | passwor ... g, "*") | -| passwords.js:170:11:170:18 | password | -| passwords.js:170:11:170:18 | password | -| passwords.js:170:11:170:39 | passwor ... g, "*") | -| passwords.js:170:11:170:39 | passwor ... g, "*") | -| passwords.js:173:17:173:26 | myPassword | -| passwords.js:173:17:173:26 | myPassword | -| passwords.js:173:17:173:26 | myPassword | -| passwords.js:176:17:176:26 | myPasscode | -| passwords.js:176:17:176:26 | myPasscode | -| passwords.js:176:17:176:26 | myPasscode | -| passwords_in_browser1.js:2:13:2:20 | password | -| passwords_in_browser1.js:2:13:2:20 | password | -| passwords_in_browser1.js:2:13:2:20 | password | -| passwords_in_browser2.js:2:13:2:20 | password | -| passwords_in_browser2.js:2:13:2:20 | password | -| passwords_in_browser2.js:2:13:2:20 | password | -| passwords_in_server_1.js:6:13:6:20 | password | -| passwords_in_server_1.js:6:13:6:20 | password | -| passwords_in_server_1.js:6:13:6:20 | password | -| passwords_in_server_2.js:3:13:3:20 | password | -| passwords_in_server_2.js:3:13:3:20 | password | -| passwords_in_server_2.js:3:13:3:20 | password | -| passwords_in_server_3.js:2:13:2:20 | password | -| passwords_in_server_3.js:2:13:2:20 | password | -| passwords_in_server_3.js:2:13:2:20 | password | -| passwords_in_server_4.js:2:13:2:20 | password | -| passwords_in_server_4.js:2:13:2:20 | password | -| passwords_in_server_4.js:2:13:2:20 | password | -| passwords_in_server_5.js:4:7:4:24 | req.query.password | -| passwords_in_server_5.js:4:7:4:24 | req.query.password | -| passwords_in_server_5.js:7:12:7:12 | x | -| passwords_in_server_5.js:8:17:8:17 | x | -| passwords_in_server_5.js:8:17:8:17 | x | edges -| passwords.js:2:17:2:24 | password | passwords.js:2:17:2:24 | password | -| passwords.js:3:17:3:26 | o.password | passwords.js:3:17:3:26 | o.password | -| passwords.js:4:17:4:29 | getPassword() | passwords.js:4:17:4:29 | getPassword() | -| passwords.js:5:17:5:31 | o.getPassword() | passwords.js:5:17:5:31 | o.getPassword() | -| passwords.js:7:20:7:20 | x | passwords.js:8:21:8:21 | x | | passwords.js:7:20:7:20 | x | passwords.js:8:21:8:21 | x | | passwords.js:10:11:10:18 | password | passwords.js:7:20:7:20 | x | -| passwords.js:10:11:10:18 | password | passwords.js:7:20:7:20 | x | -| passwords.js:12:18:12:25 | password | passwords.js:12:18:12:25 | password | -| passwords.js:14:31:14:38 | password | passwords.js:14:17:14:38 | name + ... assword | -| passwords.js:14:31:14:38 | password | passwords.js:14:17:14:38 | name + ... assword | -| passwords.js:14:31:14:38 | password | passwords.js:14:17:14:38 | name + ... assword | | passwords.js:14:31:14:38 | password | passwords.js:14:17:14:38 | name + ... assword | | passwords.js:16:29:16:36 | password | passwords.js:16:17:16:38 | `${name ... sword}` | -| passwords.js:16:29:16:36 | password | passwords.js:16:17:16:38 | `${name ... sword}` | -| passwords.js:16:29:16:36 | password | passwords.js:16:17:16:38 | `${name ... sword}` | -| passwords.js:16:29:16:36 | password | passwords.js:16:17:16:38 | `${name ... sword}` | -| passwords.js:18:9:20:5 | obj1 | passwords.js:21:17:21:20 | obj1 | -| passwords.js:18:9:20:5 | obj1 | passwords.js:21:17:21:20 | obj1 | -| passwords.js:18:16:20:5 | {\\n ... x\\n } | passwords.js:18:9:20:5 | obj1 | -| passwords.js:18:16:20:5 | {\\n ... x\\n } | passwords.js:18:9:20:5 | obj1 | -| passwords.js:23:9:25:5 | obj2 | passwords.js:26:17:26:20 | obj2 | -| passwords.js:23:9:25:5 | obj2 | passwords.js:26:17:26:20 | obj2 | -| passwords.js:23:16:25:5 | {\\n ... d\\n } | passwords.js:23:9:25:5 | obj2 | -| passwords.js:24:12:24:19 | password | passwords.js:23:16:25:5 | {\\n ... d\\n } | -| passwords.js:24:12:24:19 | password | passwords.js:23:16:25:5 | {\\n ... d\\n } | -| passwords.js:28:9:28:17 | obj3 | passwords.js:29:17:29:20 | obj3 | -| passwords.js:28:9:28:17 | obj3 | passwords.js:29:17:29:20 | obj3 | -| passwords.js:28:16:28:17 | {} | passwords.js:28:9:28:17 | obj3 | -| passwords.js:30:14:30:21 | password | passwords.js:28:16:28:17 | {} | -| passwords.js:30:14:30:21 | password | passwords.js:28:16:28:17 | {} | -| passwords.js:77:37:77:53 | req.body.password | passwords.js:78:17:78:38 | temp.en ... assword | -| passwords.js:77:37:77:53 | req.body.password | passwords.js:78:17:78:38 | temp.en ... assword | -| passwords.js:77:37:77:53 | req.body.password | passwords.js:78:17:78:38 | temp.en ... assword | -| passwords.js:77:37:77:53 | req.body.password | passwords.js:78:17:78:38 | temp.en ... assword | +| passwords.js:18:9:20:5 | obj1 [password] | passwords.js:21:17:21:20 | obj1 [password] | +| passwords.js:18:16:20:5 | {\\n ... x\\n } [password] | passwords.js:18:9:20:5 | obj1 [password] | +| passwords.js:19:19:19:19 | x | passwords.js:18:16:20:5 | {\\n ... x\\n } [password] | +| passwords.js:21:17:21:20 | obj1 [password] | passwords.js:21:17:21:20 | obj1 | +| passwords.js:23:9:25:5 | obj2 [x] | passwords.js:26:17:26:20 | obj2 [x] | +| passwords.js:23:16:25:5 | {\\n ... d\\n } [x] | passwords.js:23:9:25:5 | obj2 [x] | +| passwords.js:24:12:24:19 | password | passwords.js:23:16:25:5 | {\\n ... d\\n } [x] | +| passwords.js:26:17:26:20 | obj2 [x] | passwords.js:26:17:26:20 | obj2 | +| passwords.js:28:9:28:17 | obj3 [x] | passwords.js:29:17:29:20 | obj3 [x] | +| passwords.js:29:17:29:20 | obj3 [x] | passwords.js:29:17:29:20 | obj3 | +| passwords.js:30:5:30:8 | [post update] obj3 [x] | passwords.js:28:9:28:17 | obj3 [x] | +| passwords.js:30:14:30:21 | password | passwords.js:30:5:30:8 | [post update] obj3 [x] | +| passwords.js:77:9:77:55 | temp [encryptedPassword] | passwords.js:78:17:78:20 | temp [encryptedPassword] | +| passwords.js:77:16:77:55 | { encry ... sword } [encryptedPassword] | passwords.js:77:9:77:55 | temp [encryptedPassword] | +| passwords.js:77:37:77:53 | req.body.password | passwords.js:77:16:77:55 | { encry ... sword } [encryptedPassword] | +| passwords.js:78:17:78:20 | temp [encryptedPassword] | passwords.js:78:17:78:38 | temp.en ... assword | | passwords.js:80:9:80:25 | secret | passwords.js:81:24:81:29 | secret | | passwords.js:80:18:80:25 | password | passwords.js:80:9:80:25 | secret | -| passwords.js:80:18:80:25 | password | passwords.js:80:9:80:25 | secret | -| passwords.js:81:24:81:29 | secret | passwords.js:81:17:81:31 | `pw: ${secret}` | | passwords.js:81:24:81:29 | secret | passwords.js:81:17:81:31 | `pw: ${secret}` | | passwords.js:93:39:93:46 | password | passwords.js:93:21:93:46 | "Passwo ... assword | -| passwords.js:93:39:93:46 | password | passwords.js:93:21:93:46 | "Passwo ... assword | -| passwords.js:93:39:93:46 | password | passwords.js:93:21:93:46 | "Passwo ... assword | -| passwords.js:93:39:93:46 | password | passwords.js:93:21:93:46 | "Passwo ... assword | -| passwords.js:98:39:98:46 | password | passwords.js:98:21:98:46 | "Passwo ... assword | -| passwords.js:98:39:98:46 | password | passwords.js:98:21:98:46 | "Passwo ... assword | -| passwords.js:98:39:98:46 | password | passwords.js:98:21:98:46 | "Passwo ... assword | | passwords.js:98:39:98:46 | password | passwords.js:98:21:98:46 | "Passwo ... assword | | passwords.js:105:39:105:46 | password | passwords.js:105:21:105:46 | "Passwo ... assword | -| passwords.js:105:39:105:46 | password | passwords.js:105:21:105:46 | "Passwo ... assword | -| passwords.js:105:39:105:46 | password | passwords.js:105:21:105:46 | "Passwo ... assword | -| passwords.js:105:39:105:46 | password | passwords.js:105:21:105:46 | "Passwo ... assword | -| passwords.js:110:39:110:46 | password | passwords.js:110:21:110:46 | "Passwo ... assword | -| passwords.js:110:39:110:46 | password | passwords.js:110:21:110:46 | "Passwo ... assword | -| passwords.js:110:39:110:46 | password | passwords.js:110:21:110:46 | "Passwo ... assword | | passwords.js:110:39:110:46 | password | passwords.js:110:21:110:46 | "Passwo ... assword | | passwords.js:114:43:114:50 | password | passwords.js:114:25:114:50 | "Passwo ... assword | -| passwords.js:114:43:114:50 | password | passwords.js:114:25:114:50 | "Passwo ... assword | -| passwords.js:114:43:114:50 | password | passwords.js:114:25:114:50 | "Passwo ... assword | -| passwords.js:114:43:114:50 | password | passwords.js:114:25:114:50 | "Passwo ... assword | -| passwords.js:119:39:119:46 | password | passwords.js:119:21:119:46 | "Passwo ... assword | -| passwords.js:119:39:119:46 | password | passwords.js:119:21:119:46 | "Passwo ... assword | -| passwords.js:119:39:119:46 | password | passwords.js:119:21:119:46 | "Passwo ... assword | | passwords.js:119:39:119:46 | password | passwords.js:119:21:119:46 | "Passwo ... assword | | passwords.js:122:31:122:38 | password | passwords.js:122:31:122:49 | password.toString() | -| passwords.js:122:31:122:38 | password | passwords.js:122:31:122:49 | password.toString() | -| passwords.js:122:31:122:49 | password.toString() | passwords.js:122:17:122:49 | name + ... tring() | | passwords.js:122:31:122:49 | password.toString() | passwords.js:122:17:122:49 | name + ... tring() | | passwords.js:123:31:123:38 | password | passwords.js:123:31:123:48 | password.valueOf() | -| passwords.js:123:31:123:38 | password | passwords.js:123:31:123:48 | password.valueOf() | | passwords.js:123:31:123:48 | password.valueOf() | passwords.js:123:17:123:48 | name + ... lueOf() | -| passwords.js:123:31:123:48 | password.valueOf() | passwords.js:123:17:123:48 | name + ... lueOf() | -| passwords.js:127:9:132:5 | config | passwords.js:135:17:135:22 | config | -| passwords.js:127:9:132:5 | config | passwords.js:135:17:135:22 | config | -| passwords.js:127:18:132:5 | {\\n ... )\\n } | passwords.js:127:9:132:5 | config | -| passwords.js:127:18:132:5 | {\\n ... )\\n } | passwords.js:127:9:132:5 | config | -| passwords.js:130:12:130:19 | password | passwords.js:127:18:132:5 | {\\n ... )\\n } | -| passwords.js:130:12:130:19 | password | passwords.js:127:18:132:5 | {\\n ... )\\n } | -| passwords.js:130:12:130:19 | password | passwords.js:136:17:136:24 | config.x | -| passwords.js:130:12:130:19 | password | passwords.js:136:17:136:24 | config.x | -| passwords.js:130:12:130:19 | password | passwords.js:136:17:136:24 | config.x | -| passwords.js:130:12:130:19 | password | passwords.js:136:17:136:24 | config.x | -| passwords.js:131:12:131:24 | getPassword() | passwords.js:127:18:132:5 | {\\n ... )\\n } | -| passwords.js:131:12:131:24 | getPassword() | passwords.js:127:18:132:5 | {\\n ... )\\n } | -| passwords.js:131:12:131:24 | getPassword() | passwords.js:137:17:137:24 | config.y | -| passwords.js:131:12:131:24 | getPassword() | passwords.js:137:17:137:24 | config.y | -| passwords.js:131:12:131:24 | getPassword() | passwords.js:137:17:137:24 | config.y | -| passwords.js:131:12:131:24 | getPassword() | passwords.js:137:17:137:24 | config.y | -| passwords.js:147:12:147:19 | password | passwords.js:149:21:149:28 | config.x | -| passwords.js:147:12:147:19 | password | passwords.js:149:21:149:28 | config.x | +| passwords.js:127:9:132:5 | config [password] | passwords.js:135:17:135:22 | config [password] | +| passwords.js:127:9:132:5 | config [x] | passwords.js:135:17:135:22 | config [x] | +| passwords.js:127:9:132:5 | config [x] | passwords.js:136:17:136:22 | config [x] | +| passwords.js:127:9:132:5 | config [y] | passwords.js:135:17:135:22 | config [y] | +| passwords.js:127:9:132:5 | config [y] | passwords.js:137:17:137:22 | config [y] | +| passwords.js:127:18:132:5 | {\\n ... )\\n } [password] | passwords.js:127:9:132:5 | config [password] | +| passwords.js:127:18:132:5 | {\\n ... )\\n } [x] | passwords.js:127:9:132:5 | config [x] | +| passwords.js:127:18:132:5 | {\\n ... )\\n } [y] | passwords.js:127:9:132:5 | config [y] | +| passwords.js:128:19:128:19 | x | passwords.js:127:18:132:5 | {\\n ... )\\n } [password] | +| passwords.js:130:12:130:19 | password | passwords.js:127:18:132:5 | {\\n ... )\\n } [x] | +| passwords.js:131:12:131:24 | getPassword() | passwords.js:127:18:132:5 | {\\n ... )\\n } [y] | +| passwords.js:135:17:135:22 | config [password] | passwords.js:135:17:135:22 | config | +| passwords.js:135:17:135:22 | config [x] | passwords.js:135:17:135:22 | config | +| passwords.js:135:17:135:22 | config [y] | passwords.js:135:17:135:22 | config | +| passwords.js:136:17:136:22 | config [x] | passwords.js:136:17:136:24 | config.x | +| passwords.js:137:17:137:22 | config [y] | passwords.js:137:17:137:24 | config.y | +| passwords.js:146:9:148:5 | config [x] | passwords.js:149:21:149:26 | config [x] | +| passwords.js:146:18:148:5 | {\\n ... d\\n } [x] | passwords.js:146:9:148:5 | config [x] | +| passwords.js:147:12:147:19 | password | passwords.js:146:18:148:5 | {\\n ... d\\n } [x] | +| passwords.js:149:21:149:26 | config [x] | passwords.js:149:21:149:28 | config.x | | passwords.js:149:21:149:28 | config.x | passwords.js:142:26:142:34 | arguments | -| passwords.js:149:21:149:28 | config.x | passwords.js:142:26:142:34 | arguments | -| passwords.js:150:21:150:31 | process.env | passwords.js:142:26:142:34 | arguments | -| passwords.js:150:21:150:31 | process.env | passwords.js:142:26:142:34 | arguments | -| passwords.js:150:21:150:31 | process.env | passwords.js:142:26:142:34 | arguments | | passwords.js:150:21:150:31 | process.env | passwords.js:142:26:142:34 | arguments | | passwords.js:152:9:152:63 | procdesc | passwords.js:154:21:154:28 | procdesc | | passwords.js:152:20:152:44 | Util.in ... ss.env) | passwords.js:152:20:152:63 | Util.in ... /g, '') | | passwords.js:152:20:152:63 | Util.in ... /g, '') | passwords.js:152:9:152:63 | procdesc | | passwords.js:152:33:152:43 | process.env | passwords.js:152:20:152:44 | Util.in ... ss.env) | -| passwords.js:152:33:152:43 | process.env | passwords.js:152:20:152:44 | Util.in ... ss.env) | | passwords.js:154:21:154:28 | procdesc | passwords.js:142:26:142:34 | arguments | -| passwords.js:154:21:154:28 | procdesc | passwords.js:142:26:142:34 | arguments | -| passwords.js:156:17:156:27 | process.env | passwords.js:156:17:156:27 | process.env | -| passwords.js:163:14:163:21 | password | passwords.js:163:14:163:41 | passwor ... g, "*") | -| passwords.js:163:14:163:21 | password | passwords.js:163:14:163:41 | passwor ... g, "*") | -| passwords.js:163:14:163:21 | password | passwords.js:163:14:163:41 | passwor ... g, "*") | | passwords.js:163:14:163:21 | password | passwords.js:163:14:163:41 | passwor ... g, "*") | | passwords.js:164:14:164:21 | password | passwords.js:164:14:164:42 | passwor ... g, "*") | -| passwords.js:164:14:164:21 | password | passwords.js:164:14:164:42 | passwor ... g, "*") | -| passwords.js:164:14:164:21 | password | passwords.js:164:14:164:42 | passwor ... g, "*") | -| passwords.js:164:14:164:21 | password | passwords.js:164:14:164:42 | passwor ... g, "*") | -| passwords.js:169:17:169:24 | password | passwords.js:169:17:169:45 | passwor ... g, "*") | -| passwords.js:169:17:169:24 | password | passwords.js:169:17:169:45 | passwor ... g, "*") | -| passwords.js:169:17:169:24 | password | passwords.js:169:17:169:45 | passwor ... g, "*") | | passwords.js:169:17:169:24 | password | passwords.js:169:17:169:45 | passwor ... g, "*") | | passwords.js:170:11:170:18 | password | passwords.js:170:11:170:39 | passwor ... g, "*") | -| passwords.js:170:11:170:18 | password | passwords.js:170:11:170:39 | passwor ... g, "*") | -| passwords.js:170:11:170:18 | password | passwords.js:170:11:170:39 | passwor ... g, "*") | -| passwords.js:170:11:170:18 | password | passwords.js:170:11:170:39 | passwor ... g, "*") | -| passwords.js:173:17:173:26 | myPassword | passwords.js:173:17:173:26 | myPassword | -| passwords.js:176:17:176:26 | myPasscode | passwords.js:176:17:176:26 | myPasscode | -| passwords_in_browser1.js:2:13:2:20 | password | passwords_in_browser1.js:2:13:2:20 | password | -| passwords_in_browser2.js:2:13:2:20 | password | passwords_in_browser2.js:2:13:2:20 | password | -| passwords_in_server_1.js:6:13:6:20 | password | passwords_in_server_1.js:6:13:6:20 | password | -| passwords_in_server_2.js:3:13:3:20 | password | passwords_in_server_2.js:3:13:3:20 | password | -| passwords_in_server_3.js:2:13:2:20 | password | passwords_in_server_3.js:2:13:2:20 | password | -| passwords_in_server_4.js:2:13:2:20 | password | passwords_in_server_4.js:2:13:2:20 | password | -| passwords_in_server_5.js:4:7:4:24 | req.query.password | passwords_in_server_5.js:7:12:7:12 | x | | passwords_in_server_5.js:4:7:4:24 | req.query.password | passwords_in_server_5.js:7:12:7:12 | x | | passwords_in_server_5.js:7:12:7:12 | x | passwords_in_server_5.js:8:17:8:17 | x | -| passwords_in_server_5.js:7:12:7:12 | x | passwords_in_server_5.js:8:17:8:17 | x | +nodes +| passwords.js:2:17:2:24 | password | semmle.label | password | +| passwords.js:3:17:3:26 | o.password | semmle.label | o.password | +| passwords.js:4:17:4:29 | getPassword() | semmle.label | getPassword() | +| passwords.js:5:17:5:31 | o.getPassword() | semmle.label | o.getPassword() | +| passwords.js:7:20:7:20 | x | semmle.label | x | +| passwords.js:8:21:8:21 | x | semmle.label | x | +| passwords.js:10:11:10:18 | password | semmle.label | password | +| passwords.js:12:18:12:25 | password | semmle.label | password | +| passwords.js:14:17:14:38 | name + ... assword | semmle.label | name + ... assword | +| passwords.js:14:31:14:38 | password | semmle.label | password | +| passwords.js:16:17:16:38 | `${name ... sword}` | semmle.label | `${name ... sword}` | +| passwords.js:16:29:16:36 | password | semmle.label | password | +| passwords.js:18:9:20:5 | obj1 [password] | semmle.label | obj1 [password] | +| passwords.js:18:16:20:5 | {\\n ... x\\n } [password] | semmle.label | {\\n ... x\\n } [password] | +| passwords.js:19:19:19:19 | x | semmle.label | x | +| passwords.js:21:17:21:20 | obj1 | semmle.label | obj1 | +| passwords.js:21:17:21:20 | obj1 [password] | semmle.label | obj1 [password] | +| passwords.js:23:9:25:5 | obj2 [x] | semmle.label | obj2 [x] | +| passwords.js:23:16:25:5 | {\\n ... d\\n } [x] | semmle.label | {\\n ... d\\n } [x] | +| passwords.js:24:12:24:19 | password | semmle.label | password | +| passwords.js:26:17:26:20 | obj2 | semmle.label | obj2 | +| passwords.js:26:17:26:20 | obj2 [x] | semmle.label | obj2 [x] | +| passwords.js:28:9:28:17 | obj3 [x] | semmle.label | obj3 [x] | +| passwords.js:29:17:29:20 | obj3 | semmle.label | obj3 | +| passwords.js:29:17:29:20 | obj3 [x] | semmle.label | obj3 [x] | +| passwords.js:30:5:30:8 | [post update] obj3 [x] | semmle.label | [post update] obj3 [x] | +| passwords.js:30:14:30:21 | password | semmle.label | password | +| passwords.js:77:9:77:55 | temp [encryptedPassword] | semmle.label | temp [encryptedPassword] | +| passwords.js:77:16:77:55 | { encry ... sword } [encryptedPassword] | semmle.label | { encry ... sword } [encryptedPassword] | +| passwords.js:77:37:77:53 | req.body.password | semmle.label | req.body.password | +| passwords.js:78:17:78:20 | temp [encryptedPassword] | semmle.label | temp [encryptedPassword] | +| passwords.js:78:17:78:38 | temp.en ... assword | semmle.label | temp.en ... assword | +| passwords.js:80:9:80:25 | secret | semmle.label | secret | +| passwords.js:80:18:80:25 | password | semmle.label | password | +| passwords.js:81:17:81:31 | `pw: ${secret}` | semmle.label | `pw: ${secret}` | +| passwords.js:81:24:81:29 | secret | semmle.label | secret | +| passwords.js:93:21:93:46 | "Passwo ... assword | semmle.label | "Passwo ... assword | +| passwords.js:93:39:93:46 | password | semmle.label | password | +| passwords.js:98:21:98:46 | "Passwo ... assword | semmle.label | "Passwo ... assword | +| passwords.js:98:39:98:46 | password | semmle.label | password | +| passwords.js:105:21:105:46 | "Passwo ... assword | semmle.label | "Passwo ... assword | +| passwords.js:105:39:105:46 | password | semmle.label | password | +| passwords.js:110:21:110:46 | "Passwo ... assword | semmle.label | "Passwo ... assword | +| passwords.js:110:39:110:46 | password | semmle.label | password | +| passwords.js:114:25:114:50 | "Passwo ... assword | semmle.label | "Passwo ... assword | +| passwords.js:114:43:114:50 | password | semmle.label | password | +| passwords.js:119:21:119:46 | "Passwo ... assword | semmle.label | "Passwo ... assword | +| passwords.js:119:39:119:46 | password | semmle.label | password | +| passwords.js:122:17:122:49 | name + ... tring() | semmle.label | name + ... tring() | +| passwords.js:122:31:122:38 | password | semmle.label | password | +| passwords.js:122:31:122:49 | password.toString() | semmle.label | password.toString() | +| passwords.js:123:17:123:48 | name + ... lueOf() | semmle.label | name + ... lueOf() | +| passwords.js:123:31:123:38 | password | semmle.label | password | +| passwords.js:123:31:123:48 | password.valueOf() | semmle.label | password.valueOf() | +| passwords.js:127:9:132:5 | config [password] | semmle.label | config [password] | +| passwords.js:127:9:132:5 | config [x] | semmle.label | config [x] | +| passwords.js:127:9:132:5 | config [y] | semmle.label | config [y] | +| passwords.js:127:18:132:5 | {\\n ... )\\n } [password] | semmle.label | {\\n ... )\\n } [password] | +| passwords.js:127:18:132:5 | {\\n ... )\\n } [x] | semmle.label | {\\n ... )\\n } [x] | +| passwords.js:127:18:132:5 | {\\n ... )\\n } [y] | semmle.label | {\\n ... )\\n } [y] | +| passwords.js:128:19:128:19 | x | semmle.label | x | +| passwords.js:130:12:130:19 | password | semmle.label | password | +| passwords.js:131:12:131:24 | getPassword() | semmle.label | getPassword() | +| passwords.js:135:17:135:22 | config | semmle.label | config | +| passwords.js:135:17:135:22 | config [password] | semmle.label | config [password] | +| passwords.js:135:17:135:22 | config [x] | semmle.label | config [x] | +| passwords.js:135:17:135:22 | config [y] | semmle.label | config [y] | +| passwords.js:136:17:136:22 | config [x] | semmle.label | config [x] | +| passwords.js:136:17:136:24 | config.x | semmle.label | config.x | +| passwords.js:137:17:137:22 | config [y] | semmle.label | config [y] | +| passwords.js:137:17:137:24 | config.y | semmle.label | config.y | +| passwords.js:142:26:142:34 | arguments | semmle.label | arguments | +| passwords.js:146:9:148:5 | config [x] | semmle.label | config [x] | +| passwords.js:146:18:148:5 | {\\n ... d\\n } [x] | semmle.label | {\\n ... d\\n } [x] | +| passwords.js:147:12:147:19 | password | semmle.label | password | +| passwords.js:149:21:149:26 | config [x] | semmle.label | config [x] | +| passwords.js:149:21:149:28 | config.x | semmle.label | config.x | +| passwords.js:150:21:150:31 | process.env | semmle.label | process.env | +| passwords.js:152:9:152:63 | procdesc | semmle.label | procdesc | +| passwords.js:152:20:152:44 | Util.in ... ss.env) | semmle.label | Util.in ... ss.env) | +| passwords.js:152:20:152:63 | Util.in ... /g, '') | semmle.label | Util.in ... /g, '') | +| passwords.js:152:33:152:43 | process.env | semmle.label | process.env | +| passwords.js:154:21:154:28 | procdesc | semmle.label | procdesc | +| passwords.js:156:17:156:27 | process.env | semmle.label | process.env | +| passwords.js:163:14:163:21 | password | semmle.label | password | +| passwords.js:163:14:163:41 | passwor ... g, "*") | semmle.label | passwor ... g, "*") | +| passwords.js:164:14:164:21 | password | semmle.label | password | +| passwords.js:164:14:164:42 | passwor ... g, "*") | semmle.label | passwor ... g, "*") | +| passwords.js:169:17:169:24 | password | semmle.label | password | +| passwords.js:169:17:169:45 | passwor ... g, "*") | semmle.label | passwor ... g, "*") | +| passwords.js:170:11:170:18 | password | semmle.label | password | +| passwords.js:170:11:170:39 | passwor ... g, "*") | semmle.label | passwor ... g, "*") | +| passwords.js:173:17:173:26 | myPassword | semmle.label | myPassword | +| passwords.js:176:17:176:26 | myPasscode | semmle.label | myPasscode | +| passwords_in_browser1.js:2:13:2:20 | password | semmle.label | password | +| passwords_in_browser2.js:2:13:2:20 | password | semmle.label | password | +| passwords_in_server_1.js:6:13:6:20 | password | semmle.label | password | +| passwords_in_server_2.js:3:13:3:20 | password | semmle.label | password | +| passwords_in_server_3.js:2:13:2:20 | password | semmle.label | password | +| passwords_in_server_4.js:2:13:2:20 | password | semmle.label | password | +| passwords_in_server_5.js:4:7:4:24 | req.query.password | semmle.label | req.query.password | +| passwords_in_server_5.js:7:12:7:12 | x | semmle.label | x | +| passwords_in_server_5.js:8:17:8:17 | x | semmle.label | x | +subpaths #select | passwords.js:2:17:2:24 | password | passwords.js:2:17:2:24 | password | passwords.js:2:17:2:24 | password | This logs sensitive data returned by $@ as clear text. | passwords.js:2:17:2:24 | password | an access to password | | passwords.js:3:17:3:26 | o.password | passwords.js:3:17:3:26 | o.password | passwords.js:3:17:3:26 | o.password | This logs sensitive data returned by $@ as clear text. | passwords.js:3:17:3:26 | o.password | an access to password | @@ -304,7 +179,7 @@ edges | passwords.js:12:18:12:25 | password | passwords.js:12:18:12:25 | password | passwords.js:12:18:12:25 | password | This logs sensitive data returned by $@ as clear text. | passwords.js:12:18:12:25 | password | an access to password | | passwords.js:14:17:14:38 | name + ... assword | passwords.js:14:31:14:38 | password | passwords.js:14:17:14:38 | name + ... assword | This logs sensitive data returned by $@ as clear text. | passwords.js:14:31:14:38 | password | an access to password | | passwords.js:16:17:16:38 | `${name ... sword}` | passwords.js:16:29:16:36 | password | passwords.js:16:17:16:38 | `${name ... sword}` | This logs sensitive data returned by $@ as clear text. | passwords.js:16:29:16:36 | password | an access to password | -| passwords.js:21:17:21:20 | obj1 | passwords.js:18:16:20:5 | {\\n ... x\\n } | passwords.js:21:17:21:20 | obj1 | This logs sensitive data returned by $@ as clear text. | passwords.js:18:16:20:5 | {\\n ... x\\n } | an access to password | +| passwords.js:21:17:21:20 | obj1 | passwords.js:19:19:19:19 | x | passwords.js:21:17:21:20 | obj1 | This logs sensitive data returned by $@ as clear text. | passwords.js:19:19:19:19 | x | an access to password | | passwords.js:26:17:26:20 | obj2 | passwords.js:24:12:24:19 | password | passwords.js:26:17:26:20 | obj2 | This logs sensitive data returned by $@ as clear text. | passwords.js:24:12:24:19 | password | an access to password | | passwords.js:29:17:29:20 | obj3 | passwords.js:30:14:30:21 | password | passwords.js:29:17:29:20 | obj3 | This logs sensitive data returned by $@ as clear text. | passwords.js:30:14:30:21 | password | an access to password | | passwords.js:78:17:78:38 | temp.en ... assword | passwords.js:77:37:77:53 | req.body.password | passwords.js:78:17:78:38 | temp.en ... assword | This logs sensitive data returned by $@ as clear text. | passwords.js:77:37:77:53 | req.body.password | an access to password | @@ -317,7 +192,7 @@ edges | passwords.js:119:21:119:46 | "Passwo ... assword | passwords.js:119:39:119:46 | password | passwords.js:119:21:119:46 | "Passwo ... assword | This logs sensitive data returned by $@ as clear text. | passwords.js:119:39:119:46 | password | an access to password | | passwords.js:122:17:122:49 | name + ... tring() | passwords.js:122:31:122:38 | password | passwords.js:122:17:122:49 | name + ... tring() | This logs sensitive data returned by $@ as clear text. | passwords.js:122:31:122:38 | password | an access to password | | passwords.js:123:17:123:48 | name + ... lueOf() | passwords.js:123:31:123:38 | password | passwords.js:123:17:123:48 | name + ... lueOf() | This logs sensitive data returned by $@ as clear text. | passwords.js:123:31:123:38 | password | an access to password | -| passwords.js:135:17:135:22 | config | passwords.js:127:18:132:5 | {\\n ... )\\n } | passwords.js:135:17:135:22 | config | This logs sensitive data returned by $@ as clear text. | passwords.js:127:18:132:5 | {\\n ... )\\n } | an access to password | +| passwords.js:135:17:135:22 | config | passwords.js:128:19:128:19 | x | passwords.js:135:17:135:22 | config | This logs sensitive data returned by $@ as clear text. | passwords.js:128:19:128:19 | x | an access to password | | passwords.js:135:17:135:22 | config | passwords.js:130:12:130:19 | password | passwords.js:135:17:135:22 | config | This logs sensitive data returned by $@ as clear text. | passwords.js:130:12:130:19 | password | an access to password | | passwords.js:135:17:135:22 | config | passwords.js:131:12:131:24 | getPassword() | passwords.js:135:17:135:22 | config | This logs sensitive data returned by $@ as clear text. | passwords.js:131:12:131:24 | getPassword() | a call to getPassword | | passwords.js:136:17:136:24 | config.x | passwords.js:130:12:130:19 | password | passwords.js:136:17:136:24 | config.x | This logs sensitive data returned by $@ as clear text. | passwords.js:130:12:130:19 | password | an access to password | From 40d68cb4dc9bbb792f191308b8dc6d1299a60b1e Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:43:27 +0200 Subject: [PATCH 061/514] JS: Port CleartextStorage --- .../dataflow/CleartextStorageQuery.qll | 15 ++++- .../src/Security/CWE-312/CleartextStorage.ql | 6 +- .../CWE-312/CleartextStorage.expected | 65 +++++-------------- 3 files changed, 34 insertions(+), 52 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextStorageQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextStorageQuery.qll index cb97badf0ec..d4ee8a8297d 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextStorageQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextStorageQuery.qll @@ -19,7 +19,20 @@ import CleartextStorageCustomizations::CleartextStorage * added either by extending the relevant class, or by subclassing this configuration itself, * and amending the sources and sinks. */ -class Configuration extends TaintTracking::Configuration { +module ClearTextStorageConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +module ClearTextStorageFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `ClearTextStorageFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "ClearTextStorage" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-312/CleartextStorage.ql b/javascript/ql/src/Security/CWE-312/CleartextStorage.ql index 4660c4add9f..6f9bef802be 100644 --- a/javascript/ql/src/Security/CWE-312/CleartextStorage.ql +++ b/javascript/ql/src/Security/CWE-312/CleartextStorage.ql @@ -15,9 +15,9 @@ import javascript import semmle.javascript.security.dataflow.CleartextStorageQuery -import DataFlow::PathGraph +import ClearTextStorageFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from ClearTextStorageFlow::PathNode source, ClearTextStorageFlow::PathNode sink +where ClearTextStorageFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This stores sensitive data returned by $@ as clear text.", source.getNode(), source.getNode().(Source).describe() diff --git a/javascript/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected b/javascript/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected index 7016dbbffa8..5d1885142c9 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected @@ -1,57 +1,26 @@ -nodes -| CleartextStorage2.js:5:7:5:58 | pw | -| CleartextStorage2.js:5:12:5:58 | url.par ... assword | -| CleartextStorage2.js:5:12:5:58 | url.par ... assword | -| CleartextStorage2.js:7:19:7:34 | 'password=' + pw | -| CleartextStorage2.js:7:19:7:34 | 'password=' + pw | -| CleartextStorage2.js:7:33:7:34 | pw | -| CleartextStorage.js:5:7:5:40 | pw | -| CleartextStorage.js:5:12:5:40 | req.par ... sword") | -| CleartextStorage.js:5:12:5:40 | req.par ... sword") | -| CleartextStorage.js:7:26:7:27 | pw | -| CleartextStorage.js:7:26:7:27 | pw | -| tst-angularjs.js:3:32:3:45 | data1.password | -| tst-angularjs.js:3:32:3:45 | data1.password | -| tst-angularjs.js:3:32:3:45 | data1.password | -| tst-angularjs.js:4:33:4:46 | data2.password | -| tst-angularjs.js:4:33:4:46 | data2.password | -| tst-angularjs.js:4:33:4:46 | data2.password | -| tst-angularjs.js:5:27:5:40 | data3.password | -| tst-angularjs.js:5:27:5:40 | data3.password | -| tst-angularjs.js:5:27:5:40 | data3.password | -| tst-angularjs.js:6:33:6:46 | data4.password | -| tst-angularjs.js:6:33:6:46 | data4.password | -| tst-angularjs.js:6:33:6:46 | data4.password | -| tst-webstorage.js:1:18:1:30 | data.password | -| tst-webstorage.js:1:18:1:30 | data.password | -| tst-webstorage.js:1:18:1:30 | data.password | -| tst-webstorage.js:2:27:2:39 | data.password | -| tst-webstorage.js:2:27:2:39 | data.password | -| tst-webstorage.js:2:27:2:39 | data.password | -| tst-webstorage.js:3:20:3:32 | data.password | -| tst-webstorage.js:3:20:3:32 | data.password | -| tst-webstorage.js:3:20:3:32 | data.password | -| tst-webstorage.js:4:29:4:41 | data.password | -| tst-webstorage.js:4:29:4:41 | data.password | -| tst-webstorage.js:4:29:4:41 | data.password | edges | CleartextStorage2.js:5:7:5:58 | pw | CleartextStorage2.js:7:33:7:34 | pw | | CleartextStorage2.js:5:12:5:58 | url.par ... assword | CleartextStorage2.js:5:7:5:58 | pw | -| CleartextStorage2.js:5:12:5:58 | url.par ... assword | CleartextStorage2.js:5:7:5:58 | pw | -| CleartextStorage2.js:7:33:7:34 | pw | CleartextStorage2.js:7:19:7:34 | 'password=' + pw | | CleartextStorage2.js:7:33:7:34 | pw | CleartextStorage2.js:7:19:7:34 | 'password=' + pw | | CleartextStorage.js:5:7:5:40 | pw | CleartextStorage.js:7:26:7:27 | pw | -| CleartextStorage.js:5:7:5:40 | pw | CleartextStorage.js:7:26:7:27 | pw | | CleartextStorage.js:5:12:5:40 | req.par ... sword") | CleartextStorage.js:5:7:5:40 | pw | -| CleartextStorage.js:5:12:5:40 | req.par ... sword") | CleartextStorage.js:5:7:5:40 | pw | -| tst-angularjs.js:3:32:3:45 | data1.password | tst-angularjs.js:3:32:3:45 | data1.password | -| tst-angularjs.js:4:33:4:46 | data2.password | tst-angularjs.js:4:33:4:46 | data2.password | -| tst-angularjs.js:5:27:5:40 | data3.password | tst-angularjs.js:5:27:5:40 | data3.password | -| tst-angularjs.js:6:33:6:46 | data4.password | tst-angularjs.js:6:33:6:46 | data4.password | -| tst-webstorage.js:1:18:1:30 | data.password | tst-webstorage.js:1:18:1:30 | data.password | -| tst-webstorage.js:2:27:2:39 | data.password | tst-webstorage.js:2:27:2:39 | data.password | -| tst-webstorage.js:3:20:3:32 | data.password | tst-webstorage.js:3:20:3:32 | data.password | -| tst-webstorage.js:4:29:4:41 | data.password | tst-webstorage.js:4:29:4:41 | data.password | +nodes +| CleartextStorage2.js:5:7:5:58 | pw | semmle.label | pw | +| CleartextStorage2.js:5:12:5:58 | url.par ... assword | semmle.label | url.par ... assword | +| CleartextStorage2.js:7:19:7:34 | 'password=' + pw | semmle.label | 'password=' + pw | +| CleartextStorage2.js:7:33:7:34 | pw | semmle.label | pw | +| CleartextStorage.js:5:7:5:40 | pw | semmle.label | pw | +| CleartextStorage.js:5:12:5:40 | req.par ... sword") | semmle.label | req.par ... sword") | +| CleartextStorage.js:7:26:7:27 | pw | semmle.label | pw | +| tst-angularjs.js:3:32:3:45 | data1.password | semmle.label | data1.password | +| tst-angularjs.js:4:33:4:46 | data2.password | semmle.label | data2.password | +| tst-angularjs.js:5:27:5:40 | data3.password | semmle.label | data3.password | +| tst-angularjs.js:6:33:6:46 | data4.password | semmle.label | data4.password | +| tst-webstorage.js:1:18:1:30 | data.password | semmle.label | data.password | +| tst-webstorage.js:2:27:2:39 | data.password | semmle.label | data.password | +| tst-webstorage.js:3:20:3:32 | data.password | semmle.label | data.password | +| tst-webstorage.js:4:29:4:41 | data.password | semmle.label | data.password | +subpaths #select | CleartextStorage2.js:7:19:7:34 | 'password=' + pw | CleartextStorage2.js:5:12:5:58 | url.par ... assword | CleartextStorage2.js:7:19:7:34 | 'password=' + pw | This stores sensitive data returned by $@ as clear text. | CleartextStorage2.js:5:12:5:58 | url.par ... assword | an access to current_password | | CleartextStorage.js:7:26:7:27 | pw | CleartextStorage.js:5:12:5:40 | req.par ... sword") | CleartextStorage.js:7:26:7:27 | pw | This stores sensitive data returned by $@ as clear text. | CleartextStorage.js:5:12:5:40 | req.par ... sword") | a call to param | From ae680e747b161d2f2f9ef99bf8766079f7067984 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:45:08 +0200 Subject: [PATCH 062/514] JS: Port LoopBoundInjection --- .../LoopBoundInjectionCustomizations.qll | 40 ++++++-- .../dataflow/LoopBoundInjectionQuery.qll | 37 +++++++- .../Security/CWE-834/LoopBoundInjection.ql | 6 +- .../CWE-834/LoopBoundInjection.expected | 93 ++++++------------- 4 files changed, 98 insertions(+), 78 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionCustomizations.qll index 75f48032f3f..c140eed0785 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionCustomizations.qll @@ -166,6 +166,30 @@ module LoopBoundInjection { */ abstract class Source extends DataFlow::Node { } + /** + * A barrier guard for looping on tainted objects with unbounded length. + */ + 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 source of remote user input objects. */ @@ -174,12 +198,12 @@ module LoopBoundInjection { /** * A sanitizer that blocks taint flow if the array is checked to be an array using an `isArray` function. */ - class IsArraySanitizerGuard extends TaintTracking::LabeledSanitizerGuardNode, DataFlow::ValueNode { + class IsArraySanitizerGuard extends BarrierGuardLegacy, DataFlow::ValueNode { override CallExpr astNode; IsArraySanitizerGuard() { astNode.getCalleeName() = "isArray" } - override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { true = outcome and e = astNode.getAnArgument() and label = TaintedObject::label() @@ -189,9 +213,7 @@ module LoopBoundInjection { /** * A sanitizer that blocks taint flow if the array is checked to be an array using an `X instanceof Array` check. */ - class InstanceofArraySanitizerGuard extends TaintTracking::LabeledSanitizerGuardNode, - DataFlow::ValueNode - { + class InstanceofArraySanitizerGuard extends BarrierGuardLegacy, DataFlow::ValueNode { override BinaryExpr astNode; InstanceofArraySanitizerGuard() { @@ -199,7 +221,7 @@ module LoopBoundInjection { DataFlow::globalVarRef("Array").flowsToExpr(astNode.getRightOperand()) } - override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { true = outcome and e = astNode.getLeftOperand() and label = TaintedObject::label() @@ -211,9 +233,7 @@ module LoopBoundInjection { * * Also implicitly makes sure that only the first DoS-prone loop is selected by the query (as the .length test has outcome=false when exiting the loop). */ - class LengthCheckSanitizerGuard extends TaintTracking::LabeledSanitizerGuardNode, - DataFlow::ValueNode - { + class LengthCheckSanitizerGuard extends BarrierGuardLegacy, DataFlow::ValueNode { override RelationalComparison astNode; DataFlow::PropRead propRead; @@ -222,7 +242,7 @@ module LoopBoundInjection { propRead.getPropertyName() = "length" } - override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { false = outcome and e = propRead.getBase().asExpr() and label = TaintedObject::label() diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionQuery.qll index 165f96f7f29..a8316705a38 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionQuery.qll @@ -14,7 +14,42 @@ import LoopBoundInjectionCustomizations::LoopBoundInjection /** * A taint tracking configuration for reasoning about looping on tainted objects with unbounded length. */ -class Configuration extends TaintTracking::Configuration { +module LoopBoundInjectionConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; + + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { + source instanceof Source and label = TaintedObject::label() + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { + sink instanceof Sink and label = TaintedObject::label() + } + + predicate isBarrier(DataFlow::Node node) { + node = DataFlow::MakeBarrierGuard::getABarrierNode() + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel label) { + node = DataFlow::MakeLabeledBarrierGuard::getABarrierNode(label) or + node = TaintedObject::SanitizerGuard::getABarrierNode(label) + } + + predicate isAdditionalFlowStep( + DataFlow::Node src, DataFlow::FlowLabel inlbl, DataFlow::Node trg, DataFlow::FlowLabel outlbl + ) { + TaintedObject::step(src, trg, inlbl, outlbl) + } +} + +/** + * Taint tracking configuration for reasoning about looping on tainted objects with unbounded length. + */ +module LoopBoundInjectionFlow = TaintTracking::GlobalWithState; + +/** + * DEPRECATED. Use the `LoopBoundInjectionFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "LoopBoundInjection" } override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { diff --git a/javascript/ql/src/Security/CWE-834/LoopBoundInjection.ql b/javascript/ql/src/Security/CWE-834/LoopBoundInjection.ql index 1970378ea9a..8a8c74e9847 100644 --- a/javascript/ql/src/Security/CWE-834/LoopBoundInjection.ql +++ b/javascript/ql/src/Security/CWE-834/LoopBoundInjection.ql @@ -14,10 +14,10 @@ import javascript import semmle.javascript.security.dataflow.LoopBoundInjectionQuery -import DataFlow::PathGraph +import LoopBoundInjectionFlow::PathGraph -from Configuration dataflow, DataFlow::PathNode source, DataFlow::PathNode sink -where dataflow.hasFlowPath(source, sink) +from LoopBoundInjectionFlow::PathNode source, LoopBoundInjectionFlow::PathNode sink +where LoopBoundInjectionFlow::flowPath(source, sink) select sink, source, sink, "Iteration over a user-controlled object with a potentially unbounded .length property from a $@.", source, "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjection.expected b/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjection.expected index 7000c777eee..464b21ca14e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjection.expected @@ -1,86 +1,51 @@ -nodes -| LoopBoundInjectionBad.js:8:13:8:20 | req.body | -| LoopBoundInjectionBad.js:8:13:8:20 | req.body | -| LoopBoundInjectionBad.js:10:15:10:22 | req.body | -| LoopBoundInjectionBad.js:10:15:10:22 | req.body | -| LoopBoundInjectionBad.js:12:25:12:32 | req.body | -| LoopBoundInjectionBad.js:12:25:12:32 | req.body | -| LoopBoundInjectionBad.js:14:19:14:26 | req.body | -| LoopBoundInjectionBad.js:14:19:14:26 | req.body | -| LoopBoundInjectionBad.js:17:18:17:20 | val | -| LoopBoundInjectionBad.js:20:25:20:27 | val | -| LoopBoundInjectionBad.js:20:25:20:27 | val | -| LoopBoundInjectionBad.js:25:20:25:22 | val | -| LoopBoundInjectionBad.js:29:16:29:18 | val | -| LoopBoundInjectionBad.js:29:16:29:18 | val | -| LoopBoundInjectionBad.js:35:30:35:32 | val | -| LoopBoundInjectionBad.js:38:15:38:17 | val | -| LoopBoundInjectionBad.js:38:15:38:17 | val | -| LoopBoundInjectionBad.js:46:24:46:26 | val | -| LoopBoundInjectionBad.js:51:25:51:27 | val | -| LoopBoundInjectionBad.js:51:25:51:27 | val | -| LoopBoundInjectionExitBad.js:8:9:8:16 | req.body | -| LoopBoundInjectionExitBad.js:8:9:8:16 | req.body | -| LoopBoundInjectionExitBad.js:10:9:10:16 | req.body | -| LoopBoundInjectionExitBad.js:10:9:10:16 | req.body | -| LoopBoundInjectionExitBad.js:12:10:12:17 | req.body | -| LoopBoundInjectionExitBad.js:12:10:12:17 | req.body | -| LoopBoundInjectionExitBad.js:14:14:14:21 | req.body | -| LoopBoundInjectionExitBad.js:14:14:14:21 | req.body | -| LoopBoundInjectionExitBad.js:17:17:17:19 | val | -| LoopBoundInjectionExitBad.js:20:22:20:24 | val | -| LoopBoundInjectionExitBad.js:20:22:20:24 | val | -| LoopBoundInjectionExitBad.js:31:17:31:19 | val | -| LoopBoundInjectionExitBad.js:34:22:34:24 | val | -| LoopBoundInjectionExitBad.js:34:22:34:24 | val | -| LoopBoundInjectionExitBad.js:46:18:46:20 | val | -| LoopBoundInjectionExitBad.js:49:22:49:24 | val | -| LoopBoundInjectionExitBad.js:49:22:49:24 | val | -| LoopBoundInjectionExitBad.js:59:22:59:24 | val | -| LoopBoundInjectionExitBad.js:60:8:60:10 | val | -| LoopBoundInjectionExitBad.js:60:8:60:10 | val | -| LoopBoundInjectionLodash.js:9:13:9:20 | req.body | -| LoopBoundInjectionLodash.js:9:13:9:20 | req.body | -| LoopBoundInjectionLodash.js:12:18:12:20 | val | -| LoopBoundInjectionLodash.js:13:13:13:15 | val | -| LoopBoundInjectionLodash.js:13:13:13:15 | val | edges | LoopBoundInjectionBad.js:8:13:8:20 | req.body | LoopBoundInjectionBad.js:17:18:17:20 | val | -| LoopBoundInjectionBad.js:8:13:8:20 | req.body | LoopBoundInjectionBad.js:17:18:17:20 | val | -| LoopBoundInjectionBad.js:10:15:10:22 | req.body | LoopBoundInjectionBad.js:25:20:25:22 | val | | LoopBoundInjectionBad.js:10:15:10:22 | req.body | LoopBoundInjectionBad.js:25:20:25:22 | val | | LoopBoundInjectionBad.js:12:25:12:32 | req.body | LoopBoundInjectionBad.js:35:30:35:32 | val | -| LoopBoundInjectionBad.js:12:25:12:32 | req.body | LoopBoundInjectionBad.js:35:30:35:32 | val | -| LoopBoundInjectionBad.js:14:19:14:26 | req.body | LoopBoundInjectionBad.js:46:24:46:26 | val | | LoopBoundInjectionBad.js:14:19:14:26 | req.body | LoopBoundInjectionBad.js:46:24:46:26 | val | | LoopBoundInjectionBad.js:17:18:17:20 | val | LoopBoundInjectionBad.js:20:25:20:27 | val | -| LoopBoundInjectionBad.js:17:18:17:20 | val | LoopBoundInjectionBad.js:20:25:20:27 | val | -| LoopBoundInjectionBad.js:25:20:25:22 | val | LoopBoundInjectionBad.js:29:16:29:18 | val | | LoopBoundInjectionBad.js:25:20:25:22 | val | LoopBoundInjectionBad.js:29:16:29:18 | val | | LoopBoundInjectionBad.js:35:30:35:32 | val | LoopBoundInjectionBad.js:38:15:38:17 | val | -| LoopBoundInjectionBad.js:35:30:35:32 | val | LoopBoundInjectionBad.js:38:15:38:17 | val | -| LoopBoundInjectionBad.js:46:24:46:26 | val | LoopBoundInjectionBad.js:51:25:51:27 | val | | LoopBoundInjectionBad.js:46:24:46:26 | val | LoopBoundInjectionBad.js:51:25:51:27 | val | | LoopBoundInjectionExitBad.js:8:9:8:16 | req.body | LoopBoundInjectionExitBad.js:17:17:17:19 | val | -| LoopBoundInjectionExitBad.js:8:9:8:16 | req.body | LoopBoundInjectionExitBad.js:17:17:17:19 | val | -| LoopBoundInjectionExitBad.js:10:9:10:16 | req.body | LoopBoundInjectionExitBad.js:31:17:31:19 | val | | LoopBoundInjectionExitBad.js:10:9:10:16 | req.body | LoopBoundInjectionExitBad.js:31:17:31:19 | val | | LoopBoundInjectionExitBad.js:12:10:12:17 | req.body | LoopBoundInjectionExitBad.js:46:18:46:20 | val | -| LoopBoundInjectionExitBad.js:12:10:12:17 | req.body | LoopBoundInjectionExitBad.js:46:18:46:20 | val | -| LoopBoundInjectionExitBad.js:14:14:14:21 | req.body | LoopBoundInjectionExitBad.js:59:22:59:24 | val | | LoopBoundInjectionExitBad.js:14:14:14:21 | req.body | LoopBoundInjectionExitBad.js:59:22:59:24 | val | | LoopBoundInjectionExitBad.js:17:17:17:19 | val | LoopBoundInjectionExitBad.js:20:22:20:24 | val | -| LoopBoundInjectionExitBad.js:17:17:17:19 | val | LoopBoundInjectionExitBad.js:20:22:20:24 | val | -| LoopBoundInjectionExitBad.js:31:17:31:19 | val | LoopBoundInjectionExitBad.js:34:22:34:24 | val | | LoopBoundInjectionExitBad.js:31:17:31:19 | val | LoopBoundInjectionExitBad.js:34:22:34:24 | val | | LoopBoundInjectionExitBad.js:46:18:46:20 | val | LoopBoundInjectionExitBad.js:49:22:49:24 | val | -| LoopBoundInjectionExitBad.js:46:18:46:20 | val | LoopBoundInjectionExitBad.js:49:22:49:24 | val | -| LoopBoundInjectionExitBad.js:59:22:59:24 | val | LoopBoundInjectionExitBad.js:60:8:60:10 | val | | LoopBoundInjectionExitBad.js:59:22:59:24 | val | LoopBoundInjectionExitBad.js:60:8:60:10 | val | | LoopBoundInjectionLodash.js:9:13:9:20 | req.body | LoopBoundInjectionLodash.js:12:18:12:20 | val | -| LoopBoundInjectionLodash.js:9:13:9:20 | req.body | LoopBoundInjectionLodash.js:12:18:12:20 | val | -| LoopBoundInjectionLodash.js:12:18:12:20 | val | LoopBoundInjectionLodash.js:13:13:13:15 | val | | LoopBoundInjectionLodash.js:12:18:12:20 | val | LoopBoundInjectionLodash.js:13:13:13:15 | val | +nodes +| LoopBoundInjectionBad.js:8:13:8:20 | req.body | semmle.label | req.body | +| LoopBoundInjectionBad.js:10:15:10:22 | req.body | semmle.label | req.body | +| LoopBoundInjectionBad.js:12:25:12:32 | req.body | semmle.label | req.body | +| LoopBoundInjectionBad.js:14:19:14:26 | req.body | semmle.label | req.body | +| LoopBoundInjectionBad.js:17:18:17:20 | val | semmle.label | val | +| LoopBoundInjectionBad.js:20:25:20:27 | val | semmle.label | val | +| LoopBoundInjectionBad.js:25:20:25:22 | val | semmle.label | val | +| LoopBoundInjectionBad.js:29:16:29:18 | val | semmle.label | val | +| LoopBoundInjectionBad.js:35:30:35:32 | val | semmle.label | val | +| LoopBoundInjectionBad.js:38:15:38:17 | val | semmle.label | val | +| LoopBoundInjectionBad.js:46:24:46:26 | val | semmle.label | val | +| LoopBoundInjectionBad.js:51:25:51:27 | val | semmle.label | val | +| LoopBoundInjectionExitBad.js:8:9:8:16 | req.body | semmle.label | req.body | +| LoopBoundInjectionExitBad.js:10:9:10:16 | req.body | semmle.label | req.body | +| LoopBoundInjectionExitBad.js:12:10:12:17 | req.body | semmle.label | req.body | +| LoopBoundInjectionExitBad.js:14:14:14:21 | req.body | semmle.label | req.body | +| LoopBoundInjectionExitBad.js:17:17:17:19 | val | semmle.label | val | +| LoopBoundInjectionExitBad.js:20:22:20:24 | val | semmle.label | val | +| LoopBoundInjectionExitBad.js:31:17:31:19 | val | semmle.label | val | +| LoopBoundInjectionExitBad.js:34:22:34:24 | val | semmle.label | val | +| LoopBoundInjectionExitBad.js:46:18:46:20 | val | semmle.label | val | +| LoopBoundInjectionExitBad.js:49:22:49:24 | val | semmle.label | val | +| LoopBoundInjectionExitBad.js:59:22:59:24 | val | semmle.label | val | +| LoopBoundInjectionExitBad.js:60:8:60:10 | val | semmle.label | val | +| LoopBoundInjectionLodash.js:9:13:9:20 | req.body | semmle.label | req.body | +| LoopBoundInjectionLodash.js:12:18:12:20 | val | semmle.label | val | +| LoopBoundInjectionLodash.js:13:13:13:15 | val | semmle.label | val | +subpaths #select | LoopBoundInjectionBad.js:20:25:20:27 | val | LoopBoundInjectionBad.js:8:13:8:20 | req.body | LoopBoundInjectionBad.js:20:25:20:27 | val | Iteration over a user-controlled object with a potentially unbounded .length property from a $@. | LoopBoundInjectionBad.js:8:13:8:20 | req.body | user-provided value | | LoopBoundInjectionBad.js:29:16:29:18 | val | LoopBoundInjectionBad.js:10:15:10:22 | req.body | LoopBoundInjectionBad.js:29:16:29:18 | val | Iteration over a user-controlled object with a potentially unbounded .length property from a $@. | LoopBoundInjectionBad.js:10:15:10:22 | req.body | user-provided value | From e9189f965f28e3a325a568889c735d6e4691e237 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 21:45:44 +0200 Subject: [PATCH 063/514] JS: Port LogInjection --- .../security/dataflow/LogInjectionQuery.qll | 18 +- .../ql/src/Security/CWE-117/LogInjection.ql | 6 +- .../Security/CWE-117/LogInjection.expected | 222 +++++++----------- 3 files changed, 106 insertions(+), 140 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/LogInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/LogInjectionQuery.qll index 6a98db71c72..e8e4847bfce 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/LogInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/LogInjectionQuery.qll @@ -22,7 +22,23 @@ abstract class Sanitizer extends DataFlow::Node { } /** * A taint-tracking configuration for untrusted user input used in log entries. */ -class LogInjectionConfiguration extends TaintTracking::Configuration { +module LogInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint-tracking for untrusted user input used in log entries. + */ +module LogInjectionFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `LogInjectionFlow` module instead. + */ +deprecated class LogInjectionConfiguration extends TaintTracking::Configuration { LogInjectionConfiguration() { this = "LogInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-117/LogInjection.ql b/javascript/ql/src/Security/CWE-117/LogInjection.ql index d80c3214e74..02fe187ac48 100644 --- a/javascript/ql/src/Security/CWE-117/LogInjection.ql +++ b/javascript/ql/src/Security/CWE-117/LogInjection.ql @@ -12,10 +12,10 @@ */ import javascript -import DataFlow::PathGraph import semmle.javascript.security.dataflow.LogInjectionQuery +import LogInjectionFlow::PathGraph -from LogInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) +from LogInjectionFlow::PathNode source, LogInjectionFlow::PathNode sink +where LogInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Log entry depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-117/LogInjection.expected b/javascript/ql/test/query-tests/Security/CWE-117/LogInjection.expected index db473a17d2c..0e4ce448c75 100644 --- a/javascript/ql/test/query-tests/Security/CWE-117/LogInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-117/LogInjection.expected @@ -1,126 +1,23 @@ -nodes -| logInjectionBad.js:19:9:19:36 | q | -| logInjectionBad.js:19:13:19:36 | url.par ... , true) | -| logInjectionBad.js:19:23:19:29 | req.url | -| logInjectionBad.js:19:23:19:29 | req.url | -| logInjectionBad.js:20:9:20:35 | username | -| logInjectionBad.js:20:20:20:20 | q | -| logInjectionBad.js:20:20:20:26 | q.query | -| logInjectionBad.js:20:20:20:35 | q.query.username | -| logInjectionBad.js:22:18:22:43 | `[INFO] ... rname}` | -| logInjectionBad.js:22:18:22:43 | `[INFO] ... rname}` | -| logInjectionBad.js:22:34:22:41 | username | -| logInjectionBad.js:23:37:23:44 | username | -| logInjectionBad.js:23:37:23:44 | username | -| logInjectionBad.js:24:35:24:42 | username | -| logInjectionBad.js:24:35:24:42 | username | -| logInjectionBad.js:25:36:25:43 | username | -| logInjectionBad.js:25:36:25:43 | username | -| logInjectionBad.js:28:9:28:32 | exceptional return of check_u ... ername) | -| logInjectionBad.js:28:24:28:31 | username | -| logInjectionBad.js:29:14:29:18 | error | -| logInjectionBad.js:30:23:30:49 | `[ERROR ... rror}"` | -| logInjectionBad.js:30:23:30:49 | `[ERROR ... rror}"` | -| logInjectionBad.js:30:42:30:46 | error | -| logInjectionBad.js:46:9:46:36 | q | -| logInjectionBad.js:46:13:46:36 | url.par ... , true) | -| logInjectionBad.js:46:23:46:29 | req.url | -| logInjectionBad.js:46:23:46:29 | req.url | -| logInjectionBad.js:47:9:47:35 | username | -| logInjectionBad.js:47:20:47:20 | q | -| logInjectionBad.js:47:20:47:26 | q.query | -| logInjectionBad.js:47:20:47:35 | q.query.username | -| logInjectionBad.js:49:18:49:54 | ansiCol ... ername) | -| logInjectionBad.js:49:18:49:54 | ansiCol ... ername) | -| logInjectionBad.js:49:46:49:53 | username | -| logInjectionBad.js:50:18:50:47 | colors. ... ername) | -| logInjectionBad.js:50:18:50:47 | colors. ... ername) | -| logInjectionBad.js:50:39:50:46 | username | -| logInjectionBad.js:51:18:51:61 | wrapAns ... e), 20) | -| logInjectionBad.js:51:18:51:61 | wrapAns ... e), 20) | -| logInjectionBad.js:51:27:51:56 | colors. ... ername) | -| logInjectionBad.js:51:48:51:55 | username | -| logInjectionBad.js:52:17:52:47 | underli ... name))) | -| logInjectionBad.js:52:17:52:47 | underli ... name))) | -| logInjectionBad.js:52:27:52:46 | bold(blue(username)) | -| logInjectionBad.js:52:32:52:45 | blue(username) | -| logInjectionBad.js:52:37:52:44 | username | -| logInjectionBad.js:53:17:53:76 | highlig ... true}) | -| logInjectionBad.js:53:17:53:76 | highlig ... true}) | -| logInjectionBad.js:53:27:53:34 | username | -| logInjectionBad.js:54:17:54:51 | clc.red ... ername) | -| logInjectionBad.js:54:17:54:51 | clc.red ... ername) | -| logInjectionBad.js:54:43:54:50 | username | -| logInjectionBad.js:55:17:55:65 | sliceAn ... 20, 30) | -| logInjectionBad.js:55:17:55:65 | sliceAn ... 20, 30) | -| logInjectionBad.js:55:27:55:56 | colors. ... ername) | -| logInjectionBad.js:55:48:55:55 | username | -| logInjectionBad.js:56:17:56:55 | kleur.b ... ername) | -| logInjectionBad.js:56:17:56:55 | kleur.b ... ername) | -| logInjectionBad.js:56:47:56:54 | username | -| logInjectionBad.js:57:17:57:48 | chalk.u ... ername) | -| logInjectionBad.js:57:17:57:48 | chalk.u ... ername) | -| logInjectionBad.js:57:40:57:47 | username | -| logInjectionBad.js:58:17:58:59 | stripAn ... rname)) | -| logInjectionBad.js:58:17:58:59 | stripAn ... rname)) | -| logInjectionBad.js:58:27:58:58 | chalk.u ... ername) | -| logInjectionBad.js:58:50:58:57 | username | -| logInjectionBad.js:63:9:63:36 | q | -| logInjectionBad.js:63:13:63:36 | url.par ... , true) | -| logInjectionBad.js:63:23:63:29 | req.url | -| logInjectionBad.js:63:23:63:29 | req.url | -| logInjectionBad.js:64:9:64:35 | username | -| logInjectionBad.js:64:20:64:20 | q | -| logInjectionBad.js:64:20:64:26 | q.query | -| logInjectionBad.js:64:20:64:35 | q.query.username | -| logInjectionBad.js:66:17:66:43 | prettyj ... ername) | -| logInjectionBad.js:66:17:66:43 | prettyj ... ername) | -| logInjectionBad.js:66:35:66:42 | username | -| logInjectionBad.js:72:9:72:36 | q | -| logInjectionBad.js:72:13:72:36 | url.par ... , true) | -| logInjectionBad.js:72:23:72:29 | req.url | -| logInjectionBad.js:72:23:72:29 | req.url | -| logInjectionBad.js:73:9:73:35 | username | -| logInjectionBad.js:73:20:73:20 | q | -| logInjectionBad.js:73:20:73:26 | q.query | -| logInjectionBad.js:73:20:73:35 | q.query.username | -| logInjectionBad.js:75:15:75:22 | username | -| logInjectionBad.js:75:15:75:22 | username | -| logInjectionBad.js:82:30:82:37 | username | -| logInjectionBad.js:82:30:82:37 | username | -| logInjectionBad.js:91:26:91:33 | username | -| logInjectionBad.js:91:26:91:33 | username | -| logInjectionBad.js:99:26:99:33 | username | -| logInjectionBad.js:99:26:99:33 | username | -| logInjectionBad.js:113:37:113:44 | username | -| logInjectionBad.js:113:37:113:44 | username | edges +| logInjectionBad.js:7:25:7:32 | username | logInjectionBad.js:8:38:8:45 | username | | logInjectionBad.js:19:9:19:36 | q | logInjectionBad.js:20:20:20:20 | q | | logInjectionBad.js:19:13:19:36 | url.par ... , true) | logInjectionBad.js:19:9:19:36 | q | | logInjectionBad.js:19:23:19:29 | req.url | logInjectionBad.js:19:13:19:36 | url.par ... , true) | -| logInjectionBad.js:19:23:19:29 | req.url | logInjectionBad.js:19:13:19:36 | url.par ... , true) | | logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:22:34:22:41 | username | | logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:23:37:23:44 | username | -| logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:23:37:23:44 | username | | logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:24:35:24:42 | username | -| logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:24:35:24:42 | username | -| logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:25:36:25:43 | username | | logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:25:36:25:43 | username | | logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:28:24:28:31 | username | -| logInjectionBad.js:20:20:20:20 | q | logInjectionBad.js:20:20:20:26 | q.query | -| logInjectionBad.js:20:20:20:26 | q.query | logInjectionBad.js:20:20:20:35 | q.query.username | -| logInjectionBad.js:20:20:20:35 | q.query.username | logInjectionBad.js:20:9:20:35 | username | -| logInjectionBad.js:22:34:22:41 | username | logInjectionBad.js:22:18:22:43 | `[INFO] ... rname}` | +| logInjectionBad.js:20:20:20:20 | q | logInjectionBad.js:20:9:20:35 | username | | logInjectionBad.js:22:34:22:41 | username | logInjectionBad.js:22:18:22:43 | `[INFO] ... rname}` | | logInjectionBad.js:28:9:28:32 | exceptional return of check_u ... ername) | logInjectionBad.js:29:14:29:18 | error | +| logInjectionBad.js:28:24:28:31 | username | logInjectionBad.js:7:25:7:32 | username | | logInjectionBad.js:28:24:28:31 | username | logInjectionBad.js:28:9:28:32 | exceptional return of check_u ... ername) | | logInjectionBad.js:29:14:29:18 | error | logInjectionBad.js:30:42:30:46 | error | | logInjectionBad.js:30:42:30:46 | error | logInjectionBad.js:30:23:30:49 | `[ERROR ... rror}"` | -| logInjectionBad.js:30:42:30:46 | error | logInjectionBad.js:30:23:30:49 | `[ERROR ... rror}"` | | logInjectionBad.js:46:9:46:36 | q | logInjectionBad.js:47:20:47:20 | q | | logInjectionBad.js:46:13:46:36 | url.par ... , true) | logInjectionBad.js:46:9:46:36 | q | | logInjectionBad.js:46:23:46:29 | req.url | logInjectionBad.js:46:13:46:36 | url.par ... , true) | -| logInjectionBad.js:46:23:46:29 | req.url | logInjectionBad.js:46:13:46:36 | url.par ... , true) | | logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:49:46:49:53 | username | | logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:50:39:50:46 | username | | logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:51:48:51:55 | username | @@ -131,61 +28,114 @@ edges | logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:56:47:56:54 | username | | logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:57:40:57:47 | username | | logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:58:50:58:57 | username | -| logInjectionBad.js:47:20:47:20 | q | logInjectionBad.js:47:20:47:26 | q.query | -| logInjectionBad.js:47:20:47:26 | q.query | logInjectionBad.js:47:20:47:35 | q.query.username | -| logInjectionBad.js:47:20:47:35 | q.query.username | logInjectionBad.js:47:9:47:35 | username | -| logInjectionBad.js:49:46:49:53 | username | logInjectionBad.js:49:18:49:54 | ansiCol ... ername) | +| logInjectionBad.js:47:20:47:20 | q | logInjectionBad.js:47:9:47:35 | username | | logInjectionBad.js:49:46:49:53 | username | logInjectionBad.js:49:18:49:54 | ansiCol ... ername) | | logInjectionBad.js:50:39:50:46 | username | logInjectionBad.js:50:18:50:47 | colors. ... ername) | -| logInjectionBad.js:50:39:50:46 | username | logInjectionBad.js:50:18:50:47 | colors. ... ername) | -| logInjectionBad.js:51:27:51:56 | colors. ... ername) | logInjectionBad.js:51:18:51:61 | wrapAns ... e), 20) | | logInjectionBad.js:51:27:51:56 | colors. ... ername) | logInjectionBad.js:51:18:51:61 | wrapAns ... e), 20) | | logInjectionBad.js:51:48:51:55 | username | logInjectionBad.js:51:27:51:56 | colors. ... ername) | | logInjectionBad.js:52:27:52:46 | bold(blue(username)) | logInjectionBad.js:52:17:52:47 | underli ... name))) | -| logInjectionBad.js:52:27:52:46 | bold(blue(username)) | logInjectionBad.js:52:17:52:47 | underli ... name))) | | logInjectionBad.js:52:32:52:45 | blue(username) | logInjectionBad.js:52:27:52:46 | bold(blue(username)) | | logInjectionBad.js:52:37:52:44 | username | logInjectionBad.js:52:32:52:45 | blue(username) | | logInjectionBad.js:53:27:53:34 | username | logInjectionBad.js:53:17:53:76 | highlig ... true}) | -| logInjectionBad.js:53:27:53:34 | username | logInjectionBad.js:53:17:53:76 | highlig ... true}) | | logInjectionBad.js:54:43:54:50 | username | logInjectionBad.js:54:17:54:51 | clc.red ... ername) | -| logInjectionBad.js:54:43:54:50 | username | logInjectionBad.js:54:17:54:51 | clc.red ... ername) | -| logInjectionBad.js:55:27:55:56 | colors. ... ername) | logInjectionBad.js:55:17:55:65 | sliceAn ... 20, 30) | | logInjectionBad.js:55:27:55:56 | colors. ... ername) | logInjectionBad.js:55:17:55:65 | sliceAn ... 20, 30) | | logInjectionBad.js:55:48:55:55 | username | logInjectionBad.js:55:27:55:56 | colors. ... ername) | | logInjectionBad.js:56:47:56:54 | username | logInjectionBad.js:56:17:56:55 | kleur.b ... ername) | -| logInjectionBad.js:56:47:56:54 | username | logInjectionBad.js:56:17:56:55 | kleur.b ... ername) | | logInjectionBad.js:57:40:57:47 | username | logInjectionBad.js:57:17:57:48 | chalk.u ... ername) | -| logInjectionBad.js:57:40:57:47 | username | logInjectionBad.js:57:17:57:48 | chalk.u ... ername) | -| logInjectionBad.js:58:27:58:58 | chalk.u ... ername) | logInjectionBad.js:58:17:58:59 | stripAn ... rname)) | | logInjectionBad.js:58:27:58:58 | chalk.u ... ername) | logInjectionBad.js:58:17:58:59 | stripAn ... rname)) | | logInjectionBad.js:58:50:58:57 | username | logInjectionBad.js:58:27:58:58 | chalk.u ... ername) | | logInjectionBad.js:63:9:63:36 | q | logInjectionBad.js:64:20:64:20 | q | | logInjectionBad.js:63:13:63:36 | url.par ... , true) | logInjectionBad.js:63:9:63:36 | q | | logInjectionBad.js:63:23:63:29 | req.url | logInjectionBad.js:63:13:63:36 | url.par ... , true) | -| logInjectionBad.js:63:23:63:29 | req.url | logInjectionBad.js:63:13:63:36 | url.par ... , true) | | logInjectionBad.js:64:9:64:35 | username | logInjectionBad.js:66:35:66:42 | username | -| logInjectionBad.js:64:20:64:20 | q | logInjectionBad.js:64:20:64:26 | q.query | -| logInjectionBad.js:64:20:64:26 | q.query | logInjectionBad.js:64:20:64:35 | q.query.username | -| logInjectionBad.js:64:20:64:35 | q.query.username | logInjectionBad.js:64:9:64:35 | username | -| logInjectionBad.js:66:35:66:42 | username | logInjectionBad.js:66:17:66:43 | prettyj ... ername) | +| logInjectionBad.js:64:20:64:20 | q | logInjectionBad.js:64:9:64:35 | username | | logInjectionBad.js:66:35:66:42 | username | logInjectionBad.js:66:17:66:43 | prettyj ... ername) | | logInjectionBad.js:72:9:72:36 | q | logInjectionBad.js:73:20:73:20 | q | | logInjectionBad.js:72:13:72:36 | url.par ... , true) | logInjectionBad.js:72:9:72:36 | q | | logInjectionBad.js:72:23:72:29 | req.url | logInjectionBad.js:72:13:72:36 | url.par ... , true) | -| logInjectionBad.js:72:23:72:29 | req.url | logInjectionBad.js:72:13:72:36 | url.par ... , true) | | logInjectionBad.js:73:9:73:35 | username | logInjectionBad.js:75:15:75:22 | username | | logInjectionBad.js:73:9:73:35 | username | logInjectionBad.js:75:15:75:22 | username | -| logInjectionBad.js:73:9:73:35 | username | logInjectionBad.js:82:30:82:37 | username | -| logInjectionBad.js:73:9:73:35 | username | logInjectionBad.js:82:30:82:37 | username | -| logInjectionBad.js:73:9:73:35 | username | logInjectionBad.js:91:26:91:33 | username | -| logInjectionBad.js:73:9:73:35 | username | logInjectionBad.js:91:26:91:33 | username | -| logInjectionBad.js:73:9:73:35 | username | logInjectionBad.js:99:26:99:33 | username | -| logInjectionBad.js:73:9:73:35 | username | logInjectionBad.js:99:26:99:33 | username | -| logInjectionBad.js:73:9:73:35 | username | logInjectionBad.js:113:37:113:44 | username | -| logInjectionBad.js:73:9:73:35 | username | logInjectionBad.js:113:37:113:44 | username | -| logInjectionBad.js:73:20:73:20 | q | logInjectionBad.js:73:20:73:26 | q.query | -| logInjectionBad.js:73:20:73:26 | q.query | logInjectionBad.js:73:20:73:35 | q.query.username | -| logInjectionBad.js:73:20:73:35 | q.query.username | logInjectionBad.js:73:9:73:35 | username | +| logInjectionBad.js:73:20:73:20 | q | logInjectionBad.js:73:9:73:35 | username | +| logInjectionBad.js:75:15:75:22 | username | logInjectionBad.js:77:5:85:5 | functio ... ;\\n } [username] | +| logInjectionBad.js:75:15:75:22 | username | logInjectionBad.js:87:5:94:5 | functio ... ;\\n } [username] | +| logInjectionBad.js:75:15:75:22 | username | logInjectionBad.js:96:5:103:5 | functio ... ;\\n } [username] | +| logInjectionBad.js:75:15:75:22 | username | logInjectionBad.js:105:5:118:5 | functio ... ;\\n } [username] | +| logInjectionBad.js:77:5:85:5 | functio ... ;\\n } [username] | logInjectionBad.js:82:30:82:37 | username | +| logInjectionBad.js:87:5:94:5 | functio ... ;\\n } [username] | logInjectionBad.js:91:26:91:33 | username | +| logInjectionBad.js:96:5:103:5 | functio ... ;\\n } [username] | logInjectionBad.js:99:26:99:33 | username | +| logInjectionBad.js:105:5:118:5 | functio ... ;\\n } [username] | logInjectionBad.js:113:37:113:44 | username | +nodes +| logInjectionBad.js:7:25:7:32 | username | semmle.label | username | +| logInjectionBad.js:8:38:8:45 | username | semmle.label | username | +| logInjectionBad.js:19:9:19:36 | q | semmle.label | q | +| logInjectionBad.js:19:13:19:36 | url.par ... , true) | semmle.label | url.par ... , true) | +| logInjectionBad.js:19:23:19:29 | req.url | semmle.label | req.url | +| logInjectionBad.js:20:9:20:35 | username | semmle.label | username | +| logInjectionBad.js:20:20:20:20 | q | semmle.label | q | +| logInjectionBad.js:22:18:22:43 | `[INFO] ... rname}` | semmle.label | `[INFO] ... rname}` | +| logInjectionBad.js:22:34:22:41 | username | semmle.label | username | +| logInjectionBad.js:23:37:23:44 | username | semmle.label | username | +| logInjectionBad.js:24:35:24:42 | username | semmle.label | username | +| logInjectionBad.js:25:36:25:43 | username | semmle.label | username | +| logInjectionBad.js:28:9:28:32 | exceptional return of check_u ... ername) | semmle.label | exceptional return of check_u ... ername) | +| logInjectionBad.js:28:24:28:31 | username | semmle.label | username | +| logInjectionBad.js:29:14:29:18 | error | semmle.label | error | +| logInjectionBad.js:30:23:30:49 | `[ERROR ... rror}"` | semmle.label | `[ERROR ... rror}"` | +| logInjectionBad.js:30:42:30:46 | error | semmle.label | error | +| logInjectionBad.js:46:9:46:36 | q | semmle.label | q | +| logInjectionBad.js:46:13:46:36 | url.par ... , true) | semmle.label | url.par ... , true) | +| logInjectionBad.js:46:23:46:29 | req.url | semmle.label | req.url | +| logInjectionBad.js:47:9:47:35 | username | semmle.label | username | +| logInjectionBad.js:47:20:47:20 | q | semmle.label | q | +| logInjectionBad.js:49:18:49:54 | ansiCol ... ername) | semmle.label | ansiCol ... ername) | +| logInjectionBad.js:49:46:49:53 | username | semmle.label | username | +| logInjectionBad.js:50:18:50:47 | colors. ... ername) | semmle.label | colors. ... ername) | +| logInjectionBad.js:50:39:50:46 | username | semmle.label | username | +| logInjectionBad.js:51:18:51:61 | wrapAns ... e), 20) | semmle.label | wrapAns ... e), 20) | +| logInjectionBad.js:51:27:51:56 | colors. ... ername) | semmle.label | colors. ... ername) | +| logInjectionBad.js:51:48:51:55 | username | semmle.label | username | +| logInjectionBad.js:52:17:52:47 | underli ... name))) | semmle.label | underli ... name))) | +| logInjectionBad.js:52:27:52:46 | bold(blue(username)) | semmle.label | bold(blue(username)) | +| logInjectionBad.js:52:32:52:45 | blue(username) | semmle.label | blue(username) | +| logInjectionBad.js:52:37:52:44 | username | semmle.label | username | +| logInjectionBad.js:53:17:53:76 | highlig ... true}) | semmle.label | highlig ... true}) | +| logInjectionBad.js:53:27:53:34 | username | semmle.label | username | +| logInjectionBad.js:54:17:54:51 | clc.red ... ername) | semmle.label | clc.red ... ername) | +| logInjectionBad.js:54:43:54:50 | username | semmle.label | username | +| logInjectionBad.js:55:17:55:65 | sliceAn ... 20, 30) | semmle.label | sliceAn ... 20, 30) | +| logInjectionBad.js:55:27:55:56 | colors. ... ername) | semmle.label | colors. ... ername) | +| logInjectionBad.js:55:48:55:55 | username | semmle.label | username | +| logInjectionBad.js:56:17:56:55 | kleur.b ... ername) | semmle.label | kleur.b ... ername) | +| logInjectionBad.js:56:47:56:54 | username | semmle.label | username | +| logInjectionBad.js:57:17:57:48 | chalk.u ... ername) | semmle.label | chalk.u ... ername) | +| logInjectionBad.js:57:40:57:47 | username | semmle.label | username | +| logInjectionBad.js:58:17:58:59 | stripAn ... rname)) | semmle.label | stripAn ... rname)) | +| logInjectionBad.js:58:27:58:58 | chalk.u ... ername) | semmle.label | chalk.u ... ername) | +| logInjectionBad.js:58:50:58:57 | username | semmle.label | username | +| logInjectionBad.js:63:9:63:36 | q | semmle.label | q | +| logInjectionBad.js:63:13:63:36 | url.par ... , true) | semmle.label | url.par ... , true) | +| logInjectionBad.js:63:23:63:29 | req.url | semmle.label | req.url | +| logInjectionBad.js:64:9:64:35 | username | semmle.label | username | +| logInjectionBad.js:64:20:64:20 | q | semmle.label | q | +| logInjectionBad.js:66:17:66:43 | prettyj ... ername) | semmle.label | prettyj ... ername) | +| logInjectionBad.js:66:35:66:42 | username | semmle.label | username | +| logInjectionBad.js:72:9:72:36 | q | semmle.label | q | +| logInjectionBad.js:72:13:72:36 | url.par ... , true) | semmle.label | url.par ... , true) | +| logInjectionBad.js:72:23:72:29 | req.url | semmle.label | req.url | +| logInjectionBad.js:73:9:73:35 | username | semmle.label | username | +| logInjectionBad.js:73:20:73:20 | q | semmle.label | q | +| logInjectionBad.js:75:15:75:22 | username | semmle.label | username | +| logInjectionBad.js:75:15:75:22 | username | semmle.label | username | +| logInjectionBad.js:77:5:85:5 | functio ... ;\\n } [username] | semmle.label | functio ... ;\\n } [username] | +| logInjectionBad.js:82:30:82:37 | username | semmle.label | username | +| logInjectionBad.js:87:5:94:5 | functio ... ;\\n } [username] | semmle.label | functio ... ;\\n } [username] | +| logInjectionBad.js:91:26:91:33 | username | semmle.label | username | +| logInjectionBad.js:96:5:103:5 | functio ... ;\\n } [username] | semmle.label | functio ... ;\\n } [username] | +| logInjectionBad.js:99:26:99:33 | username | semmle.label | username | +| logInjectionBad.js:105:5:118:5 | functio ... ;\\n } [username] | semmle.label | functio ... ;\\n } [username] | +| logInjectionBad.js:113:37:113:44 | username | semmle.label | username | +subpaths +| logInjectionBad.js:28:24:28:31 | username | logInjectionBad.js:7:25:7:32 | username | logInjectionBad.js:8:38:8:45 | username | logInjectionBad.js:28:9:28:32 | exceptional return of check_u ... ername) | #select | logInjectionBad.js:22:18:22:43 | `[INFO] ... rname}` | logInjectionBad.js:19:23:19:29 | req.url | logInjectionBad.js:22:18:22:43 | `[INFO] ... rname}` | Log entry depends on a $@. | logInjectionBad.js:19:23:19:29 | req.url | user-provided value | | logInjectionBad.js:23:37:23:44 | username | logInjectionBad.js:19:23:19:29 | req.url | logInjectionBad.js:23:37:23:44 | username | Log entry depends on a $@. | logInjectionBad.js:19:23:19:29 | req.url | user-provided value | From 7a1aead83185c97759ef80dc1ba3ab065975e8a3 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 22:12:06 +0200 Subject: [PATCH 064/514] JS: Port ZipSlip --- .../security/dataflow/ZipSlipQuery.qll | 36 ++++- javascript/ql/src/Security/CWE-022/ZipSlip.ql | 6 +- .../Security/CWE-022/ZipSlip/ZipSlip.expected | 136 ++++-------------- 3 files changed, 61 insertions(+), 117 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ZipSlipQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ZipSlipQuery.qll index 9aad934759d..87da9d2b325 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ZipSlipQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ZipSlipQuery.qll @@ -20,7 +20,39 @@ private class ConcreteSplitPath extends TaintedPath::Label::SplitPath { } /** A taint tracking configuration for unsafe archive extraction. */ -class Configuration extends DataFlow::Configuration { +module ZipSlipConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; + + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { + label = source.(Source).getAFlowLabel() + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { + label = sink.(Sink).getAFlowLabel() + } + + predicate isBarrier(DataFlow::Node node) { + node instanceof TaintedPath::Sanitizer or + node = DataFlow::MakeBarrierGuard::getABarrierNode() + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel label) { + node = DataFlow::MakeLabeledBarrierGuard::getABarrierNode(label) + } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowLabel state1, DataFlow::Node node2, + DataFlow::FlowLabel state2 + ) { + TaintedPath::isAdditionalTaintedPathFlowStep(node1, node2, state1, state2) + } +} + +/** A taint tracking configuration for unsafe archive extraction. */ +module ZipSlipFlow = DataFlow::GlobalWithState; + +/** A taint tracking configuration for unsafe archive extraction. */ +deprecated class Configuration extends DataFlow::Configuration { Configuration() { this = "ZipSlip" } override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { @@ -44,6 +76,6 @@ class Configuration extends DataFlow::Configuration { DataFlow::Node src, DataFlow::Node dst, DataFlow::FlowLabel srclabel, DataFlow::FlowLabel dstlabel ) { - TaintedPath::isAdditionalTaintedPathFlowStep(src, dst, srclabel, dstlabel) + ZipSlipConfig::isAdditionalFlowStep(src, srclabel, dst, dstlabel) } } diff --git a/javascript/ql/src/Security/CWE-022/ZipSlip.ql b/javascript/ql/src/Security/CWE-022/ZipSlip.ql index aef13830eb1..e2f13d0e1f6 100644 --- a/javascript/ql/src/Security/CWE-022/ZipSlip.ql +++ b/javascript/ql/src/Security/CWE-022/ZipSlip.ql @@ -14,10 +14,10 @@ import javascript import semmle.javascript.security.dataflow.ZipSlipQuery -import DataFlow::PathGraph +import DataFlow::DeduplicatePathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from PathNode source, PathNode sink +where ZipSlipFlow::flowPath(source.getAnOriginalPathNode(), sink.getAnOriginalPathNode()) select source.getNode(), source, sink, "Unsanitized archive entry, which may contain '..', is used in a $@.", sink.getNode(), "file system operation" diff --git a/javascript/ql/test/query-tests/Security/CWE-022/ZipSlip/ZipSlip.expected b/javascript/ql/test/query-tests/Security/CWE-022/ZipSlip/ZipSlip.expected index 253bca10b03..9b147acdd88 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/ZipSlip/ZipSlip.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/ZipSlip/ZipSlip.expected @@ -1,130 +1,42 @@ nodes -| AdmZipBad.js:6:24:6:41 | zipEntry.entryName | -| AdmZipBad.js:6:24:6:41 | zipEntry.entryName | -| AdmZipBad.js:6:24:6:41 | zipEntry.entryName | -| AdmZipBad.js:6:24:6:41 | zipEntry.entryName | -| TarSlipBad.js:6:36:6:46 | header.name | -| TarSlipBad.js:6:36:6:46 | header.name | -| TarSlipBad.js:6:36:6:46 | header.name | -| TarSlipBad.js:6:36:6:46 | header.name | -| TarSlipBad.js:9:17:9:31 | header.linkname | -| TarSlipBad.js:9:17:9:31 | header.linkname | -| TarSlipBad.js:9:17:9:31 | header.linkname | -| TarSlipBad.js:9:17:9:31 | header.linkname | -| ZipSlipBad2.js:5:9:5:46 | fileName | -| ZipSlipBad2.js:5:9:5:46 | fileName | -| ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | -| ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | -| ZipSlipBad2.js:5:37:5:46 | entry.path | -| ZipSlipBad2.js:5:37:5:46 | entry.path | -| ZipSlipBad2.js:5:37:5:46 | entry.path | -| ZipSlipBad2.js:6:22:6:29 | fileName | -| ZipSlipBad2.js:6:22:6:29 | fileName | -| ZipSlipBad2.js:6:22:6:29 | fileName | -| ZipSlipBad.js:7:11:7:31 | fileName | -| ZipSlipBad.js:7:11:7:31 | fileName | -| ZipSlipBad.js:7:22:7:31 | entry.path | -| ZipSlipBad.js:7:22:7:31 | entry.path | -| ZipSlipBad.js:7:22:7:31 | entry.path | -| ZipSlipBad.js:8:37:8:44 | fileName | -| ZipSlipBad.js:8:37:8:44 | fileName | -| ZipSlipBad.js:8:37:8:44 | fileName | -| ZipSlipBad.js:15:11:15:31 | fileName | -| ZipSlipBad.js:15:11:15:31 | fileName | -| ZipSlipBad.js:15:22:15:31 | entry.path | -| ZipSlipBad.js:15:22:15:31 | entry.path | -| ZipSlipBad.js:15:22:15:31 | entry.path | -| ZipSlipBad.js:16:30:16:37 | fileName | -| ZipSlipBad.js:16:30:16:37 | fileName | -| ZipSlipBad.js:16:30:16:37 | fileName | -| ZipSlipBad.js:22:11:22:31 | fileName | -| ZipSlipBad.js:22:11:22:31 | fileName | -| ZipSlipBad.js:22:22:22:31 | entry.path | -| ZipSlipBad.js:22:22:22:31 | entry.path | -| ZipSlipBad.js:22:22:22:31 | entry.path | -| ZipSlipBad.js:23:28:23:35 | fileName | -| ZipSlipBad.js:23:28:23:35 | fileName | -| ZipSlipBad.js:23:28:23:35 | fileName | -| ZipSlipBad.js:30:14:30:17 | name | -| ZipSlipBad.js:30:14:30:17 | name | -| ZipSlipBad.js:30:14:30:17 | name | -| ZipSlipBad.js:31:26:31:29 | name | -| ZipSlipBad.js:31:26:31:29 | name | -| ZipSlipBad.js:31:26:31:29 | name | -| ZipSlipBad.js:34:16:34:19 | name | -| ZipSlipBad.js:34:16:34:19 | name | -| ZipSlipBad.js:34:16:34:19 | name | -| ZipSlipBad.js:35:26:35:29 | name | -| ZipSlipBad.js:35:26:35:29 | name | -| ZipSlipBad.js:35:26:35:29 | name | -| ZipSlipBadUnzipper.js:7:9:7:29 | fileName | -| ZipSlipBadUnzipper.js:7:9:7:29 | fileName | -| ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | -| ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | -| ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | -| ZipSlipBadUnzipper.js:8:37:8:44 | fileName | -| ZipSlipBadUnzipper.js:8:37:8:44 | fileName | -| ZipSlipBadUnzipper.js:8:37:8:44 | fileName | +| AdmZipBad.js:6:24:6:41 | zipEntry.entryName | semmle.label | zipEntry.entryName | +| TarSlipBad.js:6:36:6:46 | header.name | semmle.label | header.name | +| TarSlipBad.js:9:17:9:31 | header.linkname | semmle.label | header.linkname | +| ZipSlipBad2.js:5:9:5:46 | fileName | semmle.label | fileName | +| ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | semmle.label | 'output ... ry.path | +| ZipSlipBad2.js:5:37:5:46 | entry.path | semmle.label | entry.path | +| ZipSlipBad2.js:6:22:6:29 | fileName | semmle.label | fileName | +| ZipSlipBad.js:7:11:7:31 | fileName | semmle.label | fileName | +| ZipSlipBad.js:7:22:7:31 | entry.path | semmle.label | entry.path | +| ZipSlipBad.js:8:37:8:44 | fileName | semmle.label | fileName | +| ZipSlipBad.js:15:11:15:31 | fileName | semmle.label | fileName | +| ZipSlipBad.js:15:22:15:31 | entry.path | semmle.label | entry.path | +| ZipSlipBad.js:16:30:16:37 | fileName | semmle.label | fileName | +| ZipSlipBad.js:22:11:22:31 | fileName | semmle.label | fileName | +| ZipSlipBad.js:22:22:22:31 | entry.path | semmle.label | entry.path | +| ZipSlipBad.js:23:28:23:35 | fileName | semmle.label | fileName | +| ZipSlipBad.js:30:14:30:17 | name | semmle.label | name | +| ZipSlipBad.js:31:26:31:29 | name | semmle.label | name | +| ZipSlipBad.js:34:16:34:19 | name | semmle.label | name | +| ZipSlipBad.js:35:26:35:29 | name | semmle.label | name | +| ZipSlipBadUnzipper.js:7:9:7:29 | fileName | semmle.label | fileName | +| ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | semmle.label | entry.path | +| ZipSlipBadUnzipper.js:8:37:8:44 | fileName | semmle.label | fileName | edges -| AdmZipBad.js:6:24:6:41 | zipEntry.entryName | AdmZipBad.js:6:24:6:41 | zipEntry.entryName | -| TarSlipBad.js:6:36:6:46 | header.name | TarSlipBad.js:6:36:6:46 | header.name | -| TarSlipBad.js:9:17:9:31 | header.linkname | TarSlipBad.js:9:17:9:31 | header.linkname | -| ZipSlipBad2.js:5:9:5:46 | fileName | ZipSlipBad2.js:6:22:6:29 | fileName | -| ZipSlipBad2.js:5:9:5:46 | fileName | ZipSlipBad2.js:6:22:6:29 | fileName | -| ZipSlipBad2.js:5:9:5:46 | fileName | ZipSlipBad2.js:6:22:6:29 | fileName | | ZipSlipBad2.js:5:9:5:46 | fileName | ZipSlipBad2.js:6:22:6:29 | fileName | | ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | ZipSlipBad2.js:5:9:5:46 | fileName | -| ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | ZipSlipBad2.js:5:9:5:46 | fileName | -| ZipSlipBad2.js:5:37:5:46 | entry.path | ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | -| ZipSlipBad2.js:5:37:5:46 | entry.path | ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | -| ZipSlipBad2.js:5:37:5:46 | entry.path | ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | | ZipSlipBad2.js:5:37:5:46 | entry.path | ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | | ZipSlipBad.js:7:11:7:31 | fileName | ZipSlipBad.js:8:37:8:44 | fileName | -| ZipSlipBad.js:7:11:7:31 | fileName | ZipSlipBad.js:8:37:8:44 | fileName | -| ZipSlipBad.js:7:11:7:31 | fileName | ZipSlipBad.js:8:37:8:44 | fileName | -| ZipSlipBad.js:7:11:7:31 | fileName | ZipSlipBad.js:8:37:8:44 | fileName | -| ZipSlipBad.js:7:22:7:31 | entry.path | ZipSlipBad.js:7:11:7:31 | fileName | -| ZipSlipBad.js:7:22:7:31 | entry.path | ZipSlipBad.js:7:11:7:31 | fileName | -| ZipSlipBad.js:7:22:7:31 | entry.path | ZipSlipBad.js:7:11:7:31 | fileName | | ZipSlipBad.js:7:22:7:31 | entry.path | ZipSlipBad.js:7:11:7:31 | fileName | | ZipSlipBad.js:15:11:15:31 | fileName | ZipSlipBad.js:16:30:16:37 | fileName | -| ZipSlipBad.js:15:11:15:31 | fileName | ZipSlipBad.js:16:30:16:37 | fileName | -| ZipSlipBad.js:15:11:15:31 | fileName | ZipSlipBad.js:16:30:16:37 | fileName | -| ZipSlipBad.js:15:11:15:31 | fileName | ZipSlipBad.js:16:30:16:37 | fileName | -| ZipSlipBad.js:15:22:15:31 | entry.path | ZipSlipBad.js:15:11:15:31 | fileName | -| ZipSlipBad.js:15:22:15:31 | entry.path | ZipSlipBad.js:15:11:15:31 | fileName | -| ZipSlipBad.js:15:22:15:31 | entry.path | ZipSlipBad.js:15:11:15:31 | fileName | | ZipSlipBad.js:15:22:15:31 | entry.path | ZipSlipBad.js:15:11:15:31 | fileName | | ZipSlipBad.js:22:11:22:31 | fileName | ZipSlipBad.js:23:28:23:35 | fileName | -| ZipSlipBad.js:22:11:22:31 | fileName | ZipSlipBad.js:23:28:23:35 | fileName | -| ZipSlipBad.js:22:11:22:31 | fileName | ZipSlipBad.js:23:28:23:35 | fileName | -| ZipSlipBad.js:22:11:22:31 | fileName | ZipSlipBad.js:23:28:23:35 | fileName | -| ZipSlipBad.js:22:22:22:31 | entry.path | ZipSlipBad.js:22:11:22:31 | fileName | -| ZipSlipBad.js:22:22:22:31 | entry.path | ZipSlipBad.js:22:11:22:31 | fileName | -| ZipSlipBad.js:22:22:22:31 | entry.path | ZipSlipBad.js:22:11:22:31 | fileName | | ZipSlipBad.js:22:22:22:31 | entry.path | ZipSlipBad.js:22:11:22:31 | fileName | | ZipSlipBad.js:30:14:30:17 | name | ZipSlipBad.js:31:26:31:29 | name | -| ZipSlipBad.js:30:14:30:17 | name | ZipSlipBad.js:31:26:31:29 | name | -| ZipSlipBad.js:30:14:30:17 | name | ZipSlipBad.js:31:26:31:29 | name | -| ZipSlipBad.js:30:14:30:17 | name | ZipSlipBad.js:31:26:31:29 | name | -| ZipSlipBad.js:30:14:30:17 | name | ZipSlipBad.js:31:26:31:29 | name | -| ZipSlipBad.js:30:14:30:17 | name | ZipSlipBad.js:31:26:31:29 | name | -| ZipSlipBad.js:30:14:30:17 | name | ZipSlipBad.js:31:26:31:29 | name | -| ZipSlipBad.js:34:16:34:19 | name | ZipSlipBad.js:35:26:35:29 | name | -| ZipSlipBad.js:34:16:34:19 | name | ZipSlipBad.js:35:26:35:29 | name | -| ZipSlipBad.js:34:16:34:19 | name | ZipSlipBad.js:35:26:35:29 | name | -| ZipSlipBad.js:34:16:34:19 | name | ZipSlipBad.js:35:26:35:29 | name | -| ZipSlipBad.js:34:16:34:19 | name | ZipSlipBad.js:35:26:35:29 | name | -| ZipSlipBad.js:34:16:34:19 | name | ZipSlipBad.js:35:26:35:29 | name | | ZipSlipBad.js:34:16:34:19 | name | ZipSlipBad.js:35:26:35:29 | name | | ZipSlipBadUnzipper.js:7:9:7:29 | fileName | ZipSlipBadUnzipper.js:8:37:8:44 | fileName | -| ZipSlipBadUnzipper.js:7:9:7:29 | fileName | ZipSlipBadUnzipper.js:8:37:8:44 | fileName | -| ZipSlipBadUnzipper.js:7:9:7:29 | fileName | ZipSlipBadUnzipper.js:8:37:8:44 | fileName | -| ZipSlipBadUnzipper.js:7:9:7:29 | fileName | ZipSlipBadUnzipper.js:8:37:8:44 | fileName | -| ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | ZipSlipBadUnzipper.js:7:9:7:29 | fileName | -| ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | ZipSlipBadUnzipper.js:7:9:7:29 | fileName | -| ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | ZipSlipBadUnzipper.js:7:9:7:29 | fileName | | ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | ZipSlipBadUnzipper.js:7:9:7:29 | fileName | +subpaths #select | AdmZipBad.js:6:24:6:41 | zipEntry.entryName | AdmZipBad.js:6:24:6:41 | zipEntry.entryName | AdmZipBad.js:6:24:6:41 | zipEntry.entryName | Unsanitized archive entry, which may contain '..', is used in a $@. | AdmZipBad.js:6:24:6:41 | zipEntry.entryName | file system operation | | TarSlipBad.js:6:36:6:46 | header.name | TarSlipBad.js:6:36:6:46 | header.name | TarSlipBad.js:6:36:6:46 | header.name | Unsanitized archive entry, which may contain '..', is used in a $@. | TarSlipBad.js:6:36:6:46 | header.name | file system operation | From 395f52303c81cf82641fbdbf049847e5b9ce358c Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:08:56 +0200 Subject: [PATCH 065/514] JS: Port barriers in UrlConcatenation.qll --- .../javascript/security/dataflow/UrlConcatenation.qll | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UrlConcatenation.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UrlConcatenation.qll index fe036872ee3..4fc434bf178 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UrlConcatenation.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UrlConcatenation.qll @@ -103,8 +103,16 @@ predicate hostnameSanitizingPrefixEdge(DataFlow::Node source, DataFlow::Node sin class HostnameSanitizerGuard extends TaintTracking::SanitizerGuardNode, StringOps::StartsWith { HostnameSanitizerGuard() { hasHostnameSanitizingSubstring(this.getSubstring()) } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + /** Holds if this node blocks flow through `e`, provided it evaluates to `outcome`. */ + predicate blocksExpr(boolean outcome, Expr e) { outcome = this.getPolarity() and e = this.getBaseString().asExpr() } } + +/** + * A check that sanitizes the hostname of a URL. + */ +module HostnameSanitizerGuard = DataFlow::MakeBarrierGuard; From 85617c292e14233d8255bc82350f2dd2554c9dbf Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:12:29 +0200 Subject: [PATCH 066/514] JS: Port BrokenCryptoAlgorithm --- .../dataflow/BrokenCryptoAlgorithmQuery.qll | 18 ++++++++++- .../Security/CWE-327/BrokenCryptoAlgorithm.ql | 6 ++-- .../CWE-327/BrokenCryptoAlgorithm.expected | 31 +++++-------------- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/BrokenCryptoAlgorithmQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/BrokenCryptoAlgorithmQuery.qll index d0e4d56f630..90fb4b4ffa5 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/BrokenCryptoAlgorithmQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/BrokenCryptoAlgorithmQuery.qll @@ -19,7 +19,23 @@ import BrokenCryptoAlgorithmCustomizations::BrokenCryptoAlgorithm * added either by extending the relevant class, or by subclassing this configuration itself, * and amending the sources and sinks. */ -class Configuration extends TaintTracking::Configuration { +module BrokenCryptoAlgorithmConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint tracking flow for sensitive information in broken or weak cryptographic algorithms. + */ +module BrokenCryptoAlgorithmFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `BrokenCryptoAlgorithmFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "BrokenCryptoAlgorithm" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql b/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql index 9826ebefe5f..755effd3113 100644 --- a/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql +++ b/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql @@ -14,11 +14,11 @@ import javascript import semmle.javascript.security.dataflow.BrokenCryptoAlgorithmQuery import semmle.javascript.security.SensitiveActions -import DataFlow::PathGraph +import BrokenCryptoAlgorithmFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink +from BrokenCryptoAlgorithmFlow::PathNode source, BrokenCryptoAlgorithmFlow::PathNode sink where - cfg.hasFlowPath(source, sink) and + BrokenCryptoAlgorithmFlow::flowPath(source, sink) and not source.getNode() instanceof CleartextPasswordExpr // flagged by js/insufficient-password-hash select sink.getNode(), source, sink, "A broken or weak cryptographic algorithm depends on $@.", source.getNode(), "sensitive data from " + source.getNode().(Source).describe() diff --git a/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected b/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected index 1938b020355..b565021866b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected +++ b/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected @@ -1,30 +1,15 @@ -nodes -| tst.js:3:5:3:24 | secretText | -| tst.js:3:18:3:24 | trusted | -| tst.js:3:18:3:24 | trusted | -| tst.js:11:17:11:26 | secretText | -| tst.js:11:17:11:26 | secretText | -| tst.js:11:17:11:26 | secretText | -| tst.js:17:17:17:25 | o.trusted | -| tst.js:17:17:17:25 | o.trusted | -| tst.js:17:17:17:25 | o.trusted | -| tst.js:19:17:19:24 | password | -| tst.js:19:17:19:24 | password | -| tst.js:19:17:19:24 | password | -| tst.js:22:21:22:30 | secretText | -| tst.js:22:21:22:30 | secretText | -| tst.js:22:21:22:30 | secretText | edges | tst.js:3:5:3:24 | secretText | tst.js:11:17:11:26 | secretText | -| tst.js:3:5:3:24 | secretText | tst.js:11:17:11:26 | secretText | -| tst.js:3:5:3:24 | secretText | tst.js:22:21:22:30 | secretText | | tst.js:3:5:3:24 | secretText | tst.js:22:21:22:30 | secretText | | tst.js:3:18:3:24 | trusted | tst.js:3:5:3:24 | secretText | -| tst.js:3:18:3:24 | trusted | tst.js:3:5:3:24 | secretText | -| tst.js:11:17:11:26 | secretText | tst.js:11:17:11:26 | secretText | -| tst.js:17:17:17:25 | o.trusted | tst.js:17:17:17:25 | o.trusted | -| tst.js:19:17:19:24 | password | tst.js:19:17:19:24 | password | -| tst.js:22:21:22:30 | secretText | tst.js:22:21:22:30 | secretText | +nodes +| tst.js:3:5:3:24 | secretText | semmle.label | secretText | +| tst.js:3:18:3:24 | trusted | semmle.label | trusted | +| tst.js:11:17:11:26 | secretText | semmle.label | secretText | +| tst.js:17:17:17:25 | o.trusted | semmle.label | o.trusted | +| tst.js:19:17:19:24 | password | semmle.label | password | +| tst.js:22:21:22:30 | secretText | semmle.label | secretText | +subpaths #select | tst.js:11:17:11:26 | secretText | tst.js:3:18:3:24 | trusted | tst.js:11:17:11:26 | secretText | A broken or weak cryptographic algorithm depends on $@. | tst.js:3:18:3:24 | trusted | sensitive data from an access to trusted | | tst.js:11:17:11:26 | secretText | tst.js:11:17:11:26 | secretText | tst.js:11:17:11:26 | secretText | A broken or weak cryptographic algorithm depends on $@. | tst.js:11:17:11:26 | secretText | sensitive data from an access to secretText | From 2296a273c4932047576a235bd83e3bb0fb3c5be0 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:12:49 +0200 Subject: [PATCH 067/514] JS: Port BuildArtifactLeak --- .../dataflow/BuildArtifactLeakQuery.qll | 28 ++++- .../src/Security/CWE-312/BuildArtifactLeak.ql | 6 +- .../CWE-312/BuildArtifactLeak.expected | 108 +++++++++--------- 3 files changed, 82 insertions(+), 60 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/BuildArtifactLeakQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/BuildArtifactLeakQuery.qll index db48ae25952..0e010e35eeb 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/BuildArtifactLeakQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/BuildArtifactLeakQuery.qll @@ -14,7 +14,33 @@ import CleartextLoggingCustomizations::CleartextLogging as CleartextLogging /** * A taint tracking configuration for storage of sensitive information in build artifact. */ -class Configuration extends TaintTracking::Configuration { +module BuildArtifactLeakConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof CleartextLogging::Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof CleartextLogging::Barrier } + + predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg) { + CleartextLogging::isAdditionalTaintStep(src, trg) + } + + predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet contents) { + // All properties of a leaked object are themselves leaked. + contents = DataFlow::ContentSet::anyProperty() and + isSink(node) + } +} + +/** + * Taint tracking flow for storage of sensitive information in build artifact. + */ +module BuildArtifactLeakFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `BuildArtifactLeakFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "BuildArtifactLeak" } override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel lbl) { diff --git a/javascript/ql/src/Security/CWE-312/BuildArtifactLeak.ql b/javascript/ql/src/Security/CWE-312/BuildArtifactLeak.ql index 0e61cc1ebf2..79d2d4d41ed 100644 --- a/javascript/ql/src/Security/CWE-312/BuildArtifactLeak.ql +++ b/javascript/ql/src/Security/CWE-312/BuildArtifactLeak.ql @@ -15,10 +15,10 @@ import javascript import semmle.javascript.security.dataflow.BuildArtifactLeakQuery -import DataFlow::PathGraph +import BuildArtifactLeakFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from BuildArtifactLeakFlow::PathNode source, BuildArtifactLeakFlow::PathNode sink +where BuildArtifactLeakFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This creates a build artifact that depends on $@.", source.getNode(), "sensitive data returned by" + source.getNode().(CleartextLogging::Source).describe() diff --git a/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected b/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected index 8514ae58104..973b7da8555 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected @@ -1,67 +1,63 @@ -nodes -| build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | -| build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | -| build-leaks.js:5:20:5:46 | JSON.st ... ss.env) | -| build-leaks.js:5:35:5:45 | process.env | -| build-leaks.js:5:35:5:45 | process.env | -| build-leaks.js:13:11:19:10 | raw | -| build-leaks.js:13:17:19:10 | Object. ... }) | -| build-leaks.js:14:18:14:20 | env | -| build-leaks.js:15:24:15:34 | process.env | -| build-leaks.js:15:24:15:34 | process.env | -| build-leaks.js:15:24:15:39 | process.env[key] | -| build-leaks.js:16:20:16:22 | env | -| build-leaks.js:21:11:26:5 | stringifed | -| build-leaks.js:21:24:26:5 | {\\n ... )\\n } | -| build-leaks.js:22:24:25:14 | Object. ... }, {}) | -| build-leaks.js:22:49:22:51 | env | -| build-leaks.js:23:24:23:47 | JSON.st ... w[key]) | -| build-leaks.js:23:39:23:41 | raw | -| build-leaks.js:23:39:23:46 | raw[key] | -| build-leaks.js:24:20:24:22 | env | -| build-leaks.js:30:22:30:31 | stringifed | -| build-leaks.js:34:26:34:57 | getEnv( ... ngified | -| build-leaks.js:34:26:34:57 | getEnv( ... ngified | -| build-leaks.js:40:9:40:60 | pw | -| build-leaks.js:40:14:40:60 | url.par ... assword | -| build-leaks.js:40:14:40:60 | url.par ... assword | -| build-leaks.js:41:43:41:86 | { "proc ... y(pw) } | -| build-leaks.js:41:43:41:86 | { "proc ... y(pw) } | -| build-leaks.js:41:67:41:84 | JSON.stringify(pw) | -| build-leaks.js:41:82:41:83 | pw | edges -| build-leaks.js:5:20:5:46 | JSON.st ... ss.env) | build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | -| build-leaks.js:5:20:5:46 | JSON.st ... ss.env) | build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | +| build-leaks.js:4:39:6:1 | [post update] { // NO ... .env)\\n} [process.env] | build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | +| build-leaks.js:5:20:5:46 | JSON.st ... ss.env) | build-leaks.js:4:39:6:1 | [post update] { // NO ... .env)\\n} [process.env] | | build-leaks.js:5:35:5:45 | process.env | build-leaks.js:5:20:5:46 | JSON.st ... ss.env) | -| build-leaks.js:5:35:5:45 | process.env | build-leaks.js:5:20:5:46 | JSON.st ... ss.env) | -| build-leaks.js:13:11:19:10 | raw | build-leaks.js:23:39:23:41 | raw | +| build-leaks.js:13:11:19:10 | raw | build-leaks.js:22:36:22:38 | raw | | build-leaks.js:13:17:19:10 | Object. ... }) | build-leaks.js:13:11:19:10 | raw | | build-leaks.js:14:18:14:20 | env | build-leaks.js:16:20:16:22 | env | -| build-leaks.js:15:24:15:34 | process.env | build-leaks.js:14:18:14:20 | env | -| build-leaks.js:15:24:15:34 | process.env | build-leaks.js:14:18:14:20 | env | -| build-leaks.js:15:24:15:34 | process.env | build-leaks.js:15:24:15:39 | process.env[key] | -| build-leaks.js:15:24:15:34 | process.env | build-leaks.js:15:24:15:39 | process.env[key] | -| build-leaks.js:15:24:15:39 | process.env[key] | build-leaks.js:14:18:14:20 | env | +| build-leaks.js:15:13:15:15 | [post update] env | build-leaks.js:14:18:14:20 | env | +| build-leaks.js:15:13:15:15 | [post update] env | build-leaks.js:17:12:19:9 | [post update] {\\n ... } | +| build-leaks.js:15:24:15:34 | process.env | build-leaks.js:15:13:15:15 | [post update] env | | build-leaks.js:16:20:16:22 | env | build-leaks.js:13:17:19:10 | Object. ... }) | -| build-leaks.js:16:20:16:22 | env | build-leaks.js:14:18:14:20 | env | -| build-leaks.js:21:11:26:5 | stringifed | build-leaks.js:30:22:30:31 | stringifed | -| build-leaks.js:21:24:26:5 | {\\n ... )\\n } | build-leaks.js:21:11:26:5 | stringifed | -| build-leaks.js:22:24:25:14 | Object. ... }, {}) | build-leaks.js:21:24:26:5 | {\\n ... )\\n } | -| build-leaks.js:22:49:22:51 | env | build-leaks.js:24:20:24:22 | env | -| build-leaks.js:23:24:23:47 | JSON.st ... w[key]) | build-leaks.js:22:49:22:51 | env | -| build-leaks.js:23:39:23:41 | raw | build-leaks.js:22:49:22:51 | env | -| build-leaks.js:23:39:23:41 | raw | build-leaks.js:23:39:23:46 | raw[key] | -| build-leaks.js:23:39:23:46 | raw[key] | build-leaks.js:23:24:23:47 | JSON.st ... w[key]) | -| build-leaks.js:24:20:24:22 | env | build-leaks.js:22:24:25:14 | Object. ... }, {}) | -| build-leaks.js:24:20:24:22 | env | build-leaks.js:22:49:22:51 | env | -| build-leaks.js:30:22:30:31 | stringifed | build-leaks.js:34:26:34:57 | getEnv( ... ngified | -| build-leaks.js:30:22:30:31 | stringifed | build-leaks.js:34:26:34:57 | getEnv( ... ngified | +| build-leaks.js:17:12:19:9 | [post update] {\\n ... } | build-leaks.js:17:12:19:9 | {\\n ... } | +| build-leaks.js:17:12:19:9 | {\\n ... } | build-leaks.js:13:17:19:10 | Object. ... }) | +| build-leaks.js:21:11:26:5 | stringifed [process.env] | build-leaks.js:30:22:30:31 | stringifed [process.env] | +| build-leaks.js:21:24:26:5 | {\\n ... )\\n } [process.env] | build-leaks.js:21:11:26:5 | stringifed [process.env] | +| build-leaks.js:22:24:25:14 | Object. ... }, {}) | build-leaks.js:21:24:26:5 | {\\n ... )\\n } [process.env] | +| build-leaks.js:22:36:22:38 | raw | build-leaks.js:22:24:25:14 | Object. ... }, {}) | +| build-leaks.js:22:36:22:38 | raw | build-leaks.js:25:12:25:13 | [post update] {} | +| build-leaks.js:25:12:25:13 | [post update] {} | build-leaks.js:25:12:25:13 | {} | +| build-leaks.js:25:12:25:13 | {} | build-leaks.js:22:24:25:14 | Object. ... }, {}) | +| build-leaks.js:28:12:31:5 | {\\n ... d\\n } [stringified, process.env] | build-leaks.js:34:26:34:45 | getEnv('production') [stringified, process.env] | +| build-leaks.js:30:22:30:31 | stringifed [process.env] | build-leaks.js:28:12:31:5 | {\\n ... d\\n } [stringified, process.env] | +| build-leaks.js:34:26:34:45 | getEnv('production') [stringified, process.env] | build-leaks.js:34:26:34:57 | getEnv( ... ngified [process.env] | +| build-leaks.js:34:26:34:57 | getEnv( ... ngified [process.env] | build-leaks.js:34:26:34:57 | getEnv( ... ngified | | build-leaks.js:40:9:40:60 | pw | build-leaks.js:41:82:41:83 | pw | | build-leaks.js:40:14:40:60 | url.par ... assword | build-leaks.js:40:9:40:60 | pw | -| build-leaks.js:40:14:40:60 | url.par ... assword | build-leaks.js:40:9:40:60 | pw | -| build-leaks.js:41:67:41:84 | JSON.stringify(pw) | build-leaks.js:41:43:41:86 | { "proc ... y(pw) } | -| build-leaks.js:41:67:41:84 | JSON.stringify(pw) | build-leaks.js:41:43:41:86 | { "proc ... y(pw) } | +| build-leaks.js:41:43:41:86 | [post update] { "proc ... y(pw) } [process.env.secret] | build-leaks.js:41:43:41:86 | { "proc ... y(pw) } | +| build-leaks.js:41:67:41:84 | JSON.stringify(pw) | build-leaks.js:41:43:41:86 | [post update] { "proc ... y(pw) } [process.env.secret] | | build-leaks.js:41:82:41:83 | pw | build-leaks.js:41:67:41:84 | JSON.stringify(pw) | +nodes +| build-leaks.js:4:39:6:1 | [post update] { // NO ... .env)\\n} [process.env] | semmle.label | [post update] { // NO ... .env)\\n} [process.env] | +| build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | semmle.label | { // NO ... .env)\\n} | +| build-leaks.js:5:20:5:46 | JSON.st ... ss.env) | semmle.label | JSON.st ... ss.env) | +| build-leaks.js:5:35:5:45 | process.env | semmle.label | process.env | +| build-leaks.js:13:11:19:10 | raw | semmle.label | raw | +| build-leaks.js:13:17:19:10 | Object. ... }) | semmle.label | Object. ... }) | +| build-leaks.js:14:18:14:20 | env | semmle.label | env | +| build-leaks.js:15:13:15:15 | [post update] env | semmle.label | [post update] env | +| build-leaks.js:15:24:15:34 | process.env | semmle.label | process.env | +| build-leaks.js:16:20:16:22 | env | semmle.label | env | +| build-leaks.js:17:12:19:9 | [post update] {\\n ... } | semmle.label | [post update] {\\n ... } | +| build-leaks.js:17:12:19:9 | {\\n ... } | semmle.label | {\\n ... } | +| build-leaks.js:21:11:26:5 | stringifed [process.env] | semmle.label | stringifed [process.env] | +| build-leaks.js:21:24:26:5 | {\\n ... )\\n } [process.env] | semmle.label | {\\n ... )\\n } [process.env] | +| build-leaks.js:22:24:25:14 | Object. ... }, {}) | semmle.label | Object. ... }, {}) | +| build-leaks.js:22:36:22:38 | raw | semmle.label | raw | +| build-leaks.js:25:12:25:13 | [post update] {} | semmle.label | [post update] {} | +| build-leaks.js:25:12:25:13 | {} | semmle.label | {} | +| build-leaks.js:28:12:31:5 | {\\n ... d\\n } [stringified, process.env] | semmle.label | {\\n ... d\\n } [stringified, process.env] | +| build-leaks.js:30:22:30:31 | stringifed [process.env] | semmle.label | stringifed [process.env] | +| build-leaks.js:34:26:34:45 | getEnv('production') [stringified, process.env] | semmle.label | getEnv('production') [stringified, process.env] | +| build-leaks.js:34:26:34:57 | getEnv( ... ngified | semmle.label | getEnv( ... ngified | +| build-leaks.js:34:26:34:57 | getEnv( ... ngified [process.env] | semmle.label | getEnv( ... ngified [process.env] | +| build-leaks.js:40:9:40:60 | pw | semmle.label | pw | +| build-leaks.js:40:14:40:60 | url.par ... assword | semmle.label | url.par ... assword | +| build-leaks.js:41:43:41:86 | [post update] { "proc ... y(pw) } [process.env.secret] | semmle.label | [post update] { "proc ... y(pw) } [process.env.secret] | +| build-leaks.js:41:43:41:86 | { "proc ... y(pw) } | semmle.label | { "proc ... y(pw) } | +| build-leaks.js:41:67:41:84 | JSON.stringify(pw) | semmle.label | JSON.stringify(pw) | +| build-leaks.js:41:82:41:83 | pw | semmle.label | pw | +subpaths #select | build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | build-leaks.js:5:35:5:45 | process.env | build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | This creates a build artifact that depends on $@. | build-leaks.js:5:35:5:45 | process.env | sensitive data returned byprocess environment | | build-leaks.js:34:26:34:57 | getEnv( ... ngified | build-leaks.js:15:24:15:34 | process.env | build-leaks.js:34:26:34:57 | getEnv( ... ngified | This creates a build artifact that depends on $@. | build-leaks.js:15:24:15:34 | process.env | sensitive data returned byprocess environment | From f14303acea4eb19c53bd95cfcb6293ced12645b6 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:13:00 +0200 Subject: [PATCH 068/514] JS: Port ConditionalBypass --- .../dataflow/ConditionalBypassQuery.qll | 90 ++++++++++- .../src/Security/CWE-807/ConditionalBypass.ql | 10 +- .../CWE-807/ConditionalBypass.expected | 144 +++++------------- 3 files changed, 130 insertions(+), 114 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ConditionalBypassQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ConditionalBypassQuery.qll index 0d1319800a8..6482b09a754 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ConditionalBypassQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ConditionalBypassQuery.qll @@ -13,7 +13,28 @@ import ConditionalBypassCustomizations::ConditionalBypass /** * A taint tracking configuration for bypass of sensitive action guards. */ -class Configuration extends TaintTracking::Configuration { +module ConditionalBypassConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node dst) { + // comparing a tainted expression against a constant gives a tainted result + dst.asExpr().(Comparison).hasOperands(src.asExpr(), any(ConstantExpr c)) + } +} + +/** + * Taint tracking flow for bypass of sensitive action guards. + */ +module ConditionalBypassFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `ConditionalBypassFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "ConditionalBypass" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -26,8 +47,7 @@ class Configuration extends TaintTracking::Configuration { } override predicate isAdditionalTaintStep(DataFlow::Node src, DataFlow::Node dst) { - // comparing a tainted expression against a constant gives a tainted result - dst.asExpr().(Comparison).hasOperands(src.asExpr(), any(ConstantExpr c)) + ConditionalBypassConfig::isAdditionalFlowStep(src, dst) } } @@ -72,7 +92,67 @@ class SensitiveActionGuardComparisonOperand extends Sink { * If flow from `source` taints `sink`, then an attacker can * control if `action` should be executed or not. */ -predicate isTaintedGuardForSensitiveAction( +predicate isTaintedGuardNodeForSensitiveAction( + ConditionalBypassFlow::PathNode sink, ConditionalBypassFlow::PathNode source, + SensitiveAction action +) { + action = sink.getNode().(Sink).getAction() and + // exclude the intermediary sink + not sink.getNode() instanceof SensitiveActionGuardComparisonOperand and + ( + // ordinary taint tracking to a guard + ConditionalBypassFlow::flowPath(source, sink) + or + // taint tracking to both operands of a guard comparison + exists( + SensitiveActionGuardComparison cmp, ConditionalBypassFlow::PathNode lSource, + ConditionalBypassFlow::PathNode rSource, ConditionalBypassFlow::PathNode lSink, + ConditionalBypassFlow::PathNode rSink + | + sink.getNode() = cmp.getGuard() and + ConditionalBypassFlow::flowPath(lSource, lSink) and + lSink.getNode() = DataFlow::valueNode(cmp.getLeftOperand()) and + ConditionalBypassFlow::flowPath(rSource, rSink) and + rSink.getNode() = DataFlow::valueNode(cmp.getRightOperand()) + | + source = lSource or + source = rSource + ) + ) +} + +/** + * Holds if `e` effectively guards access to `action` by returning or throwing early. + * + * Example: `if (e) return; action(x)`. + */ +predicate isEarlyAbortGuardNode(ConditionalBypassFlow::PathNode e, SensitiveAction action) { + exists(IfStmt guard | + // `e` is in the condition of an if-statement ... + e.getNode().(Sink).asExpr().getParentExpr*() = guard.getCondition() and + // ... where the then-branch always throws or returns + exists(Stmt abort | + abort instanceof ThrowStmt or + abort instanceof ReturnStmt + | + abort.nestedIn(guard) and + abort.getBasicBlock().(ReachableBasicBlock).postDominates(guard.getThen().getBasicBlock()) + ) and + // ... and the else-branch does not exist + not exists(guard.getElse()) + | + // ... and `action` is outside the if-statement + not action.asExpr().getEnclosingStmt().nestedIn(guard) + ) +} + +/** + * Holds if `sink` guards `action`, and `source` taints `sink`. + * + * If flow from `source` taints `sink`, then an attacker can + * control if `action` should be executed or not. + */ +deprecated predicate isTaintedGuardForSensitiveAction( DataFlow::PathNode sink, DataFlow::PathNode source, SensitiveAction action ) { action = sink.getNode().(Sink).getAction() and @@ -104,7 +184,7 @@ predicate isTaintedGuardForSensitiveAction( * * Example: `if (e) return; action(x)`. */ -predicate isEarlyAbortGuard(DataFlow::PathNode e, SensitiveAction action) { +deprecated predicate isEarlyAbortGuard(DataFlow::PathNode e, SensitiveAction action) { exists(IfStmt guard | // `e` is in the condition of an if-statement ... e.getNode().(Sink).asExpr().getParentExpr*() = guard.getCondition() and diff --git a/javascript/ql/src/Security/CWE-807/ConditionalBypass.ql b/javascript/ql/src/Security/CWE-807/ConditionalBypass.ql index 492dc5b8b6e..a493662453e 100644 --- a/javascript/ql/src/Security/CWE-807/ConditionalBypass.ql +++ b/javascript/ql/src/Security/CWE-807/ConditionalBypass.ql @@ -13,11 +13,13 @@ import javascript import semmle.javascript.security.dataflow.ConditionalBypassQuery -import DataFlow::PathGraph +import ConditionalBypassFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, SensitiveAction action +from + ConditionalBypassFlow::PathNode source, ConditionalBypassFlow::PathNode sink, + SensitiveAction action where - isTaintedGuardForSensitiveAction(sink, source, action) and - not isEarlyAbortGuard(sink, action) + isTaintedGuardNodeForSensitiveAction(sink, source, action) and + not isEarlyAbortGuardNode(sink, action) select sink.getNode(), source, sink, "This condition guards a sensitive $@, but a $@ controls it.", action, "action", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected b/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected index 6f4dcb31bd5..f78e2428b90 100644 --- a/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected +++ b/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected @@ -1,122 +1,56 @@ -nodes -| example_bypass.js:6:9:6:19 | req.cookies | -| example_bypass.js:6:9:6:19 | req.cookies | -| example_bypass.js:6:9:6:34 | req.coo ... nUserId | -| example_bypass.js:6:9:6:34 | req.coo ... nUserId | -| example_bypass.js:6:40:6:56 | req.params.userId | -| example_bypass.js:6:40:6:56 | req.params.userId | -| example_bypass.js:6:40:6:56 | req.params.userId | -| example_bypass.js:17:46:17:62 | req.params.userId | -| example_bypass.js:17:46:17:62 | req.params.userId | -| example_bypass.js:17:46:17:62 | req.params.userId | -| tst.js:9:8:9:26 | req.params.shutDown | -| tst.js:9:8:9:26 | req.params.shutDown | -| tst.js:9:8:9:26 | req.params.shutDown | -| tst.js:13:9:13:19 | req.cookies | -| tst.js:13:9:13:19 | req.cookies | -| tst.js:13:9:13:30 | req.coo ... inThing | -| tst.js:13:9:13:30 | req.coo ... inThing | -| tst.js:27:9:27:37 | v3 | -| tst.js:27:14:27:37 | id(req. ... okieId) | -| tst.js:27:17:27:27 | req.cookies | -| tst.js:27:17:27:27 | req.cookies | -| tst.js:27:17:27:36 | req.cookies.cookieId | -| tst.js:28:9:28:10 | v3 | -| tst.js:28:9:28:10 | v3 | -| tst.js:33:13:33:23 | req.cookies | -| tst.js:33:13:33:23 | req.cookies | -| tst.js:33:13:33:32 | req.cookies.cookieId | -| tst.js:33:13:33:32 | req.cookies.cookieId | -| tst.js:38:9:38:19 | req.cookies | -| tst.js:38:9:38:19 | req.cookies | -| tst.js:38:9:38:28 | req.cookies.cookieId | -| tst.js:38:9:38:28 | req.cookies.cookieId | -| tst.js:44:8:44:23 | req.params.login | -| tst.js:44:8:44:23 | req.params.login | -| tst.js:44:8:44:23 | req.params.login | -| tst.js:57:8:57:23 | req.params.login | -| tst.js:57:8:57:23 | req.params.login | -| tst.js:57:8:57:23 | req.params.login | -| tst.js:61:9:61:19 | req.cookies | -| tst.js:61:9:61:19 | req.cookies | -| tst.js:61:9:61:28 | req.cookies.cookieId | -| tst.js:61:9:61:28 | req.cookies.cookieId | -| tst.js:61:34:61:53 | req.params.requestId | -| tst.js:61:34:61:53 | req.params.requestId | -| tst.js:61:34:61:53 | req.params.requestId | -| tst.js:65:14:65:24 | req.cookies | -| tst.js:65:14:65:24 | req.cookies | -| tst.js:65:14:65:33 | req.cookies.cookieId | -| tst.js:65:14:65:33 | req.cookies.cookieId | -| tst.js:65:39:65:58 | req.params.requestId | -| tst.js:65:39:65:58 | req.params.requestId | -| tst.js:65:39:65:58 | req.params.requestId | -| tst.js:78:9:78:19 | req.cookies | -| tst.js:78:9:78:19 | req.cookies | -| tst.js:78:9:78:28 | req.cookies.cookieId | -| tst.js:78:9:78:28 | req.cookies.cookieId | -| tst.js:78:9:78:41 | req.coo ... secret" | -| tst.js:78:9:78:41 | req.coo ... secret" | -| tst.js:91:10:91:17 | req.body | -| tst.js:91:10:91:17 | req.body | -| tst.js:91:10:91:17 | req.body | -| tst.js:98:13:98:32 | req.query.vulnerable | -| tst.js:98:13:98:32 | req.query.vulnerable | -| tst.js:98:13:98:32 | req.query.vulnerable | -| tst.js:105:13:105:32 | req.query.vulnerable | -| tst.js:105:13:105:32 | req.query.vulnerable | -| tst.js:105:13:105:32 | req.query.vulnerable | -| tst.js:113:13:113:32 | req.query.vulnerable | -| tst.js:113:13:113:32 | req.query.vulnerable | -| tst.js:113:13:113:32 | req.query.vulnerable | edges | example_bypass.js:6:9:6:19 | req.cookies | example_bypass.js:6:9:6:34 | req.coo ... nUserId | -| example_bypass.js:6:9:6:19 | req.cookies | example_bypass.js:6:9:6:34 | req.coo ... nUserId | -| example_bypass.js:6:9:6:19 | req.cookies | example_bypass.js:6:9:6:34 | req.coo ... nUserId | -| example_bypass.js:6:9:6:19 | req.cookies | example_bypass.js:6:9:6:34 | req.coo ... nUserId | -| example_bypass.js:6:40:6:56 | req.params.userId | example_bypass.js:6:40:6:56 | req.params.userId | -| example_bypass.js:17:46:17:62 | req.params.userId | example_bypass.js:17:46:17:62 | req.params.userId | -| tst.js:9:8:9:26 | req.params.shutDown | tst.js:9:8:9:26 | req.params.shutDown | | tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing | -| tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing | -| tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing | -| tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing | -| tst.js:27:9:27:37 | v3 | tst.js:28:9:28:10 | v3 | +| tst.js:24:17:24:17 | v | tst.js:25:16:25:16 | v | | tst.js:27:9:27:37 | v3 | tst.js:28:9:28:10 | v3 | | tst.js:27:14:27:37 | id(req. ... okieId) | tst.js:27:9:27:37 | v3 | | tst.js:27:17:27:27 | req.cookies | tst.js:27:17:27:36 | req.cookies.cookieId | -| tst.js:27:17:27:27 | req.cookies | tst.js:27:17:27:36 | req.cookies.cookieId | +| tst.js:27:17:27:36 | req.cookies.cookieId | tst.js:24:17:24:17 | v | | tst.js:27:17:27:36 | req.cookies.cookieId | tst.js:27:14:27:37 | id(req. ... okieId) | | tst.js:33:13:33:23 | req.cookies | tst.js:33:13:33:32 | req.cookies.cookieId | -| tst.js:33:13:33:23 | req.cookies | tst.js:33:13:33:32 | req.cookies.cookieId | -| tst.js:33:13:33:23 | req.cookies | tst.js:33:13:33:32 | req.cookies.cookieId | -| tst.js:33:13:33:23 | req.cookies | tst.js:33:13:33:32 | req.cookies.cookieId | | tst.js:38:9:38:19 | req.cookies | tst.js:38:9:38:28 | req.cookies.cookieId | -| tst.js:38:9:38:19 | req.cookies | tst.js:38:9:38:28 | req.cookies.cookieId | -| tst.js:38:9:38:19 | req.cookies | tst.js:38:9:38:28 | req.cookies.cookieId | -| tst.js:38:9:38:19 | req.cookies | tst.js:38:9:38:28 | req.cookies.cookieId | -| tst.js:44:8:44:23 | req.params.login | tst.js:44:8:44:23 | req.params.login | -| tst.js:57:8:57:23 | req.params.login | tst.js:57:8:57:23 | req.params.login | | tst.js:61:9:61:19 | req.cookies | tst.js:61:9:61:28 | req.cookies.cookieId | -| tst.js:61:9:61:19 | req.cookies | tst.js:61:9:61:28 | req.cookies.cookieId | -| tst.js:61:9:61:19 | req.cookies | tst.js:61:9:61:28 | req.cookies.cookieId | -| tst.js:61:9:61:19 | req.cookies | tst.js:61:9:61:28 | req.cookies.cookieId | -| tst.js:61:34:61:53 | req.params.requestId | tst.js:61:34:61:53 | req.params.requestId | | tst.js:65:14:65:24 | req.cookies | tst.js:65:14:65:33 | req.cookies.cookieId | -| tst.js:65:14:65:24 | req.cookies | tst.js:65:14:65:33 | req.cookies.cookieId | -| tst.js:65:14:65:24 | req.cookies | tst.js:65:14:65:33 | req.cookies.cookieId | -| tst.js:65:14:65:24 | req.cookies | tst.js:65:14:65:33 | req.cookies.cookieId | -| tst.js:65:39:65:58 | req.params.requestId | tst.js:65:39:65:58 | req.params.requestId | -| tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:28 | req.cookies.cookieId | -| tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:28 | req.cookies.cookieId | | tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:28 | req.cookies.cookieId | | tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:28 | req.cookies.cookieId | | tst.js:78:9:78:28 | req.cookies.cookieId | tst.js:78:9:78:41 | req.coo ... secret" | -| tst.js:78:9:78:28 | req.cookies.cookieId | tst.js:78:9:78:41 | req.coo ... secret" | -| tst.js:91:10:91:17 | req.body | tst.js:91:10:91:17 | req.body | -| tst.js:98:13:98:32 | req.query.vulnerable | tst.js:98:13:98:32 | req.query.vulnerable | -| tst.js:105:13:105:32 | req.query.vulnerable | tst.js:105:13:105:32 | req.query.vulnerable | -| tst.js:113:13:113:32 | req.query.vulnerable | tst.js:113:13:113:32 | req.query.vulnerable | +nodes +| example_bypass.js:6:9:6:19 | req.cookies | semmle.label | req.cookies | +| example_bypass.js:6:9:6:34 | req.coo ... nUserId | semmle.label | req.coo ... nUserId | +| example_bypass.js:6:40:6:56 | req.params.userId | semmle.label | req.params.userId | +| example_bypass.js:17:46:17:62 | req.params.userId | semmle.label | req.params.userId | +| tst.js:9:8:9:26 | req.params.shutDown | semmle.label | req.params.shutDown | +| tst.js:13:9:13:19 | req.cookies | semmle.label | req.cookies | +| tst.js:13:9:13:30 | req.coo ... inThing | semmle.label | req.coo ... inThing | +| tst.js:24:17:24:17 | v | semmle.label | v | +| tst.js:25:16:25:16 | v | semmle.label | v | +| tst.js:27:9:27:37 | v3 | semmle.label | v3 | +| tst.js:27:14:27:37 | id(req. ... okieId) | semmle.label | id(req. ... okieId) | +| tst.js:27:17:27:27 | req.cookies | semmle.label | req.cookies | +| tst.js:27:17:27:36 | req.cookies.cookieId | semmle.label | req.cookies.cookieId | +| tst.js:28:9:28:10 | v3 | semmle.label | v3 | +| tst.js:33:13:33:23 | req.cookies | semmle.label | req.cookies | +| tst.js:33:13:33:32 | req.cookies.cookieId | semmle.label | req.cookies.cookieId | +| tst.js:38:9:38:19 | req.cookies | semmle.label | req.cookies | +| tst.js:38:9:38:28 | req.cookies.cookieId | semmle.label | req.cookies.cookieId | +| tst.js:44:8:44:23 | req.params.login | semmle.label | req.params.login | +| tst.js:57:8:57:23 | req.params.login | semmle.label | req.params.login | +| tst.js:61:9:61:19 | req.cookies | semmle.label | req.cookies | +| tst.js:61:9:61:28 | req.cookies.cookieId | semmle.label | req.cookies.cookieId | +| tst.js:61:34:61:53 | req.params.requestId | semmle.label | req.params.requestId | +| tst.js:65:14:65:24 | req.cookies | semmle.label | req.cookies | +| tst.js:65:14:65:33 | req.cookies.cookieId | semmle.label | req.cookies.cookieId | +| tst.js:65:39:65:58 | req.params.requestId | semmle.label | req.params.requestId | +| tst.js:78:9:78:19 | req.cookies | semmle.label | req.cookies | +| tst.js:78:9:78:28 | req.cookies.cookieId | semmle.label | req.cookies.cookieId | +| tst.js:78:9:78:28 | req.cookies.cookieId | semmle.label | req.cookies.cookieId | +| tst.js:78:9:78:41 | req.coo ... secret" | semmle.label | req.coo ... secret" | +| tst.js:91:10:91:17 | req.body | semmle.label | req.body | +| tst.js:98:13:98:32 | req.query.vulnerable | semmle.label | req.query.vulnerable | +| tst.js:105:13:105:32 | req.query.vulnerable | semmle.label | req.query.vulnerable | +| tst.js:113:13:113:32 | req.query.vulnerable | semmle.label | req.query.vulnerable | +subpaths +| tst.js:27:17:27:36 | req.cookies.cookieId | tst.js:24:17:24:17 | v | tst.js:25:16:25:16 | v | tst.js:27:14:27:37 | id(req. ... okieId) | #select | tst.js:9:8:9:26 | req.params.shutDown | tst.js:9:8:9:26 | req.params.shutDown | tst.js:9:8:9:26 | req.params.shutDown | This condition guards a sensitive $@, but a $@ controls it. | tst.js:10:9:10:22 | process.exit() | action | tst.js:9:8:9:26 | req.params.shutDown | user-provided value | | tst.js:13:9:13:30 | req.coo ... inThing | tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing | This condition guards a sensitive $@, but a $@ controls it. | tst.js:14:9:14:17 | o.login() | action | tst.js:13:9:13:19 | req.cookies | user-provided value | From 30f1fbc10dc2b4edcc10b9b824c9d332c7eaeaef Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:13:42 +0200 Subject: [PATCH 069/514] JS: Port CorsMisconfigurationForCredentials --- ...orsMisconfigurationForCredentialsQuery.qll | 21 ++++++++++++- .../CorsMisconfigurationForCredentials.ql | 6 ++-- ...orsMisconfigurationForCredentials.expected | 31 ++++++------------- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentialsQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentialsQuery.qll index 57cabe0ea79..0be461f5118 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentialsQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentialsQuery.qll @@ -14,7 +14,26 @@ import CorsMisconfigurationForCredentialsCustomizations::CorsMisconfigurationFor /** * A data flow configuration for CORS misconfiguration for credentials transfer. */ -class Configuration extends TaintTracking::Configuration { +module CorsMisconfigurationConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { + node instanceof Sanitizer or + node = TaintTracking::AdHocWhitelistCheckSanitizer::getABarrierNode() + } +} + +/** + * Data flow for CORS misconfiguration for credentials transfer. + */ +module CorsMisconfigurationFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `CorsMisconfigurationFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "CorsMisconfigurationForCredentials" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-346/CorsMisconfigurationForCredentials.ql b/javascript/ql/src/Security/CWE-346/CorsMisconfigurationForCredentials.ql index 279f09f71ba..ac8acac4742 100644 --- a/javascript/ql/src/Security/CWE-346/CorsMisconfigurationForCredentials.ql +++ b/javascript/ql/src/Security/CWE-346/CorsMisconfigurationForCredentials.ql @@ -14,10 +14,10 @@ import javascript import semmle.javascript.security.dataflow.CorsMisconfigurationForCredentialsQuery -import DataFlow::PathGraph +import CorsMisconfigurationFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from CorsMisconfigurationFlow::PathNode source, CorsMisconfigurationFlow::PathNode sink +where CorsMisconfigurationFlow::flowPath(source, sink) select sink.getNode(), source, sink, "$@ leak vulnerability due to a $@.", sink.getNode().(Sink).getCredentialsHeader(), "Credential", source.getNode(), "misconfigured CORS header value" diff --git a/javascript/ql/test/query-tests/Security/CWE-346/CorsMisconfigurationForCredentials.expected b/javascript/ql/test/query-tests/Security/CWE-346/CorsMisconfigurationForCredentials.expected index 83e103f121b..fdbf937e0a2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-346/CorsMisconfigurationForCredentials.expected +++ b/javascript/ql/test/query-tests/Security/CWE-346/CorsMisconfigurationForCredentials.expected @@ -1,28 +1,15 @@ -nodes -| tst.js:12:9:12:54 | origin | -| tst.js:12:18:12:41 | url.par ... , true) | -| tst.js:12:18:12:47 | url.par ... ).query | -| tst.js:12:18:12:54 | url.par ... .origin | -| tst.js:12:28:12:34 | req.url | -| tst.js:12:28:12:34 | req.url | -| tst.js:13:50:13:55 | origin | -| tst.js:13:50:13:55 | origin | -| tst.js:18:50:18:53 | null | -| tst.js:18:50:18:53 | null | -| tst.js:18:50:18:53 | null | -| tst.js:23:50:23:55 | "null" | -| tst.js:23:50:23:55 | "null" | -| tst.js:23:50:23:55 | "null" | edges | tst.js:12:9:12:54 | origin | tst.js:13:50:13:55 | origin | -| tst.js:12:9:12:54 | origin | tst.js:13:50:13:55 | origin | -| tst.js:12:18:12:41 | url.par ... , true) | tst.js:12:18:12:47 | url.par ... ).query | -| tst.js:12:18:12:47 | url.par ... ).query | tst.js:12:18:12:54 | url.par ... .origin | -| tst.js:12:18:12:54 | url.par ... .origin | tst.js:12:9:12:54 | origin | +| tst.js:12:18:12:41 | url.par ... , true) | tst.js:12:9:12:54 | origin | | tst.js:12:28:12:34 | req.url | tst.js:12:18:12:41 | url.par ... , true) | -| tst.js:12:28:12:34 | req.url | tst.js:12:18:12:41 | url.par ... , true) | -| tst.js:18:50:18:53 | null | tst.js:18:50:18:53 | null | -| tst.js:23:50:23:55 | "null" | tst.js:23:50:23:55 | "null" | +nodes +| tst.js:12:9:12:54 | origin | semmle.label | origin | +| tst.js:12:18:12:41 | url.par ... , true) | semmle.label | url.par ... , true) | +| tst.js:12:28:12:34 | req.url | semmle.label | req.url | +| tst.js:13:50:13:55 | origin | semmle.label | origin | +| tst.js:18:50:18:53 | null | semmle.label | null | +| tst.js:23:50:23:55 | "null" | semmle.label | "null" | +subpaths #select | tst.js:13:50:13:55 | origin | tst.js:12:28:12:34 | req.url | tst.js:13:50:13:55 | origin | $@ leak vulnerability due to a $@. | tst.js:14:5:14:59 | res.set ... , true) | Credential | tst.js:12:28:12:34 | req.url | misconfigured CORS header value | | tst.js:18:50:18:53 | null | tst.js:18:50:18:53 | null | tst.js:18:50:18:53 | null | $@ leak vulnerability due to a $@. | tst.js:19:5:19:59 | res.set ... , true) | Credential | tst.js:18:50:18:53 | null | misconfigured CORS header value | From d324e554f33beb419fa8066b2c4685a94169b148 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:13:57 +0200 Subject: [PATCH 070/514] JS: Port DeepObjectResourceExhaustion --- .../DeepObjectResourceExhaustionQuery.qll | 36 ++++++++++++++++++- .../CWE-400/DeepObjectResourceExhaustion.ql | 9 +++-- .../DeepObjectResourceExhaustion.expected | 6 ++-- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DeepObjectResourceExhaustionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DeepObjectResourceExhaustionQuery.qll index 918ef0663c8..84053319d02 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DeepObjectResourceExhaustionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/DeepObjectResourceExhaustionQuery.qll @@ -11,7 +11,41 @@ import DeepObjectResourceExhaustionCustomizations::DeepObjectResourceExhaustion * A taint tracking configuration for reasoning about DoS attacks due to inefficient handling * of user-controlled objects. */ -class Configuration extends TaintTracking::Configuration { +module DeepObjectResourceExhaustionConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; + + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { + source.(Source).getAFlowLabel() = label + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { + sink instanceof Sink and label = TaintedObject::label() + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel label) { + node = TaintedObject::SanitizerGuard::getABarrierNode(label) + } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate isAdditionalFlowStep( + DataFlow::Node src, DataFlow::FlowLabel inlbl, DataFlow::Node trg, DataFlow::FlowLabel outlbl + ) { + TaintedObject::step(src, trg, inlbl, outlbl) + } +} + +/** + * Taint tracking for reasoning about DoS attacks due to inefficient handling + * of user-controlled objects. + */ +module DeepObjectResourceExhaustionFlow = + TaintTracking::GlobalWithState; + +/** + * DEPRECATED. Use the `DeepObjectResourceExhaustionFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "DeepObjectResourceExhaustion" } override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { diff --git a/javascript/ql/src/Security/CWE-400/DeepObjectResourceExhaustion.ql b/javascript/ql/src/Security/CWE-400/DeepObjectResourceExhaustion.ql index a9ea46c4510..066c3f148d5 100644 --- a/javascript/ql/src/Security/CWE-400/DeepObjectResourceExhaustion.ql +++ b/javascript/ql/src/Security/CWE-400/DeepObjectResourceExhaustion.ql @@ -11,14 +11,13 @@ */ import javascript -import DataFlow::PathGraph import semmle.javascript.security.dataflow.DeepObjectResourceExhaustionQuery +import DataFlow::DeduplicatePathGraph -from - Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node link, - string reason +from PathNode source, PathNode sink, DataFlow::Node link, string reason where - cfg.hasFlowPath(source, sink) and + DeepObjectResourceExhaustionFlow::flowPath(source.getAnOriginalPathNode(), + sink.getAnOriginalPathNode()) and sink.getNode().(Sink).hasReason(link, reason) select sink, source, sink, "Denial of service caused by processing $@ with $@.", source.getNode(), "user input", link, reason diff --git a/javascript/ql/test/query-tests/Security/CWE-400/DeepObjectResourceExhaustion/DeepObjectResourceExhaustion.expected b/javascript/ql/test/query-tests/Security/CWE-400/DeepObjectResourceExhaustion/DeepObjectResourceExhaustion.expected index 1b6796f21c4..5c3caed8152 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/DeepObjectResourceExhaustion/DeepObjectResourceExhaustion.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/DeepObjectResourceExhaustion/DeepObjectResourceExhaustion.expected @@ -1,8 +1,6 @@ nodes -| tst.js:9:29:9:36 | req.body | -| tst.js:9:29:9:36 | req.body | -| tst.js:9:29:9:36 | req.body | +| tst.js:9:29:9:36 | req.body | semmle.label | req.body | edges -| tst.js:9:29:9:36 | req.body | tst.js:9:29:9:36 | req.body | +subpaths #select | tst.js:9:29:9:36 | req.body | tst.js:9:29:9:36 | req.body | tst.js:9:29:9:36 | req.body | Denial of service caused by processing $@ with $@. | tst.js:9:29:9:36 | req.body | user input | tst.js:4:21:4:35 | allErrors: true | allErrors: true | From abd937a49d9ac442a70a96d5abeaae4da0d55591 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:14:14 +0200 Subject: [PATCH 071/514] JS: Port DifferentKindsComparisonBypass --- .../DifferentKindsComparisonBypassQuery.qll | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DifferentKindsComparisonBypassQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DifferentKindsComparisonBypassQuery.qll index 045a33e3211..266d0b9413f 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DifferentKindsComparisonBypassQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/DifferentKindsComparisonBypassQuery.qll @@ -14,19 +14,20 @@ import DifferentKindsComparisonBypassCustomizations::DifferentKindsComparisonByp /** * A taint tracking configuration for comparisons that relies on different kinds of HTTP request data. */ -private class Configuration extends TaintTracking::Configuration { - Configuration() { this = "DifferentKindsComparisonBypass" } +private module DifferentKindsComparisonBypassConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } - override predicate isSource(DataFlow::Node source) { source instanceof Source } + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } } +/** + * Taint tracking for comparisons that relies on different kinds of HTTP request data. + */ +private module DifferentKindsComparisonBypassFlow = + TaintTracking::Global; + /** * A comparison that relies on different kinds of HTTP request data. */ @@ -35,11 +36,9 @@ class DifferentKindsComparison extends Comparison { Source rSource; DifferentKindsComparison() { - exists(Configuration cfg | - cfg.hasFlow(lSource, DataFlow::valueNode(this.getLeftOperand())) and - cfg.hasFlow(rSource, DataFlow::valueNode(this.getRightOperand())) and - lSource.isSuspiciousToCompareWith(rSource) - ) + DifferentKindsComparisonBypassFlow::flow(lSource, DataFlow::valueNode(this.getLeftOperand())) and + DifferentKindsComparisonBypassFlow::flow(rSource, DataFlow::valueNode(this.getRightOperand())) and + lSource.isSuspiciousToCompareWith(rSource) } /** Gets the left operand source of this comparison. */ From 8e95a90d036cbf3464849829c1372b2a4478ac19 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:17:26 +0200 Subject: [PATCH 072/514] JS: Port UntrustedDataToExternalAPI --- .../ExternalAPIUsedWithUntrustedDataQuery.qll | 41 +++++- .../CWE-020/UntrustedDataToExternalAPI.ql | 8 +- .../UntrustedDataToExternalAPI.expected | 121 ++++++------------ 3 files changed, 81 insertions(+), 89 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll index b6d8c7fa088..b05190e4b7a 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll @@ -10,15 +10,44 @@ import javascript import ExternalAPIUsedWithUntrustedDataCustomizations::ExternalApiUsedWithUntrustedData +/** + * A taint tracking configuration for untrusted data flowing to an external API. + */ +module ExternalAPIUsedWithUntrustedDataConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate isBarrierIn(DataFlow::Node node) { + // Block flow from the location to its properties, as the relevant properties (hash and search) are taint sources of their own. + // The location source is only used for propagating through API calls like `new URL(location)` and into external APIs where + // the whole location object escapes. + node = DOM::locationRef().getAPropertyRead() + } + + predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet contents) { + // Also report values that escape while inside a property + isSink(node) and contents = DataFlow::ContentSet::anyProperty() + } +} + +/** + * Taint tracking for untrusted data flowing to an external API. + */ +module ExternalAPIUsedWithUntrustedDataFlow = + TaintTracking::Global; + /** Flow label for objects from which a tainted value is reachable. */ -private class ObjectWrapperFlowLabel extends DataFlow::FlowLabel { +deprecated private class ObjectWrapperFlowLabel extends DataFlow::FlowLabel { ObjectWrapperFlowLabel() { this = "object-wrapper" } } /** - * A taint tracking configuration for untrusted data flowing to an external API. + * DEPRECATED. Use the `ExternalAPIUsedWithUntrustedDataFlow` module instead. */ -class Configuration extends TaintTracking::Configuration { +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "ExternalAPIUsedWithUntrustedData" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -59,10 +88,10 @@ class ExternalApiDataNode extends DataFlow::Node instanceof Sink { } /** A node representing untrusted data being passed to an external API. */ class UntrustedExternalApiDataNode extends ExternalApiDataNode { - UntrustedExternalApiDataNode() { any(Configuration c).hasFlow(_, this) } + UntrustedExternalApiDataNode() { ExternalAPIUsedWithUntrustedDataFlow::flow(_, this) } /** Gets a source of untrusted data which is passed to this external API data node. */ - DataFlow::Node getAnUntrustedSource() { any(Configuration c).hasFlow(result, this) } + DataFlow::Node getAnUntrustedSource() { ExternalAPIUsedWithUntrustedDataFlow::flow(result, this) } } /** @@ -72,7 +101,7 @@ private newtype TExternalApi = /** An external API sink with `name`. */ MkExternalApiNode(string name) { exists(Sink sink | - any(Configuration c).hasFlow(_, sink) and + ExternalAPIUsedWithUntrustedDataFlow::flow(_, sink) and name = sink.getApiName() ) } diff --git a/javascript/ql/src/Security/CWE-020/UntrustedDataToExternalAPI.ql b/javascript/ql/src/Security/CWE-020/UntrustedDataToExternalAPI.ql index 67d6f14f660..30931a6a582 100644 --- a/javascript/ql/src/Security/CWE-020/UntrustedDataToExternalAPI.ql +++ b/javascript/ql/src/Security/CWE-020/UntrustedDataToExternalAPI.ql @@ -11,10 +11,12 @@ import javascript import semmle.javascript.security.dataflow.ExternalAPIUsedWithUntrustedDataQuery -import DataFlow::PathGraph +import ExternalAPIUsedWithUntrustedDataFlow::PathGraph -from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) +from + ExternalAPIUsedWithUntrustedDataFlow::PathNode source, + ExternalAPIUsedWithUntrustedDataFlow::PathNode sink +where ExternalAPIUsedWithUntrustedDataFlow::flowPath(source, sink) select sink, source, sink, "Call to " + sink.getNode().(Sink).getApiName() + " with untrusted data from $@.", source, source.toString() diff --git a/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected b/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected index 9d4a6fc4a9a..c523b2dabd0 100644 --- a/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected +++ b/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected @@ -1,98 +1,60 @@ -nodes -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | -| tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | -| tst-UntrustedDataToExternalAPI.js:5:13:5:21 | untrusted | -| tst-UntrustedDataToExternalAPI.js:5:13:5:21 | untrusted | -| tst-UntrustedDataToExternalAPI.js:6:17:6:25 | untrusted | -| tst-UntrustedDataToExternalAPI.js:6:17:6:25 | untrusted | -| tst-UntrustedDataToExternalAPI.js:7:16:7:24 | untrusted | -| tst-UntrustedDataToExternalAPI.js:7:16:7:24 | untrusted | -| tst-UntrustedDataToExternalAPI.js:8:31:8:39 | untrusted | -| tst-UntrustedDataToExternalAPI.js:8:31:8:39 | untrusted | -| tst-UntrustedDataToExternalAPI.js:9:18:9:26 | untrusted | -| tst-UntrustedDataToExternalAPI.js:9:18:9:26 | untrusted | -| tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | -| tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | -| tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | -| tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | -| tst-UntrustedDataToExternalAPI.js:11:20:11:28 | untrusted | -| tst-UntrustedDataToExternalAPI.js:11:20:11:28 | untrusted | -| tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } | -| tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } | -| tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } | -| tst-UntrustedDataToExternalAPI.js:15:16:15:24 | untrusted | -| tst-UntrustedDataToExternalAPI.js:21:12:27:5 | {\\n ... }\\n } | -| tst-UntrustedDataToExternalAPI.js:22:12:26:9 | {\\n ... } | -| tst-UntrustedDataToExternalAPI.js:23:16:25:13 | {\\n ... } | -| tst-UntrustedDataToExternalAPI.js:24:20:24:42 | [JSON.p ... usted)] | -| tst-UntrustedDataToExternalAPI.js:24:20:24:42 | [JSON.p ... usted)] | -| tst-UntrustedDataToExternalAPI.js:24:21:24:41 | JSON.pa ... rusted) | -| tst-UntrustedDataToExternalAPI.js:24:32:24:40 | untrusted | -| tst-UntrustedDataToExternalAPI.js:30:13:30:30 | getDeepUntrusted() | -| tst-UntrustedDataToExternalAPI.js:30:13:30:30 | getDeepUntrusted() | -| tst-UntrustedDataToExternalAPI.js:30:13:30:30 | getDeepUntrusted() | -| tst-UntrustedDataToExternalAPI.js:33:14:33:22 | untrusted | -| tst-UntrustedDataToExternalAPI.js:33:14:33:22 | untrusted | -| tst-UntrustedDataToExternalAPI.js:34:34:34:42 | untrusted | -| tst-UntrustedDataToExternalAPI.js:34:34:34:42 | untrusted | -| tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | -| tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | -| tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted | -| tst-UntrustedDataToExternalAPI.js:43:8:43:16 | untrusted | -| tst-UntrustedDataToExternalAPI.js:44:8:44:16 | untrusted | edges | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:5:13:5:21 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:5:13:5:21 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:6:17:6:25 | untrusted | | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:6:17:6:25 | untrusted | | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:7:16:7:24 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:7:16:7:24 | untrusted | | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:8:31:8:39 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:8:31:8:39 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:9:18:9:26 | untrusted | | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:9:18:9:26 | untrusted | | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:11:20:11:28 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:11:20:11:28 | untrusted | | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:15:16:15:24 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:24:32:24:40 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:30:13:30:30 | getDeepUntrusted() | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:30:13:30:30 | getDeepUntrusted() | | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:33:14:33:22 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:33:14:33:22 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:34:34:34:42 | untrusted | | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:34:34:34:42 | untrusted | | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted | | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:43:8:43:16 | untrusted | | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:44:8:44:16 | untrusted | | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | +| tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] [1] | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | | tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | -| tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | -| tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | -| tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } | -| tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } | -| tst-UntrustedDataToExternalAPI.js:15:16:15:24 | untrusted | tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } | -| tst-UntrustedDataToExternalAPI.js:21:12:27:5 | {\\n ... }\\n } | tst-UntrustedDataToExternalAPI.js:30:13:30:30 | getDeepUntrusted() | -| tst-UntrustedDataToExternalAPI.js:21:12:27:5 | {\\n ... }\\n } | tst-UntrustedDataToExternalAPI.js:30:13:30:30 | getDeepUntrusted() | -| tst-UntrustedDataToExternalAPI.js:22:12:26:9 | {\\n ... } | tst-UntrustedDataToExternalAPI.js:21:12:27:5 | {\\n ... }\\n } | -| tst-UntrustedDataToExternalAPI.js:23:16:25:13 | {\\n ... } | tst-UntrustedDataToExternalAPI.js:22:12:26:9 | {\\n ... } | -| tst-UntrustedDataToExternalAPI.js:24:20:24:42 | [JSON.p ... usted)] | tst-UntrustedDataToExternalAPI.js:23:16:25:13 | {\\n ... } | -| tst-UntrustedDataToExternalAPI.js:24:20:24:42 | [JSON.p ... usted)] | tst-UntrustedDataToExternalAPI.js:23:16:25:13 | {\\n ... } | -| tst-UntrustedDataToExternalAPI.js:24:21:24:41 | JSON.pa ... rusted) | tst-UntrustedDataToExternalAPI.js:24:20:24:42 | [JSON.p ... usted)] | -| tst-UntrustedDataToExternalAPI.js:24:21:24:41 | JSON.pa ... rusted) | tst-UntrustedDataToExternalAPI.js:24:20:24:42 | [JSON.p ... usted)] | -| tst-UntrustedDataToExternalAPI.js:24:32:24:40 | untrusted | tst-UntrustedDataToExternalAPI.js:24:21:24:41 | JSON.pa ... rusted) | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | -| tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | -| tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | -| tst-UntrustedDataToExternalAPI.js:43:8:43:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | -| tst-UntrustedDataToExternalAPI.js:43:8:43:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | -| tst-UntrustedDataToExternalAPI.js:44:8:44:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | -| tst-UntrustedDataToExternalAPI.js:44:8:44:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | +| tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] [1] | +| tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } [y, z] | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } | +| tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } [z] | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } [y, z] | +| tst-UntrustedDataToExternalAPI.js:15:16:15:24 | untrusted | tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } [z] | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [x] | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [x] | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [y] | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [y] | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [z] | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [z] | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | +| tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [x] | +| tst-UntrustedDataToExternalAPI.js:43:8:43:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [y] | +| tst-UntrustedDataToExternalAPI.js:44:8:44:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [z] | +nodes +| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | semmle.label | untrusted | +| tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | semmle.label | window.name | +| tst-UntrustedDataToExternalAPI.js:5:13:5:21 | untrusted | semmle.label | untrusted | +| tst-UntrustedDataToExternalAPI.js:6:17:6:25 | untrusted | semmle.label | untrusted | +| tst-UntrustedDataToExternalAPI.js:7:16:7:24 | untrusted | semmle.label | untrusted | +| tst-UntrustedDataToExternalAPI.js:8:31:8:39 | untrusted | semmle.label | untrusted | +| tst-UntrustedDataToExternalAPI.js:9:18:9:26 | untrusted | semmle.label | untrusted | +| tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | semmle.label | ['x', u ... d, 'y'] | +| tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] [1] | semmle.label | ['x', u ... d, 'y'] [1] | +| tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | semmle.label | untrusted | +| tst-UntrustedDataToExternalAPI.js:11:20:11:28 | untrusted | semmle.label | untrusted | +| tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } | semmle.label | {\\n ... }\\n } | +| tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } [y, z] | semmle.label | {\\n ... }\\n } [y, z] | +| tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } [z] | semmle.label | {\\n ... } [z] | +| tst-UntrustedDataToExternalAPI.js:15:16:15:24 | untrusted | semmle.label | untrusted | +| tst-UntrustedDataToExternalAPI.js:33:14:33:22 | untrusted | semmle.label | untrusted | +| tst-UntrustedDataToExternalAPI.js:34:34:34:42 | untrusted | semmle.label | untrusted | +| tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | semmle.label | {} | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [x] | semmle.label | [post update] {\\n x ... usted\\n} [x] | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [y] | semmle.label | [post update] {\\n x ... usted\\n} [y] | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [z] | semmle.label | [post update] {\\n x ... usted\\n} [z] | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | semmle.label | {\\n x ... usted\\n} | +| tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted | semmle.label | untrusted | +| tst-UntrustedDataToExternalAPI.js:43:8:43:16 | untrusted | semmle.label | untrusted | +| tst-UntrustedDataToExternalAPI.js:44:8:44:16 | untrusted | semmle.label | untrusted | +subpaths #select | tst-UntrustedDataToExternalAPI.js:5:13:5:21 | untrusted | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:5:13:5:21 | untrusted | Call to external-lib() [param 0] with untrusted data from $@. | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | window.name | | tst-UntrustedDataToExternalAPI.js:6:17:6:25 | untrusted | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:6:17:6:25 | untrusted | Call to external-lib() [param 0 'x'] with untrusted data from $@. | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | window.name | @@ -102,7 +64,6 @@ edges | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | Call to external-lib() [param 0] with untrusted data from $@. | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | window.name | | tst-UntrustedDataToExternalAPI.js:11:20:11:28 | untrusted | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:11:20:11:28 | untrusted | Call to external-lib() [param 1] with untrusted data from $@. | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | window.name | | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } | Call to external-lib() [param 0 'x'] with untrusted data from $@. | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | window.name | -| tst-UntrustedDataToExternalAPI.js:30:13:30:30 | getDeepUntrusted() | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:30:13:30:30 | getDeepUntrusted() | Call to external-lib() [param 0] with untrusted data from $@. | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | window.name | | tst-UntrustedDataToExternalAPI.js:33:14:33:22 | untrusted | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:33:14:33:22 | untrusted | Call to external-lib.get.[callback].[param 'res'].send() [param 0] with untrusted data from $@. | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | window.name | | tst-UntrustedDataToExternalAPI.js:34:34:34:42 | untrusted | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:34:34:34:42 | untrusted | Call to external-lib.get.[callback].[param 'req'].app.locals.something.foo() [param 0] with untrusted data from $@. | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | window.name | | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | Call to lodash.merge() [param 0] with untrusted data from $@. | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | window.name | From 2935aac559e202fc023a1a1a0342b525e2a5e5ba Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:18:11 +0200 Subject: [PATCH 073/514] JS: Port FileAccessToHttp --- .../dataflow/FileAccessToHttpQuery.qll | 25 ++- .../src/Security/CWE-200/FileAccessToHttp.ql | 6 +- .../CWE-200/FileAccessToHttp.expected | 178 +++++++----------- 3 files changed, 99 insertions(+), 110 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/FileAccessToHttpQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/FileAccessToHttpQuery.qll index 9ce03476755..7f3d2c5f341 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/FileAccessToHttpQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/FileAccessToHttpQuery.qll @@ -13,7 +13,30 @@ import FileAccessToHttpCustomizations::FileAccessToHttp /** * A taint tracking configuration for file data in outbound network requests. */ -class Configuration extends TaintTracking::Configuration { +module FileAccessToHttpConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet contents) { + isSink(node) and + // or + // node = any(DataFlow::MethodCallNode call | call.getMethodName() = "stringify").getAnArgument() + contents = DataFlow::ContentSet::anyProperty() + } +} + +/** + * Taint tracking for file data in outbound network requests. + */ +module FileAccessToHttpFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `FileAccessToHttpFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "FileAccessToHttp" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-200/FileAccessToHttp.ql b/javascript/ql/src/Security/CWE-200/FileAccessToHttp.ql index a0145f6034f..75a09efb96b 100644 --- a/javascript/ql/src/Security/CWE-200/FileAccessToHttp.ql +++ b/javascript/ql/src/Security/CWE-200/FileAccessToHttp.ql @@ -12,9 +12,9 @@ import javascript import semmle.javascript.security.dataflow.FileAccessToHttpQuery -import DataFlow::PathGraph +import FileAccessToHttpFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from FileAccessToHttpFlow::PathNode source, FileAccessToHttpFlow::PathNode sink +where FileAccessToHttpFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Outbound network request depends on $@.", source.getNode(), "file data" diff --git a/javascript/ql/test/query-tests/Security/CWE-200/FileAccessToHttp.expected b/javascript/ql/test/query-tests/Security/CWE-200/FileAccessToHttp.expected index a38e0d41942..b9c024c5590 100644 --- a/javascript/ql/test/query-tests/Security/CWE-200/FileAccessToHttp.expected +++ b/javascript/ql/test/query-tests/Security/CWE-200/FileAccessToHttp.expected @@ -1,123 +1,35 @@ -nodes -| FileAccessToHttp.js:4:5:4:47 | content | -| FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | -| FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | -| FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | -| FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | -| FileAccessToHttp.js:9:12:9:31 | { Referer: content } | -| FileAccessToHttp.js:9:23:9:29 | content | -| bufferRead.js:12:13:12:43 | buffer | -| bufferRead.js:12:22:12:43 | new Buf ... s.size) | -| bufferRead.js:12:22:12:43 | new Buf ... s.size) | -| bufferRead.js:15:15:15:62 | postData | -| bufferRead.js:15:26:15:31 | buffer | -| bufferRead.js:15:26:15:62 | buffer. ... esRead) | -| bufferRead.js:33:21:33:28 | postData | -| bufferRead.js:33:21:33:28 | postData | -| googlecompiler.js:7:19:7:28 | codestring | -| googlecompiler.js:9:7:15:4 | post_data | -| googlecompiler.js:9:19:15:4 | queryst ... dy\\n }) | -| googlecompiler.js:9:41:15:3 | {\\n ... ody\\n } | -| googlecompiler.js:14:21:14:30 | codestring | -| googlecompiler.js:38:18:38:26 | post_data | -| googlecompiler.js:38:18:38:26 | post_data | -| googlecompiler.js:44:54:44:57 | data | -| googlecompiler.js:44:54:44:57 | data | -| googlecompiler.js:56:14:56:17 | data | -| readFileSync.js:5:5:5:39 | data | -| readFileSync.js:5:12:5:39 | fs.read ... t.txt") | -| readFileSync.js:5:12:5:39 | fs.read ... t.txt") | -| readFileSync.js:7:7:7:25 | s | -| readFileSync.js:7:11:7:14 | data | -| readFileSync.js:7:11:7:25 | data.toString() | -| readFileSync.js:26:18:26:18 | s | -| readFileSync.js:26:18:26:18 | s | -| readStreamRead.js:13:13:13:35 | chunk | -| readStreamRead.js:13:21:13:35 | readable.read() | -| readStreamRead.js:13:21:13:35 | readable.read() | -| readStreamRead.js:30:19:30:23 | chunk | -| readStreamRead.js:30:19:30:23 | chunk | -| request.js:6:19:6:26 | jsonData | -| request.js:8:11:8:20 | {jsonData} | -| request.js:8:11:8:20 | {jsonData} | -| request.js:8:12:8:19 | jsonData | -| request.js:13:18:13:24 | xmlData | -| request.js:16:11:23:3 | {\\n u ... ody\\n } | -| request.js:16:11:23:3 | {\\n u ... ody\\n } | -| request.js:22:11:22:17 | xmlData | -| request.js:28:52:28:55 | data | -| request.js:28:52:28:55 | data | -| request.js:35:14:35:17 | data | -| request.js:43:51:43:54 | data | -| request.js:43:51:43:54 | data | -| request.js:50:13:50:16 | data | -| sentAsHeaders.js:10:79:10:84 | buffer | -| sentAsHeaders.js:10:79:10:84 | buffer | -| sentAsHeaders.js:11:13:11:59 | content | -| sentAsHeaders.js:11:23:11:28 | buffer | -| sentAsHeaders.js:11:23:11:59 | buffer. ... esRead) | -| sentAsHeaders.js:12:9:12:81 | content | -| sentAsHeaders.js:12:19:12:25 | content | -| sentAsHeaders.js:12:19:12:74 | content ... =", "") | -| sentAsHeaders.js:12:19:12:81 | content ... .trim() | -| sentAsHeaders.js:14:20:19:9 | {\\n ... } | -| sentAsHeaders.js:14:20:19:9 | {\\n ... } | -| sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } | -| sentAsHeaders.js:18:31:18:53 | "http:/ ... content | -| sentAsHeaders.js:18:47:18:53 | content | -| sentAsHeaders.js:20:20:25:9 | {\\n ... } | -| sentAsHeaders.js:20:20:25:9 | {\\n ... } | -| sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } | -| sentAsHeaders.js:24:31:24:53 | "http:/ ... content | -| sentAsHeaders.js:24:47:24:53 | content | edges | FileAccessToHttp.js:4:5:4:47 | content | FileAccessToHttp.js:9:23:9:29 | content | | FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | FileAccessToHttp.js:4:5:4:47 | content | -| FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | FileAccessToHttp.js:4:5:4:47 | content | -| FileAccessToHttp.js:9:12:9:31 | { Referer: content } | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | -| FileAccessToHttp.js:9:12:9:31 | { Referer: content } | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | -| FileAccessToHttp.js:9:23:9:29 | content | FileAccessToHttp.js:9:12:9:31 | { Referer: content } | -| bufferRead.js:12:13:12:43 | buffer | bufferRead.js:15:26:15:31 | buffer | +| FileAccessToHttp.js:5:11:10:1 | [post update] {\\n hos ... ent }\\n} [headers, Referer] | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | +| FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | FileAccessToHttp.js:5:11:10:1 | [post update] {\\n hos ... ent }\\n} [headers, Referer] | +| FileAccessToHttp.js:9:23:9:29 | content | FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | +| bufferRead.js:12:13:12:43 | buffer | bufferRead.js:13:21:13:26 | buffer | +| bufferRead.js:12:13:12:43 | buffer | bufferRead.js:13:32:13:37 | buffer | | bufferRead.js:12:22:12:43 | new Buf ... s.size) | bufferRead.js:12:13:12:43 | buffer | -| bufferRead.js:12:22:12:43 | new Buf ... s.size) | bufferRead.js:12:13:12:43 | buffer | -| bufferRead.js:15:15:15:62 | postData | bufferRead.js:33:21:33:28 | postData | +| bufferRead.js:13:21:13:26 | buffer | bufferRead.js:13:32:13:37 | buffer | +| bufferRead.js:13:32:13:37 | buffer | bufferRead.js:15:26:15:31 | buffer | | bufferRead.js:15:15:15:62 | postData | bufferRead.js:33:21:33:28 | postData | | bufferRead.js:15:26:15:31 | buffer | bufferRead.js:15:26:15:62 | buffer. ... esRead) | | bufferRead.js:15:26:15:62 | buffer. ... esRead) | bufferRead.js:15:15:15:62 | postData | -| googlecompiler.js:7:19:7:28 | codestring | googlecompiler.js:14:21:14:30 | codestring | -| googlecompiler.js:9:7:15:4 | post_data | googlecompiler.js:38:18:38:26 | post_data | -| googlecompiler.js:9:7:15:4 | post_data | googlecompiler.js:38:18:38:26 | post_data | -| googlecompiler.js:9:19:15:4 | queryst ... dy\\n }) | googlecompiler.js:9:7:15:4 | post_data | -| googlecompiler.js:9:41:15:3 | {\\n ... ody\\n } | googlecompiler.js:9:19:15:4 | queryst ... dy\\n }) | -| googlecompiler.js:14:21:14:30 | codestring | googlecompiler.js:9:41:15:3 | {\\n ... ody\\n } | -| googlecompiler.js:44:54:44:57 | data | googlecompiler.js:56:14:56:17 | data | -| googlecompiler.js:44:54:44:57 | data | googlecompiler.js:56:14:56:17 | data | -| googlecompiler.js:56:14:56:17 | data | googlecompiler.js:7:19:7:28 | codestring | | readFileSync.js:5:5:5:39 | data | readFileSync.js:7:11:7:14 | data | | readFileSync.js:5:12:5:39 | fs.read ... t.txt") | readFileSync.js:5:5:5:39 | data | -| readFileSync.js:5:12:5:39 | fs.read ... t.txt") | readFileSync.js:5:5:5:39 | data | -| readFileSync.js:7:7:7:25 | s | readFileSync.js:26:18:26:18 | s | | readFileSync.js:7:7:7:25 | s | readFileSync.js:26:18:26:18 | s | | readFileSync.js:7:11:7:14 | data | readFileSync.js:7:11:7:25 | data.toString() | | readFileSync.js:7:11:7:25 | data.toString() | readFileSync.js:7:7:7:25 | s | | readStreamRead.js:13:13:13:35 | chunk | readStreamRead.js:30:19:30:23 | chunk | -| readStreamRead.js:13:13:13:35 | chunk | readStreamRead.js:30:19:30:23 | chunk | -| readStreamRead.js:13:21:13:35 | readable.read() | readStreamRead.js:13:13:13:35 | chunk | | readStreamRead.js:13:21:13:35 | readable.read() | readStreamRead.js:13:13:13:35 | chunk | | request.js:6:19:6:26 | jsonData | request.js:8:12:8:19 | jsonData | -| request.js:8:12:8:19 | jsonData | request.js:8:11:8:20 | {jsonData} | -| request.js:8:12:8:19 | jsonData | request.js:8:11:8:20 | {jsonData} | +| request.js:8:11:8:20 | [post update] {jsonData} [jsonData] | request.js:8:11:8:20 | {jsonData} | +| request.js:8:12:8:19 | jsonData | request.js:8:11:8:20 | [post update] {jsonData} [jsonData] | | request.js:13:18:13:24 | xmlData | request.js:22:11:22:17 | xmlData | -| request.js:22:11:22:17 | xmlData | request.js:16:11:23:3 | {\\n u ... ody\\n } | -| request.js:22:11:22:17 | xmlData | request.js:16:11:23:3 | {\\n u ... ody\\n } | -| request.js:28:52:28:55 | data | request.js:35:14:35:17 | data | +| request.js:16:11:23:3 | [post update] {\\n u ... ody\\n } [body] | request.js:16:11:23:3 | {\\n u ... ody\\n } | +| request.js:22:11:22:17 | xmlData | request.js:16:11:23:3 | [post update] {\\n u ... ody\\n } [body] | | request.js:28:52:28:55 | data | request.js:35:14:35:17 | data | | request.js:35:14:35:17 | data | request.js:6:19:6:26 | jsonData | | request.js:43:51:43:54 | data | request.js:50:13:50:16 | data | -| request.js:43:51:43:54 | data | request.js:50:13:50:16 | data | | request.js:50:13:50:16 | data | request.js:13:18:13:24 | xmlData | | sentAsHeaders.js:10:79:10:84 | buffer | sentAsHeaders.js:11:23:11:28 | buffer | -| sentAsHeaders.js:10:79:10:84 | buffer | sentAsHeaders.js:11:23:11:28 | buffer | | sentAsHeaders.js:11:13:11:59 | content | sentAsHeaders.js:12:19:12:25 | content | | sentAsHeaders.js:11:23:11:28 | buffer | sentAsHeaders.js:11:23:11:59 | buffer. ... esRead) | | sentAsHeaders.js:11:23:11:59 | buffer. ... esRead) | sentAsHeaders.js:11:13:11:59 | content | @@ -126,18 +38,72 @@ edges | sentAsHeaders.js:12:19:12:25 | content | sentAsHeaders.js:12:19:12:74 | content ... =", "") | | sentAsHeaders.js:12:19:12:74 | content ... =", "") | sentAsHeaders.js:12:19:12:81 | content ... .trim() | | sentAsHeaders.js:12:19:12:81 | content ... .trim() | sentAsHeaders.js:12:9:12:81 | content | -| sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } | sentAsHeaders.js:14:20:19:9 | {\\n ... } | -| sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } | sentAsHeaders.js:14:20:19:9 | {\\n ... } | -| sentAsHeaders.js:18:31:18:53 | "http:/ ... content | sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } | +| sentAsHeaders.js:14:20:19:9 | [post update] {\\n ... } [headers, Referer] | sentAsHeaders.js:14:20:19:9 | {\\n ... } | +| sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } [Referer] | sentAsHeaders.js:14:20:19:9 | [post update] {\\n ... } [headers, Referer] | +| sentAsHeaders.js:18:31:18:53 | "http:/ ... content | sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } [Referer] | | sentAsHeaders.js:18:47:18:53 | content | sentAsHeaders.js:18:31:18:53 | "http:/ ... content | -| sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } | sentAsHeaders.js:20:20:25:9 | {\\n ... } | -| sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } | sentAsHeaders.js:20:20:25:9 | {\\n ... } | -| sentAsHeaders.js:24:31:24:53 | "http:/ ... content | sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } | +| sentAsHeaders.js:20:20:25:9 | [post update] {\\n ... } [headers, Referer] | sentAsHeaders.js:20:20:25:9 | {\\n ... } | +| sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } [Referer] | sentAsHeaders.js:20:20:25:9 | [post update] {\\n ... } [headers, Referer] | +| sentAsHeaders.js:24:31:24:53 | "http:/ ... content | sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } [Referer] | | sentAsHeaders.js:24:47:24:53 | content | sentAsHeaders.js:24:31:24:53 | "http:/ ... content | +nodes +| FileAccessToHttp.js:4:5:4:47 | content | semmle.label | content | +| FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | semmle.label | fs.read ... "utf8") | +| FileAccessToHttp.js:5:11:10:1 | [post update] {\\n hos ... ent }\\n} [headers, Referer] | semmle.label | [post update] {\\n hos ... ent }\\n} [headers, Referer] | +| FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | semmle.label | {\\n hos ... ent }\\n} | +| FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | semmle.label | { Referer: content } [Referer] | +| FileAccessToHttp.js:9:23:9:29 | content | semmle.label | content | +| bufferRead.js:12:13:12:43 | buffer | semmle.label | buffer | +| bufferRead.js:12:22:12:43 | new Buf ... s.size) | semmle.label | new Buf ... s.size) | +| bufferRead.js:13:21:13:26 | buffer | semmle.label | buffer | +| bufferRead.js:13:32:13:37 | buffer | semmle.label | buffer | +| bufferRead.js:15:15:15:62 | postData | semmle.label | postData | +| bufferRead.js:15:26:15:31 | buffer | semmle.label | buffer | +| bufferRead.js:15:26:15:62 | buffer. ... esRead) | semmle.label | buffer. ... esRead) | +| bufferRead.js:33:21:33:28 | postData | semmle.label | postData | +| readFileSync.js:5:5:5:39 | data | semmle.label | data | +| readFileSync.js:5:12:5:39 | fs.read ... t.txt") | semmle.label | fs.read ... t.txt") | +| readFileSync.js:7:7:7:25 | s | semmle.label | s | +| readFileSync.js:7:11:7:14 | data | semmle.label | data | +| readFileSync.js:7:11:7:25 | data.toString() | semmle.label | data.toString() | +| readFileSync.js:26:18:26:18 | s | semmle.label | s | +| readStreamRead.js:13:13:13:35 | chunk | semmle.label | chunk | +| readStreamRead.js:13:21:13:35 | readable.read() | semmle.label | readable.read() | +| readStreamRead.js:30:19:30:23 | chunk | semmle.label | chunk | +| request.js:6:19:6:26 | jsonData | semmle.label | jsonData | +| request.js:8:11:8:20 | [post update] {jsonData} [jsonData] | semmle.label | [post update] {jsonData} [jsonData] | +| request.js:8:11:8:20 | {jsonData} | semmle.label | {jsonData} | +| request.js:8:12:8:19 | jsonData | semmle.label | jsonData | +| request.js:13:18:13:24 | xmlData | semmle.label | xmlData | +| request.js:16:11:23:3 | [post update] {\\n u ... ody\\n } [body] | semmle.label | [post update] {\\n u ... ody\\n } [body] | +| request.js:16:11:23:3 | {\\n u ... ody\\n } | semmle.label | {\\n u ... ody\\n } | +| request.js:22:11:22:17 | xmlData | semmle.label | xmlData | +| request.js:28:52:28:55 | data | semmle.label | data | +| request.js:35:14:35:17 | data | semmle.label | data | +| request.js:43:51:43:54 | data | semmle.label | data | +| request.js:50:13:50:16 | data | semmle.label | data | +| sentAsHeaders.js:10:79:10:84 | buffer | semmle.label | buffer | +| sentAsHeaders.js:11:13:11:59 | content | semmle.label | content | +| sentAsHeaders.js:11:23:11:28 | buffer | semmle.label | buffer | +| sentAsHeaders.js:11:23:11:59 | buffer. ... esRead) | semmle.label | buffer. ... esRead) | +| sentAsHeaders.js:12:9:12:81 | content | semmle.label | content | +| sentAsHeaders.js:12:19:12:25 | content | semmle.label | content | +| sentAsHeaders.js:12:19:12:74 | content ... =", "") | semmle.label | content ... =", "") | +| sentAsHeaders.js:12:19:12:81 | content ... .trim() | semmle.label | content ... .trim() | +| sentAsHeaders.js:14:20:19:9 | [post update] {\\n ... } [headers, Referer] | semmle.label | [post update] {\\n ... } [headers, Referer] | +| sentAsHeaders.js:14:20:19:9 | {\\n ... } | semmle.label | {\\n ... } | +| sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } [Referer] | semmle.label | { Refer ... ntent } [Referer] | +| sentAsHeaders.js:18:31:18:53 | "http:/ ... content | semmle.label | "http:/ ... content | +| sentAsHeaders.js:18:47:18:53 | content | semmle.label | content | +| sentAsHeaders.js:20:20:25:9 | [post update] {\\n ... } [headers, Referer] | semmle.label | [post update] {\\n ... } [headers, Referer] | +| sentAsHeaders.js:20:20:25:9 | {\\n ... } | semmle.label | {\\n ... } | +| sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } [Referer] | semmle.label | { Refer ... ntent } [Referer] | +| sentAsHeaders.js:24:31:24:53 | "http:/ ... content | semmle.label | "http:/ ... content | +| sentAsHeaders.js:24:47:24:53 | content | semmle.label | content | +subpaths #select | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | Outbound network request depends on $@. | FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | file data | | bufferRead.js:33:21:33:28 | postData | bufferRead.js:12:22:12:43 | new Buf ... s.size) | bufferRead.js:33:21:33:28 | postData | Outbound network request depends on $@. | bufferRead.js:12:22:12:43 | new Buf ... s.size) | file data | -| googlecompiler.js:38:18:38:26 | post_data | googlecompiler.js:44:54:44:57 | data | googlecompiler.js:38:18:38:26 | post_data | Outbound network request depends on $@. | googlecompiler.js:44:54:44:57 | data | file data | | readFileSync.js:26:18:26:18 | s | readFileSync.js:5:12:5:39 | fs.read ... t.txt") | readFileSync.js:26:18:26:18 | s | Outbound network request depends on $@. | readFileSync.js:5:12:5:39 | fs.read ... t.txt") | file data | | readStreamRead.js:30:19:30:23 | chunk | readStreamRead.js:13:21:13:35 | readable.read() | readStreamRead.js:30:19:30:23 | chunk | Outbound network request depends on $@. | readStreamRead.js:13:21:13:35 | readable.read() | file data | | request.js:8:11:8:20 | {jsonData} | request.js:28:52:28:55 | data | request.js:8:11:8:20 | {jsonData} | Outbound network request depends on $@. | request.js:28:52:28:55 | data | file data | From f4d62c3225824fd4d3024d9e1b3ae791e3e1b022 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:18:23 +0200 Subject: [PATCH 074/514] JS: Port HttpToFileAccess --- .../dataflow/HttpToFileAccessQuery.qll | 18 ++++++++- .../src/Security/CWE-912/HttpToFileAccess.ql | 6 +-- .../CWE-912/HttpToFileAccess.expected | 37 +++++++------------ 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/HttpToFileAccessQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/HttpToFileAccessQuery.qll index 992b0cd1e8d..9b3d7635c87 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/HttpToFileAccessQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/HttpToFileAccessQuery.qll @@ -11,7 +11,23 @@ private import HttpToFileAccessCustomizations::HttpToFileAccess /** * A taint tracking configuration for writing user-controlled data to files. */ -class Configuration extends TaintTracking::Configuration { +module HttpToFileAccessConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint tracking for writing user-controlled data to files. + */ +module HttpToFileAccessFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `HttpToFileAccessFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "HttpToFileAccess" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-912/HttpToFileAccess.ql b/javascript/ql/src/Security/CWE-912/HttpToFileAccess.ql index a2953365b64..88362ce545d 100644 --- a/javascript/ql/src/Security/CWE-912/HttpToFileAccess.ql +++ b/javascript/ql/src/Security/CWE-912/HttpToFileAccess.ql @@ -13,9 +13,9 @@ import javascript import semmle.javascript.security.dataflow.HttpToFileAccessQuery -import DataFlow::PathGraph +import HttpToFileAccessFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from HttpToFileAccessFlow::PathNode source, HttpToFileAccessFlow::PathNode sink +where HttpToFileAccessFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Write to file system depends on $@.", source.getNode(), "Untrusted data" diff --git a/javascript/ql/test/query-tests/Security/CWE-912/HttpToFileAccess.expected b/javascript/ql/test/query-tests/Security/CWE-912/HttpToFileAccess.expected index e5e9fb9b051..a9973f75465 100644 --- a/javascript/ql/test/query-tests/Security/CWE-912/HttpToFileAccess.expected +++ b/javascript/ql/test/query-tests/Security/CWE-912/HttpToFileAccess.expected @@ -1,33 +1,22 @@ -nodes -| HttpToFileAccess.js:5:18:5:18 | d | -| HttpToFileAccess.js:5:18:5:18 | d | -| HttpToFileAccess.js:6:37:6:37 | d | -| HttpToFileAccess.js:6:37:6:37 | d | -| tst.js:15:26:15:26 | c | -| tst.js:15:26:15:26 | c | -| tst.js:16:33:16:33 | c | -| tst.js:16:33:16:33 | c | -| tst.js:19:25:19:25 | c | -| tst.js:19:25:19:25 | c | -| tst.js:24:22:24:22 | c | -| tst.js:24:22:24:22 | c | edges | HttpToFileAccess.js:5:18:5:18 | d | HttpToFileAccess.js:6:37:6:37 | d | -| HttpToFileAccess.js:5:18:5:18 | d | HttpToFileAccess.js:6:37:6:37 | d | -| HttpToFileAccess.js:5:18:5:18 | d | HttpToFileAccess.js:6:37:6:37 | d | -| HttpToFileAccess.js:5:18:5:18 | d | HttpToFileAccess.js:6:37:6:37 | d | -| tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | -| tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | | tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | | tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | | tst.js:15:26:15:26 | c | tst.js:19:25:19:25 | c | | tst.js:15:26:15:26 | c | tst.js:19:25:19:25 | c | -| tst.js:15:26:15:26 | c | tst.js:19:25:19:25 | c | -| tst.js:15:26:15:26 | c | tst.js:19:25:19:25 | c | -| tst.js:15:26:15:26 | c | tst.js:24:22:24:22 | c | -| tst.js:15:26:15:26 | c | tst.js:24:22:24:22 | c | -| tst.js:15:26:15:26 | c | tst.js:24:22:24:22 | c | -| tst.js:15:26:15:26 | c | tst.js:24:22:24:22 | c | +| tst.js:16:33:16:33 | c | tst.js:19:25:19:25 | c | +| tst.js:16:33:16:33 | c | tst.js:19:25:19:25 | c | +| tst.js:19:25:19:25 | c | tst.js:24:22:24:22 | c | +nodes +| HttpToFileAccess.js:5:18:5:18 | d | semmle.label | d | +| HttpToFileAccess.js:6:37:6:37 | d | semmle.label | d | +| tst.js:15:26:15:26 | c | semmle.label | c | +| tst.js:16:33:16:33 | c | semmle.label | c | +| tst.js:16:33:16:33 | c | semmle.label | c | +| tst.js:19:25:19:25 | c | semmle.label | c | +| tst.js:19:25:19:25 | c | semmle.label | c | +| tst.js:24:22:24:22 | c | semmle.label | c | +subpaths #select | HttpToFileAccess.js:6:37:6:37 | d | HttpToFileAccess.js:5:18:5:18 | d | HttpToFileAccess.js:6:37:6:37 | d | Write to file system depends on $@. | HttpToFileAccess.js:5:18:5:18 | d | Untrusted data | | tst.js:16:33:16:33 | c | tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | Write to file system depends on $@. | tst.js:15:26:15:26 | c | Untrusted data | From 4bac90252c49ec62ea7d652a767349de722e115b Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:18:36 +0200 Subject: [PATCH 075/514] JS: Port HardcodedCredentials --- .../dataflow/HardcodedCredentialsQuery.qll | 42 +- .../Security/CWE-798/HardcodedCredentials.ql | 6 +- .../CWE-798/HardcodedCredentials.expected | 478 +++++------------- 3 files changed, 151 insertions(+), 375 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedCredentialsQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedCredentialsQuery.qll index b38d1908faf..121f6d247c4 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedCredentialsQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedCredentialsQuery.qll @@ -12,19 +12,14 @@ import HardcodedCredentialsCustomizations::HardcodedCredentials /** * A data flow tracking configuration for hardcoded credentials. */ -class Configuration extends DataFlow::Configuration { - Configuration() { this = "HardcodedCredentials" } +module HardcodedCredentialsConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node instanceof Source } - override predicate isSource(DataFlow::Node source) { source instanceof Source } + predicate isSink(DataFlow::Node node) { node instanceof Sink } - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } - override predicate isBarrier(DataFlow::Node node) { - super.isBarrier(node) or - node instanceof Sanitizer - } - - override predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg) { + predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg) { exists(Base64::Encode encode | src = encode.getInput() and trg = encode.getOutput()) or trg.(StringOps::ConcatenationRoot).getALeaf() = src and @@ -37,3 +32,30 @@ class Configuration extends DataFlow::Configuration { ) } } + +/** + * Data flow for reasoning about hardcoded credentials. + */ +module HardcodedCredentials = DataFlow::Global; + +/** + * DEPRECATED. Use the `HardcodedCredentials` module instead. + */ +deprecated class Configuration extends DataFlow::Configuration { + Configuration() { this = "HardcodedCredentials" } + + override predicate isSource(DataFlow::Node source) { + HardcodedCredentialsConfig::isSource(source) + } + + override predicate isSink(DataFlow::Node sink) { HardcodedCredentialsConfig::isSink(sink) } + + override predicate isBarrier(DataFlow::Node node) { + super.isBarrier(node) or + HardcodedCredentialsConfig::isBarrier(node) + } + + override predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg) { + HardcodedCredentialsConfig::isAdditionalFlowStep(src, trg) + } +} diff --git a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql index 3cc63e51dcf..0fb996acb27 100644 --- a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql +++ b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql @@ -15,14 +15,14 @@ import javascript import semmle.javascript.security.dataflow.HardcodedCredentialsQuery -import DataFlow::PathGraph +import HardcodedCredentials::PathGraph bindingset[s] predicate looksLikeATemplate(string s) { s.regexpMatch(".*((\\{\\{.*\\}\\})|(<.*>)|(\\(.*\\))).*") } -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, string value +from HardcodedCredentials::PathNode source, HardcodedCredentials::PathNode sink, string value where - cfg.hasFlowPath(source, sink) and + HardcodedCredentials::flowPath(source, sink) and // use source value in message if it's available if source.getNode().asExpr() instanceof ConstantString then diff --git a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected index 3635090cb43..a1806eb239f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected +++ b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected @@ -1,340 +1,9 @@ -nodes -| HardcodedCredentials.js:5:15:5:22 | 'dbuser' | -| HardcodedCredentials.js:5:15:5:22 | 'dbuser' | -| HardcodedCredentials.js:5:15:5:22 | 'dbuser' | -| HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | -| HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | -| HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | -| HardcodedCredentials.js:15:36:15:50 | "user:hgfedcba" | -| HardcodedCredentials.js:15:36:15:50 | "user:hgfedcba" | -| HardcodedCredentials.js:15:36:15:50 | "user:hgfedcba" | -| HardcodedCredentials.js:16:37:16:51 | "user:hgfedcba" | -| HardcodedCredentials.js:16:37:16:51 | "user:hgfedcba" | -| HardcodedCredentials.js:16:37:16:51 | "user:hgfedcba" | -| HardcodedCredentials.js:18:16:18:30 | "user:hgfedcba" | -| HardcodedCredentials.js:18:16:18:30 | "user:hgfedcba" | -| HardcodedCredentials.js:20:36:20:51 | getCredentials() | -| HardcodedCredentials.js:20:36:20:51 | getCredentials() | -| HardcodedCredentials.js:27:25:27:31 | 'admin' | -| HardcodedCredentials.js:27:25:27:31 | 'admin' | -| HardcodedCredentials.js:27:25:27:31 | 'admin' | -| HardcodedCredentials.js:27:34:27:43 | 'hgfedcba' | -| HardcodedCredentials.js:27:34:27:43 | 'hgfedcba' | -| HardcodedCredentials.js:27:34:27:43 | 'hgfedcba' | -| HardcodedCredentials.js:29:11:29:30 | 'unknown-admin-name' | -| HardcodedCredentials.js:29:11:29:30 | 'unknown-admin-name' | -| HardcodedCredentials.js:29:11:29:30 | 'unknown-admin-name' | -| HardcodedCredentials.js:29:35:29:44 | 'hgfedcba' | -| HardcodedCredentials.js:29:35:29:44 | 'hgfedcba' | -| HardcodedCredentials.js:29:35:29:44 | 'hgfedcba' | -| HardcodedCredentials.js:35:15:35:24 | 'username' | -| HardcodedCredentials.js:35:15:35:24 | 'username' | -| HardcodedCredentials.js:35:15:35:24 | 'username' | -| HardcodedCredentials.js:35:27:35:36 | 'hgfedcba' | -| HardcodedCredentials.js:35:27:35:36 | 'hgfedcba' | -| HardcodedCredentials.js:35:27:35:36 | 'hgfedcba' | -| HardcodedCredentials.js:41:38:41:47 | 'username' | -| HardcodedCredentials.js:41:38:41:47 | 'username' | -| HardcodedCredentials.js:41:38:41:47 | 'username' | -| HardcodedCredentials.js:41:67:41:76 | 'hgfedcba' | -| HardcodedCredentials.js:41:67:41:76 | 'hgfedcba' | -| HardcodedCredentials.js:41:67:41:76 | 'hgfedcba' | -| HardcodedCredentials.js:42:35:42:44 | 'username' | -| HardcodedCredentials.js:42:35:42:44 | 'username' | -| HardcodedCredentials.js:42:35:42:44 | 'username' | -| HardcodedCredentials.js:42:64:42:73 | 'hgfedcba' | -| HardcodedCredentials.js:42:64:42:73 | 'hgfedcba' | -| HardcodedCredentials.js:42:64:42:73 | 'hgfedcba' | -| HardcodedCredentials.js:44:34:44:43 | 'username' | -| HardcodedCredentials.js:44:34:44:43 | 'username' | -| HardcodedCredentials.js:44:34:44:43 | 'username' | -| HardcodedCredentials.js:44:63:44:72 | 'hgfedcba' | -| HardcodedCredentials.js:44:63:44:72 | 'hgfedcba' | -| HardcodedCredentials.js:44:63:44:72 | 'hgfedcba' | -| HardcodedCredentials.js:46:25:46:34 | 'hgfedcba' | -| HardcodedCredentials.js:46:25:46:34 | 'hgfedcba' | -| HardcodedCredentials.js:46:25:46:34 | 'hgfedcba' | -| HardcodedCredentials.js:53:27:53:36 | 'username' | -| HardcodedCredentials.js:53:27:53:36 | 'username' | -| HardcodedCredentials.js:53:27:53:36 | 'username' | -| HardcodedCredentials.js:53:39:53:48 | 'hgfedcba' | -| HardcodedCredentials.js:53:39:53:48 | 'hgfedcba' | -| HardcodedCredentials.js:53:39:53:48 | 'hgfedcba' | -| HardcodedCredentials.js:56:21:56:30 | 'username' | -| HardcodedCredentials.js:56:21:56:30 | 'username' | -| HardcodedCredentials.js:56:21:56:30 | 'username' | -| HardcodedCredentials.js:57:21:57:30 | 'hgfedcba' | -| HardcodedCredentials.js:57:21:57:30 | 'hgfedcba' | -| HardcodedCredentials.js:57:21:57:30 | 'hgfedcba' | -| HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | -| HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | -| HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | -| HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | -| HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | -| HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | -| HardcodedCredentials.js:69:28:69:37 | 'username' | -| HardcodedCredentials.js:69:28:69:37 | 'username' | -| HardcodedCredentials.js:69:28:69:37 | 'username' | -| HardcodedCredentials.js:69:40:69:49 | 'hgfedcba' | -| HardcodedCredentials.js:69:40:69:49 | 'hgfedcba' | -| HardcodedCredentials.js:69:40:69:49 | 'hgfedcba' | -| HardcodedCredentials.js:70:28:70:37 | 'username' | -| HardcodedCredentials.js:70:28:70:37 | 'username' | -| HardcodedCredentials.js:70:28:70:37 | 'username' | -| HardcodedCredentials.js:70:40:70:49 | 'hgfedcba' | -| HardcodedCredentials.js:70:40:70:49 | 'hgfedcba' | -| HardcodedCredentials.js:70:40:70:49 | 'hgfedcba' | -| HardcodedCredentials.js:72:23:72:32 | 'username' | -| HardcodedCredentials.js:72:23:72:32 | 'username' | -| HardcodedCredentials.js:72:23:72:32 | 'username' | -| HardcodedCredentials.js:72:35:72:44 | 'hgfedcba' | -| HardcodedCredentials.js:72:35:72:44 | 'hgfedcba' | -| HardcodedCredentials.js:72:35:72:44 | 'hgfedcba' | -| HardcodedCredentials.js:75:21:75:30 | 'username' | -| HardcodedCredentials.js:75:21:75:30 | 'username' | -| HardcodedCredentials.js:75:21:75:30 | 'username' | -| HardcodedCredentials.js:76:21:76:30 | 'hgfedcba' | -| HardcodedCredentials.js:76:21:76:30 | 'hgfedcba' | -| HardcodedCredentials.js:76:21:76:30 | 'hgfedcba' | -| HardcodedCredentials.js:84:38:84:47 | 'username' | -| HardcodedCredentials.js:84:38:84:47 | 'username' | -| HardcodedCredentials.js:84:38:84:47 | 'username' | -| HardcodedCredentials.js:84:50:84:59 | 'hgfedcba' | -| HardcodedCredentials.js:84:50:84:59 | 'hgfedcba' | -| HardcodedCredentials.js:84:50:84:59 | 'hgfedcba' | -| HardcodedCredentials.js:86:44:86:53 | 'username' | -| HardcodedCredentials.js:86:44:86:53 | 'username' | -| HardcodedCredentials.js:86:44:86:53 | 'username' | -| HardcodedCredentials.js:86:56:86:65 | 'hgfedcba' | -| HardcodedCredentials.js:86:56:86:65 | 'hgfedcba' | -| HardcodedCredentials.js:86:56:86:65 | 'hgfedcba' | -| HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | -| HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | -| HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | -| HardcodedCredentials.js:98:18:98:21 | 'x1' | -| HardcodedCredentials.js:98:18:98:21 | 'x1' | -| HardcodedCredentials.js:98:18:98:21 | 'x1' | -| HardcodedCredentials.js:99:16:99:19 | 'x2' | -| HardcodedCredentials.js:99:16:99:19 | 'x2' | -| HardcodedCredentials.js:99:16:99:19 | 'x2' | -| HardcodedCredentials.js:100:25:100:28 | 'x3' | -| HardcodedCredentials.js:100:25:100:28 | 'x3' | -| HardcodedCredentials.js:100:25:100:28 | 'x3' | -| HardcodedCredentials.js:101:19:101:22 | 'x4' | -| HardcodedCredentials.js:101:19:101:22 | 'x4' | -| HardcodedCredentials.js:101:19:101:22 | 'x4' | -| HardcodedCredentials.js:102:14:102:23 | 'hgfedcba' | -| HardcodedCredentials.js:102:14:102:23 | 'hgfedcba' | -| HardcodedCredentials.js:102:14:102:23 | 'hgfedcba' | -| HardcodedCredentials.js:103:17:103:26 | 'hgfedcba' | -| HardcodedCredentials.js:103:17:103:26 | 'hgfedcba' | -| HardcodedCredentials.js:103:17:103:26 | 'hgfedcba' | -| HardcodedCredentials.js:104:27:104:36 | 'hgfedcba' | -| HardcodedCredentials.js:104:27:104:36 | 'hgfedcba' | -| HardcodedCredentials.js:104:27:104:36 | 'hgfedcba' | -| HardcodedCredentials.js:105:19:105:28 | 'hgfedcba' | -| HardcodedCredentials.js:105:19:105:28 | 'hgfedcba' | -| HardcodedCredentials.js:105:19:105:28 | 'hgfedcba' | -| HardcodedCredentials.js:106:16:106:25 | 'hgfedcba' | -| HardcodedCredentials.js:106:16:106:25 | 'hgfedcba' | -| HardcodedCredentials.js:106:16:106:25 | 'hgfedcba' | -| HardcodedCredentials.js:112:19:112:22 | 'x5' | -| HardcodedCredentials.js:112:19:112:22 | 'x5' | -| HardcodedCredentials.js:112:19:112:22 | 'x5' | -| HardcodedCredentials.js:113:19:113:28 | 'hgfedcba' | -| HardcodedCredentials.js:113:19:113:28 | 'hgfedcba' | -| HardcodedCredentials.js:113:19:113:28 | 'hgfedcba' | -| HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | -| HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | -| HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | -| HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | -| HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | -| HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | -| HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | -| HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | -| HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | -| HardcodedCredentials.js:160:38:160:48 | "change_me" | -| HardcodedCredentials.js:160:38:160:48 | "change_me" | -| HardcodedCredentials.js:160:38:160:48 | "change_me" | -| HardcodedCredentials.js:161:41:161:51 | 'change_me' | -| HardcodedCredentials.js:161:41:161:51 | 'change_me' | -| HardcodedCredentials.js:161:41:161:51 | 'change_me' | -| HardcodedCredentials.js:164:35:164:45 | 'change_me' | -| HardcodedCredentials.js:164:35:164:45 | 'change_me' | -| HardcodedCredentials.js:164:35:164:45 | 'change_me' | -| HardcodedCredentials.js:171:11:171:25 | USER | -| HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | -| HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | -| HardcodedCredentials.js:172:11:172:25 | PASS | -| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | -| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | -| HardcodedCredentials.js:173:11:173:49 | AUTH | -| HardcodedCredentials.js:173:18:173:49 | base64. ... PASS}`) | -| HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | -| HardcodedCredentials.js:173:35:173:38 | USER | -| HardcodedCredentials.js:173:43:173:46 | PASS | -| HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | -| HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | -| HardcodedCredentials.js:178:39:178:42 | AUTH | -| HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | -| HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | -| HardcodedCredentials.js:188:39:188:42 | AUTH | -| HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | -| HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | -| HardcodedCredentials.js:195:46:195:49 | AUTH | -| HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` | -| HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` | -| HardcodedCredentials.js:204:44:204:47 | AUTH | -| HardcodedCredentials.js:214:11:214:25 | USER | -| HardcodedCredentials.js:214:18:214:25 | 'sdsdag' | -| HardcodedCredentials.js:214:18:214:25 | 'sdsdag' | -| HardcodedCredentials.js:215:11:215:25 | PASS | -| HardcodedCredentials.js:215:18:215:25 | 'sdsdag' | -| HardcodedCredentials.js:215:18:215:25 | 'sdsdag' | -| HardcodedCredentials.js:216:11:216:49 | AUTH | -| HardcodedCredentials.js:216:18:216:49 | base64. ... PASS}`) | -| HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | -| HardcodedCredentials.js:216:35:216:38 | USER | -| HardcodedCredentials.js:216:43:216:46 | PASS | -| HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | -| HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | -| HardcodedCredentials.js:221:46:221:49 | AUTH | -| HardcodedCredentials.js:231:11:231:29 | username | -| HardcodedCredentials.js:231:22:231:29 | 'sdsdag' | -| HardcodedCredentials.js:231:22:231:29 | 'sdsdag' | -| HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') | -| HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') | -| HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) | -| HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | -| HardcodedCredentials.js:237:47:237:54 | username | -| HardcodedCredentials.js:237:47:237:71 | usernam ... assword | -| HardcodedCredentials.js:245:9:245:44 | privateKey | -| HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | -| HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | -| HardcodedCredentials.js:246:42:246:51 | privateKey | -| HardcodedCredentials.js:246:42:246:51 | privateKey | -| HardcodedCredentials.js:260:30:260:40 | `Basic foo` | -| HardcodedCredentials.js:260:30:260:40 | `Basic foo` | -| HardcodedCredentials.js:260:30:260:40 | `Basic foo` | -| HardcodedCredentials.js:268:30:268:73 | `${foo ... Token}` | -| HardcodedCredentials.js:268:30:268:73 | `${foo ... Token}` | -| HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | -| HardcodedCredentials.js:268:39:268:46 | 'Bearer' | -| HardcodedCredentials.js:268:39:268:46 | 'Bearer' | -| HardcodedCredentials.js:268:50:268:56 | 'OAuth' | -| HardcodedCredentials.js:268:50:268:56 | 'OAuth' | -| HardcodedCredentials.js:275:36:275:59 | "user:{ ... ERE }}" | -| HardcodedCredentials.js:275:36:275:59 | "user:{ ... ERE }}" | -| HardcodedCredentials.js:275:36:275:59 | "user:{ ... ERE }}" | -| HardcodedCredentials.js:276:36:276:65 | "user:t ... ERE }}" | -| HardcodedCredentials.js:276:36:276:65 | "user:t ... ERE }}" | -| HardcodedCredentials.js:276:36:276:65 | "user:t ... ERE }}" | -| HardcodedCredentials.js:277:36:277:57 | "user:( ... HERE )" | -| HardcodedCredentials.js:277:36:277:57 | "user:( ... HERE )" | -| HardcodedCredentials.js:277:36:277:57 | "user:( ... HERE )" | -| HardcodedCredentials.js:278:36:278:64 | "user:{ ... ken }}" | -| HardcodedCredentials.js:278:36:278:64 | "user:{ ... ken }}" | -| HardcodedCredentials.js:278:36:278:64 | "user:{ ... ken }}" | -| HardcodedCredentials.js:279:36:279:50 | "user:abcdefgh" | -| HardcodedCredentials.js:279:36:279:50 | "user:abcdefgh" | -| HardcodedCredentials.js:279:36:279:50 | "user:abcdefgh" | -| HardcodedCredentials.js:280:36:280:50 | "user:12345678" | -| HardcodedCredentials.js:280:36:280:50 | "user:12345678" | -| HardcodedCredentials.js:280:36:280:50 | "user:12345678" | -| HardcodedCredentials.js:281:36:281:45 | "user:foo" | -| HardcodedCredentials.js:281:36:281:45 | "user:foo" | -| HardcodedCredentials.js:281:36:281:45 | "user:foo" | -| HardcodedCredentials.js:282:36:282:52 | "user:mypassword" | -| HardcodedCredentials.js:282:36:282:52 | "user:mypassword" | -| HardcodedCredentials.js:282:36:282:52 | "user:mypassword" | -| HardcodedCredentials.js:283:36:283:49 | "user:mytoken" | -| HardcodedCredentials.js:283:36:283:49 | "user:mytoken" | -| HardcodedCredentials.js:283:36:283:49 | "user:mytoken" | -| HardcodedCredentials.js:284:36:284:52 | "user:fake token" | -| HardcodedCredentials.js:284:36:284:52 | "user:fake token" | -| HardcodedCredentials.js:284:36:284:52 | "user:fake token" | -| HardcodedCredentials.js:285:36:285:46 | "user:dcba" | -| HardcodedCredentials.js:285:36:285:46 | "user:dcba" | -| HardcodedCredentials.js:285:36:285:46 | "user:dcba" | -| HardcodedCredentials.js:286:36:286:55 | "user:custom string" | -| HardcodedCredentials.js:286:36:286:55 | "user:custom string" | -| HardcodedCredentials.js:286:36:286:55 | "user:custom string" | -| HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | -| HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | -| HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | -| HardcodedCredentials.js:293:37:293:65 | `Basic ... xxxxxx` | -| HardcodedCredentials.js:293:37:293:65 | `Basic ... xxxxxx` | -| HardcodedCredentials.js:293:37:293:65 | `Basic ... xxxxxx` | -| HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | -| HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | -| HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | -| HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | -| HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | -| HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | edges -| HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | -| HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | -| HardcodedCredentials.js:15:36:15:50 | "user:hgfedcba" | HardcodedCredentials.js:15:36:15:50 | "user:hgfedcba" | -| HardcodedCredentials.js:16:37:16:51 | "user:hgfedcba" | HardcodedCredentials.js:16:37:16:51 | "user:hgfedcba" | | HardcodedCredentials.js:18:16:18:30 | "user:hgfedcba" | HardcodedCredentials.js:20:36:20:51 | getCredentials() | -| HardcodedCredentials.js:18:16:18:30 | "user:hgfedcba" | HardcodedCredentials.js:20:36:20:51 | getCredentials() | -| HardcodedCredentials.js:18:16:18:30 | "user:hgfedcba" | HardcodedCredentials.js:20:36:20:51 | getCredentials() | -| HardcodedCredentials.js:18:16:18:30 | "user:hgfedcba" | HardcodedCredentials.js:20:36:20:51 | getCredentials() | -| HardcodedCredentials.js:27:25:27:31 | 'admin' | HardcodedCredentials.js:27:25:27:31 | 'admin' | -| HardcodedCredentials.js:27:34:27:43 | 'hgfedcba' | HardcodedCredentials.js:27:34:27:43 | 'hgfedcba' | -| HardcodedCredentials.js:29:11:29:30 | 'unknown-admin-name' | HardcodedCredentials.js:29:11:29:30 | 'unknown-admin-name' | -| HardcodedCredentials.js:29:35:29:44 | 'hgfedcba' | HardcodedCredentials.js:29:35:29:44 | 'hgfedcba' | -| HardcodedCredentials.js:35:15:35:24 | 'username' | HardcodedCredentials.js:35:15:35:24 | 'username' | -| HardcodedCredentials.js:35:27:35:36 | 'hgfedcba' | HardcodedCredentials.js:35:27:35:36 | 'hgfedcba' | -| HardcodedCredentials.js:41:38:41:47 | 'username' | HardcodedCredentials.js:41:38:41:47 | 'username' | -| HardcodedCredentials.js:41:67:41:76 | 'hgfedcba' | HardcodedCredentials.js:41:67:41:76 | 'hgfedcba' | -| HardcodedCredentials.js:42:35:42:44 | 'username' | HardcodedCredentials.js:42:35:42:44 | 'username' | -| HardcodedCredentials.js:42:64:42:73 | 'hgfedcba' | HardcodedCredentials.js:42:64:42:73 | 'hgfedcba' | -| HardcodedCredentials.js:44:34:44:43 | 'username' | HardcodedCredentials.js:44:34:44:43 | 'username' | -| HardcodedCredentials.js:44:63:44:72 | 'hgfedcba' | HardcodedCredentials.js:44:63:44:72 | 'hgfedcba' | -| HardcodedCredentials.js:46:25:46:34 | 'hgfedcba' | HardcodedCredentials.js:46:25:46:34 | 'hgfedcba' | -| HardcodedCredentials.js:53:27:53:36 | 'username' | HardcodedCredentials.js:53:27:53:36 | 'username' | -| HardcodedCredentials.js:53:39:53:48 | 'hgfedcba' | HardcodedCredentials.js:53:39:53:48 | 'hgfedcba' | -| HardcodedCredentials.js:56:21:56:30 | 'username' | HardcodedCredentials.js:56:21:56:30 | 'username' | -| HardcodedCredentials.js:57:21:57:30 | 'hgfedcba' | HardcodedCredentials.js:57:21:57:30 | 'hgfedcba' | -| HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | -| HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | -| HardcodedCredentials.js:69:28:69:37 | 'username' | HardcodedCredentials.js:69:28:69:37 | 'username' | -| HardcodedCredentials.js:69:40:69:49 | 'hgfedcba' | HardcodedCredentials.js:69:40:69:49 | 'hgfedcba' | -| HardcodedCredentials.js:70:28:70:37 | 'username' | HardcodedCredentials.js:70:28:70:37 | 'username' | -| HardcodedCredentials.js:70:40:70:49 | 'hgfedcba' | HardcodedCredentials.js:70:40:70:49 | 'hgfedcba' | -| HardcodedCredentials.js:72:23:72:32 | 'username' | HardcodedCredentials.js:72:23:72:32 | 'username' | -| HardcodedCredentials.js:72:35:72:44 | 'hgfedcba' | HardcodedCredentials.js:72:35:72:44 | 'hgfedcba' | -| HardcodedCredentials.js:75:21:75:30 | 'username' | HardcodedCredentials.js:75:21:75:30 | 'username' | -| HardcodedCredentials.js:76:21:76:30 | 'hgfedcba' | HardcodedCredentials.js:76:21:76:30 | 'hgfedcba' | -| HardcodedCredentials.js:84:38:84:47 | 'username' | HardcodedCredentials.js:84:38:84:47 | 'username' | -| HardcodedCredentials.js:84:50:84:59 | 'hgfedcba' | HardcodedCredentials.js:84:50:84:59 | 'hgfedcba' | -| HardcodedCredentials.js:86:44:86:53 | 'username' | HardcodedCredentials.js:86:44:86:53 | 'username' | -| HardcodedCredentials.js:86:56:86:65 | 'hgfedcba' | HardcodedCredentials.js:86:56:86:65 | 'hgfedcba' | -| HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | -| HardcodedCredentials.js:98:18:98:21 | 'x1' | HardcodedCredentials.js:98:18:98:21 | 'x1' | -| HardcodedCredentials.js:99:16:99:19 | 'x2' | HardcodedCredentials.js:99:16:99:19 | 'x2' | -| HardcodedCredentials.js:100:25:100:28 | 'x3' | HardcodedCredentials.js:100:25:100:28 | 'x3' | -| HardcodedCredentials.js:101:19:101:22 | 'x4' | HardcodedCredentials.js:101:19:101:22 | 'x4' | -| HardcodedCredentials.js:102:14:102:23 | 'hgfedcba' | HardcodedCredentials.js:102:14:102:23 | 'hgfedcba' | -| HardcodedCredentials.js:103:17:103:26 | 'hgfedcba' | HardcodedCredentials.js:103:17:103:26 | 'hgfedcba' | -| HardcodedCredentials.js:104:27:104:36 | 'hgfedcba' | HardcodedCredentials.js:104:27:104:36 | 'hgfedcba' | -| HardcodedCredentials.js:105:19:105:28 | 'hgfedcba' | HardcodedCredentials.js:105:19:105:28 | 'hgfedcba' | -| HardcodedCredentials.js:106:16:106:25 | 'hgfedcba' | HardcodedCredentials.js:106:16:106:25 | 'hgfedcba' | -| HardcodedCredentials.js:112:19:112:22 | 'x5' | HardcodedCredentials.js:112:19:112:22 | 'x5' | -| HardcodedCredentials.js:113:19:113:28 | 'hgfedcba' | HardcodedCredentials.js:113:19:113:28 | 'hgfedcba' | -| HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | -| HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | -| HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | -| HardcodedCredentials.js:160:38:160:48 | "change_me" | HardcodedCredentials.js:160:38:160:48 | "change_me" | -| HardcodedCredentials.js:161:41:161:51 | 'change_me' | HardcodedCredentials.js:161:41:161:51 | 'change_me' | -| HardcodedCredentials.js:164:35:164:45 | 'change_me' | HardcodedCredentials.js:164:35:164:45 | 'change_me' | | HardcodedCredentials.js:171:11:171:25 | USER | HardcodedCredentials.js:173:35:173:38 | USER | | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:11:171:25 | USER | -| HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:11:171:25 | USER | | HardcodedCredentials.js:172:11:172:25 | PASS | HardcodedCredentials.js:173:43:173:46 | PASS | | HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:172:11:172:25 | PASS | -| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:172:11:172:25 | PASS | | HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:178:39:178:42 | AUTH | | HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:188:39:188:42 | AUTH | | HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:195:46:195:49 | AUTH | @@ -344,61 +13,146 @@ edges | HardcodedCredentials.js:173:35:173:38 | USER | HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | | HardcodedCredentials.js:173:43:173:46 | PASS | HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | | HardcodedCredentials.js:178:39:178:42 | AUTH | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | -| HardcodedCredentials.js:178:39:178:42 | AUTH | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | -| HardcodedCredentials.js:188:39:188:42 | AUTH | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | | HardcodedCredentials.js:188:39:188:42 | AUTH | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | | HardcodedCredentials.js:195:46:195:49 | AUTH | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | -| HardcodedCredentials.js:195:46:195:49 | AUTH | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | -| HardcodedCredentials.js:204:44:204:47 | AUTH | HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` | | HardcodedCredentials.js:204:44:204:47 | AUTH | HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` | | HardcodedCredentials.js:214:11:214:25 | USER | HardcodedCredentials.js:216:35:216:38 | USER | | HardcodedCredentials.js:214:18:214:25 | 'sdsdag' | HardcodedCredentials.js:214:11:214:25 | USER | -| HardcodedCredentials.js:214:18:214:25 | 'sdsdag' | HardcodedCredentials.js:214:11:214:25 | USER | | HardcodedCredentials.js:215:11:215:25 | PASS | HardcodedCredentials.js:216:43:216:46 | PASS | | HardcodedCredentials.js:215:18:215:25 | 'sdsdag' | HardcodedCredentials.js:215:11:215:25 | PASS | -| HardcodedCredentials.js:215:18:215:25 | 'sdsdag' | HardcodedCredentials.js:215:11:215:25 | PASS | | HardcodedCredentials.js:216:11:216:49 | AUTH | HardcodedCredentials.js:221:46:221:49 | AUTH | | HardcodedCredentials.js:216:18:216:49 | base64. ... PASS}`) | HardcodedCredentials.js:216:11:216:49 | AUTH | | HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | HardcodedCredentials.js:216:18:216:49 | base64. ... PASS}`) | | HardcodedCredentials.js:216:35:216:38 | USER | HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | | HardcodedCredentials.js:216:43:216:46 | PASS | HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | | HardcodedCredentials.js:221:46:221:49 | AUTH | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | -| HardcodedCredentials.js:221:46:221:49 | AUTH | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | | HardcodedCredentials.js:231:11:231:29 | username | HardcodedCredentials.js:237:47:237:54 | username | | HardcodedCredentials.js:231:22:231:29 | 'sdsdag' | HardcodedCredentials.js:231:11:231:29 | username | -| HardcodedCredentials.js:231:22:231:29 | 'sdsdag' | HardcodedCredentials.js:231:11:231:29 | username | | HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) | HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | | HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') | -| HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') | | HardcodedCredentials.js:237:47:237:54 | username | HardcodedCredentials.js:237:47:237:71 | usernam ... assword | | HardcodedCredentials.js:237:47:237:71 | usernam ... assword | HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) | | HardcodedCredentials.js:245:9:245:44 | privateKey | HardcodedCredentials.js:246:42:246:51 | privateKey | -| HardcodedCredentials.js:245:9:245:44 | privateKey | HardcodedCredentials.js:246:42:246:51 | privateKey | | HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:245:9:245:44 | privateKey | -| HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:245:9:245:44 | privateKey | -| HardcodedCredentials.js:260:30:260:40 | `Basic foo` | HardcodedCredentials.js:260:30:260:40 | `Basic foo` | -| HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | HardcodedCredentials.js:268:30:268:73 | `${foo ... Token}` | | HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | HardcodedCredentials.js:268:30:268:73 | `${foo ... Token}` | | HardcodedCredentials.js:268:39:268:46 | 'Bearer' | HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | -| HardcodedCredentials.js:268:39:268:46 | 'Bearer' | HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | | HardcodedCredentials.js:268:50:268:56 | 'OAuth' | HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | -| HardcodedCredentials.js:268:50:268:56 | 'OAuth' | HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | -| HardcodedCredentials.js:275:36:275:59 | "user:{ ... ERE }}" | HardcodedCredentials.js:275:36:275:59 | "user:{ ... ERE }}" | -| HardcodedCredentials.js:276:36:276:65 | "user:t ... ERE }}" | HardcodedCredentials.js:276:36:276:65 | "user:t ... ERE }}" | -| HardcodedCredentials.js:277:36:277:57 | "user:( ... HERE )" | HardcodedCredentials.js:277:36:277:57 | "user:( ... HERE )" | -| HardcodedCredentials.js:278:36:278:64 | "user:{ ... ken }}" | HardcodedCredentials.js:278:36:278:64 | "user:{ ... ken }}" | -| HardcodedCredentials.js:279:36:279:50 | "user:abcdefgh" | HardcodedCredentials.js:279:36:279:50 | "user:abcdefgh" | -| HardcodedCredentials.js:280:36:280:50 | "user:12345678" | HardcodedCredentials.js:280:36:280:50 | "user:12345678" | -| HardcodedCredentials.js:281:36:281:45 | "user:foo" | HardcodedCredentials.js:281:36:281:45 | "user:foo" | -| HardcodedCredentials.js:282:36:282:52 | "user:mypassword" | HardcodedCredentials.js:282:36:282:52 | "user:mypassword" | -| HardcodedCredentials.js:283:36:283:49 | "user:mytoken" | HardcodedCredentials.js:283:36:283:49 | "user:mytoken" | -| HardcodedCredentials.js:284:36:284:52 | "user:fake token" | HardcodedCredentials.js:284:36:284:52 | "user:fake token" | -| HardcodedCredentials.js:285:36:285:46 | "user:dcba" | HardcodedCredentials.js:285:36:285:46 | "user:dcba" | -| HardcodedCredentials.js:286:36:286:55 | "user:custom string" | HardcodedCredentials.js:286:36:286:55 | "user:custom string" | -| HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | -| HardcodedCredentials.js:293:37:293:65 | `Basic ... xxxxxx` | HardcodedCredentials.js:293:37:293:65 | `Basic ... xxxxxx` | -| HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | -| HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | +nodes +| HardcodedCredentials.js:5:15:5:22 | 'dbuser' | semmle.label | 'dbuser' | +| HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:15:36:15:50 | "user:hgfedcba" | semmle.label | "user:hgfedcba" | +| HardcodedCredentials.js:16:37:16:51 | "user:hgfedcba" | semmle.label | "user:hgfedcba" | +| HardcodedCredentials.js:18:16:18:30 | "user:hgfedcba" | semmle.label | "user:hgfedcba" | +| HardcodedCredentials.js:20:36:20:51 | getCredentials() | semmle.label | getCredentials() | +| HardcodedCredentials.js:27:25:27:31 | 'admin' | semmle.label | 'admin' | +| HardcodedCredentials.js:27:34:27:43 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:29:11:29:30 | 'unknown-admin-name' | semmle.label | 'unknown-admin-name' | +| HardcodedCredentials.js:29:35:29:44 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:35:15:35:24 | 'username' | semmle.label | 'username' | +| HardcodedCredentials.js:35:27:35:36 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:41:38:41:47 | 'username' | semmle.label | 'username' | +| HardcodedCredentials.js:41:67:41:76 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:42:35:42:44 | 'username' | semmle.label | 'username' | +| HardcodedCredentials.js:42:64:42:73 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:44:34:44:43 | 'username' | semmle.label | 'username' | +| HardcodedCredentials.js:44:63:44:72 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:46:25:46:34 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:53:27:53:36 | 'username' | semmle.label | 'username' | +| HardcodedCredentials.js:53:39:53:48 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:56:21:56:30 | 'username' | semmle.label | 'username' | +| HardcodedCredentials.js:57:21:57:30 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | semmle.label | 'bearerToken' | +| HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | semmle.label | 'bearerToken' | +| HardcodedCredentials.js:69:28:69:37 | 'username' | semmle.label | 'username' | +| HardcodedCredentials.js:69:40:69:49 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:70:28:70:37 | 'username' | semmle.label | 'username' | +| HardcodedCredentials.js:70:40:70:49 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:72:23:72:32 | 'username' | semmle.label | 'username' | +| HardcodedCredentials.js:72:35:72:44 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:75:21:75:30 | 'username' | semmle.label | 'username' | +| HardcodedCredentials.js:76:21:76:30 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:84:38:84:47 | 'username' | semmle.label | 'username' | +| HardcodedCredentials.js:84:50:84:59 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:86:44:86:53 | 'username' | semmle.label | 'username' | +| HardcodedCredentials.js:86:56:86:65 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | semmle.label | 'TOKEN' | +| HardcodedCredentials.js:98:18:98:21 | 'x1' | semmle.label | 'x1' | +| HardcodedCredentials.js:99:16:99:19 | 'x2' | semmle.label | 'x2' | +| HardcodedCredentials.js:100:25:100:28 | 'x3' | semmle.label | 'x3' | +| HardcodedCredentials.js:101:19:101:22 | 'x4' | semmle.label | 'x4' | +| HardcodedCredentials.js:102:14:102:23 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:103:17:103:26 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:104:27:104:36 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:105:19:105:28 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:106:16:106:25 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:112:19:112:22 | 'x5' | semmle.label | 'x5' | +| HardcodedCredentials.js:113:19:113:28 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | semmle.label | 'hgfedcba' | +| HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | semmle.label | "hgfedcba" | +| HardcodedCredentials.js:160:38:160:48 | "change_me" | semmle.label | "change_me" | +| HardcodedCredentials.js:161:41:161:51 | 'change_me' | semmle.label | 'change_me' | +| HardcodedCredentials.js:164:35:164:45 | 'change_me' | semmle.label | 'change_me' | +| HardcodedCredentials.js:171:11:171:25 | USER | semmle.label | USER | +| HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | semmle.label | 'sdsdag' | +| HardcodedCredentials.js:172:11:172:25 | PASS | semmle.label | PASS | +| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | semmle.label | 'sdsdag' | +| HardcodedCredentials.js:173:11:173:49 | AUTH | semmle.label | AUTH | +| HardcodedCredentials.js:173:18:173:49 | base64. ... PASS}`) | semmle.label | base64. ... PASS}`) | +| HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | semmle.label | `${USER}:${PASS}` | +| HardcodedCredentials.js:173:35:173:38 | USER | semmle.label | USER | +| HardcodedCredentials.js:173:43:173:46 | PASS | semmle.label | PASS | +| HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | semmle.label | `Basic ${AUTH}` | +| HardcodedCredentials.js:178:39:178:42 | AUTH | semmle.label | AUTH | +| HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | semmle.label | `Basic ${AUTH}` | +| HardcodedCredentials.js:188:39:188:42 | AUTH | semmle.label | AUTH | +| HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | semmle.label | `Basic ${AUTH}` | +| HardcodedCredentials.js:195:46:195:49 | AUTH | semmle.label | AUTH | +| HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` | semmle.label | `Basic ${AUTH}` | +| HardcodedCredentials.js:204:44:204:47 | AUTH | semmle.label | AUTH | +| HardcodedCredentials.js:214:11:214:25 | USER | semmle.label | USER | +| HardcodedCredentials.js:214:18:214:25 | 'sdsdag' | semmle.label | 'sdsdag' | +| HardcodedCredentials.js:215:11:215:25 | PASS | semmle.label | PASS | +| HardcodedCredentials.js:215:18:215:25 | 'sdsdag' | semmle.label | 'sdsdag' | +| HardcodedCredentials.js:216:11:216:49 | AUTH | semmle.label | AUTH | +| HardcodedCredentials.js:216:18:216:49 | base64. ... PASS}`) | semmle.label | base64. ... PASS}`) | +| HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | semmle.label | `${USER}:${PASS}` | +| HardcodedCredentials.js:216:35:216:38 | USER | semmle.label | USER | +| HardcodedCredentials.js:216:43:216:46 | PASS | semmle.label | PASS | +| HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | semmle.label | `Basic ${AUTH}` | +| HardcodedCredentials.js:221:46:221:49 | AUTH | semmle.label | AUTH | +| HardcodedCredentials.js:231:11:231:29 | username | semmle.label | username | +| HardcodedCredentials.js:231:22:231:29 | 'sdsdag' | semmle.label | 'sdsdag' | +| HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') | semmle.label | 'Basic ... ase64') | +| HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) | semmle.label | Buffer. ... ssword) | +| HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | semmle.label | Buffer. ... ase64') | +| HardcodedCredentials.js:237:47:237:54 | username | semmle.label | username | +| HardcodedCredentials.js:237:47:237:71 | usernam ... assword | semmle.label | usernam ... assword | +| HardcodedCredentials.js:245:9:245:44 | privateKey | semmle.label | privateKey | +| HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | semmle.label | "myHard ... ateKey" | +| HardcodedCredentials.js:246:42:246:51 | privateKey | semmle.label | privateKey | +| HardcodedCredentials.js:260:30:260:40 | `Basic foo` | semmle.label | `Basic foo` | +| HardcodedCredentials.js:268:30:268:73 | `${foo ... Token}` | semmle.label | `${foo ... Token}` | +| HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | semmle.label | foo ? ' ... 'OAuth' | +| HardcodedCredentials.js:268:39:268:46 | 'Bearer' | semmle.label | 'Bearer' | +| HardcodedCredentials.js:268:50:268:56 | 'OAuth' | semmle.label | 'OAuth' | +| HardcodedCredentials.js:275:36:275:59 | "user:{ ... ERE }}" | semmle.label | "user:{ ... ERE }}" | +| HardcodedCredentials.js:276:36:276:65 | "user:t ... ERE }}" | semmle.label | "user:t ... ERE }}" | +| HardcodedCredentials.js:277:36:277:57 | "user:( ... HERE )" | semmle.label | "user:( ... HERE )" | +| HardcodedCredentials.js:278:36:278:64 | "user:{ ... ken }}" | semmle.label | "user:{ ... ken }}" | +| HardcodedCredentials.js:279:36:279:50 | "user:abcdefgh" | semmle.label | "user:abcdefgh" | +| HardcodedCredentials.js:280:36:280:50 | "user:12345678" | semmle.label | "user:12345678" | +| HardcodedCredentials.js:281:36:281:45 | "user:foo" | semmle.label | "user:foo" | +| HardcodedCredentials.js:282:36:282:52 | "user:mypassword" | semmle.label | "user:mypassword" | +| HardcodedCredentials.js:283:36:283:49 | "user:mytoken" | semmle.label | "user:mytoken" | +| HardcodedCredentials.js:284:36:284:52 | "user:fake token" | semmle.label | "user:fake token" | +| HardcodedCredentials.js:285:36:285:46 | "user:dcba" | semmle.label | "user:dcba" | +| HardcodedCredentials.js:286:36:286:55 | "user:custom string" | semmle.label | "user:custom string" | +| HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | semmle.label | `Basic ... sdsdag` | +| HardcodedCredentials.js:293:37:293:65 | `Basic ... xxxxxx` | semmle.label | `Basic ... xxxxxx` | +| HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | semmle.label | `Basic ... gbbbbb` | +| HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | semmle.label | `Basic ... 000001` | +subpaths #select | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | The hard-coded value "dbuser" is used as $@. | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | user name | | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | The hard-coded value "hgfedcba" is used as $@. | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | password | From bc88f50a5f4ca858d047123d4f913be337f5a734 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:18:51 +0200 Subject: [PATCH 076/514] JS: Port HardcodedDataInterpretedAsCode --- .../HardcodedDataInterpretedAsCodeQuery.qll | 32 +++++++++- .../CWE-506/HardcodedDataInterpretedAsCode.ql | 8 ++- .../HardcodedDataInterpretedAsCode.expected | 63 ++++++++++--------- 3 files changed, 68 insertions(+), 35 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedDataInterpretedAsCodeQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedDataInterpretedAsCodeQuery.qll index 7318681a882..55ecdbffe80 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedDataInterpretedAsCodeQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedDataInterpretedAsCodeQuery.qll @@ -15,7 +15,37 @@ import HardcodedDataInterpretedAsCodeCustomizations::HardcodedDataInterpretedAsC * A taint-tracking configuration for reasoning about hard-coded data * being interpreted as code */ -class Configuration extends TaintTracking::Configuration { +module HardcodedDataInterpretedAsCodeConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; + + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel lbl) { + source.(Source).getLabel() = lbl + } + + predicate isSink(DataFlow::Node nd, DataFlow::FlowLabel lbl) { nd.(Sink).getLabel() = lbl } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowLabel state1, DataFlow::Node node2, + DataFlow::FlowLabel state2 + ) { + TaintTracking::defaultTaintStep(node1, node2) and + state1.isDataOrTaint() and + state2.isTaint() + } +} + +/** + * Taint-tracking for reasoning about hard-coded data being interpreted as code + */ +module HardcodedDataInterpretedAsCodeFlow = + DataFlow::GlobalWithState; + +/** + * DEPRECATED. Use the `HardcodedDataInterpretedAsCodeFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "HardcodedDataInterpretedAsCode" } override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel lbl) { diff --git a/javascript/ql/src/Security/CWE-506/HardcodedDataInterpretedAsCode.ql b/javascript/ql/src/Security/CWE-506/HardcodedDataInterpretedAsCode.ql index 9fd53ce9916..bc6a5e5466f 100644 --- a/javascript/ql/src/Security/CWE-506/HardcodedDataInterpretedAsCode.ql +++ b/javascript/ql/src/Security/CWE-506/HardcodedDataInterpretedAsCode.ql @@ -14,10 +14,12 @@ import javascript import semmle.javascript.security.dataflow.HardcodedDataInterpretedAsCodeQuery -import DataFlow::PathGraph +import DataFlow::DeduplicatePathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from PathNode source, PathNode sink +where + HardcodedDataInterpretedAsCodeFlow::flowPath(source.getAnOriginalPathNode(), + sink.getAnOriginalPathNode()) select sink.getNode(), source, sink, "$@ is interpreted as " + sink.getNode().(Sink).getKind() + ".", source.getNode(), "Hard-coded data" diff --git a/javascript/ql/test/query-tests/Security/CWE-506/HardcodedDataInterpretedAsCode.expected b/javascript/ql/test/query-tests/Security/CWE-506/HardcodedDataInterpretedAsCode.expected index 76c630812c5..50fb024e033 100644 --- a/javascript/ql/test/query-tests/Security/CWE-506/HardcodedDataInterpretedAsCode.expected +++ b/javascript/ql/test/query-tests/Security/CWE-506/HardcodedDataInterpretedAsCode.expected @@ -1,45 +1,46 @@ nodes -| event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | -| event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | -| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | -| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | -| event-stream.js:9:11:9:37 | e("2e2f ... 17461") | -| event-stream.js:9:11:9:37 | e("2e2f ... 17461") | -| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | -| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | -| tst.js:1:5:1:88 | totallyHarmlessString | -| tst.js:1:29:1:88 | '636f6e ... 6e2729' | -| tst.js:1:29:1:88 | '636f6e ... 6e2729' | -| tst.js:2:6:2:46 | Buffer. ... 'hex') | -| tst.js:2:6:2:57 | Buffer. ... tring() | -| tst.js:2:6:2:57 | Buffer. ... tring() | -| tst.js:2:18:2:38 | totally ... sString | -| tst.js:5:5:5:23 | test | -| tst.js:5:12:5:23 | "0123456789" | -| tst.js:5:12:5:23 | "0123456789" | -| tst.js:7:8:7:11 | test | -| tst.js:7:8:7:15 | test+"n" | -| tst.js:7:8:7:15 | test+"n" | +| event-stream-orig.js:93:16:93:16 | r | semmle.label | r | +| event-stream-orig.js:94:14:94:34 | Buffer. ... "hex") | semmle.label | Buffer. ... "hex") | +| event-stream-orig.js:94:14:94:45 | Buffer. ... tring() | semmle.label | Buffer. ... tring() | +| event-stream-orig.js:94:26:94:26 | r | semmle.label | r | +| event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | semmle.label | e("2e2f ... 17461") | +| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | semmle.label | "2e2f74 ... 617461" | +| event-stream.js:5:12:5:12 | r | semmle.label | r | +| event-stream.js:6:10:6:30 | Buffer. ... "hex") | semmle.label | Buffer. ... "hex") | +| event-stream.js:6:10:6:41 | Buffer. ... tring() | semmle.label | Buffer. ... tring() | +| event-stream.js:6:22:6:22 | r | semmle.label | r | +| event-stream.js:9:11:9:37 | e("2e2f ... 17461") | semmle.label | e("2e2f ... 17461") | +| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | semmle.label | "2e2f74 ... 617461" | +| tst.js:1:5:1:88 | totallyHarmlessString | semmle.label | totallyHarmlessString | +| tst.js:1:29:1:88 | '636f6e ... 6e2729' | semmle.label | '636f6e ... 6e2729' | +| tst.js:2:6:2:46 | Buffer. ... 'hex') | semmle.label | Buffer. ... 'hex') | +| tst.js:2:6:2:57 | Buffer. ... tring() | semmle.label | Buffer. ... tring() | +| tst.js:2:18:2:38 | totally ... sString | semmle.label | totally ... sString | +| tst.js:5:5:5:23 | test | semmle.label | test | +| tst.js:5:12:5:23 | "0123456789" | semmle.label | "0123456789" | +| tst.js:7:8:7:11 | test | semmle.label | test | +| tst.js:7:8:7:15 | test+"n" | semmle.label | test+"n" | edges +| event-stream-orig.js:93:16:93:16 | r | event-stream-orig.js:94:26:94:26 | r | +| event-stream-orig.js:94:14:94:34 | Buffer. ... "hex") | event-stream-orig.js:94:14:94:45 | Buffer. ... tring() | +| event-stream-orig.js:94:26:94:26 | r | event-stream-orig.js:94:14:94:34 | Buffer. ... "hex") | +| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:93:16:93:16 | r | | event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | -| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | -| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | -| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | -| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | -| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | -| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | +| event-stream.js:5:12:5:12 | r | event-stream.js:6:22:6:22 | r | +| event-stream.js:6:10:6:30 | Buffer. ... "hex") | event-stream.js:6:10:6:41 | Buffer. ... tring() | +| event-stream.js:6:22:6:22 | r | event-stream.js:6:10:6:30 | Buffer. ... "hex") | +| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:5:12:5:12 | r | | event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | | tst.js:1:5:1:88 | totallyHarmlessString | tst.js:2:18:2:38 | totally ... sString | | tst.js:1:29:1:88 | '636f6e ... 6e2729' | tst.js:1:5:1:88 | totallyHarmlessString | -| tst.js:1:29:1:88 | '636f6e ... 6e2729' | tst.js:1:5:1:88 | totallyHarmlessString | -| tst.js:2:6:2:46 | Buffer. ... 'hex') | tst.js:2:6:2:57 | Buffer. ... tring() | | tst.js:2:6:2:46 | Buffer. ... 'hex') | tst.js:2:6:2:57 | Buffer. ... tring() | | tst.js:2:18:2:38 | totally ... sString | tst.js:2:6:2:46 | Buffer. ... 'hex') | | tst.js:5:5:5:23 | test | tst.js:7:8:7:11 | test | | tst.js:5:12:5:23 | "0123456789" | tst.js:5:5:5:23 | test | -| tst.js:5:12:5:23 | "0123456789" | tst.js:5:5:5:23 | test | -| tst.js:7:8:7:11 | test | tst.js:7:8:7:15 | test+"n" | | tst.js:7:8:7:11 | test | tst.js:7:8:7:15 | test+"n" | +subpaths +| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:93:16:93:16 | r | event-stream-orig.js:94:14:94:45 | Buffer. ... tring() | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | +| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:5:12:5:12 | r | event-stream.js:6:10:6:41 | Buffer. ... tring() | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | #select | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | $@ is interpreted as An import path. | event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | Hard-coded data | | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | $@ is interpreted as An import path. | event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | Hard-coded data | From 8715c1b324d078b4417259a235db96d30f22d766 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:19:32 +0200 Subject: [PATCH 077/514] JS: Port HostHeaderPoisoningInEmailGeneration --- ...tHeaderPoisoningInEmailGenerationQuery.qll | 23 +++++++++++++++++-- .../HostHeaderPoisoningInEmailGeneration.ql | 6 ++--- ...tHeaderPoisoningInEmailGeneration.expected | 21 +++++------------ 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGenerationQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGenerationQuery.qll index f87938dfb71..88950066802 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGenerationQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGenerationQuery.qll @@ -6,9 +6,28 @@ import javascript /** - * A taint tracking configuration for host header poisoning in email generation. + * A taint tracking configuration for host header poisoning. */ -class Configuration extends TaintTracking::Configuration { +module HostHeaderPoisoningConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { + exists(Http::RequestHeaderAccess input | node = input | + input.getKind() = "header" and + input.getAHeaderName() = "host" + ) + } + + predicate isSink(DataFlow::Node node) { exists(EmailSender email | node = email.getABody()) } +} + +/** + * Taint tracking configuration host header poisoning. + */ +module HostHeaderPoisoningFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `HostHeaderPoisoningFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "TaintedHostHeader" } override predicate isSource(DataFlow::Node node) { diff --git a/javascript/ql/src/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.ql b/javascript/ql/src/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.ql index 9cb88a29b9d..377fcfcd1cb 100644 --- a/javascript/ql/src/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.ql +++ b/javascript/ql/src/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.ql @@ -13,9 +13,9 @@ import javascript import semmle.javascript.security.dataflow.HostHeaderPoisoningInEmailGenerationQuery -import DataFlow::PathGraph +import HostHeaderPoisoningFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from HostHeaderPoisoningFlow::PathNode source, HostHeaderPoisoningFlow::PathNode sink +where HostHeaderPoisoningFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Links in this email can be hijacked by poisoning the $@.", source.getNode(), "HTTP host header" diff --git a/javascript/ql/test/query-tests/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.expected b/javascript/ql/test/query-tests/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.expected index c1ac8d456f2..12c11f7b2fe 100644 --- a/javascript/ql/test/query-tests/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.expected +++ b/javascript/ql/test/query-tests/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.expected @@ -1,21 +1,12 @@ -nodes -| tst.js:17:11:17:113 | `Hi, lo ... token}` | -| tst.js:17:11:17:113 | `Hi, lo ... token}` | -| tst.js:17:84:17:91 | req.host | -| tst.js:17:84:17:91 | req.host | -| tst.js:18:11:18:127 | `Hi, lo ... reset.` | -| tst.js:18:11:18:127 | `Hi, lo ... reset.` | -| tst.js:18:78:18:85 | req.host | -| tst.js:18:78:18:85 | req.host | edges | tst.js:17:84:17:91 | req.host | tst.js:17:11:17:113 | `Hi, lo ... token}` | -| tst.js:17:84:17:91 | req.host | tst.js:17:11:17:113 | `Hi, lo ... token}` | -| tst.js:17:84:17:91 | req.host | tst.js:17:11:17:113 | `Hi, lo ... token}` | -| tst.js:17:84:17:91 | req.host | tst.js:17:11:17:113 | `Hi, lo ... token}` | -| tst.js:18:78:18:85 | req.host | tst.js:18:11:18:127 | `Hi, lo ... reset.` | -| tst.js:18:78:18:85 | req.host | tst.js:18:11:18:127 | `Hi, lo ... reset.` | -| tst.js:18:78:18:85 | req.host | tst.js:18:11:18:127 | `Hi, lo ... reset.` | | tst.js:18:78:18:85 | req.host | tst.js:18:11:18:127 | `Hi, lo ... reset.` | +nodes +| tst.js:17:11:17:113 | `Hi, lo ... token}` | semmle.label | `Hi, lo ... token}` | +| tst.js:17:84:17:91 | req.host | semmle.label | req.host | +| tst.js:18:11:18:127 | `Hi, lo ... reset.` | semmle.label | `Hi, lo ... reset.` | +| tst.js:18:78:18:85 | req.host | semmle.label | req.host | +subpaths #select | tst.js:17:11:17:113 | `Hi, lo ... token}` | tst.js:17:84:17:91 | req.host | tst.js:17:11:17:113 | `Hi, lo ... token}` | Links in this email can be hijacked by poisoning the $@. | tst.js:17:84:17:91 | req.host | HTTP host header | | tst.js:18:11:18:127 | `Hi, lo ... reset.` | tst.js:18:78:18:85 | req.host | tst.js:18:11:18:127 | `Hi, lo ... reset.` | Links in this email can be hijacked by poisoning the $@. | tst.js:18:78:18:85 | req.host | HTTP host header | From 91287226279b31258eaeb8f15c34f96de78f2578 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:19:50 +0200 Subject: [PATCH 078/514] JS: Port ImproperCodeSanitization --- .../ImproperCodeSanitizationQuery.qll | 18 +++- .../CWE-094/ImproperCodeSanitization.ql | 6 +- .../ImproperCodeSanitization.expected | 85 ++++++------------- 3 files changed, 45 insertions(+), 64 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ImproperCodeSanitizationQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ImproperCodeSanitizationQuery.qll index fd68b3a7077..aad78a027d8 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ImproperCodeSanitizationQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ImproperCodeSanitizationQuery.qll @@ -13,7 +13,23 @@ import ImproperCodeSanitizationCustomizations::ImproperCodeSanitization /** * A taint-tracking configuration for reasoning about improper code sanitization vulnerabilities. */ -class Configuration extends TaintTracking::Configuration { +module ImproperCodeSanitizationConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint-tracking for reasoning about improper code sanitization vulnerabilities. + */ +module ImproperCodeSanitizationFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `ImproperCodeSanitizationFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "ImproperCodeSanitization" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-094/ImproperCodeSanitization.ql b/javascript/ql/src/Security/CWE-094/ImproperCodeSanitization.ql index 181079b05bb..2f13568e928 100644 --- a/javascript/ql/src/Security/CWE-094/ImproperCodeSanitization.ql +++ b/javascript/ql/src/Security/CWE-094/ImproperCodeSanitization.ql @@ -14,9 +14,9 @@ import javascript import semmle.javascript.security.dataflow.ImproperCodeSanitizationQuery -import DataFlow::PathGraph private import semmle.javascript.heuristics.HeuristicSinks private import semmle.javascript.security.dataflow.CodeInjectionCustomizations +import ImproperCodeSanitizationFlow::PathGraph /** * Gets a type-tracked instance of `RemoteFlowSource` using type-tracker `t`. @@ -60,9 +60,9 @@ private DataFlow::Node endsInCodeInjectionSink() { result = endsInCodeInjectionSink(DataFlow::TypeBackTracker::end()) } -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink +from ImproperCodeSanitizationFlow::PathNode source, ImproperCodeSanitizationFlow::PathNode sink where - cfg.hasFlowPath(source, sink) and + ImproperCodeSanitizationFlow::flowPath(source, sink) and // Basic detection of duplicate results with `js/code-injection`. not ( sink.getNode().(StringOps::ConcatenationLeaf).getRoot() = endsInCodeInjectionSink() and diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/ImproperCodeSanitization.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/ImproperCodeSanitization.expected index 0ab2f14e556..ee2425775bb 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/ImproperCodeSanitization.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/ImproperCodeSanitization.expected @@ -1,69 +1,34 @@ -nodes -| bad-code-sanitization.js:2:12:2:90 | /^[_$a- ... key)}]` | -| bad-code-sanitization.js:2:65:2:90 | `[${JSO ... key)}]` | -| bad-code-sanitization.js:2:69:2:87 | JSON.stringify(key) | -| bad-code-sanitization.js:2:69:2:87 | JSON.stringify(key) | -| bad-code-sanitization.js:6:11:6:25 | statements | -| bad-code-sanitization.js:6:24:6:25 | [] | -| bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | -| bad-code-sanitization.js:7:31:7:43 | safeProp(key) | -| bad-code-sanitization.js:8:27:8:36 | statements | -| bad-code-sanitization.js:8:27:8:46 | statements.join(';') | -| bad-code-sanitization.js:8:27:8:46 | statements.join(';') | -| bad-code-sanitization.js:15:44:15:63 | htmlescape(pathname) | -| bad-code-sanitization.js:15:44:15:63 | htmlescape(pathname) | -| bad-code-sanitization.js:15:44:15:63 | htmlescape(pathname) | -| bad-code-sanitization.js:19:27:19:47 | JSON.st ... (input) | -| bad-code-sanitization.js:19:27:19:47 | JSON.st ... (input) | -| bad-code-sanitization.js:19:27:19:47 | JSON.st ... (input) | -| bad-code-sanitization.js:31:30:31:50 | JSON.st ... (input) | -| bad-code-sanitization.js:31:30:31:50 | JSON.st ... (input) | -| bad-code-sanitization.js:31:30:31:50 | JSON.st ... (input) | -| bad-code-sanitization.js:40:23:40:43 | JSON.st ... (input) | -| bad-code-sanitization.js:40:23:40:43 | JSON.st ... (input) | -| bad-code-sanitization.js:40:23:40:43 | JSON.st ... (input) | -| bad-code-sanitization.js:44:22:44:42 | JSON.st ... (input) | -| bad-code-sanitization.js:44:22:44:42 | JSON.st ... (input) | -| bad-code-sanitization.js:44:22:44:42 | JSON.st ... (input) | -| bad-code-sanitization.js:52:28:52:62 | JSON.st ... bble")) | -| bad-code-sanitization.js:52:28:52:62 | JSON.st ... bble")) | -| bad-code-sanitization.js:52:28:52:62 | JSON.st ... bble")) | -| bad-code-sanitization.js:54:29:54:63 | JSON.st ... bble")) | -| bad-code-sanitization.js:54:29:54:63 | JSON.st ... bble")) | -| bad-code-sanitization.js:54:29:54:63 | JSON.st ... bble")) | -| bad-code-sanitization.js:58:29:58:49 | JSON.st ... (taint) | -| bad-code-sanitization.js:58:29:58:49 | JSON.st ... (taint) | -| bad-code-sanitization.js:58:29:58:49 | JSON.st ... (taint) | -| bad-code-sanitization.js:63:11:63:55 | assignment | -| bad-code-sanitization.js:63:24:63:55 | `obj[${ ... )}]=42` | -| bad-code-sanitization.js:63:31:63:49 | JSON.stringify(key) | -| bad-code-sanitization.js:63:31:63:49 | JSON.stringify(key) | -| bad-code-sanitization.js:64:27:64:36 | assignment | -| bad-code-sanitization.js:64:27:64:36 | assignment | edges | bad-code-sanitization.js:2:12:2:90 | /^[_$a- ... key)}]` | bad-code-sanitization.js:7:31:7:43 | safeProp(key) | -| bad-code-sanitization.js:2:65:2:90 | `[${JSO ... key)}]` | bad-code-sanitization.js:2:12:2:90 | /^[_$a- ... key)}]` | -| bad-code-sanitization.js:2:69:2:87 | JSON.stringify(key) | bad-code-sanitization.js:2:65:2:90 | `[${JSO ... key)}]` | -| bad-code-sanitization.js:2:69:2:87 | JSON.stringify(key) | bad-code-sanitization.js:2:65:2:90 | `[${JSO ... key)}]` | +| bad-code-sanitization.js:2:69:2:87 | JSON.stringify(key) | bad-code-sanitization.js:2:12:2:90 | /^[_$a- ... key)}]` | | bad-code-sanitization.js:6:11:6:25 | statements | bad-code-sanitization.js:8:27:8:36 | statements | -| bad-code-sanitization.js:6:24:6:25 | [] | bad-code-sanitization.js:6:11:6:25 | statements | -| bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | bad-code-sanitization.js:6:24:6:25 | [] | +| bad-code-sanitization.js:7:5:7:14 | [post update] statements | bad-code-sanitization.js:6:11:6:25 | statements | +| bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | bad-code-sanitization.js:7:5:7:14 | [post update] statements | | bad-code-sanitization.js:7:31:7:43 | safeProp(key) | bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | | bad-code-sanitization.js:8:27:8:36 | statements | bad-code-sanitization.js:8:27:8:46 | statements.join(';') | -| bad-code-sanitization.js:8:27:8:36 | statements | bad-code-sanitization.js:8:27:8:46 | statements.join(';') | -| bad-code-sanitization.js:15:44:15:63 | htmlescape(pathname) | bad-code-sanitization.js:15:44:15:63 | htmlescape(pathname) | -| bad-code-sanitization.js:19:27:19:47 | JSON.st ... (input) | bad-code-sanitization.js:19:27:19:47 | JSON.st ... (input) | -| bad-code-sanitization.js:31:30:31:50 | JSON.st ... (input) | bad-code-sanitization.js:31:30:31:50 | JSON.st ... (input) | -| bad-code-sanitization.js:40:23:40:43 | JSON.st ... (input) | bad-code-sanitization.js:40:23:40:43 | JSON.st ... (input) | -| bad-code-sanitization.js:44:22:44:42 | JSON.st ... (input) | bad-code-sanitization.js:44:22:44:42 | JSON.st ... (input) | -| bad-code-sanitization.js:52:28:52:62 | JSON.st ... bble")) | bad-code-sanitization.js:52:28:52:62 | JSON.st ... bble")) | -| bad-code-sanitization.js:54:29:54:63 | JSON.st ... bble")) | bad-code-sanitization.js:54:29:54:63 | JSON.st ... bble")) | -| bad-code-sanitization.js:58:29:58:49 | JSON.st ... (taint) | bad-code-sanitization.js:58:29:58:49 | JSON.st ... (taint) | | bad-code-sanitization.js:63:11:63:55 | assignment | bad-code-sanitization.js:64:27:64:36 | assignment | -| bad-code-sanitization.js:63:11:63:55 | assignment | bad-code-sanitization.js:64:27:64:36 | assignment | -| bad-code-sanitization.js:63:24:63:55 | `obj[${ ... )}]=42` | bad-code-sanitization.js:63:11:63:55 | assignment | -| bad-code-sanitization.js:63:31:63:49 | JSON.stringify(key) | bad-code-sanitization.js:63:24:63:55 | `obj[${ ... )}]=42` | -| bad-code-sanitization.js:63:31:63:49 | JSON.stringify(key) | bad-code-sanitization.js:63:24:63:55 | `obj[${ ... )}]=42` | +| bad-code-sanitization.js:63:31:63:49 | JSON.stringify(key) | bad-code-sanitization.js:63:11:63:55 | assignment | +nodes +| bad-code-sanitization.js:2:12:2:90 | /^[_$a- ... key)}]` | semmle.label | /^[_$a- ... key)}]` | +| bad-code-sanitization.js:2:69:2:87 | JSON.stringify(key) | semmle.label | JSON.stringify(key) | +| bad-code-sanitization.js:6:11:6:25 | statements | semmle.label | statements | +| bad-code-sanitization.js:7:5:7:14 | [post update] statements | semmle.label | [post update] statements | +| bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | semmle.label | `${name ... key])}` | +| bad-code-sanitization.js:7:31:7:43 | safeProp(key) | semmle.label | safeProp(key) | +| bad-code-sanitization.js:8:27:8:36 | statements | semmle.label | statements | +| bad-code-sanitization.js:8:27:8:46 | statements.join(';') | semmle.label | statements.join(';') | +| bad-code-sanitization.js:15:44:15:63 | htmlescape(pathname) | semmle.label | htmlescape(pathname) | +| bad-code-sanitization.js:19:27:19:47 | JSON.st ... (input) | semmle.label | JSON.st ... (input) | +| bad-code-sanitization.js:31:30:31:50 | JSON.st ... (input) | semmle.label | JSON.st ... (input) | +| bad-code-sanitization.js:40:23:40:43 | JSON.st ... (input) | semmle.label | JSON.st ... (input) | +| bad-code-sanitization.js:44:22:44:42 | JSON.st ... (input) | semmle.label | JSON.st ... (input) | +| bad-code-sanitization.js:52:28:52:62 | JSON.st ... bble")) | semmle.label | JSON.st ... bble")) | +| bad-code-sanitization.js:54:29:54:63 | JSON.st ... bble")) | semmle.label | JSON.st ... bble")) | +| bad-code-sanitization.js:58:29:58:49 | JSON.st ... (taint) | semmle.label | JSON.st ... (taint) | +| bad-code-sanitization.js:63:11:63:55 | assignment | semmle.label | assignment | +| bad-code-sanitization.js:63:31:63:49 | JSON.stringify(key) | semmle.label | JSON.stringify(key) | +| bad-code-sanitization.js:64:27:64:36 | assignment | semmle.label | assignment | +subpaths #select | bad-code-sanitization.js:8:27:8:46 | statements.join(';') | bad-code-sanitization.js:2:69:2:87 | JSON.stringify(key) | bad-code-sanitization.js:8:27:8:46 | statements.join(';') | Code construction depends on an $@. | bad-code-sanitization.js:2:69:2:87 | JSON.stringify(key) | improperly sanitized value | | bad-code-sanitization.js:15:44:15:63 | htmlescape(pathname) | bad-code-sanitization.js:15:44:15:63 | htmlescape(pathname) | bad-code-sanitization.js:15:44:15:63 | htmlescape(pathname) | Code construction depends on an $@. | bad-code-sanitization.js:15:44:15:63 | htmlescape(pathname) | improperly sanitized value | From e3ab5bdd1632cf606bfd01d388cf7124a3236742 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:20:09 +0200 Subject: [PATCH 079/514] JS: Port IncompleteHtmlAttributeSanitization --- ...completeHtmlAttributeSanitizationQuery.qll | 29 +++++++- .../IncompleteHtmlAttributeSanitization.ql | 8 +- ...completeHtmlAttributeSanitization.expected | 73 +++++-------------- 3 files changed, 50 insertions(+), 60 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/IncompleteHtmlAttributeSanitizationQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/IncompleteHtmlAttributeSanitizationQuery.qll index 730fa6a0e80..824d689445e 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/IncompleteHtmlAttributeSanitizationQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/IncompleteHtmlAttributeSanitizationQuery.qll @@ -25,7 +25,34 @@ private module Label { /** * A taint-tracking configuration for reasoning about incomplete HTML sanitization vulnerabilities. */ -class Configuration extends TaintTracking::Configuration { +module IncompleteHtmlAttributeSanitizationConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; + + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { + label = Label::characterToLabel(source.(Source).getAnUnsanitizedCharacter()) + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { + label = Label::characterToLabel(sink.(Sink).getADangerousCharacter()) + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel lbl) { + lbl = Label::characterToLabel(node.(StringReplaceCall).getAReplacedString()) + } + + predicate isBarrier(DataFlow::Node n) { n instanceof Sanitizer } +} + +/** + * Taint-tracking for reasoning about incomplete HTML sanitization vulnerabilities. + */ +module IncompleteHtmlAttributeSanitizationFlow = + TaintTracking::GlobalWithState; + +/** + * DEPRECATED. Use the `IncompleteHtmlAttributeSanitizationFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "IncompleteHtmlAttributeSanitization" } override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { diff --git a/javascript/ql/src/Security/CWE-116/IncompleteHtmlAttributeSanitization.ql b/javascript/ql/src/Security/CWE-116/IncompleteHtmlAttributeSanitization.ql index eec14ab7ba3..46b60ea9c99 100644 --- a/javascript/ql/src/Security/CWE-116/IncompleteHtmlAttributeSanitization.ql +++ b/javascript/ql/src/Security/CWE-116/IncompleteHtmlAttributeSanitization.ql @@ -15,9 +15,9 @@ */ import javascript -import DataFlow::PathGraph import semmle.javascript.security.dataflow.IncompleteHtmlAttributeSanitizationQuery import semmle.javascript.security.IncompleteBlacklistSanitizer +import DataFlow::DeduplicatePathGraph /** * Gets a pretty string of the dangerous characters for `sink`. @@ -31,8 +31,10 @@ string prettyPrintDangerousCharaters(Sink sink) { ).regexpReplaceAll(",(?=[^,]+$)", " or") } -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from PathNode source, PathNode sink +where + IncompleteHtmlAttributeSanitizationFlow::flowPath(source.getAnOriginalPathNode(), + sink.getAnOriginalPathNode()) select sink.getNode(), source, sink, // this message is slightly sub-optimal as we do not have an easy way // to get the flow labels that reach the sink, so the message includes diff --git a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteHtmlAttributeSanitization.expected b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteHtmlAttributeSanitization.expected index 7c80b54be34..326e6ea7436 100644 --- a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteHtmlAttributeSanitization.expected +++ b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteHtmlAttributeSanitization.expected @@ -1,64 +1,25 @@ nodes -| tst.js:243:9:243:31 | s().rep ... ]/g,'') | -| tst.js:243:9:243:31 | s().rep ... ]/g,'') | -| tst.js:243:9:243:31 | s().rep ... ]/g,'') | -| tst.js:244:9:244:33 | s().rep ... /g, '') | -| tst.js:244:9:244:33 | s().rep ... /g, '') | -| tst.js:244:9:244:33 | s().rep ... /g, '') | -| tst.js:249:9:249:33 | s().rep ... ]/g,'') | -| tst.js:249:9:249:33 | s().rep ... ]/g,'') | -| tst.js:249:9:249:33 | s().rep ... ]/g,'') | -| tst.js:250:9:250:33 | s().rep ... ]/g,'') | -| tst.js:250:9:250:33 | s().rep ... ]/g,'') | -| tst.js:250:9:250:33 | s().rep ... ]/g,'') | -| tst.js:253:21:253:45 | s().rep ... /g, '') | -| tst.js:253:21:253:45 | s().rep ... /g, '') | -| tst.js:253:21:253:45 | s().rep ... /g, '') | -| tst.js:254:32:254:56 | s().rep ... /g, '') | -| tst.js:254:32:254:56 | s().rep ... /g, '') | -| tst.js:254:32:254:56 | s().rep ... /g, '') | -| tst.js:270:61:270:85 | s().rep ... /g, '') | -| tst.js:270:61:270:85 | s().rep ... /g, '') | -| tst.js:270:61:270:85 | s().rep ... /g, '') | -| tst.js:274:6:274:94 | arr | -| tst.js:274:12:274:94 | s().val ... g , '') | -| tst.js:274:12:274:94 | s().val ... g , '') | -| tst.js:275:9:275:11 | arr | -| tst.js:275:9:275:21 | arr.join(" ") | -| tst.js:275:9:275:21 | arr.join(" ") | -| tst.js:300:10:300:33 | s().rep ... ]/g,'') | -| tst.js:300:10:300:33 | s().rep ... ]/g,'') | -| tst.js:300:10:300:33 | s().rep ... ]/g,'') | -| tst.js:301:10:301:32 | s().rep ... ]/g,'') | -| tst.js:301:10:301:32 | s().rep ... ]/g,'') | -| tst.js:301:10:301:32 | s().rep ... ]/g,'') | -| tst.js:302:10:302:34 | s().rep ... ]/g,'') | -| tst.js:302:10:302:34 | s().rep ... ]/g,'') | -| tst.js:302:10:302:34 | s().rep ... ]/g,'') | -| tst.js:303:10:303:34 | s().rep ... /g, '') | -| tst.js:303:10:303:34 | s().rep ... /g, '') | -| tst.js:303:10:303:34 | s().rep ... /g, '') | -| tst.js:309:10:318:3 | s().rep ... ;";\\n\\t}) | -| tst.js:309:10:318:3 | s().rep ... ;";\\n\\t}) | -| tst.js:309:10:318:3 | s().rep ... ;";\\n\\t}) | +| tst.js:243:9:243:31 | s().rep ... ]/g,'') | semmle.label | s().rep ... ]/g,'') | +| tst.js:244:9:244:33 | s().rep ... /g, '') | semmle.label | s().rep ... /g, '') | +| tst.js:249:9:249:33 | s().rep ... ]/g,'') | semmle.label | s().rep ... ]/g,'') | +| tst.js:250:9:250:33 | s().rep ... ]/g,'') | semmle.label | s().rep ... ]/g,'') | +| tst.js:253:21:253:45 | s().rep ... /g, '') | semmle.label | s().rep ... /g, '') | +| tst.js:254:32:254:56 | s().rep ... /g, '') | semmle.label | s().rep ... /g, '') | +| tst.js:270:61:270:85 | s().rep ... /g, '') | semmle.label | s().rep ... /g, '') | +| tst.js:274:6:274:94 | arr | semmle.label | arr | +| tst.js:274:12:274:94 | s().val ... g , '') | semmle.label | s().val ... g , '') | +| tst.js:275:9:275:11 | arr | semmle.label | arr | +| tst.js:275:9:275:21 | arr.join(" ") | semmle.label | arr.join(" ") | +| tst.js:300:10:300:33 | s().rep ... ]/g,'') | semmle.label | s().rep ... ]/g,'') | +| tst.js:301:10:301:32 | s().rep ... ]/g,'') | semmle.label | s().rep ... ]/g,'') | +| tst.js:302:10:302:34 | s().rep ... ]/g,'') | semmle.label | s().rep ... ]/g,'') | +| tst.js:303:10:303:34 | s().rep ... /g, '') | semmle.label | s().rep ... /g, '') | +| tst.js:309:10:318:3 | s().rep ... ;";\\n\\t}) | semmle.label | s().rep ... ;";\\n\\t}) | edges -| tst.js:243:9:243:31 | s().rep ... ]/g,'') | tst.js:243:9:243:31 | s().rep ... ]/g,'') | -| tst.js:244:9:244:33 | s().rep ... /g, '') | tst.js:244:9:244:33 | s().rep ... /g, '') | -| tst.js:249:9:249:33 | s().rep ... ]/g,'') | tst.js:249:9:249:33 | s().rep ... ]/g,'') | -| tst.js:250:9:250:33 | s().rep ... ]/g,'') | tst.js:250:9:250:33 | s().rep ... ]/g,'') | -| tst.js:253:21:253:45 | s().rep ... /g, '') | tst.js:253:21:253:45 | s().rep ... /g, '') | -| tst.js:254:32:254:56 | s().rep ... /g, '') | tst.js:254:32:254:56 | s().rep ... /g, '') | -| tst.js:270:61:270:85 | s().rep ... /g, '') | tst.js:270:61:270:85 | s().rep ... /g, '') | | tst.js:274:6:274:94 | arr | tst.js:275:9:275:11 | arr | | tst.js:274:12:274:94 | s().val ... g , '') | tst.js:274:6:274:94 | arr | -| tst.js:274:12:274:94 | s().val ... g , '') | tst.js:274:6:274:94 | arr | | tst.js:275:9:275:11 | arr | tst.js:275:9:275:21 | arr.join(" ") | -| tst.js:275:9:275:11 | arr | tst.js:275:9:275:21 | arr.join(" ") | -| tst.js:300:10:300:33 | s().rep ... ]/g,'') | tst.js:300:10:300:33 | s().rep ... ]/g,'') | -| tst.js:301:10:301:32 | s().rep ... ]/g,'') | tst.js:301:10:301:32 | s().rep ... ]/g,'') | -| tst.js:302:10:302:34 | s().rep ... ]/g,'') | tst.js:302:10:302:34 | s().rep ... ]/g,'') | -| tst.js:303:10:303:34 | s().rep ... /g, '') | tst.js:303:10:303:34 | s().rep ... /g, '') | -| tst.js:309:10:318:3 | s().rep ... ;";\\n\\t}) | tst.js:309:10:318:3 | s().rep ... ;";\\n\\t}) | +subpaths #select | tst.js:243:9:243:31 | s().rep ... ]/g,'') | tst.js:243:9:243:31 | s().rep ... ]/g,'') | tst.js:243:9:243:31 | s().rep ... ]/g,'') | Cross-site scripting vulnerability as the output of $@ may contain double quotes when it reaches this attribute definition. | tst.js:243:9:243:31 | s().rep ... ]/g,'') | this final HTML sanitizer step | | tst.js:244:9:244:33 | s().rep ... /g, '') | tst.js:244:9:244:33 | s().rep ... /g, '') | tst.js:244:9:244:33 | s().rep ... /g, '') | Cross-site scripting vulnerability as the output of $@ may contain double quotes when it reaches this attribute definition. | tst.js:244:9:244:33 | s().rep ... /g, '') | this final HTML sanitizer step | From 8c001916b6234e6c2996f117313d46a7f77d7000 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:20:36 +0200 Subject: [PATCH 080/514] JS: Port IndirectCommandInjection --- .../IndirectCommandInjectionQuery.qll | 32 +- .../CWE-078/IndirectCommandInjection.ql | 12 +- .../IndirectCommandInjection.expected | 519 ++++++------------ 3 files changed, 213 insertions(+), 350 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/IndirectCommandInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/IndirectCommandInjectionQuery.qll index d2de26d5cd0..94294627662 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/IndirectCommandInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/IndirectCommandInjectionQuery.qll @@ -10,7 +10,37 @@ private import IndirectCommandArgument /** * A taint-tracking configuration for reasoning about command-injection vulnerabilities. */ -class Configuration extends TaintTracking::Configuration { +module IndirectCommandInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + /** + * Holds if `sink` is a data-flow sink for command-injection vulnerabilities, and + * the alert should be placed at the node `highlight`. + */ + additional predicate isSinkWithHighlight(DataFlow::Node sink, DataFlow::Node highlight) { + sink instanceof Sink and highlight = sink + or + isIndirectCommandArgument(sink, highlight) + } + + predicate isSink(DataFlow::Node sink) { isSinkWithHighlight(sink, _) } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { + argsParseStep(pred, succ) + } +} + +/** + * Taint-tracking for reasoning about command-injection vulnerabilities. + */ +module IndirectCommandInjectionFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `IndirectCommandInjectionFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "IndirectCommandInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-078/IndirectCommandInjection.ql b/javascript/ql/src/Security/CWE-078/IndirectCommandInjection.ql index 34f89023441..cd229cd1f39 100644 --- a/javascript/ql/src/Security/CWE-078/IndirectCommandInjection.ql +++ b/javascript/ql/src/Security/CWE-078/IndirectCommandInjection.ql @@ -15,14 +15,16 @@ */ import javascript -import DataFlow::PathGraph import semmle.javascript.security.dataflow.IndirectCommandInjectionQuery +import IndirectCommandInjectionFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node highlight +from + IndirectCommandInjectionFlow::PathNode source, IndirectCommandInjectionFlow::PathNode sink, + DataFlow::Node highlight where - cfg.hasFlowPath(source, sink) and - if cfg.isSinkWithHighlight(sink.getNode(), _) - then cfg.isSinkWithHighlight(sink.getNode(), highlight) + IndirectCommandInjectionFlow::flowPath(source, sink) and + if IndirectCommandInjectionConfig::isSinkWithHighlight(sink.getNode(), _) + then IndirectCommandInjectionConfig::isSinkWithHighlight(sink.getNode(), highlight) else highlight = sink.getNode() select highlight, source, sink, "This command depends on an unsanitized $@.", source.getNode(), source.getNode().(Source).describe() diff --git a/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected index 47d8d4adcb1..51c52e86449 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected @@ -1,427 +1,258 @@ -nodes -| actions.js:4:6:4:16 | process.env | -| actions.js:4:6:4:16 | process.env | -| actions.js:4:6:4:29 | process ... _DATA'] | -| actions.js:4:6:4:29 | process ... _DATA'] | -| actions.js:7:15:7:15 | e | -| actions.js:8:10:8:10 | e | -| actions.js:8:10:8:23 | e['TEST_DATA'] | -| actions.js:8:10:8:23 | e['TEST_DATA'] | -| actions.js:12:6:12:16 | process.env | -| actions.js:12:6:12:16 | process.env | -| actions.js:14:6:14:21 | getInput('data') | -| actions.js:14:6:14:21 | getInput('data') | -| actions.js:14:6:14:21 | getInput('data') | -| command-line-parameter-command-injection.js:4:10:4:21 | process.argv | -| command-line-parameter-command-injection.js:4:10:4:21 | process.argv | -| command-line-parameter-command-injection.js:4:10:4:21 | process.argv | -| command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | -| command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | -| command-line-parameter-command-injection.js:8:22:8:33 | process.argv | -| command-line-parameter-command-injection.js:8:22:8:33 | process.argv | -| command-line-parameter-command-injection.js:8:22:8:36 | process.argv[2] | -| command-line-parameter-command-injection.js:10:6:10:33 | args | -| command-line-parameter-command-injection.js:10:13:10:24 | process.argv | -| command-line-parameter-command-injection.js:10:13:10:24 | process.argv | -| command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | -| command-line-parameter-command-injection.js:11:14:11:17 | args | -| command-line-parameter-command-injection.js:11:14:11:20 | args[0] | -| command-line-parameter-command-injection.js:11:14:11:20 | args[0] | -| command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | -| command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | -| command-line-parameter-command-injection.js:12:26:12:29 | args | -| command-line-parameter-command-injection.js:12:26:12:32 | args[0] | -| command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | -| command-line-parameter-command-injection.js:14:18:14:21 | args | -| command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | -| command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | -| command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | -| command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | -| command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | -| command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | -| command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | -| command-line-parameter-command-injection.js:16:26:16:37 | fewerArgs[0] | -| command-line-parameter-command-injection.js:18:6:18:24 | arg0 | -| command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | -| command-line-parameter-command-injection.js:18:13:18:24 | fewerArgs[0] | -| command-line-parameter-command-injection.js:19:14:19:17 | arg0 | -| command-line-parameter-command-injection.js:19:14:19:17 | arg0 | -| command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | -| command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | -| command-line-parameter-command-injection.js:20:26:20:29 | arg0 | -| command-line-parameter-command-injection.js:24:8:24:35 | args | -| command-line-parameter-command-injection.js:24:15:24:26 | process.argv | -| command-line-parameter-command-injection.js:24:15:24:26 | process.argv | -| command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | -| command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | -| command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | -| command-line-parameter-command-injection.js:26:32:26:35 | args | -| command-line-parameter-command-injection.js:26:32:26:38 | args[0] | -| command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | -| command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | -| command-line-parameter-command-injection.js:27:32:27:35 | args | -| command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | -| command-line-parameter-command-injection.js:30:9:30:50 | "cmd.sh ... )().foo | -| command-line-parameter-command-injection.js:30:9:30:50 | "cmd.sh ... )().foo | -| command-line-parameter-command-injection.js:30:21:30:46 | require ... rgs")() | -| command-line-parameter-command-injection.js:30:21:30:46 | require ... rgs")() | -| command-line-parameter-command-injection.js:30:21:30:50 | require ... )().foo | -| command-line-parameter-command-injection.js:32:9:32:45 | "cmd.sh ... rgv.foo | -| command-line-parameter-command-injection.js:32:9:32:45 | "cmd.sh ... rgv.foo | -| command-line-parameter-command-injection.js:32:21:32:41 | require ... ").argv | -| command-line-parameter-command-injection.js:32:21:32:41 | require ... ").argv | -| command-line-parameter-command-injection.js:32:21:32:45 | require ... rgv.foo | -| command-line-parameter-command-injection.js:33:9:33:48 | "cmd.sh ... rgv.foo | -| command-line-parameter-command-injection.js:33:9:33:48 | "cmd.sh ... rgv.foo | -| command-line-parameter-command-injection.js:33:21:33:44 | require ... ").argv | -| command-line-parameter-command-injection.js:33:21:33:44 | require ... ").argv | -| command-line-parameter-command-injection.js:33:21:33:48 | require ... rgv.foo | -| command-line-parameter-command-injection.js:36:6:39:7 | args | -| command-line-parameter-command-injection.js:36:13:39:7 | require ... \\t\\t.argv | -| command-line-parameter-command-injection.js:36:13:39:7 | require ... \\t\\t.argv | -| command-line-parameter-command-injection.js:41:10:41:25 | "cmd.sh " + args | -| command-line-parameter-command-injection.js:41:10:41:25 | "cmd.sh " + args | -| command-line-parameter-command-injection.js:41:22:41:25 | args | -| command-line-parameter-command-injection.js:43:10:43:62 | "cmd.sh ... e().foo | -| command-line-parameter-command-injection.js:43:10:43:62 | "cmd.sh ... e().foo | -| command-line-parameter-command-injection.js:43:22:43:58 | require ... parse() | -| command-line-parameter-command-injection.js:43:22:43:58 | require ... parse() | -| command-line-parameter-command-injection.js:43:22:43:62 | require ... e().foo | -| command-line-parameter-command-injection.js:47:8:53:12 | args | -| command-line-parameter-command-injection.js:48:3:50:3 | argv: { ... rgs\\n\\t\\t} | -| command-line-parameter-command-injection.js:48:3:50:3 | argv: { ... rgs\\n\\t\\t} | -| command-line-parameter-command-injection.js:48:9:50:3 | {\\n\\t\\t\\t...args\\n\\t\\t} | -| command-line-parameter-command-injection.js:55:10:55:25 | "cmd.sh " + args | -| command-line-parameter-command-injection.js:55:10:55:25 | "cmd.sh " + args | -| command-line-parameter-command-injection.js:55:22:55:25 | args | -| command-line-parameter-command-injection.js:57:6:57:37 | tainted1 | -| command-line-parameter-command-injection.js:57:17:57:37 | require ... ').argv | -| command-line-parameter-command-injection.js:57:17:57:37 | require ... ').argv | -| command-line-parameter-command-injection.js:58:6:58:40 | tainted2 | -| command-line-parameter-command-injection.js:58:17:58:40 | require ... parse() | -| command-line-parameter-command-injection.js:58:17:58:40 | require ... parse() | -| command-line-parameter-command-injection.js:60:8:63:2 | taint1rest | -| command-line-parameter-command-injection.js:60:8:63:2 | taint2rest | -| command-line-parameter-command-injection.js:60:9:60:31 | taint1: ... t1rest} | -| command-line-parameter-command-injection.js:60:17:60:31 | {...taint1rest} | -| command-line-parameter-command-injection.js:60:33:60:55 | taint2: ... t2rest} | -| command-line-parameter-command-injection.js:60:41:60:55 | {...taint2rest} | -| command-line-parameter-command-injection.js:61:11:61:18 | tainted1 | -| command-line-parameter-command-injection.js:62:11:62:18 | tainted2 | -| command-line-parameter-command-injection.js:65:10:65:31 | "cmd.sh ... nt1rest | -| command-line-parameter-command-injection.js:65:10:65:31 | "cmd.sh ... nt1rest | -| command-line-parameter-command-injection.js:65:22:65:31 | taint1rest | -| command-line-parameter-command-injection.js:66:10:66:31 | "cmd.sh ... nt2rest | -| command-line-parameter-command-injection.js:66:10:66:31 | "cmd.sh ... nt2rest | -| command-line-parameter-command-injection.js:66:22:66:31 | taint2rest | -| command-line-parameter-command-injection.js:68:6:68:16 | {...taint3} | -| command-line-parameter-command-injection.js:68:6:68:40 | taint3 | -| command-line-parameter-command-injection.js:68:20:68:40 | require ... ').argv | -| command-line-parameter-command-injection.js:68:20:68:40 | require ... ').argv | -| command-line-parameter-command-injection.js:69:10:69:27 | "cmd.sh " + taint3 | -| command-line-parameter-command-injection.js:69:10:69:27 | "cmd.sh " + taint3 | -| command-line-parameter-command-injection.js:69:22:69:27 | taint3 | -| command-line-parameter-command-injection.js:71:6:71:16 | [...taint4] | -| command-line-parameter-command-injection.js:71:6:71:40 | taint4 | -| command-line-parameter-command-injection.js:71:20:71:40 | require ... ').argv | -| command-line-parameter-command-injection.js:71:20:71:40 | require ... ').argv | -| command-line-parameter-command-injection.js:72:10:72:27 | "cmd.sh " + taint4 | -| command-line-parameter-command-injection.js:72:10:72:27 | "cmd.sh " + taint4 | -| command-line-parameter-command-injection.js:72:22:72:27 | taint4 | -| command-line-parameter-command-injection.js:76:8:76:35 | argv | -| command-line-parameter-command-injection.js:76:15:76:26 | process.argv | -| command-line-parameter-command-injection.js:76:15:76:26 | process.argv | -| command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | -| command-line-parameter-command-injection.js:79:10:79:39 | "cmd.sh ... gv).foo | -| command-line-parameter-command-injection.js:79:10:79:39 | "cmd.sh ... gv).foo | -| command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | -| command-line-parameter-command-injection.js:79:22:79:39 | minimist(argv).foo | -| command-line-parameter-command-injection.js:79:31:79:34 | argv | -| command-line-parameter-command-injection.js:82:10:82:54 | "cmd.sh ... 2)).foo | -| command-line-parameter-command-injection.js:82:10:82:54 | "cmd.sh ... 2)).foo | -| command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | -| command-line-parameter-command-injection.js:82:22:82:54 | subarg( ... 2)).foo | -| command-line-parameter-command-injection.js:82:29:82:40 | process.argv | -| command-line-parameter-command-injection.js:82:29:82:40 | process.argv | -| command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | -| command-line-parameter-command-injection.js:85:10:85:59 | "cmd.sh ... 2)).foo | -| command-line-parameter-command-injection.js:85:10:85:59 | "cmd.sh ... 2)).foo | -| command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | -| command-line-parameter-command-injection.js:85:22:85:59 | yargsPa ... 2)).foo | -| command-line-parameter-command-injection.js:85:34:85:45 | process.argv | -| command-line-parameter-command-injection.js:85:34:85:45 | process.argv | -| command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | -| command-line-parameter-command-injection.js:88:6:88:37 | flags | -| command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | -| command-line-parameter-command-injection.js:88:25:88:36 | process.argv | -| command-line-parameter-command-injection.js:88:25:88:36 | process.argv | -| command-line-parameter-command-injection.js:89:10:89:30 | "cmd.sh ... ags.foo | -| command-line-parameter-command-injection.js:89:10:89:30 | "cmd.sh ... ags.foo | -| command-line-parameter-command-injection.js:89:22:89:26 | flags | -| command-line-parameter-command-injection.js:89:22:89:30 | flags.foo | -| command-line-parameter-command-injection.js:91:6:91:38 | flags | -| command-line-parameter-command-injection.js:91:14:91:38 | require ... .spec}) | -| command-line-parameter-command-injection.js:91:14:91:38 | require ... .spec}) | -| command-line-parameter-command-injection.js:92:10:92:30 | "cmd.sh ... ags.foo | -| command-line-parameter-command-injection.js:92:10:92:30 | "cmd.sh ... ags.foo | -| command-line-parameter-command-injection.js:92:22:92:26 | flags | -| command-line-parameter-command-injection.js:92:22:92:30 | flags.foo | -| command-line-parameter-command-injection.js:102:10:102:44 | "cmd.sh ... s().foo | -| command-line-parameter-command-injection.js:102:10:102:44 | "cmd.sh ... s().foo | -| command-line-parameter-command-injection.js:102:22:102:40 | parser.parse_args() | -| command-line-parameter-command-injection.js:102:22:102:40 | parser.parse_args() | -| command-line-parameter-command-injection.js:102:22:102:44 | parser. ... s().foo | -| command-line-parameter-command-injection.js:107:8:107:51 | options | -| command-line-parameter-command-injection.js:107:18:107:51 | command ... itions) | -| command-line-parameter-command-injection.js:107:18:107:51 | command ... itions) | -| command-line-parameter-command-injection.js:108:10:108:32 | "cmd.sh ... ons.foo | -| command-line-parameter-command-injection.js:108:10:108:32 | "cmd.sh ... ons.foo | -| command-line-parameter-command-injection.js:108:22:108:28 | options | -| command-line-parameter-command-injection.js:108:22:108:32 | options.foo | -| command-line-parameter-command-injection.js:114:8:114:52 | cli | -| command-line-parameter-command-injection.js:114:14:114:52 | meow(`h ... lags}}) | -| command-line-parameter-command-injection.js:114:14:114:52 | meow(`h ... lags}}) | -| command-line-parameter-command-injection.js:116:10:116:33 | "cmd.sh ... nput[0] | -| command-line-parameter-command-injection.js:116:10:116:33 | "cmd.sh ... nput[0] | -| command-line-parameter-command-injection.js:116:22:116:24 | cli | -| command-line-parameter-command-injection.js:116:22:116:30 | cli.input | -| command-line-parameter-command-injection.js:116:22:116:33 | cli.input[0] | -| command-line-parameter-command-injection.js:122:6:122:46 | opts | -| command-line-parameter-command-injection.js:122:13:122:46 | dashdas ... tions}) | -| command-line-parameter-command-injection.js:122:13:122:46 | dashdas ... tions}) | -| command-line-parameter-command-injection.js:124:10:124:29 | "cmd.sh " + opts.foo | -| command-line-parameter-command-injection.js:124:10:124:29 | "cmd.sh " + opts.foo | -| command-line-parameter-command-injection.js:124:22:124:25 | opts | -| command-line-parameter-command-injection.js:124:22:124:29 | opts.foo | -| command-line-parameter-command-injection.js:127:6:127:26 | opts | -| command-line-parameter-command-injection.js:127:13:127:26 | parser.parse() | -| command-line-parameter-command-injection.js:127:13:127:26 | parser.parse() | -| command-line-parameter-command-injection.js:129:10:129:29 | "cmd.sh " + opts.foo | -| command-line-parameter-command-injection.js:129:10:129:29 | "cmd.sh " + opts.foo | -| command-line-parameter-command-injection.js:129:22:129:25 | opts | -| command-line-parameter-command-injection.js:129:22:129:29 | opts.foo | -| command-line-parameter-command-injection.js:133:8:133:41 | program | -| command-line-parameter-command-injection.js:133:10:133:16 | program | -| command-line-parameter-command-injection.js:133:10:133:16 | program | -| command-line-parameter-command-injection.js:136:10:136:45 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:136:10:136:45 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:136:22:136:35 | program.opts() | -| command-line-parameter-command-injection.js:136:22:136:35 | program.opts() | -| command-line-parameter-command-injection.js:136:22:136:45 | program ... zzaType | -| command-line-parameter-command-injection.js:136:22:136:45 | program ... zzaType | -| command-line-parameter-command-injection.js:137:10:137:38 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:137:10:137:38 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:137:22:137:28 | program | -| command-line-parameter-command-injection.js:137:22:137:38 | program.pizzaType | -| command-line-parameter-command-injection.js:137:22:137:38 | program.pizzaType | -| command-line-parameter-command-injection.js:145:10:145:45 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:145:10:145:45 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:145:22:145:35 | program.opts() | -| command-line-parameter-command-injection.js:145:22:145:35 | program.opts() | -| command-line-parameter-command-injection.js:145:22:145:45 | program ... zzaType | -| command-line-parameter-command-injection.js:145:22:145:45 | program ... zzaType | -| command-line-parameter-command-injection.js:146:10:146:38 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:146:10:146:38 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:146:22:146:38 | program.pizzaType | -| command-line-parameter-command-injection.js:146:22:146:38 | program.pizzaType | edges | actions.js:4:6:4:16 | process.env | actions.js:4:6:4:29 | process ... _DATA'] | -| actions.js:4:6:4:16 | process.env | actions.js:4:6:4:29 | process ... _DATA'] | -| actions.js:4:6:4:16 | process.env | actions.js:4:6:4:29 | process ... _DATA'] | -| actions.js:4:6:4:16 | process.env | actions.js:4:6:4:29 | process ... _DATA'] | | actions.js:7:15:7:15 | e | actions.js:8:10:8:10 | e | | actions.js:8:10:8:10 | e | actions.js:8:10:8:23 | e['TEST_DATA'] | -| actions.js:8:10:8:10 | e | actions.js:8:10:8:23 | e['TEST_DATA'] | | actions.js:12:6:12:16 | process.env | actions.js:7:15:7:15 | e | -| actions.js:12:6:12:16 | process.env | actions.js:7:15:7:15 | e | -| actions.js:14:6:14:21 | getInput('data') | actions.js:14:6:14:21 | getInput('data') | -| command-line-parameter-command-injection.js:4:10:4:21 | process.argv | command-line-parameter-command-injection.js:4:10:4:21 | process.argv | -| command-line-parameter-command-injection.js:8:22:8:33 | process.argv | command-line-parameter-command-injection.js:8:22:8:36 | process.argv[2] | -| command-line-parameter-command-injection.js:8:22:8:33 | process.argv | command-line-parameter-command-injection.js:8:22:8:36 | process.argv[2] | -| command-line-parameter-command-injection.js:8:22:8:36 | process.argv[2] | command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | -| command-line-parameter-command-injection.js:8:22:8:36 | process.argv[2] | command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | +| command-line-parameter-command-injection.js:8:22:8:33 | process.argv | command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | | command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:11:14:11:17 | args | | command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:12:26:12:29 | args | | command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:14:18:14:21 | args | +| command-line-parameter-command-injection.js:10:6:10:33 | args [ArrayElement] | command-line-parameter-command-injection.js:14:18:14:21 | args [ArrayElement] | | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | -| command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | +| command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) [ArrayElement] | | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | command-line-parameter-command-injection.js:10:6:10:33 | args | +| command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) [ArrayElement] | command-line-parameter-command-injection.js:10:6:10:33 | args [ArrayElement] | | command-line-parameter-command-injection.js:11:14:11:17 | args | command-line-parameter-command-injection.js:11:14:11:20 | args[0] | -| command-line-parameter-command-injection.js:11:14:11:17 | args | command-line-parameter-command-injection.js:11:14:11:20 | args[0] | -| command-line-parameter-command-injection.js:12:26:12:29 | args | command-line-parameter-command-injection.js:12:26:12:32 | args[0] | -| command-line-parameter-command-injection.js:12:26:12:32 | args[0] | command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | -| command-line-parameter-command-injection.js:12:26:12:32 | args[0] | command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | +| command-line-parameter-command-injection.js:12:26:12:29 | args | command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | | command-line-parameter-command-injection.js:14:18:14:21 | args | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | +| command-line-parameter-command-injection.js:14:18:14:21 | args [ArrayElement] | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | | command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | -| command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | -| command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | command-line-parameter-command-injection.js:16:26:16:37 | fewerArgs[0] | -| command-line-parameter-command-injection.js:16:26:16:37 | fewerArgs[0] | command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | -| command-line-parameter-command-injection.js:16:26:16:37 | fewerArgs[0] | command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | -| command-line-parameter-command-injection.js:18:6:18:24 | arg0 | command-line-parameter-command-injection.js:19:14:19:17 | arg0 | +| command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | command-line-parameter-command-injection.js:19:14:19:17 | arg0 | | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | command-line-parameter-command-injection.js:20:26:20:29 | arg0 | -| command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | command-line-parameter-command-injection.js:18:13:18:24 | fewerArgs[0] | -| command-line-parameter-command-injection.js:18:13:18:24 | fewerArgs[0] | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | -| command-line-parameter-command-injection.js:20:26:20:29 | arg0 | command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | +| command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | | command-line-parameter-command-injection.js:20:26:20:29 | arg0 | command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | | command-line-parameter-command-injection.js:24:8:24:35 | args | command-line-parameter-command-injection.js:26:32:26:35 | args | | command-line-parameter-command-injection.js:24:8:24:35 | args | command-line-parameter-command-injection.js:27:32:27:35 | args | | command-line-parameter-command-injection.js:24:15:24:26 | process.argv | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | -| command-line-parameter-command-injection.js:24:15:24:26 | process.argv | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | command-line-parameter-command-injection.js:24:8:24:35 | args | -| command-line-parameter-command-injection.js:26:32:26:35 | args | command-line-parameter-command-injection.js:26:32:26:38 | args[0] | -| command-line-parameter-command-injection.js:26:32:26:38 | args[0] | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | -| command-line-parameter-command-injection.js:26:32:26:38 | args[0] | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | +| command-line-parameter-command-injection.js:26:32:26:35 | args | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | | command-line-parameter-command-injection.js:27:32:27:35 | args | command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | | command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | -| command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | -| command-line-parameter-command-injection.js:30:21:30:46 | require ... rgs")() | command-line-parameter-command-injection.js:30:21:30:50 | require ... )().foo | -| command-line-parameter-command-injection.js:30:21:30:46 | require ... rgs")() | command-line-parameter-command-injection.js:30:21:30:50 | require ... )().foo | -| command-line-parameter-command-injection.js:30:21:30:50 | require ... )().foo | command-line-parameter-command-injection.js:30:9:30:50 | "cmd.sh ... )().foo | -| command-line-parameter-command-injection.js:30:21:30:50 | require ... )().foo | command-line-parameter-command-injection.js:30:9:30:50 | "cmd.sh ... )().foo | -| command-line-parameter-command-injection.js:32:21:32:41 | require ... ").argv | command-line-parameter-command-injection.js:32:21:32:45 | require ... rgv.foo | -| command-line-parameter-command-injection.js:32:21:32:41 | require ... ").argv | command-line-parameter-command-injection.js:32:21:32:45 | require ... rgv.foo | -| command-line-parameter-command-injection.js:32:21:32:45 | require ... rgv.foo | command-line-parameter-command-injection.js:32:9:32:45 | "cmd.sh ... rgv.foo | -| command-line-parameter-command-injection.js:32:21:32:45 | require ... rgv.foo | command-line-parameter-command-injection.js:32:9:32:45 | "cmd.sh ... rgv.foo | -| command-line-parameter-command-injection.js:33:21:33:44 | require ... ").argv | command-line-parameter-command-injection.js:33:21:33:48 | require ... rgv.foo | -| command-line-parameter-command-injection.js:33:21:33:44 | require ... ").argv | command-line-parameter-command-injection.js:33:21:33:48 | require ... rgv.foo | -| command-line-parameter-command-injection.js:33:21:33:48 | require ... rgv.foo | command-line-parameter-command-injection.js:33:9:33:48 | "cmd.sh ... rgv.foo | -| command-line-parameter-command-injection.js:33:21:33:48 | require ... rgv.foo | command-line-parameter-command-injection.js:33:9:33:48 | "cmd.sh ... rgv.foo | +| command-line-parameter-command-injection.js:30:21:30:46 | require ... rgs")() | command-line-parameter-command-injection.js:30:9:30:50 | "cmd.sh ... )().foo | +| command-line-parameter-command-injection.js:32:21:32:41 | require ... ").argv | command-line-parameter-command-injection.js:32:9:32:45 | "cmd.sh ... rgv.foo | +| command-line-parameter-command-injection.js:33:21:33:44 | require ... ").argv | command-line-parameter-command-injection.js:33:9:33:48 | "cmd.sh ... rgv.foo | | command-line-parameter-command-injection.js:36:6:39:7 | args | command-line-parameter-command-injection.js:41:22:41:25 | args | | command-line-parameter-command-injection.js:36:13:39:7 | require ... \\t\\t.argv | command-line-parameter-command-injection.js:36:6:39:7 | args | -| command-line-parameter-command-injection.js:36:13:39:7 | require ... \\t\\t.argv | command-line-parameter-command-injection.js:36:6:39:7 | args | | command-line-parameter-command-injection.js:41:22:41:25 | args | command-line-parameter-command-injection.js:41:10:41:25 | "cmd.sh " + args | -| command-line-parameter-command-injection.js:41:22:41:25 | args | command-line-parameter-command-injection.js:41:10:41:25 | "cmd.sh " + args | -| command-line-parameter-command-injection.js:43:22:43:58 | require ... parse() | command-line-parameter-command-injection.js:43:22:43:62 | require ... e().foo | -| command-line-parameter-command-injection.js:43:22:43:58 | require ... parse() | command-line-parameter-command-injection.js:43:22:43:62 | require ... e().foo | -| command-line-parameter-command-injection.js:43:22:43:62 | require ... e().foo | command-line-parameter-command-injection.js:43:10:43:62 | "cmd.sh ... e().foo | -| command-line-parameter-command-injection.js:43:22:43:62 | require ... e().foo | command-line-parameter-command-injection.js:43:10:43:62 | "cmd.sh ... e().foo | +| command-line-parameter-command-injection.js:43:22:43:58 | require ... parse() | command-line-parameter-command-injection.js:43:10:43:62 | "cmd.sh ... e().foo | | command-line-parameter-command-injection.js:47:8:53:12 | args | command-line-parameter-command-injection.js:55:22:55:25 | args | | command-line-parameter-command-injection.js:48:3:50:3 | argv: { ... rgs\\n\\t\\t} | command-line-parameter-command-injection.js:48:9:50:3 | {\\n\\t\\t\\t...args\\n\\t\\t} | -| command-line-parameter-command-injection.js:48:3:50:3 | argv: { ... rgs\\n\\t\\t} | command-line-parameter-command-injection.js:48:9:50:3 | {\\n\\t\\t\\t...args\\n\\t\\t} | | command-line-parameter-command-injection.js:48:9:50:3 | {\\n\\t\\t\\t...args\\n\\t\\t} | command-line-parameter-command-injection.js:47:8:53:12 | args | | command-line-parameter-command-injection.js:55:22:55:25 | args | command-line-parameter-command-injection.js:55:10:55:25 | "cmd.sh " + args | -| command-line-parameter-command-injection.js:55:22:55:25 | args | command-line-parameter-command-injection.js:55:10:55:25 | "cmd.sh " + args | | command-line-parameter-command-injection.js:57:6:57:37 | tainted1 | command-line-parameter-command-injection.js:61:11:61:18 | tainted1 | | command-line-parameter-command-injection.js:57:17:57:37 | require ... ').argv | command-line-parameter-command-injection.js:57:6:57:37 | tainted1 | -| command-line-parameter-command-injection.js:57:17:57:37 | require ... ').argv | command-line-parameter-command-injection.js:57:6:57:37 | tainted1 | | command-line-parameter-command-injection.js:58:6:58:40 | tainted2 | command-line-parameter-command-injection.js:62:11:62:18 | tainted2 | | command-line-parameter-command-injection.js:58:17:58:40 | require ... parse() | command-line-parameter-command-injection.js:58:6:58:40 | tainted2 | -| command-line-parameter-command-injection.js:58:17:58:40 | require ... parse() | command-line-parameter-command-injection.js:58:6:58:40 | tainted2 | +| command-line-parameter-command-injection.js:60:8:60:56 | {taint1 ... 2rest}} [taint1] | command-line-parameter-command-injection.js:60:9:60:31 | taint1: ... t1rest} | +| command-line-parameter-command-injection.js:60:8:60:56 | {taint1 ... 2rest}} [taint2] | command-line-parameter-command-injection.js:60:33:60:55 | taint2: ... t2rest} | | command-line-parameter-command-injection.js:60:8:63:2 | taint1rest | command-line-parameter-command-injection.js:65:22:65:31 | taint1rest | | command-line-parameter-command-injection.js:60:8:63:2 | taint2rest | command-line-parameter-command-injection.js:66:22:66:31 | taint2rest | | command-line-parameter-command-injection.js:60:9:60:31 | taint1: ... t1rest} | command-line-parameter-command-injection.js:60:17:60:31 | {...taint1rest} | | command-line-parameter-command-injection.js:60:17:60:31 | {...taint1rest} | command-line-parameter-command-injection.js:60:8:63:2 | taint1rest | | command-line-parameter-command-injection.js:60:33:60:55 | taint2: ... t2rest} | command-line-parameter-command-injection.js:60:41:60:55 | {...taint2rest} | | command-line-parameter-command-injection.js:60:41:60:55 | {...taint2rest} | command-line-parameter-command-injection.js:60:8:63:2 | taint2rest | -| command-line-parameter-command-injection.js:61:11:61:18 | tainted1 | command-line-parameter-command-injection.js:60:9:60:31 | taint1: ... t1rest} | -| command-line-parameter-command-injection.js:62:11:62:18 | tainted2 | command-line-parameter-command-injection.js:60:33:60:55 | taint2: ... t2rest} | +| command-line-parameter-command-injection.js:60:60:63:2 | {\\n\\t\\ttai ... ted2\\n\\t} [taint1] | command-line-parameter-command-injection.js:60:8:60:56 | {taint1 ... 2rest}} [taint1] | +| command-line-parameter-command-injection.js:60:60:63:2 | {\\n\\t\\ttai ... ted2\\n\\t} [taint2] | command-line-parameter-command-injection.js:60:8:60:56 | {taint1 ... 2rest}} [taint2] | +| command-line-parameter-command-injection.js:61:11:61:18 | tainted1 | command-line-parameter-command-injection.js:60:60:63:2 | {\\n\\t\\ttai ... ted2\\n\\t} [taint1] | +| command-line-parameter-command-injection.js:62:11:62:18 | tainted2 | command-line-parameter-command-injection.js:60:60:63:2 | {\\n\\t\\ttai ... ted2\\n\\t} [taint2] | | command-line-parameter-command-injection.js:65:22:65:31 | taint1rest | command-line-parameter-command-injection.js:65:10:65:31 | "cmd.sh ... nt1rest | -| command-line-parameter-command-injection.js:65:22:65:31 | taint1rest | command-line-parameter-command-injection.js:65:10:65:31 | "cmd.sh ... nt1rest | -| command-line-parameter-command-injection.js:66:22:66:31 | taint2rest | command-line-parameter-command-injection.js:66:10:66:31 | "cmd.sh ... nt2rest | | command-line-parameter-command-injection.js:66:22:66:31 | taint2rest | command-line-parameter-command-injection.js:66:10:66:31 | "cmd.sh ... nt2rest | | command-line-parameter-command-injection.js:68:6:68:16 | {...taint3} | command-line-parameter-command-injection.js:68:6:68:40 | taint3 | | command-line-parameter-command-injection.js:68:6:68:40 | taint3 | command-line-parameter-command-injection.js:69:22:69:27 | taint3 | | command-line-parameter-command-injection.js:68:20:68:40 | require ... ').argv | command-line-parameter-command-injection.js:68:6:68:16 | {...taint3} | -| command-line-parameter-command-injection.js:68:20:68:40 | require ... ').argv | command-line-parameter-command-injection.js:68:6:68:16 | {...taint3} | -| command-line-parameter-command-injection.js:69:22:69:27 | taint3 | command-line-parameter-command-injection.js:69:10:69:27 | "cmd.sh " + taint3 | | command-line-parameter-command-injection.js:69:22:69:27 | taint3 | command-line-parameter-command-injection.js:69:10:69:27 | "cmd.sh " + taint3 | | command-line-parameter-command-injection.js:71:6:71:16 | [...taint4] | command-line-parameter-command-injection.js:71:6:71:40 | taint4 | | command-line-parameter-command-injection.js:71:6:71:40 | taint4 | command-line-parameter-command-injection.js:72:22:72:27 | taint4 | | command-line-parameter-command-injection.js:71:20:71:40 | require ... ').argv | command-line-parameter-command-injection.js:71:6:71:16 | [...taint4] | -| command-line-parameter-command-injection.js:71:20:71:40 | require ... ').argv | command-line-parameter-command-injection.js:71:6:71:16 | [...taint4] | -| command-line-parameter-command-injection.js:72:22:72:27 | taint4 | command-line-parameter-command-injection.js:72:10:72:27 | "cmd.sh " + taint4 | | command-line-parameter-command-injection.js:72:22:72:27 | taint4 | command-line-parameter-command-injection.js:72:10:72:27 | "cmd.sh " + taint4 | | command-line-parameter-command-injection.js:76:8:76:35 | argv | command-line-parameter-command-injection.js:79:31:79:34 | argv | | command-line-parameter-command-injection.js:76:15:76:26 | process.argv | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | -| command-line-parameter-command-injection.js:76:15:76:26 | process.argv | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | command-line-parameter-command-injection.js:76:8:76:35 | argv | -| command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | command-line-parameter-command-injection.js:79:22:79:39 | minimist(argv).foo | -| command-line-parameter-command-injection.js:79:22:79:39 | minimist(argv).foo | command-line-parameter-command-injection.js:79:10:79:39 | "cmd.sh ... gv).foo | -| command-line-parameter-command-injection.js:79:22:79:39 | minimist(argv).foo | command-line-parameter-command-injection.js:79:10:79:39 | "cmd.sh ... gv).foo | +| command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | command-line-parameter-command-injection.js:79:10:79:39 | "cmd.sh ... gv).foo | | command-line-parameter-command-injection.js:79:31:79:34 | argv | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | -| command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | command-line-parameter-command-injection.js:82:22:82:54 | subarg( ... 2)).foo | -| command-line-parameter-command-injection.js:82:22:82:54 | subarg( ... 2)).foo | command-line-parameter-command-injection.js:82:10:82:54 | "cmd.sh ... 2)).foo | -| command-line-parameter-command-injection.js:82:22:82:54 | subarg( ... 2)).foo | command-line-parameter-command-injection.js:82:10:82:54 | "cmd.sh ... 2)).foo | -| command-line-parameter-command-injection.js:82:29:82:40 | process.argv | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | +| command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | command-line-parameter-command-injection.js:82:10:82:54 | "cmd.sh ... 2)).foo | | command-line-parameter-command-injection.js:82:29:82:40 | process.argv | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | -| command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | command-line-parameter-command-injection.js:85:22:85:59 | yargsPa ... 2)).foo | -| command-line-parameter-command-injection.js:85:22:85:59 | yargsPa ... 2)).foo | command-line-parameter-command-injection.js:85:10:85:59 | "cmd.sh ... 2)).foo | -| command-line-parameter-command-injection.js:85:22:85:59 | yargsPa ... 2)).foo | command-line-parameter-command-injection.js:85:10:85:59 | "cmd.sh ... 2)).foo | -| command-line-parameter-command-injection.js:85:34:85:45 | process.argv | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | +| command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | command-line-parameter-command-injection.js:85:10:85:59 | "cmd.sh ... 2)).foo | | command-line-parameter-command-injection.js:85:34:85:45 | process.argv | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | | command-line-parameter-command-injection.js:88:6:88:37 | flags | command-line-parameter-command-injection.js:89:22:89:26 | flags | | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | command-line-parameter-command-injection.js:88:6:88:37 | flags | | command-line-parameter-command-injection.js:88:25:88:36 | process.argv | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | -| command-line-parameter-command-injection.js:88:25:88:36 | process.argv | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | -| command-line-parameter-command-injection.js:89:22:89:26 | flags | command-line-parameter-command-injection.js:89:22:89:30 | flags.foo | -| command-line-parameter-command-injection.js:89:22:89:30 | flags.foo | command-line-parameter-command-injection.js:89:10:89:30 | "cmd.sh ... ags.foo | -| command-line-parameter-command-injection.js:89:22:89:30 | flags.foo | command-line-parameter-command-injection.js:89:10:89:30 | "cmd.sh ... ags.foo | +| command-line-parameter-command-injection.js:89:22:89:26 | flags | command-line-parameter-command-injection.js:89:10:89:30 | "cmd.sh ... ags.foo | | command-line-parameter-command-injection.js:91:6:91:38 | flags | command-line-parameter-command-injection.js:92:22:92:26 | flags | | command-line-parameter-command-injection.js:91:14:91:38 | require ... .spec}) | command-line-parameter-command-injection.js:91:6:91:38 | flags | -| command-line-parameter-command-injection.js:91:14:91:38 | require ... .spec}) | command-line-parameter-command-injection.js:91:6:91:38 | flags | -| command-line-parameter-command-injection.js:92:22:92:26 | flags | command-line-parameter-command-injection.js:92:22:92:30 | flags.foo | -| command-line-parameter-command-injection.js:92:22:92:30 | flags.foo | command-line-parameter-command-injection.js:92:10:92:30 | "cmd.sh ... ags.foo | -| command-line-parameter-command-injection.js:92:22:92:30 | flags.foo | command-line-parameter-command-injection.js:92:10:92:30 | "cmd.sh ... ags.foo | -| command-line-parameter-command-injection.js:102:22:102:40 | parser.parse_args() | command-line-parameter-command-injection.js:102:22:102:44 | parser. ... s().foo | -| command-line-parameter-command-injection.js:102:22:102:40 | parser.parse_args() | command-line-parameter-command-injection.js:102:22:102:44 | parser. ... s().foo | -| command-line-parameter-command-injection.js:102:22:102:44 | parser. ... s().foo | command-line-parameter-command-injection.js:102:10:102:44 | "cmd.sh ... s().foo | -| command-line-parameter-command-injection.js:102:22:102:44 | parser. ... s().foo | command-line-parameter-command-injection.js:102:10:102:44 | "cmd.sh ... s().foo | +| command-line-parameter-command-injection.js:92:22:92:26 | flags | command-line-parameter-command-injection.js:92:10:92:30 | "cmd.sh ... ags.foo | +| command-line-parameter-command-injection.js:102:22:102:40 | parser.parse_args() | command-line-parameter-command-injection.js:102:10:102:44 | "cmd.sh ... s().foo | | command-line-parameter-command-injection.js:107:8:107:51 | options | command-line-parameter-command-injection.js:108:22:108:28 | options | | command-line-parameter-command-injection.js:107:18:107:51 | command ... itions) | command-line-parameter-command-injection.js:107:8:107:51 | options | -| command-line-parameter-command-injection.js:107:18:107:51 | command ... itions) | command-line-parameter-command-injection.js:107:8:107:51 | options | -| command-line-parameter-command-injection.js:108:22:108:28 | options | command-line-parameter-command-injection.js:108:22:108:32 | options.foo | -| command-line-parameter-command-injection.js:108:22:108:32 | options.foo | command-line-parameter-command-injection.js:108:10:108:32 | "cmd.sh ... ons.foo | -| command-line-parameter-command-injection.js:108:22:108:32 | options.foo | command-line-parameter-command-injection.js:108:10:108:32 | "cmd.sh ... ons.foo | +| command-line-parameter-command-injection.js:108:22:108:28 | options | command-line-parameter-command-injection.js:108:10:108:32 | "cmd.sh ... ons.foo | | command-line-parameter-command-injection.js:114:8:114:52 | cli | command-line-parameter-command-injection.js:116:22:116:24 | cli | | command-line-parameter-command-injection.js:114:14:114:52 | meow(`h ... lags}}) | command-line-parameter-command-injection.js:114:8:114:52 | cli | -| command-line-parameter-command-injection.js:114:14:114:52 | meow(`h ... lags}}) | command-line-parameter-command-injection.js:114:8:114:52 | cli | -| command-line-parameter-command-injection.js:116:22:116:24 | cli | command-line-parameter-command-injection.js:116:22:116:30 | cli.input | -| command-line-parameter-command-injection.js:116:22:116:30 | cli.input | command-line-parameter-command-injection.js:116:22:116:33 | cli.input[0] | -| command-line-parameter-command-injection.js:116:22:116:33 | cli.input[0] | command-line-parameter-command-injection.js:116:10:116:33 | "cmd.sh ... nput[0] | -| command-line-parameter-command-injection.js:116:22:116:33 | cli.input[0] | command-line-parameter-command-injection.js:116:10:116:33 | "cmd.sh ... nput[0] | +| command-line-parameter-command-injection.js:116:22:116:24 | cli | command-line-parameter-command-injection.js:116:10:116:33 | "cmd.sh ... nput[0] | | command-line-parameter-command-injection.js:122:6:122:46 | opts | command-line-parameter-command-injection.js:124:22:124:25 | opts | | command-line-parameter-command-injection.js:122:13:122:46 | dashdas ... tions}) | command-line-parameter-command-injection.js:122:6:122:46 | opts | -| command-line-parameter-command-injection.js:122:13:122:46 | dashdas ... tions}) | command-line-parameter-command-injection.js:122:6:122:46 | opts | -| command-line-parameter-command-injection.js:124:22:124:25 | opts | command-line-parameter-command-injection.js:124:22:124:29 | opts.foo | -| command-line-parameter-command-injection.js:124:22:124:29 | opts.foo | command-line-parameter-command-injection.js:124:10:124:29 | "cmd.sh " + opts.foo | -| command-line-parameter-command-injection.js:124:22:124:29 | opts.foo | command-line-parameter-command-injection.js:124:10:124:29 | "cmd.sh " + opts.foo | +| command-line-parameter-command-injection.js:124:22:124:25 | opts | command-line-parameter-command-injection.js:124:10:124:29 | "cmd.sh " + opts.foo | | command-line-parameter-command-injection.js:127:6:127:26 | opts | command-line-parameter-command-injection.js:129:22:129:25 | opts | | command-line-parameter-command-injection.js:127:13:127:26 | parser.parse() | command-line-parameter-command-injection.js:127:6:127:26 | opts | -| command-line-parameter-command-injection.js:127:13:127:26 | parser.parse() | command-line-parameter-command-injection.js:127:6:127:26 | opts | -| command-line-parameter-command-injection.js:129:22:129:25 | opts | command-line-parameter-command-injection.js:129:22:129:29 | opts.foo | -| command-line-parameter-command-injection.js:129:22:129:29 | opts.foo | command-line-parameter-command-injection.js:129:10:129:29 | "cmd.sh " + opts.foo | -| command-line-parameter-command-injection.js:129:22:129:29 | opts.foo | command-line-parameter-command-injection.js:129:10:129:29 | "cmd.sh " + opts.foo | +| command-line-parameter-command-injection.js:129:22:129:25 | opts | command-line-parameter-command-injection.js:129:10:129:29 | "cmd.sh " + opts.foo | | command-line-parameter-command-injection.js:133:8:133:41 | program | command-line-parameter-command-injection.js:137:22:137:28 | program | | command-line-parameter-command-injection.js:133:10:133:16 | program | command-line-parameter-command-injection.js:133:8:133:41 | program | -| command-line-parameter-command-injection.js:133:10:133:16 | program | command-line-parameter-command-injection.js:133:8:133:41 | program | -| command-line-parameter-command-injection.js:136:22:136:35 | program.opts() | command-line-parameter-command-injection.js:136:22:136:45 | program ... zzaType | -| command-line-parameter-command-injection.js:136:22:136:35 | program.opts() | command-line-parameter-command-injection.js:136:22:136:45 | program ... zzaType | +| command-line-parameter-command-injection.js:136:22:136:35 | program.opts() | command-line-parameter-command-injection.js:136:10:136:45 | "cmd.sh ... zzaType | | command-line-parameter-command-injection.js:136:22:136:45 | program ... zzaType | command-line-parameter-command-injection.js:136:10:136:45 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:136:22:136:45 | program ... zzaType | command-line-parameter-command-injection.js:136:10:136:45 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:136:22:136:45 | program ... zzaType | command-line-parameter-command-injection.js:136:10:136:45 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:136:22:136:45 | program ... zzaType | command-line-parameter-command-injection.js:136:10:136:45 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:137:22:137:28 | program | command-line-parameter-command-injection.js:137:22:137:38 | program.pizzaType | +| command-line-parameter-command-injection.js:137:22:137:28 | program | command-line-parameter-command-injection.js:137:10:137:38 | "cmd.sh ... zzaType | | command-line-parameter-command-injection.js:137:22:137:38 | program.pizzaType | command-line-parameter-command-injection.js:137:10:137:38 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:137:22:137:38 | program.pizzaType | command-line-parameter-command-injection.js:137:10:137:38 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:137:22:137:38 | program.pizzaType | command-line-parameter-command-injection.js:137:10:137:38 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:137:22:137:38 | program.pizzaType | command-line-parameter-command-injection.js:137:10:137:38 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:145:22:145:35 | program.opts() | command-line-parameter-command-injection.js:145:22:145:45 | program ... zzaType | -| command-line-parameter-command-injection.js:145:22:145:35 | program.opts() | command-line-parameter-command-injection.js:145:22:145:45 | program ... zzaType | -| command-line-parameter-command-injection.js:145:22:145:45 | program ... zzaType | command-line-parameter-command-injection.js:145:10:145:45 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:145:22:145:45 | program ... zzaType | command-line-parameter-command-injection.js:145:10:145:45 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:145:22:145:45 | program ... zzaType | command-line-parameter-command-injection.js:145:10:145:45 | "cmd.sh ... zzaType | +| command-line-parameter-command-injection.js:145:22:145:35 | program.opts() | command-line-parameter-command-injection.js:145:10:145:45 | "cmd.sh ... zzaType | | command-line-parameter-command-injection.js:145:22:145:45 | program ... zzaType | command-line-parameter-command-injection.js:145:10:145:45 | "cmd.sh ... zzaType | | command-line-parameter-command-injection.js:146:22:146:38 | program.pizzaType | command-line-parameter-command-injection.js:146:10:146:38 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:146:22:146:38 | program.pizzaType | command-line-parameter-command-injection.js:146:10:146:38 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:146:22:146:38 | program.pizzaType | command-line-parameter-command-injection.js:146:10:146:38 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:146:22:146:38 | program.pizzaType | command-line-parameter-command-injection.js:146:10:146:38 | "cmd.sh ... zzaType | +nodes +| actions.js:4:6:4:16 | process.env | semmle.label | process.env | +| actions.js:4:6:4:29 | process ... _DATA'] | semmle.label | process ... _DATA'] | +| actions.js:7:15:7:15 | e | semmle.label | e | +| actions.js:8:10:8:10 | e | semmle.label | e | +| actions.js:8:10:8:23 | e['TEST_DATA'] | semmle.label | e['TEST_DATA'] | +| actions.js:12:6:12:16 | process.env | semmle.label | process.env | +| actions.js:14:6:14:21 | getInput('data') | semmle.label | getInput('data') | +| command-line-parameter-command-injection.js:4:10:4:21 | process.argv | semmle.label | process.argv | +| command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | semmle.label | "cmd.sh ... argv[2] | +| command-line-parameter-command-injection.js:8:22:8:33 | process.argv | semmle.label | process.argv | +| command-line-parameter-command-injection.js:10:6:10:33 | args | semmle.label | args | +| command-line-parameter-command-injection.js:10:6:10:33 | args [ArrayElement] | semmle.label | args [ArrayElement] | +| command-line-parameter-command-injection.js:10:13:10:24 | process.argv | semmle.label | process.argv | +| command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | semmle.label | process ... lice(2) | +| command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) [ArrayElement] | semmle.label | process ... lice(2) [ArrayElement] | +| command-line-parameter-command-injection.js:11:14:11:17 | args | semmle.label | args | +| command-line-parameter-command-injection.js:11:14:11:20 | args[0] | semmle.label | args[0] | +| command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | semmle.label | "cmd.sh " + args[0] | +| command-line-parameter-command-injection.js:12:26:12:29 | args | semmle.label | args | +| command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | semmle.label | fewerArgs | +| command-line-parameter-command-injection.js:14:18:14:21 | args | semmle.label | args | +| command-line-parameter-command-injection.js:14:18:14:21 | args [ArrayElement] | semmle.label | args [ArrayElement] | +| command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | semmle.label | args.slice(1) | +| command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | semmle.label | fewerArgs | +| command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | semmle.label | fewerArgs[0] | +| command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | semmle.label | "cmd.sh ... Args[0] | +| command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | semmle.label | fewerArgs | +| command-line-parameter-command-injection.js:18:6:18:24 | arg0 | semmle.label | arg0 | +| command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | semmle.label | fewerArgs | +| command-line-parameter-command-injection.js:19:14:19:17 | arg0 | semmle.label | arg0 | +| command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | semmle.label | "cmd.sh " + arg0 | +| command-line-parameter-command-injection.js:20:26:20:29 | arg0 | semmle.label | arg0 | +| command-line-parameter-command-injection.js:24:8:24:35 | args | semmle.label | args | +| command-line-parameter-command-injection.js:24:15:24:26 | process.argv | semmle.label | process.argv | +| command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | semmle.label | process ... lice(2) | +| command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | semmle.label | `node $ ... ption"` | +| command-line-parameter-command-injection.js:26:32:26:35 | args | semmle.label | args | +| command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | semmle.label | `node $ ... ption"` | +| command-line-parameter-command-injection.js:27:32:27:35 | args | semmle.label | args | +| command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | semmle.label | args.join(' ') | +| command-line-parameter-command-injection.js:30:9:30:50 | "cmd.sh ... )().foo | semmle.label | "cmd.sh ... )().foo | +| command-line-parameter-command-injection.js:30:21:30:46 | require ... rgs")() | semmle.label | require ... rgs")() | +| command-line-parameter-command-injection.js:32:9:32:45 | "cmd.sh ... rgv.foo | semmle.label | "cmd.sh ... rgv.foo | +| command-line-parameter-command-injection.js:32:21:32:41 | require ... ").argv | semmle.label | require ... ").argv | +| command-line-parameter-command-injection.js:33:9:33:48 | "cmd.sh ... rgv.foo | semmle.label | "cmd.sh ... rgv.foo | +| command-line-parameter-command-injection.js:33:21:33:44 | require ... ").argv | semmle.label | require ... ").argv | +| command-line-parameter-command-injection.js:36:6:39:7 | args | semmle.label | args | +| command-line-parameter-command-injection.js:36:13:39:7 | require ... \\t\\t.argv | semmle.label | require ... \\t\\t.argv | +| command-line-parameter-command-injection.js:41:10:41:25 | "cmd.sh " + args | semmle.label | "cmd.sh " + args | +| command-line-parameter-command-injection.js:41:22:41:25 | args | semmle.label | args | +| command-line-parameter-command-injection.js:43:10:43:62 | "cmd.sh ... e().foo | semmle.label | "cmd.sh ... e().foo | +| command-line-parameter-command-injection.js:43:22:43:58 | require ... parse() | semmle.label | require ... parse() | +| command-line-parameter-command-injection.js:47:8:53:12 | args | semmle.label | args | +| command-line-parameter-command-injection.js:48:3:50:3 | argv: { ... rgs\\n\\t\\t} | semmle.label | argv: { ... rgs\\n\\t\\t} | +| command-line-parameter-command-injection.js:48:9:50:3 | {\\n\\t\\t\\t...args\\n\\t\\t} | semmle.label | {\\n\\t\\t\\t...args\\n\\t\\t} | +| command-line-parameter-command-injection.js:55:10:55:25 | "cmd.sh " + args | semmle.label | "cmd.sh " + args | +| command-line-parameter-command-injection.js:55:22:55:25 | args | semmle.label | args | +| command-line-parameter-command-injection.js:57:6:57:37 | tainted1 | semmle.label | tainted1 | +| command-line-parameter-command-injection.js:57:17:57:37 | require ... ').argv | semmle.label | require ... ').argv | +| command-line-parameter-command-injection.js:58:6:58:40 | tainted2 | semmle.label | tainted2 | +| command-line-parameter-command-injection.js:58:17:58:40 | require ... parse() | semmle.label | require ... parse() | +| command-line-parameter-command-injection.js:60:8:60:56 | {taint1 ... 2rest}} [taint1] | semmle.label | {taint1 ... 2rest}} [taint1] | +| command-line-parameter-command-injection.js:60:8:60:56 | {taint1 ... 2rest}} [taint2] | semmle.label | {taint1 ... 2rest}} [taint2] | +| command-line-parameter-command-injection.js:60:8:63:2 | taint1rest | semmle.label | taint1rest | +| command-line-parameter-command-injection.js:60:8:63:2 | taint2rest | semmle.label | taint2rest | +| command-line-parameter-command-injection.js:60:9:60:31 | taint1: ... t1rest} | semmle.label | taint1: ... t1rest} | +| command-line-parameter-command-injection.js:60:17:60:31 | {...taint1rest} | semmle.label | {...taint1rest} | +| command-line-parameter-command-injection.js:60:33:60:55 | taint2: ... t2rest} | semmle.label | taint2: ... t2rest} | +| command-line-parameter-command-injection.js:60:41:60:55 | {...taint2rest} | semmle.label | {...taint2rest} | +| command-line-parameter-command-injection.js:60:60:63:2 | {\\n\\t\\ttai ... ted2\\n\\t} [taint1] | semmle.label | {\\n\\t\\ttai ... ted2\\n\\t} [taint1] | +| command-line-parameter-command-injection.js:60:60:63:2 | {\\n\\t\\ttai ... ted2\\n\\t} [taint2] | semmle.label | {\\n\\t\\ttai ... ted2\\n\\t} [taint2] | +| command-line-parameter-command-injection.js:61:11:61:18 | tainted1 | semmle.label | tainted1 | +| command-line-parameter-command-injection.js:62:11:62:18 | tainted2 | semmle.label | tainted2 | +| command-line-parameter-command-injection.js:65:10:65:31 | "cmd.sh ... nt1rest | semmle.label | "cmd.sh ... nt1rest | +| command-line-parameter-command-injection.js:65:22:65:31 | taint1rest | semmle.label | taint1rest | +| command-line-parameter-command-injection.js:66:10:66:31 | "cmd.sh ... nt2rest | semmle.label | "cmd.sh ... nt2rest | +| command-line-parameter-command-injection.js:66:22:66:31 | taint2rest | semmle.label | taint2rest | +| command-line-parameter-command-injection.js:68:6:68:16 | {...taint3} | semmle.label | {...taint3} | +| command-line-parameter-command-injection.js:68:6:68:40 | taint3 | semmle.label | taint3 | +| command-line-parameter-command-injection.js:68:20:68:40 | require ... ').argv | semmle.label | require ... ').argv | +| command-line-parameter-command-injection.js:69:10:69:27 | "cmd.sh " + taint3 | semmle.label | "cmd.sh " + taint3 | +| command-line-parameter-command-injection.js:69:22:69:27 | taint3 | semmle.label | taint3 | +| command-line-parameter-command-injection.js:71:6:71:16 | [...taint4] | semmle.label | [...taint4] | +| command-line-parameter-command-injection.js:71:6:71:40 | taint4 | semmle.label | taint4 | +| command-line-parameter-command-injection.js:71:20:71:40 | require ... ').argv | semmle.label | require ... ').argv | +| command-line-parameter-command-injection.js:72:10:72:27 | "cmd.sh " + taint4 | semmle.label | "cmd.sh " + taint4 | +| command-line-parameter-command-injection.js:72:22:72:27 | taint4 | semmle.label | taint4 | +| command-line-parameter-command-injection.js:76:8:76:35 | argv | semmle.label | argv | +| command-line-parameter-command-injection.js:76:15:76:26 | process.argv | semmle.label | process.argv | +| command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | semmle.label | process ... lice(2) | +| command-line-parameter-command-injection.js:79:10:79:39 | "cmd.sh ... gv).foo | semmle.label | "cmd.sh ... gv).foo | +| command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | semmle.label | minimist(argv) | +| command-line-parameter-command-injection.js:79:31:79:34 | argv | semmle.label | argv | +| command-line-parameter-command-injection.js:82:10:82:54 | "cmd.sh ... 2)).foo | semmle.label | "cmd.sh ... 2)).foo | +| command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | semmle.label | subarg( ... ice(2)) | +| command-line-parameter-command-injection.js:82:29:82:40 | process.argv | semmle.label | process.argv | +| command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | semmle.label | process ... lice(2) | +| command-line-parameter-command-injection.js:85:10:85:59 | "cmd.sh ... 2)).foo | semmle.label | "cmd.sh ... 2)).foo | +| command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | semmle.label | yargsPa ... ice(2)) | +| command-line-parameter-command-injection.js:85:34:85:45 | process.argv | semmle.label | process.argv | +| command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | semmle.label | process ... lice(2) | +| command-line-parameter-command-injection.js:88:6:88:37 | flags | semmle.label | flags | +| command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | semmle.label | args.pa ... s.argv) | +| command-line-parameter-command-injection.js:88:25:88:36 | process.argv | semmle.label | process.argv | +| command-line-parameter-command-injection.js:89:10:89:30 | "cmd.sh ... ags.foo | semmle.label | "cmd.sh ... ags.foo | +| command-line-parameter-command-injection.js:89:22:89:26 | flags | semmle.label | flags | +| command-line-parameter-command-injection.js:91:6:91:38 | flags | semmle.label | flags | +| command-line-parameter-command-injection.js:91:14:91:38 | require ... .spec}) | semmle.label | require ... .spec}) | +| command-line-parameter-command-injection.js:92:10:92:30 | "cmd.sh ... ags.foo | semmle.label | "cmd.sh ... ags.foo | +| command-line-parameter-command-injection.js:92:22:92:26 | flags | semmle.label | flags | +| command-line-parameter-command-injection.js:102:10:102:44 | "cmd.sh ... s().foo | semmle.label | "cmd.sh ... s().foo | +| command-line-parameter-command-injection.js:102:22:102:40 | parser.parse_args() | semmle.label | parser.parse_args() | +| command-line-parameter-command-injection.js:107:8:107:51 | options | semmle.label | options | +| command-line-parameter-command-injection.js:107:18:107:51 | command ... itions) | semmle.label | command ... itions) | +| command-line-parameter-command-injection.js:108:10:108:32 | "cmd.sh ... ons.foo | semmle.label | "cmd.sh ... ons.foo | +| command-line-parameter-command-injection.js:108:22:108:28 | options | semmle.label | options | +| command-line-parameter-command-injection.js:114:8:114:52 | cli | semmle.label | cli | +| command-line-parameter-command-injection.js:114:14:114:52 | meow(`h ... lags}}) | semmle.label | meow(`h ... lags}}) | +| command-line-parameter-command-injection.js:116:10:116:33 | "cmd.sh ... nput[0] | semmle.label | "cmd.sh ... nput[0] | +| command-line-parameter-command-injection.js:116:22:116:24 | cli | semmle.label | cli | +| command-line-parameter-command-injection.js:122:6:122:46 | opts | semmle.label | opts | +| command-line-parameter-command-injection.js:122:13:122:46 | dashdas ... tions}) | semmle.label | dashdas ... tions}) | +| command-line-parameter-command-injection.js:124:10:124:29 | "cmd.sh " + opts.foo | semmle.label | "cmd.sh " + opts.foo | +| command-line-parameter-command-injection.js:124:22:124:25 | opts | semmle.label | opts | +| command-line-parameter-command-injection.js:127:6:127:26 | opts | semmle.label | opts | +| command-line-parameter-command-injection.js:127:13:127:26 | parser.parse() | semmle.label | parser.parse() | +| command-line-parameter-command-injection.js:129:10:129:29 | "cmd.sh " + opts.foo | semmle.label | "cmd.sh " + opts.foo | +| command-line-parameter-command-injection.js:129:22:129:25 | opts | semmle.label | opts | +| command-line-parameter-command-injection.js:133:8:133:41 | program | semmle.label | program | +| command-line-parameter-command-injection.js:133:10:133:16 | program | semmle.label | program | +| command-line-parameter-command-injection.js:136:10:136:45 | "cmd.sh ... zzaType | semmle.label | "cmd.sh ... zzaType | +| command-line-parameter-command-injection.js:136:22:136:35 | program.opts() | semmle.label | program.opts() | +| command-line-parameter-command-injection.js:136:22:136:45 | program ... zzaType | semmle.label | program ... zzaType | +| command-line-parameter-command-injection.js:137:10:137:38 | "cmd.sh ... zzaType | semmle.label | "cmd.sh ... zzaType | +| command-line-parameter-command-injection.js:137:22:137:28 | program | semmle.label | program | +| command-line-parameter-command-injection.js:137:22:137:38 | program.pizzaType | semmle.label | program.pizzaType | +| command-line-parameter-command-injection.js:145:10:145:45 | "cmd.sh ... zzaType | semmle.label | "cmd.sh ... zzaType | +| command-line-parameter-command-injection.js:145:22:145:35 | program.opts() | semmle.label | program.opts() | +| command-line-parameter-command-injection.js:145:22:145:45 | program ... zzaType | semmle.label | program ... zzaType | +| command-line-parameter-command-injection.js:146:10:146:38 | "cmd.sh ... zzaType | semmle.label | "cmd.sh ... zzaType | +| command-line-parameter-command-injection.js:146:22:146:38 | program.pizzaType | semmle.label | program.pizzaType | +subpaths #select | actions.js:4:6:4:29 | process ... _DATA'] | actions.js:4:6:4:16 | process.env | actions.js:4:6:4:29 | process ... _DATA'] | This command depends on an unsanitized $@. | actions.js:4:6:4:16 | process.env | environment variable | | actions.js:8:10:8:23 | e['TEST_DATA'] | actions.js:12:6:12:16 | process.env | actions.js:8:10:8:23 | e['TEST_DATA'] | This command depends on an unsanitized $@. | actions.js:12:6:12:16 | process.env | environment variable | From 99f63b1cfa6de7d9ef9d8f5f82b144127d0871f6 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:20:46 +0200 Subject: [PATCH 081/514] JS: Port InsecureDownload --- .../dataflow/InsecureDownloadQuery.qll | 32 +++++++-- .../src/Security/CWE-829/InsecureDownload.ql | 6 +- .../CWE-829/InsecureDownload.expected | 71 ++++++++++--------- 3 files changed, 66 insertions(+), 43 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureDownloadQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureDownloadQuery.qll index 8b7eb42dd25..7f7d3341d5a 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureDownloadQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureDownloadQuery.qll @@ -12,19 +12,41 @@ import InsecureDownloadCustomizations::InsecureDownload /** * A taint tracking configuration for download of sensitive file through insecure connection. */ -class Configuration extends DataFlow::Configuration { - Configuration() { this = "InsecureDownload" } +module InsecureDownloadConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; - override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { source.(Source).getALabel() = label } - override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { + predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { sink.(Sink).getALabel() = label } + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint tracking for download of sensitive file through insecure connection. + */ +module InsecureDownload = DataFlow::GlobalWithState; + +/** + * DEPRECATED. Use the `InsecureDownload` module instead. + */ +deprecated class Configuration extends DataFlow::Configuration { + Configuration() { this = "InsecureDownload" } + + override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { + InsecureDownloadConfig::isSource(source, label) + } + + override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { + InsecureDownloadConfig::isSink(sink, label) + } + override predicate isBarrier(DataFlow::Node node) { super.isBarrier(node) or - node instanceof Sanitizer + InsecureDownloadConfig::isBarrier(node) } } diff --git a/javascript/ql/src/Security/CWE-829/InsecureDownload.ql b/javascript/ql/src/Security/CWE-829/InsecureDownload.ql index d1f27267477..4644f981392 100644 --- a/javascript/ql/src/Security/CWE-829/InsecureDownload.ql +++ b/javascript/ql/src/Security/CWE-829/InsecureDownload.ql @@ -13,9 +13,9 @@ import javascript import semmle.javascript.security.dataflow.InsecureDownloadQuery -import DataFlow::PathGraph +import DataFlow::DeduplicatePathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from PathNode source, PathNode sink +where InsecureDownload::flowPath(source.getAnOriginalPathNode(), sink.getAnOriginalPathNode()) select sink.getNode(), source, sink, "$@ of sensitive file from $@.", sink.getNode().(Sink).getDownloadCall(), "Download", source.getNode(), "HTTP source" diff --git a/javascript/ql/test/query-tests/Security/CWE-829/InsecureDownload.expected b/javascript/ql/test/query-tests/Security/CWE-829/InsecureDownload.expected index 8f3d1e04673..8e0f2f5af59 100644 --- a/javascript/ql/test/query-tests/Security/CWE-829/InsecureDownload.expected +++ b/javascript/ql/test/query-tests/Security/CWE-829/InsecureDownload.expected @@ -1,43 +1,44 @@ nodes -| insecure-download.js:5:16:5:28 | installer.url | -| insecure-download.js:5:16:5:28 | installer.url | -| insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | -| insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | -| insecure-download.js:15:18:15:40 | buildTo ... llerUrl | -| insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | -| insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | -| insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | -| insecure-download.js:36:9:36:45 | url | -| insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | -| insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | -| insecure-download.js:37:23:37:25 | url | -| insecure-download.js:37:23:37:25 | url | -| insecure-download.js:39:26:39:28 | url | -| insecure-download.js:39:26:39:28 | url | -| insecure-download.js:41:12:41:41 | "ftp:// ... fe.APK" | -| insecure-download.js:41:12:41:41 | "ftp:// ... fe.APK" | -| insecure-download.js:41:12:41:41 | "ftp:// ... fe.APK" | -| insecure-download.js:48:12:48:38 | "http:/ ... unsafe" | -| insecure-download.js:48:12:48:38 | "http:/ ... unsafe" | -| insecure-download.js:48:12:48:38 | "http:/ ... unsafe" | -| insecure-download.js:52:11:52:45 | "http:/ ... nknown" | -| insecure-download.js:52:11:52:45 | "http:/ ... nknown" | -| insecure-download.js:52:11:52:45 | "http:/ ... nknown" | +| insecure-download.js:4:28:4:36 | installer [url] | semmle.label | installer [url] | +| insecure-download.js:5:16:5:24 | installer [url] | semmle.label | installer [url] | +| insecure-download.js:5:16:5:28 | installer.url | semmle.label | installer.url | +| insecure-download.js:7:9:11:5 | constants [buildTools, installerUrl] | semmle.label | constants [buildTools, installerUrl] | +| insecure-download.js:7:21:11:5 | {\\n ... }\\n } [buildTools, installerUrl] | semmle.label | {\\n ... }\\n } [buildTools, installerUrl] | +| insecure-download.js:8:21:10:9 | {\\n ... } [installerUrl] | semmle.label | {\\n ... } [installerUrl] | +| insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | semmle.label | 'http:/ ... ll.exe' | +| insecure-download.js:13:15:13:47 | buildTools [installerUrl] | semmle.label | buildTools [installerUrl] | +| insecure-download.js:13:28:13:36 | constants [buildTools, installerUrl] | semmle.label | constants [buildTools, installerUrl] | +| insecure-download.js:13:28:13:47 | constants.buildTools [installerUrl] | semmle.label | constants.buildTools [installerUrl] | +| insecure-download.js:14:16:16:9 | {\\n ... } [url] | semmle.label | {\\n ... } [url] | +| insecure-download.js:15:18:15:27 | buildTools [installerUrl] | semmle.label | buildTools [installerUrl] | +| insecure-download.js:15:18:15:40 | buildTo ... llerUrl | semmle.label | buildTo ... llerUrl | +| insecure-download.js:19:19:19:46 | getBuil ... rPath() [url] | semmle.label | getBuil ... rPath() [url] | +| insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | semmle.label | "http:/ ... fe.APK" | +| insecure-download.js:36:9:36:45 | url | semmle.label | url | +| insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | semmle.label | "http:/ ... fe.APK" | +| insecure-download.js:37:23:37:25 | url | semmle.label | url | +| insecure-download.js:39:26:39:28 | url | semmle.label | url | +| insecure-download.js:41:12:41:41 | "ftp:// ... fe.APK" | semmle.label | "ftp:// ... fe.APK" | +| insecure-download.js:48:12:48:38 | "http:/ ... unsafe" | semmle.label | "http:/ ... unsafe" | +| insecure-download.js:52:11:52:45 | "http:/ ... nknown" | semmle.label | "http:/ ... nknown" | edges -| insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | insecure-download.js:15:18:15:40 | buildTo ... llerUrl | -| insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | insecure-download.js:15:18:15:40 | buildTo ... llerUrl | -| insecure-download.js:15:18:15:40 | buildTo ... llerUrl | insecure-download.js:5:16:5:28 | installer.url | -| insecure-download.js:15:18:15:40 | buildTo ... llerUrl | insecure-download.js:5:16:5:28 | installer.url | -| insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | -| insecure-download.js:36:9:36:45 | url | insecure-download.js:37:23:37:25 | url | +| insecure-download.js:4:28:4:36 | installer [url] | insecure-download.js:5:16:5:24 | installer [url] | +| insecure-download.js:5:16:5:24 | installer [url] | insecure-download.js:5:16:5:28 | installer.url | +| insecure-download.js:7:9:11:5 | constants [buildTools, installerUrl] | insecure-download.js:13:28:13:36 | constants [buildTools, installerUrl] | +| insecure-download.js:7:21:11:5 | {\\n ... }\\n } [buildTools, installerUrl] | insecure-download.js:7:9:11:5 | constants [buildTools, installerUrl] | +| insecure-download.js:8:21:10:9 | {\\n ... } [installerUrl] | insecure-download.js:7:21:11:5 | {\\n ... }\\n } [buildTools, installerUrl] | +| insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | insecure-download.js:8:21:10:9 | {\\n ... } [installerUrl] | +| insecure-download.js:13:15:13:47 | buildTools [installerUrl] | insecure-download.js:15:18:15:27 | buildTools [installerUrl] | +| insecure-download.js:13:28:13:36 | constants [buildTools, installerUrl] | insecure-download.js:13:28:13:47 | constants.buildTools [installerUrl] | +| insecure-download.js:13:28:13:47 | constants.buildTools [installerUrl] | insecure-download.js:13:15:13:47 | buildTools [installerUrl] | +| insecure-download.js:14:16:16:9 | {\\n ... } [url] | insecure-download.js:19:19:19:46 | getBuil ... rPath() [url] | +| insecure-download.js:15:18:15:27 | buildTools [installerUrl] | insecure-download.js:15:18:15:40 | buildTo ... llerUrl | +| insecure-download.js:15:18:15:40 | buildTo ... llerUrl | insecure-download.js:14:16:16:9 | {\\n ... } [url] | +| insecure-download.js:19:19:19:46 | getBuil ... rPath() [url] | insecure-download.js:4:28:4:36 | installer [url] | | insecure-download.js:36:9:36:45 | url | insecure-download.js:37:23:37:25 | url | | insecure-download.js:36:9:36:45 | url | insecure-download.js:39:26:39:28 | url | -| insecure-download.js:36:9:36:45 | url | insecure-download.js:39:26:39:28 | url | | insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | insecure-download.js:36:9:36:45 | url | -| insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | insecure-download.js:36:9:36:45 | url | -| insecure-download.js:41:12:41:41 | "ftp:// ... fe.APK" | insecure-download.js:41:12:41:41 | "ftp:// ... fe.APK" | -| insecure-download.js:48:12:48:38 | "http:/ ... unsafe" | insecure-download.js:48:12:48:38 | "http:/ ... unsafe" | -| insecure-download.js:52:11:52:45 | "http:/ ... nknown" | insecure-download.js:52:11:52:45 | "http:/ ... nknown" | +subpaths #select | insecure-download.js:5:16:5:28 | installer.url | insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | insecure-download.js:5:16:5:28 | installer.url | $@ of sensitive file from $@. | insecure-download.js:5:9:5:44 | nugget( ... => { }) | Download | insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | HTTP source | | insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | $@ of sensitive file from $@. | insecure-download.js:30:5:30:43 | nugget( ... e.APK") | Download | insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | HTTP source | From cd1a1e25ae6dfa1da9bb4f154ecd48abf6b7e718 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:20:58 +0200 Subject: [PATCH 082/514] JS: Port InsecureRandomness --- .../dataflow/InsecureRandomnessQuery.qll | 32 ++- .../Security/CWE-338/InsecureRandomness.ql | 6 +- .../CWE-338/InsecureRandomness.expected | 197 +++++------------- 3 files changed, 91 insertions(+), 144 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureRandomnessQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureRandomnessQuery.qll index 78dfdbfe833..b4804e8f464 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureRandomnessQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureRandomnessQuery.qll @@ -15,7 +15,37 @@ private import InsecureRandomnessCustomizations::InsecureRandomness as InsecureR /** * A taint tracking configuration for random values that are not cryptographically secure. */ -class Configuration extends TaintTracking::Configuration { +module InsecureRandomnessConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate isBarrierOut(DataFlow::Node node) { + // stop propagation at the sinks to avoid double reporting + isSink(node) + } + + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { + InsecureRandomness::isAdditionalTaintStep(pred, succ) + or + // We want to make use of default taint steps but not the default taint sanitizers, as they + // generally assume numbers aren't taintable. So we use a data-flow configuration that includes all + // taint steps as additional flow steps. + TaintTracking::defaultTaintStep(pred, succ) + } +} + +/** + * Taint tracking for random values that are not cryptographically secure. + */ +module InsecureRandomnessFlow = DataFlow::Global; + +/** + * DEPRECATED. Use the `InsecureRandomnessFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "InsecureRandomness" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-338/InsecureRandomness.ql b/javascript/ql/src/Security/CWE-338/InsecureRandomness.ql index 1d30221358d..2bfcfc14d50 100644 --- a/javascript/ql/src/Security/CWE-338/InsecureRandomness.ql +++ b/javascript/ql/src/Security/CWE-338/InsecureRandomness.ql @@ -14,10 +14,10 @@ import javascript import semmle.javascript.security.dataflow.InsecureRandomnessQuery -import DataFlow::PathGraph +import InsecureRandomnessFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from InsecureRandomnessFlow::PathNode source, InsecureRandomnessFlow::PathNode sink +where InsecureRandomnessFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This uses a cryptographically insecure random number generated at $@ in a security context.", source.getNode(), source.getNode().toString() diff --git a/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected b/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected index a5a06eba7db..8d4e9c108fb 100644 --- a/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected +++ b/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected @@ -1,176 +1,93 @@ -nodes -| tst.js:2:20:2:32 | Math.random() | -| tst.js:2:20:2:32 | Math.random() | -| tst.js:2:20:2:32 | Math.random() | -| tst.js:6:20:6:43 | "prefix ... andom() | -| tst.js:6:20:6:43 | "prefix ... andom() | -| tst.js:6:31:6:43 | Math.random() | -| tst.js:6:31:6:43 | Math.random() | -| tst.js:10:20:10:32 | Math.random() | -| tst.js:10:20:10:32 | Math.random() | -| tst.js:10:20:10:32 | Math.random() | -| tst.js:19:9:19:36 | suffix | -| tst.js:19:18:19:30 | Math.random() | -| tst.js:19:18:19:30 | Math.random() | -| tst.js:19:18:19:36 | Math.random() % 255 | -| tst.js:20:20:20:36 | "prefix" + suffix | -| tst.js:20:20:20:36 | "prefix" + suffix | -| tst.js:20:31:20:36 | suffix | -| tst.js:28:9:28:26 | pw | -| tst.js:28:14:28:26 | Math.random() | -| tst.js:28:14:28:26 | Math.random() | -| tst.js:29:20:29:21 | pw | -| tst.js:29:20:29:21 | pw | -| tst.js:41:20:41:33 | !Math.random() | -| tst.js:41:20:41:33 | !Math.random() | -| tst.js:41:21:41:33 | Math.random() | -| tst.js:41:21:41:33 | Math.random() | -| tst.js:45:18:45:30 | Math.random() | -| tst.js:45:18:45:30 | Math.random() | -| tst.js:45:18:45:30 | Math.random() | -| tst.js:50:16:50:28 | Math.random() | -| tst.js:50:16:50:28 | Math.random() | -| tst.js:50:16:50:28 | Math.random() | -| tst.js:55:17:55:29 | Math.random() | -| tst.js:55:17:55:29 | Math.random() | -| tst.js:55:17:55:29 | Math.random() | -| tst.js:61:17:61:34 | '' + Math.random() | -| tst.js:61:17:61:34 | '' + Math.random() | -| tst.js:61:22:61:34 | Math.random() | -| tst.js:61:22:61:34 | Math.random() | -| tst.js:66:18:66:42 | Math.fl ... ndom()) | -| tst.js:66:18:66:42 | Math.fl ... ndom()) | -| tst.js:66:29:66:41 | Math.random() | -| tst.js:66:29:66:41 | Math.random() | -| tst.js:71:9:71:48 | rand | -| tst.js:71:16:71:48 | Math.fl ... 999999) | -| tst.js:71:27:71:39 | Math.random() | -| tst.js:71:27:71:39 | Math.random() | -| tst.js:71:27:71:47 | Math.ra ... 9999999 | -| tst.js:72:9:72:48 | concat | -| tst.js:72:18:72:48 | ts.toSt ... tring() | -| tst.js:72:34:72:37 | rand | -| tst.js:72:34:72:48 | rand.toString() | -| tst.js:73:23:73:28 | concat | -| tst.js:73:23:73:28 | concat | -| tst.js:77:16:77:21 | secret | -| tst.js:77:16:77:21 | secret | -| tst.js:80:7:80:19 | Math.random() | -| tst.js:80:7:80:19 | Math.random() | -| tst.js:84:19:84:31 | Math.random() | -| tst.js:84:19:84:31 | Math.random() | -| tst.js:84:19:84:31 | Math.random() | -| tst.js:90:32:90:44 | Math.random() | -| tst.js:90:32:90:44 | Math.random() | -| tst.js:90:32:90:44 | Math.random() | -| tst.js:95:33:95:45 | Math.random() | -| tst.js:95:33:95:45 | Math.random() | -| tst.js:95:33:95:45 | Math.random() | -| tst.js:115:16:115:56 | Math.fl ... 00_000) | -| tst.js:115:16:115:56 | Math.fl ... 00_000) | -| tst.js:115:27:115:39 | Math.random() | -| tst.js:115:27:115:39 | Math.random() | -| tst.js:115:27:115:55 | Math.ra ... 000_000 | -| tst.js:116:22:116:62 | Math.fl ... 00_000) | -| tst.js:116:22:116:62 | Math.fl ... 00_000) | -| tst.js:116:33:116:45 | Math.random() | -| tst.js:116:33:116:45 | Math.random() | -| tst.js:116:33:116:61 | Math.ra ... 000_000 | -| tst.js:117:15:117:55 | Math.fl ... 00_000) | -| tst.js:117:15:117:55 | Math.fl ... 00_000) | -| tst.js:117:26:117:38 | Math.random() | -| tst.js:117:26:117:38 | Math.random() | -| tst.js:117:26:117:54 | Math.ra ... 000_000 | -| tst.js:118:23:118:63 | Math.fl ... 00_000) | -| tst.js:118:23:118:63 | Math.fl ... 00_000) | -| tst.js:118:34:118:46 | Math.random() | -| tst.js:118:34:118:46 | Math.random() | -| tst.js:118:34:118:62 | Math.ra ... 000_000 | -| tst.js:120:16:120:28 | Math.random() | -| tst.js:120:16:120:28 | Math.random() | -| tst.js:120:16:120:28 | Math.random() | -| tst.js:121:18:121:30 | Math.random() | -| tst.js:121:18:121:30 | Math.random() | -| tst.js:121:18:121:30 | Math.random() | -| tst.js:136:9:136:67 | password | -| tst.js:136:9:136:67 | password | -| tst.js:136:21:136:67 | chars[M ... ength)] | -| tst.js:136:27:136:66 | Math.fl ... length) | -| tst.js:136:38:136:50 | Math.random() | -| tst.js:136:38:136:50 | Math.random() | -| tst.js:136:38:136:65 | Math.ra ... .length | edges -| tst.js:2:20:2:32 | Math.random() | tst.js:2:20:2:32 | Math.random() | | tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | -| tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | -| tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | -| tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | -| tst.js:10:20:10:32 | Math.random() | tst.js:10:20:10:32 | Math.random() | | tst.js:19:9:19:36 | suffix | tst.js:20:31:20:36 | suffix | | tst.js:19:18:19:30 | Math.random() | tst.js:19:18:19:36 | Math.random() % 255 | -| tst.js:19:18:19:30 | Math.random() | tst.js:19:18:19:36 | Math.random() % 255 | | tst.js:19:18:19:36 | Math.random() % 255 | tst.js:19:9:19:36 | suffix | | tst.js:20:31:20:36 | suffix | tst.js:20:20:20:36 | "prefix" + suffix | -| tst.js:20:31:20:36 | suffix | tst.js:20:20:20:36 | "prefix" + suffix | -| tst.js:28:9:28:26 | pw | tst.js:29:20:29:21 | pw | | tst.js:28:9:28:26 | pw | tst.js:29:20:29:21 | pw | | tst.js:28:14:28:26 | Math.random() | tst.js:28:9:28:26 | pw | -| tst.js:28:14:28:26 | Math.random() | tst.js:28:9:28:26 | pw | | tst.js:41:21:41:33 | Math.random() | tst.js:41:20:41:33 | !Math.random() | -| tst.js:41:21:41:33 | Math.random() | tst.js:41:20:41:33 | !Math.random() | -| tst.js:41:21:41:33 | Math.random() | tst.js:41:20:41:33 | !Math.random() | -| tst.js:41:21:41:33 | Math.random() | tst.js:41:20:41:33 | !Math.random() | -| tst.js:45:18:45:30 | Math.random() | tst.js:45:18:45:30 | Math.random() | -| tst.js:50:16:50:28 | Math.random() | tst.js:50:16:50:28 | Math.random() | -| tst.js:55:17:55:29 | Math.random() | tst.js:55:17:55:29 | Math.random() | | tst.js:61:22:61:34 | Math.random() | tst.js:61:17:61:34 | '' + Math.random() | -| tst.js:61:22:61:34 | Math.random() | tst.js:61:17:61:34 | '' + Math.random() | -| tst.js:61:22:61:34 | Math.random() | tst.js:61:17:61:34 | '' + Math.random() | -| tst.js:61:22:61:34 | Math.random() | tst.js:61:17:61:34 | '' + Math.random() | -| tst.js:66:29:66:41 | Math.random() | tst.js:66:18:66:42 | Math.fl ... ndom()) | -| tst.js:66:29:66:41 | Math.random() | tst.js:66:18:66:42 | Math.fl ... ndom()) | -| tst.js:66:29:66:41 | Math.random() | tst.js:66:18:66:42 | Math.fl ... ndom()) | | tst.js:66:29:66:41 | Math.random() | tst.js:66:18:66:42 | Math.fl ... ndom()) | | tst.js:71:9:71:48 | rand | tst.js:72:34:72:37 | rand | | tst.js:71:16:71:48 | Math.fl ... 999999) | tst.js:71:9:71:48 | rand | | tst.js:71:27:71:39 | Math.random() | tst.js:71:27:71:47 | Math.ra ... 9999999 | -| tst.js:71:27:71:39 | Math.random() | tst.js:71:27:71:47 | Math.ra ... 9999999 | | tst.js:71:27:71:47 | Math.ra ... 9999999 | tst.js:71:16:71:48 | Math.fl ... 999999) | | tst.js:72:9:72:48 | concat | tst.js:73:23:73:28 | concat | -| tst.js:72:9:72:48 | concat | tst.js:73:23:73:28 | concat | | tst.js:72:18:72:48 | ts.toSt ... tring() | tst.js:72:9:72:48 | concat | | tst.js:72:34:72:37 | rand | tst.js:72:34:72:48 | rand.toString() | | tst.js:72:34:72:48 | rand.toString() | tst.js:72:18:72:48 | ts.toSt ... tring() | | tst.js:77:16:77:21 | secret | tst.js:77:16:77:21 | secret | | tst.js:80:7:80:19 | Math.random() | tst.js:77:16:77:21 | secret | -| tst.js:80:7:80:19 | Math.random() | tst.js:77:16:77:21 | secret | -| tst.js:84:19:84:31 | Math.random() | tst.js:84:19:84:31 | Math.random() | -| tst.js:90:32:90:44 | Math.random() | tst.js:90:32:90:44 | Math.random() | -| tst.js:95:33:95:45 | Math.random() | tst.js:95:33:95:45 | Math.random() | -| tst.js:115:27:115:39 | Math.random() | tst.js:115:27:115:55 | Math.ra ... 000_000 | | tst.js:115:27:115:39 | Math.random() | tst.js:115:27:115:55 | Math.ra ... 000_000 | | tst.js:115:27:115:55 | Math.ra ... 000_000 | tst.js:115:16:115:56 | Math.fl ... 00_000) | -| tst.js:115:27:115:55 | Math.ra ... 000_000 | tst.js:115:16:115:56 | Math.fl ... 00_000) | -| tst.js:116:33:116:45 | Math.random() | tst.js:116:33:116:61 | Math.ra ... 000_000 | | tst.js:116:33:116:45 | Math.random() | tst.js:116:33:116:61 | Math.ra ... 000_000 | | tst.js:116:33:116:61 | Math.ra ... 000_000 | tst.js:116:22:116:62 | Math.fl ... 00_000) | -| tst.js:116:33:116:61 | Math.ra ... 000_000 | tst.js:116:22:116:62 | Math.fl ... 00_000) | -| tst.js:117:26:117:38 | Math.random() | tst.js:117:26:117:54 | Math.ra ... 000_000 | | tst.js:117:26:117:38 | Math.random() | tst.js:117:26:117:54 | Math.ra ... 000_000 | | tst.js:117:26:117:54 | Math.ra ... 000_000 | tst.js:117:15:117:55 | Math.fl ... 00_000) | -| tst.js:117:26:117:54 | Math.ra ... 000_000 | tst.js:117:15:117:55 | Math.fl ... 00_000) | -| tst.js:118:34:118:46 | Math.random() | tst.js:118:34:118:62 | Math.ra ... 000_000 | | tst.js:118:34:118:46 | Math.random() | tst.js:118:34:118:62 | Math.ra ... 000_000 | | tst.js:118:34:118:62 | Math.ra ... 000_000 | tst.js:118:23:118:63 | Math.fl ... 00_000) | -| tst.js:118:34:118:62 | Math.ra ... 000_000 | tst.js:118:23:118:63 | Math.fl ... 00_000) | -| tst.js:120:16:120:28 | Math.random() | tst.js:120:16:120:28 | Math.random() | -| tst.js:121:18:121:30 | Math.random() | tst.js:121:18:121:30 | Math.random() | -| tst.js:136:21:136:67 | chars[M ... ength)] | tst.js:136:9:136:67 | password | | tst.js:136:21:136:67 | chars[M ... ength)] | tst.js:136:9:136:67 | password | | tst.js:136:27:136:66 | Math.fl ... length) | tst.js:136:21:136:67 | chars[M ... ength)] | | tst.js:136:38:136:50 | Math.random() | tst.js:136:38:136:65 | Math.ra ... .length | -| tst.js:136:38:136:50 | Math.random() | tst.js:136:38:136:65 | Math.ra ... .length | | tst.js:136:38:136:65 | Math.ra ... .length | tst.js:136:27:136:66 | Math.fl ... length) | +nodes +| tst.js:2:20:2:32 | Math.random() | semmle.label | Math.random() | +| tst.js:6:20:6:43 | "prefix ... andom() | semmle.label | "prefix ... andom() | +| tst.js:6:31:6:43 | Math.random() | semmle.label | Math.random() | +| tst.js:10:20:10:32 | Math.random() | semmle.label | Math.random() | +| tst.js:19:9:19:36 | suffix | semmle.label | suffix | +| tst.js:19:18:19:30 | Math.random() | semmle.label | Math.random() | +| tst.js:19:18:19:36 | Math.random() % 255 | semmle.label | Math.random() % 255 | +| tst.js:20:20:20:36 | "prefix" + suffix | semmle.label | "prefix" + suffix | +| tst.js:20:31:20:36 | suffix | semmle.label | suffix | +| tst.js:28:9:28:26 | pw | semmle.label | pw | +| tst.js:28:14:28:26 | Math.random() | semmle.label | Math.random() | +| tst.js:29:20:29:21 | pw | semmle.label | pw | +| tst.js:41:20:41:33 | !Math.random() | semmle.label | !Math.random() | +| tst.js:41:21:41:33 | Math.random() | semmle.label | Math.random() | +| tst.js:45:18:45:30 | Math.random() | semmle.label | Math.random() | +| tst.js:50:16:50:28 | Math.random() | semmle.label | Math.random() | +| tst.js:55:17:55:29 | Math.random() | semmle.label | Math.random() | +| tst.js:61:17:61:34 | '' + Math.random() | semmle.label | '' + Math.random() | +| tst.js:61:22:61:34 | Math.random() | semmle.label | Math.random() | +| tst.js:66:18:66:42 | Math.fl ... ndom()) | semmle.label | Math.fl ... ndom()) | +| tst.js:66:29:66:41 | Math.random() | semmle.label | Math.random() | +| tst.js:71:9:71:48 | rand | semmle.label | rand | +| tst.js:71:16:71:48 | Math.fl ... 999999) | semmle.label | Math.fl ... 999999) | +| tst.js:71:27:71:39 | Math.random() | semmle.label | Math.random() | +| tst.js:71:27:71:47 | Math.ra ... 9999999 | semmle.label | Math.ra ... 9999999 | +| tst.js:72:9:72:48 | concat | semmle.label | concat | +| tst.js:72:18:72:48 | ts.toSt ... tring() | semmle.label | ts.toSt ... tring() | +| tst.js:72:34:72:37 | rand | semmle.label | rand | +| tst.js:72:34:72:48 | rand.toString() | semmle.label | rand.toString() | +| tst.js:73:23:73:28 | concat | semmle.label | concat | +| tst.js:77:16:77:21 | secret | semmle.label | secret | +| tst.js:77:16:77:21 | secret | semmle.label | secret | +| tst.js:80:7:80:19 | Math.random() | semmle.label | Math.random() | +| tst.js:84:19:84:31 | Math.random() | semmle.label | Math.random() | +| tst.js:90:32:90:44 | Math.random() | semmle.label | Math.random() | +| tst.js:95:33:95:45 | Math.random() | semmle.label | Math.random() | +| tst.js:115:16:115:56 | Math.fl ... 00_000) | semmle.label | Math.fl ... 00_000) | +| tst.js:115:27:115:39 | Math.random() | semmle.label | Math.random() | +| tst.js:115:27:115:55 | Math.ra ... 000_000 | semmle.label | Math.ra ... 000_000 | +| tst.js:116:22:116:62 | Math.fl ... 00_000) | semmle.label | Math.fl ... 00_000) | +| tst.js:116:33:116:45 | Math.random() | semmle.label | Math.random() | +| tst.js:116:33:116:61 | Math.ra ... 000_000 | semmle.label | Math.ra ... 000_000 | +| tst.js:117:15:117:55 | Math.fl ... 00_000) | semmle.label | Math.fl ... 00_000) | +| tst.js:117:26:117:38 | Math.random() | semmle.label | Math.random() | +| tst.js:117:26:117:54 | Math.ra ... 000_000 | semmle.label | Math.ra ... 000_000 | +| tst.js:118:23:118:63 | Math.fl ... 00_000) | semmle.label | Math.fl ... 00_000) | +| tst.js:118:34:118:46 | Math.random() | semmle.label | Math.random() | +| tst.js:118:34:118:62 | Math.ra ... 000_000 | semmle.label | Math.ra ... 000_000 | +| tst.js:120:16:120:28 | Math.random() | semmle.label | Math.random() | +| tst.js:121:18:121:30 | Math.random() | semmle.label | Math.random() | +| tst.js:136:9:136:67 | password | semmle.label | password | +| tst.js:136:21:136:67 | chars[M ... ength)] | semmle.label | chars[M ... ength)] | +| tst.js:136:27:136:66 | Math.fl ... length) | semmle.label | Math.fl ... length) | +| tst.js:136:38:136:50 | Math.random() | semmle.label | Math.random() | +| tst.js:136:38:136:65 | Math.ra ... .length | semmle.label | Math.ra ... .length | +subpaths #select | tst.js:2:20:2:32 | Math.random() | tst.js:2:20:2:32 | Math.random() | tst.js:2:20:2:32 | Math.random() | This uses a cryptographically insecure random number generated at $@ in a security context. | tst.js:2:20:2:32 | Math.random() | Math.random() | | tst.js:6:20:6:43 | "prefix ... andom() | tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | This uses a cryptographically insecure random number generated at $@ in a security context. | tst.js:6:31:6:43 | Math.random() | Math.random() | From fd98b2546d37a90b39bc418f0e1417212f8d133f Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:21:12 +0200 Subject: [PATCH 083/514] JS: Port InsecureTemporaryFile --- .../dataflow/InsecureTemporaryFileQuery.qll | 18 ++++++- .../Security/CWE-377/InsecureTemporaryFile.ql | 6 +-- .../CWE-377/InsecureTemporaryFile.expected | 53 +++++++------------ 3 files changed, 38 insertions(+), 39 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureTemporaryFileQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureTemporaryFileQuery.qll index 56c22972c16..66e63b0a7a4 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureTemporaryFileQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureTemporaryFileQuery.qll @@ -13,7 +13,23 @@ import InsecureTemporaryFileCustomizations::InsecureTemporaryFile /** * A taint-tracking configuration for reasoning about insecure temporary file creation. */ -class Configuration extends TaintTracking::Configuration { +module InsecureTemporaryFileConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint-tracking for reasoning about insecure temporary file creation. + */ +module InsecureTemporaryFileFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `InsecureTemporaryFileFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "InsecureTemporaryFile" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-377/InsecureTemporaryFile.ql b/javascript/ql/src/Security/CWE-377/InsecureTemporaryFile.ql index 9e9a9f12659..9a13bfbe4a5 100644 --- a/javascript/ql/src/Security/CWE-377/InsecureTemporaryFile.ql +++ b/javascript/ql/src/Security/CWE-377/InsecureTemporaryFile.ql @@ -13,10 +13,10 @@ */ import javascript -import DataFlow::PathGraph import semmle.javascript.security.dataflow.InsecureTemporaryFileQuery +import InsecureTemporaryFileFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from InsecureTemporaryFileFlow::PathNode source, InsecureTemporaryFileFlow::PathNode sink +where InsecureTemporaryFileFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Insecure creation of file in $@.", source.getNode(), "the os temp dir" diff --git a/javascript/ql/test/query-tests/Security/CWE-377/InsecureTemporaryFile.expected b/javascript/ql/test/query-tests/Security/CWE-377/InsecureTemporaryFile.expected index 8952998dd9c..113ac3bd205 100644 --- a/javascript/ql/test/query-tests/Security/CWE-377/InsecureTemporaryFile.expected +++ b/javascript/ql/test/query-tests/Security/CWE-377/InsecureTemporaryFile.expected @@ -1,50 +1,33 @@ -nodes -| insecure-temporary-file.js:7:9:11:5 | tmpLocation | -| insecure-temporary-file.js:7:23:11:5 | path.jo ... )\\n ) | -| insecure-temporary-file.js:8:9:8:45 | os.tmpd ... mpDir() | -| insecure-temporary-file.js:8:21:8:31 | os.tmpdir() | -| insecure-temporary-file.js:8:21:8:31 | os.tmpdir() | -| insecure-temporary-file.js:13:22:13:32 | tmpLocation | -| insecure-temporary-file.js:13:22:13:32 | tmpLocation | -| insecure-temporary-file.js:15:9:15:34 | tmpPath | -| insecure-temporary-file.js:15:19:15:34 | "/tmp/something" | -| insecure-temporary-file.js:15:19:15:34 | "/tmp/something" | -| insecure-temporary-file.js:17:22:17:49 | path.jo ... /foo/") | -| insecure-temporary-file.js:17:22:17:49 | path.jo ... /foo/") | -| insecure-temporary-file.js:17:32:17:38 | tmpPath | -| insecure-temporary-file.js:23:22:23:49 | path.jo ... /foo/") | -| insecure-temporary-file.js:23:22:23:49 | path.jo ... /foo/") | -| insecure-temporary-file.js:23:32:23:38 | tmpPath | -| insecure-temporary-file.js:25:11:25:92 | tmpPath2 | -| insecure-temporary-file.js:25:22:25:92 | path.jo ... )}.md`) | -| insecure-temporary-file.js:25:32:25:42 | os.tmpdir() | -| insecure-temporary-file.js:25:32:25:42 | os.tmpdir() | -| insecure-temporary-file.js:26:22:26:29 | tmpPath2 | -| insecure-temporary-file.js:26:22:26:29 | tmpPath2 | -| insecure-temporary-file.js:28:17:28:24 | tmpPath2 | -| insecure-temporary-file.js:28:17:28:24 | tmpPath2 | edges | insecure-temporary-file.js:7:9:11:5 | tmpLocation | insecure-temporary-file.js:13:22:13:32 | tmpLocation | -| insecure-temporary-file.js:7:9:11:5 | tmpLocation | insecure-temporary-file.js:13:22:13:32 | tmpLocation | | insecure-temporary-file.js:7:23:11:5 | path.jo ... )\\n ) | insecure-temporary-file.js:7:9:11:5 | tmpLocation | -| insecure-temporary-file.js:8:9:8:45 | os.tmpd ... mpDir() | insecure-temporary-file.js:7:23:11:5 | path.jo ... )\\n ) | -| insecure-temporary-file.js:8:21:8:31 | os.tmpdir() | insecure-temporary-file.js:8:9:8:45 | os.tmpd ... mpDir() | -| insecure-temporary-file.js:8:21:8:31 | os.tmpdir() | insecure-temporary-file.js:8:9:8:45 | os.tmpd ... mpDir() | +| insecure-temporary-file.js:8:21:8:31 | os.tmpdir() | insecure-temporary-file.js:7:23:11:5 | path.jo ... )\\n ) | | insecure-temporary-file.js:15:9:15:34 | tmpPath | insecure-temporary-file.js:17:32:17:38 | tmpPath | | insecure-temporary-file.js:15:9:15:34 | tmpPath | insecure-temporary-file.js:23:32:23:38 | tmpPath | | insecure-temporary-file.js:15:19:15:34 | "/tmp/something" | insecure-temporary-file.js:15:9:15:34 | tmpPath | -| insecure-temporary-file.js:15:19:15:34 | "/tmp/something" | insecure-temporary-file.js:15:9:15:34 | tmpPath | -| insecure-temporary-file.js:17:32:17:38 | tmpPath | insecure-temporary-file.js:17:22:17:49 | path.jo ... /foo/") | | insecure-temporary-file.js:17:32:17:38 | tmpPath | insecure-temporary-file.js:17:22:17:49 | path.jo ... /foo/") | | insecure-temporary-file.js:23:32:23:38 | tmpPath | insecure-temporary-file.js:23:22:23:49 | path.jo ... /foo/") | -| insecure-temporary-file.js:23:32:23:38 | tmpPath | insecure-temporary-file.js:23:22:23:49 | path.jo ... /foo/") | | insecure-temporary-file.js:25:11:25:92 | tmpPath2 | insecure-temporary-file.js:26:22:26:29 | tmpPath2 | -| insecure-temporary-file.js:25:11:25:92 | tmpPath2 | insecure-temporary-file.js:26:22:26:29 | tmpPath2 | -| insecure-temporary-file.js:25:11:25:92 | tmpPath2 | insecure-temporary-file.js:28:17:28:24 | tmpPath2 | | insecure-temporary-file.js:25:11:25:92 | tmpPath2 | insecure-temporary-file.js:28:17:28:24 | tmpPath2 | | insecure-temporary-file.js:25:22:25:92 | path.jo ... )}.md`) | insecure-temporary-file.js:25:11:25:92 | tmpPath2 | | insecure-temporary-file.js:25:32:25:42 | os.tmpdir() | insecure-temporary-file.js:25:22:25:92 | path.jo ... )}.md`) | -| insecure-temporary-file.js:25:32:25:42 | os.tmpdir() | insecure-temporary-file.js:25:22:25:92 | path.jo ... )}.md`) | +nodes +| insecure-temporary-file.js:7:9:11:5 | tmpLocation | semmle.label | tmpLocation | +| insecure-temporary-file.js:7:23:11:5 | path.jo ... )\\n ) | semmle.label | path.jo ... )\\n ) | +| insecure-temporary-file.js:8:21:8:31 | os.tmpdir() | semmle.label | os.tmpdir() | +| insecure-temporary-file.js:13:22:13:32 | tmpLocation | semmle.label | tmpLocation | +| insecure-temporary-file.js:15:9:15:34 | tmpPath | semmle.label | tmpPath | +| insecure-temporary-file.js:15:19:15:34 | "/tmp/something" | semmle.label | "/tmp/something" | +| insecure-temporary-file.js:17:22:17:49 | path.jo ... /foo/") | semmle.label | path.jo ... /foo/") | +| insecure-temporary-file.js:17:32:17:38 | tmpPath | semmle.label | tmpPath | +| insecure-temporary-file.js:23:22:23:49 | path.jo ... /foo/") | semmle.label | path.jo ... /foo/") | +| insecure-temporary-file.js:23:32:23:38 | tmpPath | semmle.label | tmpPath | +| insecure-temporary-file.js:25:11:25:92 | tmpPath2 | semmle.label | tmpPath2 | +| insecure-temporary-file.js:25:22:25:92 | path.jo ... )}.md`) | semmle.label | path.jo ... )}.md`) | +| insecure-temporary-file.js:25:32:25:42 | os.tmpdir() | semmle.label | os.tmpdir() | +| insecure-temporary-file.js:26:22:26:29 | tmpPath2 | semmle.label | tmpPath2 | +| insecure-temporary-file.js:28:17:28:24 | tmpPath2 | semmle.label | tmpPath2 | +subpaths #select | insecure-temporary-file.js:13:22:13:32 | tmpLocation | insecure-temporary-file.js:8:21:8:31 | os.tmpdir() | insecure-temporary-file.js:13:22:13:32 | tmpLocation | Insecure creation of file in $@. | insecure-temporary-file.js:8:21:8:31 | os.tmpdir() | the os temp dir | | insecure-temporary-file.js:17:22:17:49 | path.jo ... /foo/") | insecure-temporary-file.js:15:19:15:34 | "/tmp/something" | insecure-temporary-file.js:17:22:17:49 | path.jo ... /foo/") | Insecure creation of file in $@. | insecure-temporary-file.js:15:19:15:34 | "/tmp/something" | the os temp dir | From e1fae3d16d72254f2ab9603614f0ddd551c71d83 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:21:25 +0200 Subject: [PATCH 084/514] JS: Port InsufficientPasswordHash --- .../dataflow/InsufficientPasswordHashQuery.qll | 18 +++++++++++++++++- .../CWE-916/InsufficientPasswordHash.ql | 6 +++--- .../CWE-916/InsufficientPasswordHash.expected | 18 +++++------------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/InsufficientPasswordHashQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/InsufficientPasswordHashQuery.qll index 40bfcc1072b..d01e46360fd 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/InsufficientPasswordHashQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/InsufficientPasswordHashQuery.qll @@ -19,7 +19,23 @@ import InsufficientPasswordHashCustomizations::InsufficientPasswordHash * added either by extending the relevant class, or by subclassing this configuration itself, * and amending the sources and sinks. */ -class Configuration extends TaintTracking::Configuration { +module InsufficientPasswordHashConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint tracking for password hashing with insufficient computational effort. + */ +module InsufficientPasswordHashFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `InsufficientPasswordHashFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "InsufficientPasswordHash" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.ql b/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.ql index a40689f41df..1cfc3111ad9 100644 --- a/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.ql +++ b/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.ql @@ -12,9 +12,9 @@ import javascript import semmle.javascript.security.dataflow.InsufficientPasswordHashQuery -import DataFlow::PathGraph +import InsufficientPasswordHashFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from InsufficientPasswordHashFlow::PathNode source, InsufficientPasswordHashFlow::PathNode sink +where InsufficientPasswordHashFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Password from $@ is hashed insecurely.", source.getNode(), source.getNode().(Source).describe() diff --git a/javascript/ql/test/query-tests/Security/CWE-916/InsufficientPasswordHash.expected b/javascript/ql/test/query-tests/Security/CWE-916/InsufficientPasswordHash.expected index 40cd78138e4..231a4025138 100644 --- a/javascript/ql/test/query-tests/Security/CWE-916/InsufficientPasswordHash.expected +++ b/javascript/ql/test/query-tests/Security/CWE-916/InsufficientPasswordHash.expected @@ -1,17 +1,9 @@ -nodes -| tst.js:5:48:5:55 | password | -| tst.js:5:48:5:55 | password | -| tst.js:5:48:5:55 | password | -| tst.js:7:46:7:53 | password | -| tst.js:7:46:7:53 | password | -| tst.js:7:46:7:53 | password | -| tst.js:9:43:9:50 | password | -| tst.js:9:43:9:50 | password | -| tst.js:9:43:9:50 | password | edges -| tst.js:5:48:5:55 | password | tst.js:5:48:5:55 | password | -| tst.js:7:46:7:53 | password | tst.js:7:46:7:53 | password | -| tst.js:9:43:9:50 | password | tst.js:9:43:9:50 | password | +nodes +| tst.js:5:48:5:55 | password | semmle.label | password | +| tst.js:7:46:7:53 | password | semmle.label | password | +| tst.js:9:43:9:50 | password | semmle.label | password | +subpaths #select | tst.js:5:48:5:55 | password | tst.js:5:48:5:55 | password | tst.js:5:48:5:55 | password | Password from $@ is hashed insecurely. | tst.js:5:48:5:55 | password | an access to password | | tst.js:7:46:7:53 | password | tst.js:7:46:7:53 | password | tst.js:7:46:7:53 | password | Password from $@ is hashed insecurely. | tst.js:7:46:7:53 | password | an access to password | From 2400af4bc3ed11586a0a50460a59e4da6640aade Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:21:37 +0200 Subject: [PATCH 085/514] JS: Port PostMessageStar --- .../dataflow/PostMessageStarQuery.qll | 24 +++++++++- .../src/Security/CWE-201/PostMessageStar.ql | 6 +-- .../Security/CWE-201/PostMessageStar.expected | 48 +++++++------------ 3 files changed, 43 insertions(+), 35 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/PostMessageStarQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/PostMessageStarQuery.qll index ae7366146da..c267c9df8e0 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/PostMessageStarQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/PostMessageStarQuery.qll @@ -11,7 +11,7 @@ import javascript import PostMessageStarCustomizations::PostMessageStar // Materialize flow labels -private class ConcretePartiallyTaintedObject extends PartiallyTaintedObject { +deprecated private class ConcretePartiallyTaintedObject extends PartiallyTaintedObject { ConcretePartiallyTaintedObject() { this = this } } @@ -26,7 +26,27 @@ private class ConcretePartiallyTaintedObject extends PartiallyTaintedObject { * Additional sources or sinks can be added either by extending the relevant class, or by subclassing * this configuration itself, and amending the sources and sinks. */ -class Configuration extends TaintTracking::Configuration { +module PostMessageStarConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet contents) { + isSink(node) and contents = DataFlow::ContentSet::anyProperty() + } +} + +/** + * A taint tracking configuration for cross-window communication with unrestricted origin. + */ +module PostMessageStarFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `PostMessageStarFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "PostMessageStar" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-201/PostMessageStar.ql b/javascript/ql/src/Security/CWE-201/PostMessageStar.ql index 90a3d526db5..71da63e3f50 100644 --- a/javascript/ql/src/Security/CWE-201/PostMessageStar.ql +++ b/javascript/ql/src/Security/CWE-201/PostMessageStar.ql @@ -15,9 +15,9 @@ import javascript import semmle.javascript.security.dataflow.PostMessageStarQuery -import DataFlow::PathGraph +import PostMessageStarFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from PostMessageStarFlow::PathNode source, PostMessageStarFlow::PathNode sink +where PostMessageStarFlow::flowPath(source, sink) select sink.getNode(), source, sink, "$@ is sent to another window without origin restriction.", source.getNode(), "Sensitive data" diff --git a/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected b/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected index e4c14a2060c..c5a5a9ac206 100644 --- a/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected +++ b/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected @@ -1,34 +1,22 @@ -nodes -| PostMessageStar2.js:1:27:1:34 | password | -| PostMessageStar2.js:1:27:1:34 | password | -| PostMessageStar2.js:1:27:1:34 | password | -| PostMessageStar2.js:4:7:4:15 | data | -| PostMessageStar2.js:4:14:4:15 | {} | -| PostMessageStar2.js:5:14:5:21 | password | -| PostMessageStar2.js:5:14:5:21 | password | -| PostMessageStar2.js:8:29:8:32 | data | -| PostMessageStar2.js:8:29:8:32 | data | -| PostMessageStar2.js:9:29:9:36 | data.foo | -| PostMessageStar2.js:9:29:9:36 | data.foo | -| PostMessageStar2.js:13:27:13:33 | authKey | -| PostMessageStar2.js:13:27:13:33 | authKey | -| PostMessageStar2.js:13:27:13:33 | authKey | -| PostMessageStar.js:1:27:1:34 | userName | -| PostMessageStar.js:1:27:1:34 | userName | -| PostMessageStar.js:1:27:1:34 | userName | edges -| PostMessageStar2.js:1:27:1:34 | password | PostMessageStar2.js:1:27:1:34 | password | -| PostMessageStar2.js:4:7:4:15 | data | PostMessageStar2.js:8:29:8:32 | data | -| PostMessageStar2.js:4:7:4:15 | data | PostMessageStar2.js:8:29:8:32 | data | -| PostMessageStar2.js:4:14:4:15 | {} | PostMessageStar2.js:4:7:4:15 | data | -| PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:4:14:4:15 | {} | -| PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:4:14:4:15 | {} | -| PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:9:29:9:36 | data.foo | -| PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:9:29:9:36 | data.foo | -| PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:9:29:9:36 | data.foo | -| PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:9:29:9:36 | data.foo | -| PostMessageStar2.js:13:27:13:33 | authKey | PostMessageStar2.js:13:27:13:33 | authKey | -| PostMessageStar.js:1:27:1:34 | userName | PostMessageStar.js:1:27:1:34 | userName | +| PostMessageStar2.js:4:7:4:15 | data [foo] | PostMessageStar2.js:8:29:8:32 | data [foo] | +| PostMessageStar2.js:4:7:4:15 | data [foo] | PostMessageStar2.js:9:29:9:32 | data [foo] | +| PostMessageStar2.js:5:3:5:6 | [post update] data [foo] | PostMessageStar2.js:4:7:4:15 | data [foo] | +| PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:5:3:5:6 | [post update] data [foo] | +| PostMessageStar2.js:8:29:8:32 | data [foo] | PostMessageStar2.js:8:29:8:32 | data | +| PostMessageStar2.js:9:29:9:32 | data [foo] | PostMessageStar2.js:9:29:9:36 | data.foo | +nodes +| PostMessageStar2.js:1:27:1:34 | password | semmle.label | password | +| PostMessageStar2.js:4:7:4:15 | data [foo] | semmle.label | data [foo] | +| PostMessageStar2.js:5:3:5:6 | [post update] data [foo] | semmle.label | [post update] data [foo] | +| PostMessageStar2.js:5:14:5:21 | password | semmle.label | password | +| PostMessageStar2.js:8:29:8:32 | data | semmle.label | data | +| PostMessageStar2.js:8:29:8:32 | data [foo] | semmle.label | data [foo] | +| PostMessageStar2.js:9:29:9:32 | data [foo] | semmle.label | data [foo] | +| PostMessageStar2.js:9:29:9:36 | data.foo | semmle.label | data.foo | +| PostMessageStar2.js:13:27:13:33 | authKey | semmle.label | authKey | +| PostMessageStar.js:1:27:1:34 | userName | semmle.label | userName | +subpaths #select | PostMessageStar2.js:1:27:1:34 | password | PostMessageStar2.js:1:27:1:34 | password | PostMessageStar2.js:1:27:1:34 | password | $@ is sent to another window without origin restriction. | PostMessageStar2.js:1:27:1:34 | password | Sensitive data | | PostMessageStar2.js:8:29:8:32 | data | PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:8:29:8:32 | data | $@ is sent to another window without origin restriction. | PostMessageStar2.js:5:14:5:21 | password | Sensitive data | From dcc73a7f90c7b7b4c22a36807cac820cebc08aa4 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:21:46 +0200 Subject: [PATCH 086/514] JS: Port RegExpInjection --- .../dataflow/RegExpInjectionQuery.qll | 18 +- .../src/Security/CWE-730/RegExpInjection.ql | 6 +- .../Security/CWE-730/RegExpInjection.expected | 179 +++++++----------- 3 files changed, 87 insertions(+), 116 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/RegExpInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/RegExpInjectionQuery.qll index 00fe3779e12..476fd9ccd85 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/RegExpInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/RegExpInjectionQuery.qll @@ -13,7 +13,23 @@ import RegExpInjectionCustomizations::RegExpInjection /** * A taint-tracking configuration for untrusted user input used to construct regular expressions. */ -class Configuration extends TaintTracking::Configuration { +module RegExpInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint-tracking for untrusted user input used to construct regular expressions. + */ +module RegExpInjectionFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `RegExpInjectionFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "RegExpInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-730/RegExpInjection.ql b/javascript/ql/src/Security/CWE-730/RegExpInjection.ql index 5b679cf1dcf..4260c5e23ee 100644 --- a/javascript/ql/src/Security/CWE-730/RegExpInjection.ql +++ b/javascript/ql/src/Security/CWE-730/RegExpInjection.ql @@ -15,9 +15,9 @@ import javascript import semmle.javascript.security.dataflow.RegExpInjectionQuery -import DataFlow::PathGraph +import RegExpInjectionFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from RegExpInjectionFlow::PathNode source, RegExpInjectionFlow::PathNode sink +where RegExpInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This regular expression is constructed from a $@.", source.getNode(), source.getNode().(Source).describe() diff --git a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected index 391be36fbb9..936d17028e3 100644 --- a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected @@ -1,78 +1,3 @@ -nodes -| RegExpInjection.js:5:7:5:28 | key | -| RegExpInjection.js:5:13:5:28 | req.param("key") | -| RegExpInjection.js:5:13:5:28 | req.param("key") | -| RegExpInjection.js:5:31:5:56 | input | -| RegExpInjection.js:5:39:5:56 | req.param("input") | -| RegExpInjection.js:5:39:5:56 | req.param("input") | -| RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | -| RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | -| RegExpInjection.js:8:31:8:33 | key | -| RegExpInjection.js:19:14:19:22 | wrap(key) | -| RegExpInjection.js:19:14:19:22 | wrap(key) | -| RegExpInjection.js:19:19:19:21 | key | -| RegExpInjection.js:21:14:21:22 | wrap(key) | -| RegExpInjection.js:21:14:21:22 | wrap(key) | -| RegExpInjection.js:21:19:21:21 | key | -| RegExpInjection.js:24:12:24:27 | req.param("key") | -| RegExpInjection.js:24:12:24:27 | req.param("key") | -| RegExpInjection.js:27:14:27:21 | getKey() | -| RegExpInjection.js:27:14:27:21 | getKey() | -| RegExpInjection.js:29:21:29:21 | s | -| RegExpInjection.js:29:21:29:21 | s | -| RegExpInjection.js:31:23:31:23 | s | -| RegExpInjection.js:31:23:31:23 | s | -| RegExpInjection.js:31:23:31:23 | s | -| RegExpInjection.js:33:12:33:14 | key | -| RegExpInjection.js:34:12:34:19 | getKey() | -| RegExpInjection.js:40:23:40:27 | input | -| RegExpInjection.js:40:23:40:27 | input | -| RegExpInjection.js:41:26:41:30 | input | -| RegExpInjection.js:41:26:41:30 | input | -| RegExpInjection.js:42:25:42:29 | input | -| RegExpInjection.js:42:25:42:29 | input | -| RegExpInjection.js:45:24:45:28 | input | -| RegExpInjection.js:45:24:45:28 | input | -| RegExpInjection.js:46:27:46:31 | input | -| RegExpInjection.js:46:27:46:31 | input | -| RegExpInjection.js:47:26:47:30 | input | -| RegExpInjection.js:47:26:47:30 | input | -| RegExpInjection.js:54:14:54:16 | key | -| RegExpInjection.js:54:14:54:27 | key.split(".") | -| RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | -| RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | -| RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | -| RegExpInjection.js:60:31:60:56 | input | -| RegExpInjection.js:60:39:60:56 | req.param("input") | -| RegExpInjection.js:60:39:60:56 | req.param("input") | -| RegExpInjection.js:64:14:64:18 | input | -| RegExpInjection.js:64:14:64:18 | input | -| RegExpInjection.js:82:7:82:32 | input | -| RegExpInjection.js:82:15:82:32 | req.param("input") | -| RegExpInjection.js:82:15:82:32 | req.param("input") | -| RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | -| RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | -| RegExpInjection.js:87:25:87:29 | input | -| RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") | -| RegExpInjection.js:91:16:91:50 | `^${pro ... r.app$` | -| RegExpInjection.js:91:16:91:50 | `^${pro ... r.app$` | -| RegExpInjection.js:91:20:91:30 | process.env | -| RegExpInjection.js:91:20:91:30 | process.env | -| RegExpInjection.js:91:20:91:35 | process.env.HOME | -| RegExpInjection.js:93:16:93:49 | `^${pro ... r.app$` | -| RegExpInjection.js:93:16:93:49 | `^${pro ... r.app$` | -| RegExpInjection.js:93:20:93:31 | process.argv | -| RegExpInjection.js:93:20:93:31 | process.argv | -| RegExpInjection.js:93:20:93:34 | process.argv[1] | -| tst.js:1:46:1:46 | e | -| tst.js:1:46:1:46 | e | -| tst.js:2:9:2:21 | data | -| tst.js:2:16:2:16 | e | -| tst.js:2:16:2:21 | e.data | -| tst.js:3:16:3:35 | "^"+ data.name + "$" | -| tst.js:3:16:3:35 | "^"+ data.name + "$" | -| tst.js:3:21:3:24 | data | -| tst.js:3:21:3:29 | data.name | edges | RegExpInjection.js:5:7:5:28 | key | RegExpInjection.js:8:31:8:33 | key | | RegExpInjection.js:5:7:5:28 | key | RegExpInjection.js:19:19:19:21 | key | @@ -80,69 +5,99 @@ edges | RegExpInjection.js:5:7:5:28 | key | RegExpInjection.js:33:12:33:14 | key | | RegExpInjection.js:5:7:5:28 | key | RegExpInjection.js:54:14:54:16 | key | | RegExpInjection.js:5:13:5:28 | req.param("key") | RegExpInjection.js:5:7:5:28 | key | -| RegExpInjection.js:5:13:5:28 | req.param("key") | RegExpInjection.js:5:7:5:28 | key | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:40:23:40:27 | input | | RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:40:23:40:27 | input | | RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:41:26:41:30 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:41:26:41:30 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:42:25:42:29 | input | | RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:42:25:42:29 | input | | RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:45:24:45:28 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:45:24:45:28 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:46:27:46:31 | input | | RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:46:27:46:31 | input | | RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:47:26:47:30 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:47:26:47:30 | input | -| RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:5:31:5:56 | input | | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:5:31:5:56 | input | | RegExpInjection.js:8:31:8:33 | key | RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | -| RegExpInjection.js:8:31:8:33 | key | RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | +| RegExpInjection.js:10:17:10:17 | s | RegExpInjection.js:11:26:11:26 | s | +| RegExpInjection.js:11:20:11:27 | wrap2(s) | RegExpInjection.js:11:12:11:27 | "\\\\b" + wrap2(s) | +| RegExpInjection.js:11:26:11:26 | s | RegExpInjection.js:11:20:11:27 | wrap2(s) | +| RegExpInjection.js:11:26:11:26 | s | RegExpInjection.js:14:18:14:18 | s | +| RegExpInjection.js:14:18:14:18 | s | RegExpInjection.js:15:12:15:12 | s | +| RegExpInjection.js:15:12:15:12 | s | RegExpInjection.js:15:12:15:24 | s + "=(.*)\\n" | +| RegExpInjection.js:19:19:19:21 | key | RegExpInjection.js:10:17:10:17 | s | | RegExpInjection.js:19:19:19:21 | key | RegExpInjection.js:19:14:19:22 | wrap(key) | -| RegExpInjection.js:19:19:19:21 | key | RegExpInjection.js:19:14:19:22 | wrap(key) | -| RegExpInjection.js:21:19:21:21 | key | RegExpInjection.js:21:14:21:22 | wrap(key) | +| RegExpInjection.js:21:19:21:21 | key | RegExpInjection.js:10:17:10:17 | s | | RegExpInjection.js:21:19:21:21 | key | RegExpInjection.js:21:14:21:22 | wrap(key) | | RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:27:14:27:21 | getKey() | -| RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:27:14:27:21 | getKey() | -| RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:27:14:27:21 | getKey() | -| RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:27:14:27:21 | getKey() | | RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:34:12:34:19 | getKey() | -| RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:34:12:34:19 | getKey() | -| RegExpInjection.js:29:21:29:21 | s | RegExpInjection.js:31:23:31:23 | s | -| RegExpInjection.js:29:21:29:21 | s | RegExpInjection.js:31:23:31:23 | s | -| RegExpInjection.js:29:21:29:21 | s | RegExpInjection.js:31:23:31:23 | s | | RegExpInjection.js:29:21:29:21 | s | RegExpInjection.js:31:23:31:23 | s | | RegExpInjection.js:33:12:33:14 | key | RegExpInjection.js:29:21:29:21 | s | | RegExpInjection.js:34:12:34:19 | getKey() | RegExpInjection.js:29:21:29:21 | s | | RegExpInjection.js:54:14:54:16 | key | RegExpInjection.js:54:14:54:27 | key.split(".") | | RegExpInjection.js:54:14:54:27 | key.split(".") | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | -| RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | | RegExpInjection.js:60:31:60:56 | input | RegExpInjection.js:64:14:64:18 | input | -| RegExpInjection.js:60:31:60:56 | input | RegExpInjection.js:64:14:64:18 | input | -| RegExpInjection.js:60:39:60:56 | req.param("input") | RegExpInjection.js:60:31:60:56 | input | | RegExpInjection.js:60:39:60:56 | req.param("input") | RegExpInjection.js:60:31:60:56 | input | | RegExpInjection.js:82:7:82:32 | input | RegExpInjection.js:87:25:87:29 | input | | RegExpInjection.js:82:15:82:32 | req.param("input") | RegExpInjection.js:82:7:82:32 | input | -| RegExpInjection.js:82:15:82:32 | req.param("input") | RegExpInjection.js:82:7:82:32 | input | | RegExpInjection.js:87:25:87:29 | input | RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") | | RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") | RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | -| RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") | RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | -| RegExpInjection.js:91:20:91:30 | process.env | RegExpInjection.js:91:20:91:35 | process.env.HOME | -| RegExpInjection.js:91:20:91:30 | process.env | RegExpInjection.js:91:20:91:35 | process.env.HOME | -| RegExpInjection.js:91:20:91:35 | process.env.HOME | RegExpInjection.js:91:16:91:50 | `^${pro ... r.app$` | -| RegExpInjection.js:91:20:91:35 | process.env.HOME | RegExpInjection.js:91:16:91:50 | `^${pro ... r.app$` | -| RegExpInjection.js:93:20:93:31 | process.argv | RegExpInjection.js:93:20:93:34 | process.argv[1] | -| RegExpInjection.js:93:20:93:31 | process.argv | RegExpInjection.js:93:20:93:34 | process.argv[1] | -| RegExpInjection.js:93:20:93:34 | process.argv[1] | RegExpInjection.js:93:16:93:49 | `^${pro ... r.app$` | -| RegExpInjection.js:93:20:93:34 | process.argv[1] | RegExpInjection.js:93:16:93:49 | `^${pro ... r.app$` | -| tst.js:1:46:1:46 | e | tst.js:2:16:2:16 | e | +| RegExpInjection.js:91:20:91:30 | process.env | RegExpInjection.js:91:16:91:50 | `^${pro ... r.app$` | +| RegExpInjection.js:93:20:93:31 | process.argv | RegExpInjection.js:93:16:93:49 | `^${pro ... r.app$` | | tst.js:1:46:1:46 | e | tst.js:2:16:2:16 | e | | tst.js:2:9:2:21 | data | tst.js:3:21:3:24 | data | -| tst.js:2:16:2:16 | e | tst.js:2:16:2:21 | e.data | -| tst.js:2:16:2:21 | e.data | tst.js:2:9:2:21 | data | -| tst.js:3:21:3:24 | data | tst.js:3:21:3:29 | data.name | -| tst.js:3:21:3:29 | data.name | tst.js:3:16:3:35 | "^"+ data.name + "$" | -| tst.js:3:21:3:29 | data.name | tst.js:3:16:3:35 | "^"+ data.name + "$" | +| tst.js:2:16:2:16 | e | tst.js:2:9:2:21 | data | +| tst.js:3:21:3:24 | data | tst.js:3:16:3:35 | "^"+ data.name + "$" | +nodes +| RegExpInjection.js:5:7:5:28 | key | semmle.label | key | +| RegExpInjection.js:5:13:5:28 | req.param("key") | semmle.label | req.param("key") | +| RegExpInjection.js:5:31:5:56 | input | semmle.label | input | +| RegExpInjection.js:5:39:5:56 | req.param("input") | semmle.label | req.param("input") | +| RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | semmle.label | "\\\\b" + ... (.*)\\n" | +| RegExpInjection.js:8:31:8:33 | key | semmle.label | key | +| RegExpInjection.js:10:17:10:17 | s | semmle.label | s | +| RegExpInjection.js:11:12:11:27 | "\\\\b" + wrap2(s) | semmle.label | "\\\\b" + wrap2(s) | +| RegExpInjection.js:11:20:11:27 | wrap2(s) | semmle.label | wrap2(s) | +| RegExpInjection.js:11:26:11:26 | s | semmle.label | s | +| RegExpInjection.js:14:18:14:18 | s | semmle.label | s | +| RegExpInjection.js:15:12:15:12 | s | semmle.label | s | +| RegExpInjection.js:15:12:15:24 | s + "=(.*)\\n" | semmle.label | s + "=(.*)\\n" | +| RegExpInjection.js:19:14:19:22 | wrap(key) | semmle.label | wrap(key) | +| RegExpInjection.js:19:19:19:21 | key | semmle.label | key | +| RegExpInjection.js:21:14:21:22 | wrap(key) | semmle.label | wrap(key) | +| RegExpInjection.js:21:19:21:21 | key | semmle.label | key | +| RegExpInjection.js:24:12:24:27 | req.param("key") | semmle.label | req.param("key") | +| RegExpInjection.js:27:14:27:21 | getKey() | semmle.label | getKey() | +| RegExpInjection.js:29:21:29:21 | s | semmle.label | s | +| RegExpInjection.js:31:23:31:23 | s | semmle.label | s | +| RegExpInjection.js:33:12:33:14 | key | semmle.label | key | +| RegExpInjection.js:34:12:34:19 | getKey() | semmle.label | getKey() | +| RegExpInjection.js:40:23:40:27 | input | semmle.label | input | +| RegExpInjection.js:41:26:41:30 | input | semmle.label | input | +| RegExpInjection.js:42:25:42:29 | input | semmle.label | input | +| RegExpInjection.js:45:24:45:28 | input | semmle.label | input | +| RegExpInjection.js:46:27:46:31 | input | semmle.label | input | +| RegExpInjection.js:47:26:47:30 | input | semmle.label | input | +| RegExpInjection.js:54:14:54:16 | key | semmle.label | key | +| RegExpInjection.js:54:14:54:27 | key.split(".") | semmle.label | key.split(".") | +| RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | semmle.label | key.spl ... x => x) | +| RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | semmle.label | key.spl ... in("-") | +| RegExpInjection.js:60:31:60:56 | input | semmle.label | input | +| RegExpInjection.js:60:39:60:56 | req.param("input") | semmle.label | req.param("input") | +| RegExpInjection.js:64:14:64:18 | input | semmle.label | input | +| RegExpInjection.js:82:7:82:32 | input | semmle.label | input | +| RegExpInjection.js:82:15:82:32 | req.param("input") | semmle.label | req.param("input") | +| RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | semmle.label | "^.*\\.( ... + ")$" | +| RegExpInjection.js:87:25:87:29 | input | semmle.label | input | +| RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") | semmle.label | input.r ... g, "\|") | +| RegExpInjection.js:91:16:91:50 | `^${pro ... r.app$` | semmle.label | `^${pro ... r.app$` | +| RegExpInjection.js:91:20:91:30 | process.env | semmle.label | process.env | +| RegExpInjection.js:93:16:93:49 | `^${pro ... r.app$` | semmle.label | `^${pro ... r.app$` | +| RegExpInjection.js:93:20:93:31 | process.argv | semmle.label | process.argv | +| tst.js:1:46:1:46 | e | semmle.label | e | +| tst.js:2:9:2:21 | data | semmle.label | data | +| tst.js:2:16:2:16 | e | semmle.label | e | +| tst.js:3:16:3:35 | "^"+ data.name + "$" | semmle.label | "^"+ data.name + "$" | +| tst.js:3:21:3:24 | data | semmle.label | data | +subpaths +| RegExpInjection.js:11:26:11:26 | s | RegExpInjection.js:14:18:14:18 | s | RegExpInjection.js:15:12:15:24 | s + "=(.*)\\n" | RegExpInjection.js:11:20:11:27 | wrap2(s) | +| RegExpInjection.js:19:19:19:21 | key | RegExpInjection.js:10:17:10:17 | s | RegExpInjection.js:11:12:11:27 | "\\\\b" + wrap2(s) | RegExpInjection.js:19:14:19:22 | wrap(key) | +| RegExpInjection.js:21:19:21:21 | key | RegExpInjection.js:10:17:10:17 | s | RegExpInjection.js:11:12:11:27 | "\\\\b" + wrap2(s) | RegExpInjection.js:21:14:21:22 | wrap(key) | #select | RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | RegExpInjection.js:5:13:5:28 | req.param("key") | RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | This regular expression is constructed from a $@. | RegExpInjection.js:5:13:5:28 | req.param("key") | user-provided value | | RegExpInjection.js:19:14:19:22 | wrap(key) | RegExpInjection.js:5:13:5:28 | req.param("key") | RegExpInjection.js:19:14:19:22 | wrap(key) | This regular expression is constructed from a $@. | RegExpInjection.js:5:13:5:28 | req.param("key") | user-provided value | From b9bd0520e27799810cf7fff8ad3cea232f5d2784 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:21:55 +0200 Subject: [PATCH 087/514] JS: Port RemotePropertyInjection --- .../dataflow/RemotePropertyInjectionQuery.qll | 21 +++++++- .../CWE-400/RemotePropertyInjection.ql | 6 +-- .../RemotePropertyInjection.expected | 48 +++++++++---------- 3 files changed, 46 insertions(+), 29 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/RemotePropertyInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/RemotePropertyInjectionQuery.qll index 83422e8f0de..d3cbfeb8268 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/RemotePropertyInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/RemotePropertyInjectionQuery.qll @@ -14,7 +14,26 @@ import RemotePropertyInjectionCustomizations::RemotePropertyInjection /** * A taint-tracking configuration for reasoning about remote property injection. */ -class Configuration extends TaintTracking::Configuration { +module RemotePropertyInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { + node instanceof Sanitizer or + node = StringConcatenation::getRoot(any(ConstantString str).flow()) + } +} + +/** + * Taint-tracking for reasoning about remote property injection. + */ +module RemotePropertyInjectionFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `RemotePropertyInjectionFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "RemotePropertyInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-400/RemotePropertyInjection.ql b/javascript/ql/src/Security/CWE-400/RemotePropertyInjection.ql index 287b196feff..92d18b3f1a2 100644 --- a/javascript/ql/src/Security/CWE-400/RemotePropertyInjection.ql +++ b/javascript/ql/src/Security/CWE-400/RemotePropertyInjection.ql @@ -14,9 +14,9 @@ import javascript import semmle.javascript.security.dataflow.RemotePropertyInjectionQuery -import DataFlow::PathGraph +import RemotePropertyInjectionFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from RemotePropertyInjectionFlow::PathNode source, RemotePropertyInjectionFlow::PathNode sink +where RemotePropertyInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, sink.getNode().(Sink).getMessage() + " depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-400/RemovePropertyInjection/RemotePropertyInjection.expected b/javascript/ql/test/query-tests/Security/CWE-400/RemovePropertyInjection/RemotePropertyInjection.expected index 7907cc41726..d6d347c996d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/RemovePropertyInjection/RemotePropertyInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/RemovePropertyInjection/RemotePropertyInjection.expected @@ -1,37 +1,35 @@ -nodes -| tst.js:8:6:8:52 | prop | -| tst.js:8:13:8:52 | myCoolL ... rolled) | -| tst.js:8:28:8:51 | req.que ... trolled | -| tst.js:8:28:8:51 | req.que ... trolled | -| tst.js:9:8:9:11 | prop | -| tst.js:9:8:9:11 | prop | -| tst.js:13:15:13:18 | prop | -| tst.js:13:15:13:18 | prop | -| tst.js:14:31:14:34 | prop | -| tst.js:14:31:14:34 | prop | -| tst.js:16:10:16:13 | prop | -| tst.js:16:10:16:13 | prop | -| tstNonExpr.js:5:7:5:23 | userVal | -| tstNonExpr.js:5:17:5:23 | req.url | -| tstNonExpr.js:5:17:5:23 | req.url | -| tstNonExpr.js:8:17:8:23 | userVal | -| tstNonExpr.js:8:17:8:23 | userVal | edges | tst.js:8:6:8:52 | prop | tst.js:9:8:9:11 | prop | -| tst.js:8:6:8:52 | prop | tst.js:9:8:9:11 | prop | -| tst.js:8:6:8:52 | prop | tst.js:13:15:13:18 | prop | | tst.js:8:6:8:52 | prop | tst.js:13:15:13:18 | prop | | tst.js:8:6:8:52 | prop | tst.js:14:31:14:34 | prop | -| tst.js:8:6:8:52 | prop | tst.js:14:31:14:34 | prop | -| tst.js:8:6:8:52 | prop | tst.js:16:10:16:13 | prop | | tst.js:8:6:8:52 | prop | tst.js:16:10:16:13 | prop | | tst.js:8:13:8:52 | myCoolL ... rolled) | tst.js:8:6:8:52 | prop | | tst.js:8:28:8:51 | req.que ... trolled | tst.js:8:13:8:52 | myCoolL ... rolled) | -| tst.js:8:28:8:51 | req.que ... trolled | tst.js:8:13:8:52 | myCoolL ... rolled) | -| tstNonExpr.js:5:7:5:23 | userVal | tstNonExpr.js:8:17:8:23 | userVal | +| tst.js:8:28:8:51 | req.que ... trolled | tst.js:21:25:21:25 | x | +| tst.js:21:25:21:25 | x | tst.js:22:15:22:15 | x | +| tst.js:22:6:22:15 | result | tst.js:23:9:23:14 | result | +| tst.js:22:15:22:15 | x | tst.js:22:6:22:15 | result | +| tst.js:23:9:23:14 | result | tst.js:23:9:23:42 | result. ... length) | | tstNonExpr.js:5:7:5:23 | userVal | tstNonExpr.js:8:17:8:23 | userVal | | tstNonExpr.js:5:17:5:23 | req.url | tstNonExpr.js:5:7:5:23 | userVal | -| tstNonExpr.js:5:17:5:23 | req.url | tstNonExpr.js:5:7:5:23 | userVal | +nodes +| tst.js:8:6:8:52 | prop | semmle.label | prop | +| tst.js:8:13:8:52 | myCoolL ... rolled) | semmle.label | myCoolL ... rolled) | +| tst.js:8:28:8:51 | req.que ... trolled | semmle.label | req.que ... trolled | +| tst.js:9:8:9:11 | prop | semmle.label | prop | +| tst.js:13:15:13:18 | prop | semmle.label | prop | +| tst.js:14:31:14:34 | prop | semmle.label | prop | +| tst.js:16:10:16:13 | prop | semmle.label | prop | +| tst.js:21:25:21:25 | x | semmle.label | x | +| tst.js:22:6:22:15 | result | semmle.label | result | +| tst.js:22:15:22:15 | x | semmle.label | x | +| tst.js:23:9:23:14 | result | semmle.label | result | +| tst.js:23:9:23:42 | result. ... length) | semmle.label | result. ... length) | +| tstNonExpr.js:5:7:5:23 | userVal | semmle.label | userVal | +| tstNonExpr.js:5:17:5:23 | req.url | semmle.label | req.url | +| tstNonExpr.js:8:17:8:23 | userVal | semmle.label | userVal | +subpaths +| tst.js:8:28:8:51 | req.que ... trolled | tst.js:21:25:21:25 | x | tst.js:23:9:23:42 | result. ... length) | tst.js:8:13:8:52 | myCoolL ... rolled) | #select | tst.js:9:8:9:11 | prop | tst.js:8:28:8:51 | req.que ... trolled | tst.js:9:8:9:11 | prop | A property name to write to depends on a $@. | tst.js:8:28:8:51 | req.que ... trolled | user-provided value | | tst.js:13:15:13:18 | prop | tst.js:8:28:8:51 | req.que ... trolled | tst.js:13:15:13:18 | prop | A property name to write to depends on a $@. | tst.js:8:28:8:51 | req.que ... trolled | user-provided value | From 4af76943098cafa146414806cf15beefb444822b Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:22:04 +0200 Subject: [PATCH 088/514] JS: Port ResourceExhaustion --- .../ResourceExhaustionCustomizations.qll | 15 +++ .../dataflow/ResourceExhaustionQuery.qll | 30 ++++- .../Security/CWE-770/ResourceExhaustion.ql | 6 +- .../ResourceExhaustion.expected | 119 ++++++------------ 4 files changed, 80 insertions(+), 90 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionCustomizations.qll index 8307c1f6f93..a26d4a2e9a5 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionCustomizations.qll @@ -31,6 +31,21 @@ module ResourceExhaustion { */ abstract class Sanitizer extends DataFlow::Node { } + /** + * A barrier guard for resource exhaustion vulnerabilities. + */ + 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() } + } + + /** 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) } + } + /** A source of remote user input, considered as a data flow source for resource exhaustion vulnerabilities. */ class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource { RemoteFlowSourceAsSource() { diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionQuery.qll index 366d1db6973..01cab949741 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionQuery.qll @@ -13,7 +13,31 @@ import ResourceExhaustionCustomizations::ResourceExhaustion /** * A data flow configuration for resource exhaustion vulnerabilities. */ -class Configuration extends TaintTracking::Configuration { +module ResourceExhaustionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { + node instanceof Sanitizer or + node = any(DataFlow::PropRead read | read.getPropertyName() = "length") or + node = DataFlow::MakeBarrierGuard::getABarrierNode() + } + + predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node dst) { + isNumericFlowStep(src, dst) + } +} + +/** + * Data flow for resource exhaustion vulnerabilities. + */ +module ResourceExhaustionFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `ResourceExhaustionFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "ResourceExhaustion" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -49,10 +73,10 @@ predicate isNumericFlowStep(DataFlow::Node src, DataFlow::Node dst) { /** * A sanitizer that blocks taint flow if the size of a number is limited. */ -class UpperBoundsCheckSanitizerGuard extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode { +class UpperBoundsCheckSanitizerGuard extends BarrierGuardLegacy, DataFlow::ValueNode { override RelationalComparison astNode; - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { true = outcome and e = astNode.getLesserOperand() or diff --git a/javascript/ql/src/Security/CWE-770/ResourceExhaustion.ql b/javascript/ql/src/Security/CWE-770/ResourceExhaustion.ql index 4a32424ac3e..89452bea8ca 100644 --- a/javascript/ql/src/Security/CWE-770/ResourceExhaustion.ql +++ b/javascript/ql/src/Security/CWE-770/ResourceExhaustion.ql @@ -13,10 +13,10 @@ */ import javascript -import DataFlow::PathGraph import semmle.javascript.security.dataflow.ResourceExhaustionQuery +import ResourceExhaustionFlow::PathGraph -from Configuration dataflow, DataFlow::PathNode source, DataFlow::PathNode sink -where dataflow.hasFlowPath(source, sink) +from ResourceExhaustionFlow::PathNode source, ResourceExhaustionFlow::PathNode sink +where ResourceExhaustionFlow::flowPath(source, sink) select sink, source, sink, sink.getNode().(Sink).getProblemDescription() + " from a $@.", source, "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-770/ResourceExhaustion/ResourceExhaustion.expected b/javascript/ql/test/query-tests/Security/CWE-770/ResourceExhaustion/ResourceExhaustion.expected index 1c8a7172c6d..f3b767c64b4 100644 --- a/javascript/ql/test/query-tests/Security/CWE-770/ResourceExhaustion/ResourceExhaustion.expected +++ b/javascript/ql/test/query-tests/Security/CWE-770/ResourceExhaustion/ResourceExhaustion.expected @@ -1,115 +1,66 @@ -nodes -| documentaion-examples/ResourceExhaustion_timeout.js:5:6:5:59 | delay | -| documentaion-examples/ResourceExhaustion_timeout.js:5:14:5:59 | parseIn ... .delay) | -| documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:46 | url.par ... , true) | -| documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:52 | url.par ... ).query | -| documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:58 | url.par ... y.delay | -| documentaion-examples/ResourceExhaustion_timeout.js:5:33:5:39 | req.url | -| documentaion-examples/ResourceExhaustion_timeout.js:5:33:5:39 | req.url | -| documentaion-examples/ResourceExhaustion_timeout.js:7:16:7:20 | delay | -| documentaion-examples/ResourceExhaustion_timeout.js:7:16:7:20 | delay | -| resource-exhaustion.js:5:7:5:42 | s | -| resource-exhaustion.js:5:11:5:34 | url.par ... , true) | -| resource-exhaustion.js:5:11:5:40 | url.par ... ).query | -| resource-exhaustion.js:5:11:5:42 | url.par ... query.s | -| resource-exhaustion.js:5:21:5:27 | req.url | -| resource-exhaustion.js:5:21:5:27 | req.url | -| resource-exhaustion.js:6:7:6:21 | n | -| resource-exhaustion.js:6:11:6:21 | parseInt(s) | -| resource-exhaustion.js:6:20:6:20 | s | -| resource-exhaustion.js:14:16:14:16 | n | -| resource-exhaustion.js:14:16:14:16 | n | -| resource-exhaustion.js:15:22:15:22 | n | -| resource-exhaustion.js:15:22:15:22 | n | -| resource-exhaustion.js:16:26:16:26 | n | -| resource-exhaustion.js:16:26:16:26 | n | -| resource-exhaustion.js:20:20:20:20 | n | -| resource-exhaustion.js:20:20:20:20 | n | -| resource-exhaustion.js:22:18:22:18 | n | -| resource-exhaustion.js:22:18:22:18 | n | -| resource-exhaustion.js:27:9:27:9 | n | -| resource-exhaustion.js:27:9:27:9 | n | -| resource-exhaustion.js:28:13:28:13 | n | -| resource-exhaustion.js:28:13:28:13 | n | -| resource-exhaustion.js:29:9:29:9 | n | -| resource-exhaustion.js:29:9:29:9 | n | -| resource-exhaustion.js:30:9:30:9 | n | -| resource-exhaustion.js:30:9:30:9 | n | -| resource-exhaustion.js:31:9:31:9 | n | -| resource-exhaustion.js:31:9:31:9 | n | -| resource-exhaustion.js:32:9:32:9 | n | -| resource-exhaustion.js:32:9:32:9 | n | -| resource-exhaustion.js:34:12:34:12 | n | -| resource-exhaustion.js:34:12:34:12 | n | -| resource-exhaustion.js:35:12:35:12 | s | -| resource-exhaustion.js:35:12:35:12 | s | -| resource-exhaustion.js:81:17:81:17 | n | -| resource-exhaustion.js:81:17:81:17 | n | -| resource-exhaustion.js:82:17:82:17 | s | -| resource-exhaustion.js:82:17:82:17 | s | -| resource-exhaustion.js:83:18:83:18 | n | -| resource-exhaustion.js:83:18:83:18 | n | -| resource-exhaustion.js:84:18:84:18 | s | -| resource-exhaustion.js:84:18:84:18 | s | -| resource-exhaustion.js:88:16:88:16 | n | -| resource-exhaustion.js:88:16:88:16 | n | -| resource-exhaustion.js:92:18:92:18 | n | -| resource-exhaustion.js:92:18:92:18 | n | edges | documentaion-examples/ResourceExhaustion_timeout.js:5:6:5:59 | delay | documentaion-examples/ResourceExhaustion_timeout.js:7:16:7:20 | delay | -| documentaion-examples/ResourceExhaustion_timeout.js:5:6:5:59 | delay | documentaion-examples/ResourceExhaustion_timeout.js:7:16:7:20 | delay | | documentaion-examples/ResourceExhaustion_timeout.js:5:14:5:59 | parseIn ... .delay) | documentaion-examples/ResourceExhaustion_timeout.js:5:6:5:59 | delay | -| documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:46 | url.par ... , true) | documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:52 | url.par ... ).query | -| documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:52 | url.par ... ).query | documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:58 | url.par ... y.delay | +| documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:46 | url.par ... , true) | documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:58 | url.par ... y.delay | | documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:58 | url.par ... y.delay | documentaion-examples/ResourceExhaustion_timeout.js:5:14:5:59 | parseIn ... .delay) | | documentaion-examples/ResourceExhaustion_timeout.js:5:33:5:39 | req.url | documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:46 | url.par ... , true) | -| documentaion-examples/ResourceExhaustion_timeout.js:5:33:5:39 | req.url | documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:46 | url.par ... , true) | | resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:6:20:6:20 | s | | resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:35:12:35:12 | s | -| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:35:12:35:12 | s | -| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:82:17:82:17 | s | | resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:82:17:82:17 | s | | resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:84:18:84:18 | s | -| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:84:18:84:18 | s | -| resource-exhaustion.js:5:11:5:34 | url.par ... , true) | resource-exhaustion.js:5:11:5:40 | url.par ... ).query | -| resource-exhaustion.js:5:11:5:40 | url.par ... ).query | resource-exhaustion.js:5:11:5:42 | url.par ... query.s | -| resource-exhaustion.js:5:11:5:42 | url.par ... query.s | resource-exhaustion.js:5:7:5:42 | s | -| resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:5:11:5:34 | url.par ... , true) | +| resource-exhaustion.js:5:11:5:34 | url.par ... , true) | resource-exhaustion.js:5:7:5:42 | s | | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:5:11:5:34 | url.par ... , true) | | resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:14:16:14:16 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:14:16:14:16 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:15:22:15:22 | n | | resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:15:22:15:22 | n | | resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:16:26:16:26 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:16:26:16:26 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:20:20:20:20 | n | | resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:20:20:20:20 | n | | resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:22:18:22:18 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:22:18:22:18 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:27:9:27:9 | n | | resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:27:9:27:9 | n | | resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:28:13:28:13 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:28:13:28:13 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:29:9:29:9 | n | | resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:29:9:29:9 | n | | resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:30:9:30:9 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:30:9:30:9 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:31:9:31:9 | n | | resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:31:9:31:9 | n | | resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:32:9:32:9 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:32:9:32:9 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:34:12:34:12 | n | | resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:34:12:34:12 | n | | resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:81:17:81:17 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:81:17:81:17 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:83:18:83:18 | n | | resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:83:18:83:18 | n | | resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:88:16:88:16 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:88:16:88:16 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:92:18:92:18 | n | | resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:92:18:92:18 | n | | resource-exhaustion.js:6:11:6:21 | parseInt(s) | resource-exhaustion.js:6:7:6:21 | n | | resource-exhaustion.js:6:20:6:20 | s | resource-exhaustion.js:6:11:6:21 | parseInt(s) | +nodes +| documentaion-examples/ResourceExhaustion_timeout.js:5:6:5:59 | delay | semmle.label | delay | +| documentaion-examples/ResourceExhaustion_timeout.js:5:14:5:59 | parseIn ... .delay) | semmle.label | parseIn ... .delay) | +| documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:46 | url.par ... , true) | semmle.label | url.par ... , true) | +| documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:58 | url.par ... y.delay | semmle.label | url.par ... y.delay | +| documentaion-examples/ResourceExhaustion_timeout.js:5:33:5:39 | req.url | semmle.label | req.url | +| documentaion-examples/ResourceExhaustion_timeout.js:7:16:7:20 | delay | semmle.label | delay | +| resource-exhaustion.js:5:7:5:42 | s | semmle.label | s | +| resource-exhaustion.js:5:11:5:34 | url.par ... , true) | semmle.label | url.par ... , true) | +| resource-exhaustion.js:5:21:5:27 | req.url | semmle.label | req.url | +| resource-exhaustion.js:6:7:6:21 | n | semmle.label | n | +| resource-exhaustion.js:6:11:6:21 | parseInt(s) | semmle.label | parseInt(s) | +| resource-exhaustion.js:6:20:6:20 | s | semmle.label | s | +| resource-exhaustion.js:14:16:14:16 | n | semmle.label | n | +| resource-exhaustion.js:15:22:15:22 | n | semmle.label | n | +| resource-exhaustion.js:16:26:16:26 | n | semmle.label | n | +| resource-exhaustion.js:20:20:20:20 | n | semmle.label | n | +| resource-exhaustion.js:22:18:22:18 | n | semmle.label | n | +| resource-exhaustion.js:27:9:27:9 | n | semmle.label | n | +| resource-exhaustion.js:28:13:28:13 | n | semmle.label | n | +| resource-exhaustion.js:29:9:29:9 | n | semmle.label | n | +| resource-exhaustion.js:30:9:30:9 | n | semmle.label | n | +| resource-exhaustion.js:31:9:31:9 | n | semmle.label | n | +| resource-exhaustion.js:32:9:32:9 | n | semmle.label | n | +| resource-exhaustion.js:34:12:34:12 | n | semmle.label | n | +| resource-exhaustion.js:35:12:35:12 | s | semmle.label | s | +| resource-exhaustion.js:81:17:81:17 | n | semmle.label | n | +| resource-exhaustion.js:82:17:82:17 | s | semmle.label | s | +| resource-exhaustion.js:83:18:83:18 | n | semmle.label | n | +| resource-exhaustion.js:84:18:84:18 | s | semmle.label | s | +| resource-exhaustion.js:88:16:88:16 | n | semmle.label | n | +| resource-exhaustion.js:92:18:92:18 | n | semmle.label | n | +subpaths #select | documentaion-examples/ResourceExhaustion_timeout.js:7:16:7:20 | delay | documentaion-examples/ResourceExhaustion_timeout.js:5:33:5:39 | req.url | documentaion-examples/ResourceExhaustion_timeout.js:7:16:7:20 | delay | This creates a timer with a user-controlled duration from a $@. | documentaion-examples/ResourceExhaustion_timeout.js:5:33:5:39 | req.url | user-provided value | | resource-exhaustion.js:14:16:14:16 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:14:16:14:16 | n | This creates a buffer with a user-controlled size from a $@. | resource-exhaustion.js:5:21:5:27 | req.url | user-provided value | From 06835a800cd7f17394a08a9cce3b96806b04e384 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:22:40 +0200 Subject: [PATCH 089/514] JS: Port SecondOrderCommandInjection --- ...ondOrderCommandInjectionCustomizations.qll | 34 +++++++++--- .../SecondOrderCommandInjectionQuery.qll | 46 +++++++++++++++- .../CWE-078/SecondOrderCommandInjection.ql | 9 ++-- .../SecondOrderCommandInjection.expected | 53 +++++-------------- 4 files changed, 93 insertions(+), 49 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionCustomizations.qll index c405dec31f7..95a363bfa17 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionCustomizations.qll @@ -83,6 +83,30 @@ module SecondOrderCommandInjection { abstract string getVulnerableArgumentExample(); } + /** + * A barrier guard for second order command-injection vulnerabilities. + */ + 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 sink that invokes a command described by the `VulnerableCommand` class. */ @@ -190,9 +214,8 @@ module SecondOrderCommandInjection { /** * A sanitizer that blocks flow when a string is tested to start with a certain prefix. */ - class PrefixStringSanitizer extends TaintTracking::SanitizerGuardNode instanceof StringOps::StartsWith - { - override predicate sanitizes(boolean outcome, Expr e) { + class PrefixStringSanitizer extends BarrierGuardLegacy instanceof StringOps::StartsWith { + override predicate blocksExpr(boolean outcome, Expr e) { e = super.getBaseString().asExpr() and outcome = super.getPolarity() } @@ -201,11 +224,10 @@ module SecondOrderCommandInjection { /** * A sanitizer that blocks flow when a string does not start with "--" */ - class DoubleDashSanitizer extends TaintTracking::SanitizerGuardNode instanceof StringOps::StartsWith - { + class DoubleDashSanitizer extends BarrierGuardLegacy instanceof StringOps::StartsWith { DoubleDashSanitizer() { super.getSubstring().mayHaveStringValue("--") } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { e = super.getBaseString().asExpr() and outcome = super.getPolarity().booleanNot() } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionQuery.qll index fc10cd30c71..86045d167f1 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionQuery.qll @@ -14,7 +14,51 @@ private import semmle.javascript.security.TaintedObject /** * A taint-tracking configuration for reasoning about second order command-injection vulnerabilities. */ -class Configuration extends TaintTracking::Configuration { +module SecondOrderCommandInjectionConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; + + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { + source.(Source).getALabel() = label + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { + sink.(Sink).getALabel() = label + } + + predicate isBarrier(DataFlow::Node node) { + node instanceof Sanitizer or node = DataFlow::MakeBarrierGuard::getABarrierNode() + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel label) { + TaintTracking::defaultSanitizer(node) and + label.isTaint() + or + node = DataFlow::MakeLabeledBarrierGuard::getABarrierNode(label) + or + node = TaintedObject::SanitizerGuard::getABarrierNode(label) + } + + predicate isAdditionalFlowStep( + DataFlow::Node src, DataFlow::FlowLabel inlbl, DataFlow::Node trg, DataFlow::FlowLabel outlbl + ) { + TaintedObject::step(src, trg, inlbl, outlbl) + or + inlbl.isTaint() and + TaintTracking::defaultTaintStep(src, trg) and + inlbl = outlbl + } +} + +/** + * Taint-tracking for reasoning about second order command-injection vulnerabilities. + */ +module SecondOrderCommandInjectionFlow = + DataFlow::GlobalWithState; + +/** + * DEPRECATED. Use the `SecondOrderCommandInjectionFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "SecondOrderCommandInjection" } override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { diff --git a/javascript/ql/src/Security/CWE-078/SecondOrderCommandInjection.ql b/javascript/ql/src/Security/CWE-078/SecondOrderCommandInjection.ql index deb792a53ee..47f9e02d388 100644 --- a/javascript/ql/src/Security/CWE-078/SecondOrderCommandInjection.ql +++ b/javascript/ql/src/Security/CWE-078/SecondOrderCommandInjection.ql @@ -14,11 +14,14 @@ */ import javascript -import DataFlow::PathGraph import semmle.javascript.security.dataflow.SecondOrderCommandInjectionQuery +import DataFlow::DeduplicatePathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Sink sinkNode -where cfg.hasFlowPath(source, sink) and sinkNode = sink.getNode() +from PathNode source, PathNode sink, Sink sinkNode +where + SecondOrderCommandInjectionFlow::flowPath(source.getAnOriginalPathNode(), + sink.getAnOriginalPathNode()) and + sinkNode = sink.getNode() select sink.getNode(), source, sink, "Command line argument that depends on $@ can execute an arbitrary command if " + sinkNode.getVulnerableArgumentExample() + " is used with " + sinkNode.getCommand() + ".", diff --git a/javascript/ql/test/query-tests/Security/CWE-078/SecondOrderCommandInjection/SecondOrderCommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/SecondOrderCommandInjection/SecondOrderCommandInjection.expected index 653a4dcff9b..8f18ce1aa09 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/SecondOrderCommandInjection/SecondOrderCommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/SecondOrderCommandInjection/SecondOrderCommandInjection.expected @@ -1,51 +1,26 @@ nodes -| second-order.js:6:9:6:33 | remote | -| second-order.js:6:18:6:33 | req.query.remote | -| second-order.js:6:18:6:33 | req.query.remote | -| second-order.js:7:33:7:38 | remote | -| second-order.js:7:33:7:38 | remote | -| second-order.js:9:29:9:34 | remote | -| second-order.js:9:29:9:34 | remote | -| second-order.js:11:33:11:38 | remote | -| second-order.js:11:33:11:38 | remote | -| second-order.js:13:9:13:31 | myArgs | -| second-order.js:13:18:13:31 | req.query.args | -| second-order.js:13:18:13:31 | req.query.args | -| second-order.js:15:19:15:24 | myArgs | -| second-order.js:15:19:15:24 | myArgs | -| second-order.js:26:35:26:40 | remote | -| second-order.js:26:35:26:40 | remote | -| second-order.js:29:19:29:32 | req.query.args | -| second-order.js:29:19:29:32 | req.query.args | -| second-order.js:29:19:29:32 | req.query.args | -| second-order.js:40:28:40:43 | req.query.remote | -| second-order.js:40:28:40:43 | req.query.remote | -| second-order.js:40:28:40:43 | req.query.remote | -| second-order.js:42:31:42:46 | req.query.remote | -| second-order.js:42:31:42:46 | req.query.remote | -| second-order.js:42:31:42:46 | req.query.remote | -| second-order.js:44:18:44:31 | req.query.args | -| second-order.js:44:18:44:31 | req.query.args | -| second-order.js:44:18:44:31 | req.query.args | +| second-order.js:6:9:6:33 | remote | semmle.label | remote | +| second-order.js:6:18:6:33 | req.query.remote | semmle.label | req.query.remote | +| second-order.js:7:33:7:38 | remote | semmle.label | remote | +| second-order.js:9:29:9:34 | remote | semmle.label | remote | +| second-order.js:11:33:11:38 | remote | semmle.label | remote | +| second-order.js:13:9:13:31 | myArgs | semmle.label | myArgs | +| second-order.js:13:18:13:31 | req.query.args | semmle.label | req.query.args | +| second-order.js:15:19:15:24 | myArgs | semmle.label | myArgs | +| second-order.js:26:35:26:40 | remote | semmle.label | remote | +| second-order.js:29:19:29:32 | req.query.args | semmle.label | req.query.args | +| second-order.js:40:28:40:43 | req.query.remote | semmle.label | req.query.remote | +| second-order.js:42:31:42:46 | req.query.remote | semmle.label | req.query.remote | +| second-order.js:44:18:44:31 | req.query.args | semmle.label | req.query.args | edges | second-order.js:6:9:6:33 | remote | second-order.js:7:33:7:38 | remote | -| second-order.js:6:9:6:33 | remote | second-order.js:7:33:7:38 | remote | -| second-order.js:6:9:6:33 | remote | second-order.js:9:29:9:34 | remote | | second-order.js:6:9:6:33 | remote | second-order.js:9:29:9:34 | remote | | second-order.js:6:9:6:33 | remote | second-order.js:11:33:11:38 | remote | -| second-order.js:6:9:6:33 | remote | second-order.js:11:33:11:38 | remote | -| second-order.js:6:9:6:33 | remote | second-order.js:26:35:26:40 | remote | | second-order.js:6:9:6:33 | remote | second-order.js:26:35:26:40 | remote | | second-order.js:6:18:6:33 | req.query.remote | second-order.js:6:9:6:33 | remote | -| second-order.js:6:18:6:33 | req.query.remote | second-order.js:6:9:6:33 | remote | -| second-order.js:13:9:13:31 | myArgs | second-order.js:15:19:15:24 | myArgs | | second-order.js:13:9:13:31 | myArgs | second-order.js:15:19:15:24 | myArgs | | second-order.js:13:18:13:31 | req.query.args | second-order.js:13:9:13:31 | myArgs | -| second-order.js:13:18:13:31 | req.query.args | second-order.js:13:9:13:31 | myArgs | -| second-order.js:29:19:29:32 | req.query.args | second-order.js:29:19:29:32 | req.query.args | -| second-order.js:40:28:40:43 | req.query.remote | second-order.js:40:28:40:43 | req.query.remote | -| second-order.js:42:31:42:46 | req.query.remote | second-order.js:42:31:42:46 | req.query.remote | -| second-order.js:44:18:44:31 | req.query.args | second-order.js:44:18:44:31 | req.query.args | +subpaths #select | second-order.js:7:33:7:38 | remote | second-order.js:6:18:6:33 | req.query.remote | second-order.js:7:33:7:38 | remote | Command line argument that depends on $@ can execute an arbitrary command if --upload-pack is used with git. | second-order.js:6:18:6:33 | req.query.remote | a user-provided value | | second-order.js:9:29:9:34 | remote | second-order.js:6:18:6:33 | req.query.remote | second-order.js:9:29:9:34 | remote | Command line argument that depends on $@ can execute an arbitrary command if --upload-pack is used with git. | second-order.js:6:18:6:33 | req.query.remote | a user-provided value | From d446444667ad773b52182631038a36b5e0db3e00 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:23:18 +0200 Subject: [PATCH 090/514] JS: Port ShellCommandInjectionFromEnvironment --- ...llCommandInjectionFromEnvironmentQuery.qll | 26 ++++++++++++++- .../ShellCommandInjectionFromEnvironment.ql | 11 ++++--- ...llCommandInjectionFromEnvironment.expected | 33 +++++++------------ 3 files changed, 42 insertions(+), 28 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ShellCommandInjectionFromEnvironmentQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ShellCommandInjectionFromEnvironmentQuery.qll index 6e0cff12eff..8d04d283c00 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ShellCommandInjectionFromEnvironmentQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ShellCommandInjectionFromEnvironmentQuery.qll @@ -14,7 +14,31 @@ import IndirectCommandArgument /** * A taint-tracking configuration for reasoning about command-injection vulnerabilities. */ -class Configuration extends TaintTracking::Configuration { +module ShellCommandInjectionFromEnvironmentConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + /** Holds if `sink` is a command-injection sink with `highlight` as the corresponding alert location. */ + additional predicate isSinkWithHighlight(DataFlow::Node sink, DataFlow::Node highlight) { + sink instanceof Sink and highlight = sink + or + isIndirectCommandArgument(sink, highlight) + } + + predicate isSink(DataFlow::Node sink) { isSinkWithHighlight(sink, _) } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint-tracking for reasoning about command-injection vulnerabilities. + */ +module ShellCommandInjectionFromEnvironmentFlow = + TaintTracking::Global; + +/** + * DEPRECATED. Use the `ShellCommandInjectionFromEnvironmentFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "ShellCommandInjectionFromEnvironment" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-078/ShellCommandInjectionFromEnvironment.ql b/javascript/ql/src/Security/CWE-078/ShellCommandInjectionFromEnvironment.ql index cad1039814c..2fbb8187057 100644 --- a/javascript/ql/src/Security/CWE-078/ShellCommandInjectionFromEnvironment.ql +++ b/javascript/ql/src/Security/CWE-078/ShellCommandInjectionFromEnvironment.ql @@ -14,17 +14,18 @@ */ import javascript -import DataFlow::PathGraph import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironmentQuery +import ShellCommandInjectionFromEnvironmentFlow::PathGraph from - Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node highlight, + ShellCommandInjectionFromEnvironmentFlow::PathNode source, + ShellCommandInjectionFromEnvironmentFlow::PathNode sink, DataFlow::Node highlight, Source sourceNode where sourceNode = source.getNode() and - cfg.hasFlowPath(source, sink) and - if cfg.isSinkWithHighlight(sink.getNode(), _) - then cfg.isSinkWithHighlight(sink.getNode(), highlight) + ShellCommandInjectionFromEnvironmentFlow::flowPath(source, sink) and + if ShellCommandInjectionFromEnvironmentConfig::isSinkWithHighlight(sink.getNode(), _) + then ShellCommandInjectionFromEnvironmentConfig::isSinkWithHighlight(sink.getNode(), highlight) else highlight = sink.getNode() select highlight, source, sink, "This shell command depends on an uncontrolled $@.", sourceNode, sourceNode.getSourceType() diff --git a/javascript/ql/test/query-tests/Security/CWE-078/ShellCommandInjectionFromEnvironment/ShellCommandInjectionFromEnvironment.expected b/javascript/ql/test/query-tests/Security/CWE-078/ShellCommandInjectionFromEnvironment/ShellCommandInjectionFromEnvironment.expected index 7bea597fc28..c231dc9d885 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/ShellCommandInjectionFromEnvironment/ShellCommandInjectionFromEnvironment.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/ShellCommandInjectionFromEnvironment/ShellCommandInjectionFromEnvironment.expected @@ -1,32 +1,21 @@ -nodes -| tst_shell-command-injection-from-environment.js:6:14:6:53 | 'rm -rf ... "temp") | -| tst_shell-command-injection-from-environment.js:6:14:6:53 | 'rm -rf ... "temp") | -| tst_shell-command-injection-from-environment.js:6:26:6:53 | path.jo ... "temp") | -| tst_shell-command-injection-from-environment.js:6:36:6:44 | __dirname | -| tst_shell-command-injection-from-environment.js:6:36:6:44 | __dirname | -| tst_shell-command-injection-from-environment.js:8:14:8:53 | 'rm -rf ... "temp") | -| tst_shell-command-injection-from-environment.js:8:14:8:53 | 'rm -rf ... "temp") | -| tst_shell-command-injection-from-environment.js:8:26:8:53 | path.jo ... "temp") | -| tst_shell-command-injection-from-environment.js:8:36:8:44 | __dirname | -| tst_shell-command-injection-from-environment.js:8:36:8:44 | __dirname | -| tst_shell-command-injection-from-environment.js:9:18:9:57 | 'rm -rf ... "temp") | -| tst_shell-command-injection-from-environment.js:9:18:9:57 | 'rm -rf ... "temp") | -| tst_shell-command-injection-from-environment.js:9:30:9:57 | path.jo ... "temp") | -| tst_shell-command-injection-from-environment.js:9:40:9:48 | __dirname | -| tst_shell-command-injection-from-environment.js:9:40:9:48 | __dirname | edges | tst_shell-command-injection-from-environment.js:6:26:6:53 | path.jo ... "temp") | tst_shell-command-injection-from-environment.js:6:14:6:53 | 'rm -rf ... "temp") | -| tst_shell-command-injection-from-environment.js:6:26:6:53 | path.jo ... "temp") | tst_shell-command-injection-from-environment.js:6:14:6:53 | 'rm -rf ... "temp") | -| tst_shell-command-injection-from-environment.js:6:36:6:44 | __dirname | tst_shell-command-injection-from-environment.js:6:26:6:53 | path.jo ... "temp") | | tst_shell-command-injection-from-environment.js:6:36:6:44 | __dirname | tst_shell-command-injection-from-environment.js:6:26:6:53 | path.jo ... "temp") | | tst_shell-command-injection-from-environment.js:8:26:8:53 | path.jo ... "temp") | tst_shell-command-injection-from-environment.js:8:14:8:53 | 'rm -rf ... "temp") | -| tst_shell-command-injection-from-environment.js:8:26:8:53 | path.jo ... "temp") | tst_shell-command-injection-from-environment.js:8:14:8:53 | 'rm -rf ... "temp") | -| tst_shell-command-injection-from-environment.js:8:36:8:44 | __dirname | tst_shell-command-injection-from-environment.js:8:26:8:53 | path.jo ... "temp") | | tst_shell-command-injection-from-environment.js:8:36:8:44 | __dirname | tst_shell-command-injection-from-environment.js:8:26:8:53 | path.jo ... "temp") | | tst_shell-command-injection-from-environment.js:9:30:9:57 | path.jo ... "temp") | tst_shell-command-injection-from-environment.js:9:18:9:57 | 'rm -rf ... "temp") | -| tst_shell-command-injection-from-environment.js:9:30:9:57 | path.jo ... "temp") | tst_shell-command-injection-from-environment.js:9:18:9:57 | 'rm -rf ... "temp") | -| tst_shell-command-injection-from-environment.js:9:40:9:48 | __dirname | tst_shell-command-injection-from-environment.js:9:30:9:57 | path.jo ... "temp") | | tst_shell-command-injection-from-environment.js:9:40:9:48 | __dirname | tst_shell-command-injection-from-environment.js:9:30:9:57 | path.jo ... "temp") | +nodes +| tst_shell-command-injection-from-environment.js:6:14:6:53 | 'rm -rf ... "temp") | semmle.label | 'rm -rf ... "temp") | +| tst_shell-command-injection-from-environment.js:6:26:6:53 | path.jo ... "temp") | semmle.label | path.jo ... "temp") | +| tst_shell-command-injection-from-environment.js:6:36:6:44 | __dirname | semmle.label | __dirname | +| tst_shell-command-injection-from-environment.js:8:14:8:53 | 'rm -rf ... "temp") | semmle.label | 'rm -rf ... "temp") | +| tst_shell-command-injection-from-environment.js:8:26:8:53 | path.jo ... "temp") | semmle.label | path.jo ... "temp") | +| tst_shell-command-injection-from-environment.js:8:36:8:44 | __dirname | semmle.label | __dirname | +| tst_shell-command-injection-from-environment.js:9:18:9:57 | 'rm -rf ... "temp") | semmle.label | 'rm -rf ... "temp") | +| tst_shell-command-injection-from-environment.js:9:30:9:57 | path.jo ... "temp") | semmle.label | path.jo ... "temp") | +| tst_shell-command-injection-from-environment.js:9:40:9:48 | __dirname | semmle.label | __dirname | +subpaths #select | tst_shell-command-injection-from-environment.js:6:14:6:53 | 'rm -rf ... "temp") | tst_shell-command-injection-from-environment.js:6:36:6:44 | __dirname | tst_shell-command-injection-from-environment.js:6:14:6:53 | 'rm -rf ... "temp") | This shell command depends on an uncontrolled $@. | tst_shell-command-injection-from-environment.js:6:36:6:44 | __dirname | absolute path | | tst_shell-command-injection-from-environment.js:8:14:8:53 | 'rm -rf ... "temp") | tst_shell-command-injection-from-environment.js:8:36:8:44 | __dirname | tst_shell-command-injection-from-environment.js:8:14:8:53 | 'rm -rf ... "temp") | This shell command depends on an uncontrolled $@. | tst_shell-command-injection-from-environment.js:8:36:8:44 | __dirname | absolute path | From 63343b1ba4106e0147203f999e2e4b0d1a832514 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:23:28 +0200 Subject: [PATCH 091/514] JS: Port StackTraceExposure --- .../dataflow/StackTraceExposureQuery.qll | 32 ++++++++++++++---- .../Security/CWE-209/StackTraceExposure.ql | 6 ++-- .../CWE-209/StackTraceExposure.expected | 33 +++++++------------ 3 files changed, 39 insertions(+), 32 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/StackTraceExposureQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/StackTraceExposureQuery.qll index 4350fbab061..cb05f91c727 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/StackTraceExposureQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/StackTraceExposureQuery.qll @@ -14,14 +14,10 @@ import StackTraceExposureCustomizations::StackTraceExposure * A taint-tracking configuration for reasoning about stack trace * exposure problems. */ -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "StackTraceExposure" } +module StackTraceExposureConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src instanceof Source } - override predicate isSource(DataFlow::Node src) { src instanceof Source } - - override predicate isSanitizer(DataFlow::Node nd) { - super.isSanitizer(nd) - or + predicate isBarrier(DataFlow::Node nd) { // read of a property other than `stack` nd.(DataFlow::PropRead).getPropertyName() != "stack" or @@ -31,5 +27,27 @@ class Configuration extends TaintTracking::Configuration { nd = StringConcatenation::getAnOperand(_) } + predicate isSink(DataFlow::Node snk) { snk instanceof Sink } +} + +/** + * Taint-tracking for reasoning about stack trace exposure problems. + */ +module StackTraceExposureFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `StackTraceExposureFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { + Configuration() { this = "StackTraceExposure" } + + override predicate isSource(DataFlow::Node src) { src instanceof Source } + + override predicate isSanitizer(DataFlow::Node nd) { + super.isSanitizer(nd) + or + StackTraceExposureConfig::isBarrier(nd) + } + override predicate isSink(DataFlow::Node snk) { snk instanceof Sink } } diff --git a/javascript/ql/src/Security/CWE-209/StackTraceExposure.ql b/javascript/ql/src/Security/CWE-209/StackTraceExposure.ql index 8342dea6e72..b6bf246387c 100644 --- a/javascript/ql/src/Security/CWE-209/StackTraceExposure.ql +++ b/javascript/ql/src/Security/CWE-209/StackTraceExposure.ql @@ -15,9 +15,9 @@ import javascript import semmle.javascript.security.dataflow.StackTraceExposureQuery -import DataFlow::PathGraph +import StackTraceExposureFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from StackTraceExposureFlow::PathNode source, StackTraceExposureFlow::PathNode sink +where StackTraceExposureFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This information exposed to the user depends on $@.", source.getNode(), "stack trace information" diff --git a/javascript/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected b/javascript/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected index d649d3b8a64..4a14ef0aaa6 100644 --- a/javascript/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected +++ b/javascript/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected @@ -1,33 +1,22 @@ -nodes -| node.js:8:10:8:12 | err | -| node.js:8:10:8:12 | err | -| node.js:11:13:11:15 | err | -| node.js:11:13:11:21 | err.stack | -| node.js:11:13:11:21 | err.stack | -| tst.js:6:12:6:12 | e | -| tst.js:6:12:6:12 | e | -| tst.js:7:13:7:13 | e | -| tst.js:7:13:7:13 | e | -| tst.js:8:15:8:15 | e | -| tst.js:16:20:16:20 | e | -| tst.js:17:11:17:11 | e | -| tst.js:17:11:17:17 | e.stack | -| tst.js:17:11:17:17 | e.stack | edges | node.js:8:10:8:12 | err | node.js:11:13:11:15 | err | -| node.js:8:10:8:12 | err | node.js:11:13:11:15 | err | -| node.js:11:13:11:15 | err | node.js:11:13:11:21 | err.stack | | node.js:11:13:11:15 | err | node.js:11:13:11:21 | err.stack | | tst.js:6:12:6:12 | e | tst.js:7:13:7:13 | e | -| tst.js:6:12:6:12 | e | tst.js:7:13:7:13 | e | -| tst.js:6:12:6:12 | e | tst.js:7:13:7:13 | e | -| tst.js:6:12:6:12 | e | tst.js:7:13:7:13 | e | -| tst.js:6:12:6:12 | e | tst.js:8:15:8:15 | e | | tst.js:6:12:6:12 | e | tst.js:8:15:8:15 | e | | tst.js:8:15:8:15 | e | tst.js:16:20:16:20 | e | | tst.js:16:20:16:20 | e | tst.js:17:11:17:11 | e | | tst.js:17:11:17:11 | e | tst.js:17:11:17:17 | e.stack | -| tst.js:17:11:17:11 | e | tst.js:17:11:17:17 | e.stack | +nodes +| node.js:8:10:8:12 | err | semmle.label | err | +| node.js:11:13:11:15 | err | semmle.label | err | +| node.js:11:13:11:21 | err.stack | semmle.label | err.stack | +| tst.js:6:12:6:12 | e | semmle.label | e | +| tst.js:7:13:7:13 | e | semmle.label | e | +| tst.js:8:15:8:15 | e | semmle.label | e | +| tst.js:16:20:16:20 | e | semmle.label | e | +| tst.js:17:11:17:11 | e | semmle.label | e | +| tst.js:17:11:17:17 | e.stack | semmle.label | e.stack | +subpaths #select | node.js:11:13:11:21 | err.stack | node.js:8:10:8:12 | err | node.js:11:13:11:21 | err.stack | This information exposed to the user depends on $@. | node.js:8:10:8:12 | err | stack trace information | | tst.js:7:13:7:13 | e | tst.js:6:12:6:12 | e | tst.js:7:13:7:13 | e | This information exposed to the user depends on $@. | tst.js:6:12:6:12 | e | stack trace information | From 51624c02a2f4149eb2096bb3a72dc5b3f6f5c641 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:23:36 +0200 Subject: [PATCH 092/514] JS: Port TaintedFormatString --- .../dataflow/TaintedFormatStringQuery.qll | 18 ++- .../Security/CWE-134/TaintedFormatString.ql | 6 +- .../CWE-134/TaintedFormatString.expected | 103 ++++-------------- 3 files changed, 42 insertions(+), 85 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringQuery.qll index 0475999ed3c..b10088af82e 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringQuery.qll @@ -13,7 +13,23 @@ private import TaintedFormatStringCustomizations::TaintedFormatString /** * A taint-tracking configuration for format injections. */ -class Configuration extends TaintTracking::Configuration { +module TaintedFormatStringConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint-tracking for format injections. + */ +module TaintedFormatStringFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `TaintedFormatStringFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "TaintedFormatString" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-134/TaintedFormatString.ql b/javascript/ql/src/Security/CWE-134/TaintedFormatString.ql index 0a595e7e05f..1f315244cbe 100644 --- a/javascript/ql/src/Security/CWE-134/TaintedFormatString.ql +++ b/javascript/ql/src/Security/CWE-134/TaintedFormatString.ql @@ -12,9 +12,9 @@ import javascript import semmle.javascript.security.dataflow.TaintedFormatStringQuery -import DataFlow::PathGraph +import TaintedFormatStringFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from TaintedFormatStringFlow::PathNode source, TaintedFormatStringFlow::PathNode sink +where TaintedFormatStringFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Format string depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-134/TaintedFormatString.expected b/javascript/ql/test/query-tests/Security/CWE-134/TaintedFormatString.expected index 856b4edf80a..8a3688cad56 100644 --- a/javascript/ql/test/query-tests/Security/CWE-134/TaintedFormatString.expected +++ b/javascript/ql/test/query-tests/Security/CWE-134/TaintedFormatString.expected @@ -1,85 +1,26 @@ -nodes -| tst.js:5:15:5:30 | req.query.format | -| tst.js:5:15:5:30 | req.query.format | -| tst.js:5:15:5:30 | req.query.format | -| tst.js:6:26:6:41 | req.query.format | -| tst.js:6:26:6:41 | req.query.format | -| tst.js:6:26:6:41 | req.query.format | -| tst.js:7:15:7:30 | req.query.format | -| tst.js:7:15:7:30 | req.query.format | -| tst.js:7:15:7:30 | req.query.format | -| tst.js:8:17:8:32 | req.query.format | -| tst.js:8:17:8:32 | req.query.format | -| tst.js:8:17:8:32 | req.query.format | -| tst.js:9:16:9:31 | req.query.format | -| tst.js:9:16:9:31 | req.query.format | -| tst.js:9:16:9:31 | req.query.format | -| tst.js:10:12:10:27 | req.query.format | -| tst.js:10:12:10:27 | req.query.format | -| tst.js:10:12:10:27 | req.query.format | -| tst.js:11:32:11:47 | req.query.format | -| tst.js:11:32:11:47 | req.query.format | -| tst.js:11:32:11:47 | req.query.format | -| tst.js:12:21:12:36 | req.query.format | -| tst.js:12:21:12:36 | req.query.format | -| tst.js:12:21:12:36 | req.query.format | -| tst.js:13:35:13:50 | req.query.format | -| tst.js:13:35:13:50 | req.query.format | -| tst.js:13:35:13:50 | req.query.format | -| tst.js:14:29:14:44 | req.query.format | -| tst.js:14:29:14:44 | req.query.format | -| tst.js:14:29:14:44 | req.query.format | -| tst.js:15:30:15:45 | req.query.format | -| tst.js:15:30:15:45 | req.query.format | -| tst.js:15:30:15:45 | req.query.format | -| tst.js:16:26:16:41 | req.query.format | -| tst.js:16:26:16:41 | req.query.format | -| tst.js:16:26:16:41 | req.query.format | -| tst.js:17:30:17:45 | req.query.format | -| tst.js:17:30:17:45 | req.query.format | -| tst.js:17:30:17:45 | req.query.format | -| tst.js:18:38:18:53 | req.query.format | -| tst.js:18:38:18:53 | req.query.format | -| tst.js:18:38:18:53 | req.query.format | -| tst.js:20:17:20:32 | req.query.format | -| tst.js:20:17:20:32 | req.query.format | -| tst.js:20:17:20:32 | req.query.format | -| tst.js:21:16:21:31 | req.query.format | -| tst.js:21:16:21:31 | req.query.format | -| tst.js:21:16:21:31 | req.query.format | -| tst.js:22:17:22:32 | req.query.format | -| tst.js:22:17:22:32 | req.query.format | -| tst.js:22:17:22:32 | req.query.format | -| tst.js:24:25:24:40 | req.query.format | -| tst.js:24:25:24:40 | req.query.format | -| tst.js:24:25:24:40 | req.query.format | -| tst.js:25:33:25:48 | req.query.format | -| tst.js:25:33:25:48 | req.query.format | -| tst.js:25:33:25:48 | req.query.format | -| tst.js:26:34:26:49 | req.query.format | -| tst.js:26:34:26:49 | req.query.format | -| tst.js:26:34:26:49 | req.query.format | edges -| tst.js:5:15:5:30 | req.query.format | tst.js:5:15:5:30 | req.query.format | -| tst.js:6:26:6:41 | req.query.format | tst.js:6:26:6:41 | req.query.format | -| tst.js:7:15:7:30 | req.query.format | tst.js:7:15:7:30 | req.query.format | -| tst.js:8:17:8:32 | req.query.format | tst.js:8:17:8:32 | req.query.format | -| tst.js:9:16:9:31 | req.query.format | tst.js:9:16:9:31 | req.query.format | -| tst.js:10:12:10:27 | req.query.format | tst.js:10:12:10:27 | req.query.format | -| tst.js:11:32:11:47 | req.query.format | tst.js:11:32:11:47 | req.query.format | -| tst.js:12:21:12:36 | req.query.format | tst.js:12:21:12:36 | req.query.format | -| tst.js:13:35:13:50 | req.query.format | tst.js:13:35:13:50 | req.query.format | -| tst.js:14:29:14:44 | req.query.format | tst.js:14:29:14:44 | req.query.format | -| tst.js:15:30:15:45 | req.query.format | tst.js:15:30:15:45 | req.query.format | -| tst.js:16:26:16:41 | req.query.format | tst.js:16:26:16:41 | req.query.format | -| tst.js:17:30:17:45 | req.query.format | tst.js:17:30:17:45 | req.query.format | -| tst.js:18:38:18:53 | req.query.format | tst.js:18:38:18:53 | req.query.format | -| tst.js:20:17:20:32 | req.query.format | tst.js:20:17:20:32 | req.query.format | -| tst.js:21:16:21:31 | req.query.format | tst.js:21:16:21:31 | req.query.format | -| tst.js:22:17:22:32 | req.query.format | tst.js:22:17:22:32 | req.query.format | -| tst.js:24:25:24:40 | req.query.format | tst.js:24:25:24:40 | req.query.format | -| tst.js:25:33:25:48 | req.query.format | tst.js:25:33:25:48 | req.query.format | -| tst.js:26:34:26:49 | req.query.format | tst.js:26:34:26:49 | req.query.format | +nodes +| tst.js:5:15:5:30 | req.query.format | semmle.label | req.query.format | +| tst.js:6:26:6:41 | req.query.format | semmle.label | req.query.format | +| tst.js:7:15:7:30 | req.query.format | semmle.label | req.query.format | +| tst.js:8:17:8:32 | req.query.format | semmle.label | req.query.format | +| tst.js:9:16:9:31 | req.query.format | semmle.label | req.query.format | +| tst.js:10:12:10:27 | req.query.format | semmle.label | req.query.format | +| tst.js:11:32:11:47 | req.query.format | semmle.label | req.query.format | +| tst.js:12:21:12:36 | req.query.format | semmle.label | req.query.format | +| tst.js:13:35:13:50 | req.query.format | semmle.label | req.query.format | +| tst.js:14:29:14:44 | req.query.format | semmle.label | req.query.format | +| tst.js:15:30:15:45 | req.query.format | semmle.label | req.query.format | +| tst.js:16:26:16:41 | req.query.format | semmle.label | req.query.format | +| tst.js:17:30:17:45 | req.query.format | semmle.label | req.query.format | +| tst.js:18:38:18:53 | req.query.format | semmle.label | req.query.format | +| tst.js:20:17:20:32 | req.query.format | semmle.label | req.query.format | +| tst.js:21:16:21:31 | req.query.format | semmle.label | req.query.format | +| tst.js:22:17:22:32 | req.query.format | semmle.label | req.query.format | +| tst.js:24:25:24:40 | req.query.format | semmle.label | req.query.format | +| tst.js:25:33:25:48 | req.query.format | semmle.label | req.query.format | +| tst.js:26:34:26:49 | req.query.format | semmle.label | req.query.format | +subpaths #select | tst.js:5:15:5:30 | req.query.format | tst.js:5:15:5:30 | req.query.format | tst.js:5:15:5:30 | req.query.format | Format string depends on a $@. | tst.js:5:15:5:30 | req.query.format | user-provided value | | tst.js:6:26:6:41 | req.query.format | tst.js:6:26:6:41 | req.query.format | tst.js:6:26:6:41 | req.query.format | Format string depends on a $@. | tst.js:6:26:6:41 | req.query.format | user-provided value | From 25962a9ba6dbe776cb12a78ecbd66ef4ad785bc1 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:23:45 +0200 Subject: [PATCH 093/514] JS: Port TemplateObjectInjection --- .../dataflow/TemplateObjectInjectionQuery.qll | 41 ++++++- .../CWE-073/TemplateObjectInjection.ql | 7 +- .../CWE-073/TemplateObjectInjection.expected | 116 ++++++------------ 3 files changed, 81 insertions(+), 83 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TemplateObjectInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TemplateObjectInjectionQuery.qll index 22bb06e4af3..0d3c7657810 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TemplateObjectInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TemplateObjectInjectionQuery.qll @@ -14,7 +14,46 @@ private import semmle.javascript.security.TaintedObject /** * A taint tracking configuration for reasoning about template object injection vulnerabilities. */ -class TemplateObjInjectionConfig extends TaintTracking::Configuration { +module TemplateObjectInjectionConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; + + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { + source.(Source).getAFlowLabel() = label + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { + sink instanceof Sink and label = TaintedObject::label() + } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel label) { + TaintTracking::defaultSanitizer(node) and + label.isTaint() + or + node = TaintedObject::SanitizerGuard::getABarrierNode(label) + } + + predicate isAdditionalFlowStep( + DataFlow::Node src, DataFlow::FlowLabel inlbl, DataFlow::Node trg, DataFlow::FlowLabel outlbl + ) { + TaintedObject::step(src, trg, inlbl, outlbl) + or + inlbl.isTaint() and + TaintTracking::defaultTaintStep(src, trg) and + inlbl = outlbl + } +} + +/** + * Taint tracking for reasoning about template object injection vulnerabilities. + */ +module TemplateObjectInjectionFlow = DataFlow::GlobalWithState; + +/** + * DEPRECATED. Use the `TemplateObjectInjectionFlow` module instead. + */ +deprecated class TemplateObjInjectionConfig extends TaintTracking::Configuration { TemplateObjInjectionConfig() { this = "TemplateObjInjectionConfig" } override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { diff --git a/javascript/ql/src/Security/CWE-073/TemplateObjectInjection.ql b/javascript/ql/src/Security/CWE-073/TemplateObjectInjection.ql index 68ef1b12c79..1db62b2e7f0 100644 --- a/javascript/ql/src/Security/CWE-073/TemplateObjectInjection.ql +++ b/javascript/ql/src/Security/CWE-073/TemplateObjectInjection.ql @@ -12,10 +12,11 @@ */ import javascript -import DataFlow::PathGraph import semmle.javascript.security.dataflow.TemplateObjectInjectionQuery +import DataFlow::DeduplicatePathGraph -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from PathNode source, PathNode sink +where + TemplateObjectInjectionFlow::flowPath(source.getAnOriginalPathNode(), sink.getAnOriginalPathNode()) select sink.getNode(), source, sink, "Template object depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-073/TemplateObjectInjection.expected b/javascript/ql/test/query-tests/Security/CWE-073/TemplateObjectInjection.expected index eee80b29592..3ba1cc1d2d9 100644 --- a/javascript/ql/test/query-tests/Security/CWE-073/TemplateObjectInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-073/TemplateObjectInjection.expected @@ -1,112 +1,70 @@ nodes -| routes.js:2:23:2:30 | req.body | -| routes.js:2:23:2:30 | req.body | -| routes.js:2:23:2:30 | req.body | -| tst2.js:6:9:6:46 | bodyParameter | -| tst2.js:6:25:6:32 | req.body | -| tst2.js:6:25:6:32 | req.body | -| tst2.js:6:25:6:46 | req.bod ... rameter | -| tst2.js:7:28:7:40 | bodyParameter | -| tst2.js:7:28:7:40 | bodyParameter | -| tst2.js:26:9:26:46 | bodyParameter | -| tst2.js:26:25:26:32 | req.body | -| tst2.js:26:25:26:32 | req.body | -| tst2.js:26:25:26:46 | req.bod ... rameter | -| tst2.js:27:28:27:40 | bodyParameter | -| tst2.js:27:28:27:40 | bodyParameter | -| tst2.js:34:9:34:46 | bodyParameter | -| tst2.js:34:25:34:32 | req.body | -| tst2.js:34:25:34:32 | req.body | -| tst2.js:34:25:34:46 | req.bod ... rameter | -| tst2.js:35:28:35:40 | bodyParameter | -| tst2.js:35:28:35:40 | bodyParameter | -| tst2.js:42:9:42:46 | bodyParameter | -| tst2.js:42:25:42:32 | req.body | -| tst2.js:42:25:42:32 | req.body | -| tst2.js:42:25:42:46 | req.bod ... rameter | -| tst2.js:43:28:43:40 | bodyParameter | -| tst2.js:43:28:43:40 | bodyParameter | -| tst2.js:51:9:51:46 | bodyParameter | -| tst2.js:51:25:51:32 | req.body | -| tst2.js:51:25:51:32 | req.body | -| tst2.js:51:25:51:46 | req.bod ... rameter | -| tst2.js:52:28:52:40 | bodyParameter | -| tst2.js:52:28:52:40 | bodyParameter | -| tst.js:7:9:7:46 | bodyParameter | -| tst.js:7:25:7:32 | req.body | -| tst.js:7:25:7:32 | req.body | -| tst.js:7:25:7:46 | req.bod ... rameter | -| tst.js:8:9:8:49 | queryParameter | -| tst.js:8:9:8:49 | queryParameter | -| tst.js:8:26:8:49 | req.que ... rameter | -| tst.js:8:26:8:49 | req.que ... rameter | -| tst.js:8:26:8:49 | req.que ... rameter | -| tst.js:10:28:10:40 | bodyParameter | -| tst.js:10:28:10:40 | bodyParameter | -| tst.js:11:28:11:41 | queryParameter | -| tst.js:11:28:11:41 | queryParameter | -| tst.js:20:19:20:32 | queryParameter | -| tst.js:20:19:20:32 | queryParameter | -| tst.js:23:24:23:26 | obj | -| tst.js:23:24:23:26 | obj | -| tst.js:24:28:24:30 | obj | -| tst.js:24:28:24:30 | obj | -| tst.js:26:11:26:24 | str | -| tst.js:26:17:26:19 | obj | -| tst.js:26:17:26:24 | obj + "" | -| tst.js:29:28:29:42 | JSON.parse(str) | -| tst.js:29:28:29:42 | JSON.parse(str) | -| tst.js:29:39:29:41 | str | +| routes.js:2:23:2:30 | req.body | semmle.label | req.body | +| tst2.js:6:9:6:46 | bodyParameter | semmle.label | bodyParameter | +| tst2.js:6:25:6:32 | req.body | semmle.label | req.body | +| tst2.js:6:25:6:46 | req.bod ... rameter | semmle.label | req.bod ... rameter | +| tst2.js:7:28:7:40 | bodyParameter | semmle.label | bodyParameter | +| tst2.js:26:9:26:46 | bodyParameter | semmle.label | bodyParameter | +| tst2.js:26:25:26:32 | req.body | semmle.label | req.body | +| tst2.js:26:25:26:46 | req.bod ... rameter | semmle.label | req.bod ... rameter | +| tst2.js:27:28:27:40 | bodyParameter | semmle.label | bodyParameter | +| tst2.js:34:9:34:46 | bodyParameter | semmle.label | bodyParameter | +| tst2.js:34:25:34:32 | req.body | semmle.label | req.body | +| tst2.js:34:25:34:46 | req.bod ... rameter | semmle.label | req.bod ... rameter | +| tst2.js:35:28:35:40 | bodyParameter | semmle.label | bodyParameter | +| tst2.js:42:9:42:46 | bodyParameter | semmle.label | bodyParameter | +| tst2.js:42:25:42:32 | req.body | semmle.label | req.body | +| tst2.js:42:25:42:46 | req.bod ... rameter | semmle.label | req.bod ... rameter | +| tst2.js:43:28:43:40 | bodyParameter | semmle.label | bodyParameter | +| tst2.js:51:9:51:46 | bodyParameter | semmle.label | bodyParameter | +| tst2.js:51:25:51:32 | req.body | semmle.label | req.body | +| tst2.js:51:25:51:46 | req.bod ... rameter | semmle.label | req.bod ... rameter | +| tst2.js:52:28:52:40 | bodyParameter | semmle.label | bodyParameter | +| tst.js:7:9:7:46 | bodyParameter | semmle.label | bodyParameter | +| tst.js:7:25:7:32 | req.body | semmle.label | req.body | +| tst.js:7:25:7:46 | req.bod ... rameter | semmle.label | req.bod ... rameter | +| tst.js:8:9:8:49 | queryParameter | semmle.label | queryParameter | +| tst.js:8:26:8:49 | req.que ... rameter | semmle.label | req.que ... rameter | +| tst.js:10:28:10:40 | bodyParameter | semmle.label | bodyParameter | +| tst.js:11:28:11:41 | queryParameter | semmle.label | queryParameter | +| tst.js:20:19:20:32 | queryParameter | semmle.label | queryParameter | +| tst.js:23:24:23:26 | obj | semmle.label | obj | +| tst.js:24:28:24:30 | obj | semmle.label | obj | +| tst.js:26:11:26:24 | str | semmle.label | str | +| tst.js:26:17:26:19 | obj | semmle.label | obj | +| tst.js:26:17:26:24 | obj + "" | semmle.label | obj + "" | +| tst.js:29:28:29:42 | JSON.parse(str) | semmle.label | JSON.parse(str) | +| tst.js:29:39:29:41 | str | semmle.label | str | edges -| routes.js:2:23:2:30 | req.body | routes.js:2:23:2:30 | req.body | | tst2.js:6:9:6:46 | bodyParameter | tst2.js:7:28:7:40 | bodyParameter | -| tst2.js:6:9:6:46 | bodyParameter | tst2.js:7:28:7:40 | bodyParameter | -| tst2.js:6:25:6:32 | req.body | tst2.js:6:25:6:46 | req.bod ... rameter | | tst2.js:6:25:6:32 | req.body | tst2.js:6:25:6:46 | req.bod ... rameter | | tst2.js:6:25:6:46 | req.bod ... rameter | tst2.js:6:9:6:46 | bodyParameter | | tst2.js:26:9:26:46 | bodyParameter | tst2.js:27:28:27:40 | bodyParameter | -| tst2.js:26:9:26:46 | bodyParameter | tst2.js:27:28:27:40 | bodyParameter | -| tst2.js:26:25:26:32 | req.body | tst2.js:26:25:26:46 | req.bod ... rameter | | tst2.js:26:25:26:32 | req.body | tst2.js:26:25:26:46 | req.bod ... rameter | | tst2.js:26:25:26:46 | req.bod ... rameter | tst2.js:26:9:26:46 | bodyParameter | | tst2.js:34:9:34:46 | bodyParameter | tst2.js:35:28:35:40 | bodyParameter | -| tst2.js:34:9:34:46 | bodyParameter | tst2.js:35:28:35:40 | bodyParameter | -| tst2.js:34:25:34:32 | req.body | tst2.js:34:25:34:46 | req.bod ... rameter | | tst2.js:34:25:34:32 | req.body | tst2.js:34:25:34:46 | req.bod ... rameter | | tst2.js:34:25:34:46 | req.bod ... rameter | tst2.js:34:9:34:46 | bodyParameter | | tst2.js:42:9:42:46 | bodyParameter | tst2.js:43:28:43:40 | bodyParameter | -| tst2.js:42:9:42:46 | bodyParameter | tst2.js:43:28:43:40 | bodyParameter | -| tst2.js:42:25:42:32 | req.body | tst2.js:42:25:42:46 | req.bod ... rameter | | tst2.js:42:25:42:32 | req.body | tst2.js:42:25:42:46 | req.bod ... rameter | | tst2.js:42:25:42:46 | req.bod ... rameter | tst2.js:42:9:42:46 | bodyParameter | | tst2.js:51:9:51:46 | bodyParameter | tst2.js:52:28:52:40 | bodyParameter | -| tst2.js:51:9:51:46 | bodyParameter | tst2.js:52:28:52:40 | bodyParameter | -| tst2.js:51:25:51:32 | req.body | tst2.js:51:25:51:46 | req.bod ... rameter | | tst2.js:51:25:51:32 | req.body | tst2.js:51:25:51:46 | req.bod ... rameter | | tst2.js:51:25:51:46 | req.bod ... rameter | tst2.js:51:9:51:46 | bodyParameter | | tst.js:7:9:7:46 | bodyParameter | tst.js:10:28:10:40 | bodyParameter | -| tst.js:7:9:7:46 | bodyParameter | tst.js:10:28:10:40 | bodyParameter | -| tst.js:7:25:7:32 | req.body | tst.js:7:25:7:46 | req.bod ... rameter | | tst.js:7:25:7:32 | req.body | tst.js:7:25:7:46 | req.bod ... rameter | | tst.js:7:25:7:46 | req.bod ... rameter | tst.js:7:9:7:46 | bodyParameter | | tst.js:8:9:8:49 | queryParameter | tst.js:11:28:11:41 | queryParameter | -| tst.js:8:9:8:49 | queryParameter | tst.js:11:28:11:41 | queryParameter | -| tst.js:8:9:8:49 | queryParameter | tst.js:20:19:20:32 | queryParameter | | tst.js:8:9:8:49 | queryParameter | tst.js:20:19:20:32 | queryParameter | | tst.js:8:26:8:49 | req.que ... rameter | tst.js:8:9:8:49 | queryParameter | -| tst.js:8:26:8:49 | req.que ... rameter | tst.js:8:9:8:49 | queryParameter | -| tst.js:8:26:8:49 | req.que ... rameter | tst.js:8:9:8:49 | queryParameter | -| tst.js:8:26:8:49 | req.que ... rameter | tst.js:8:9:8:49 | queryParameter | | tst.js:20:19:20:32 | queryParameter | tst.js:23:24:23:26 | obj | -| tst.js:20:19:20:32 | queryParameter | tst.js:23:24:23:26 | obj | -| tst.js:23:24:23:26 | obj | tst.js:24:28:24:30 | obj | | tst.js:23:24:23:26 | obj | tst.js:24:28:24:30 | obj | | tst.js:23:24:23:26 | obj | tst.js:26:17:26:19 | obj | | tst.js:26:11:26:24 | str | tst.js:29:39:29:41 | str | | tst.js:26:17:26:19 | obj | tst.js:26:17:26:24 | obj + "" | | tst.js:26:17:26:24 | obj + "" | tst.js:26:11:26:24 | str | | tst.js:29:39:29:41 | str | tst.js:29:28:29:42 | JSON.parse(str) | -| tst.js:29:39:29:41 | str | tst.js:29:28:29:42 | JSON.parse(str) | +subpaths #select | routes.js:2:23:2:30 | req.body | routes.js:2:23:2:30 | req.body | routes.js:2:23:2:30 | req.body | Template object depends on a $@. | routes.js:2:23:2:30 | req.body | user-provided value | | tst2.js:7:28:7:40 | bodyParameter | tst2.js:6:25:6:32 | req.body | tst2.js:7:28:7:40 | bodyParameter | Template object depends on a $@. | tst2.js:6:25:6:32 | req.body | user-provided value | From 5af608c93719cedaac9656a0f0aa2e02de75de9c Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:24:00 +0200 Subject: [PATCH 094/514] JS: Port TypeConfusionThroughParameterTampering --- ...hroughParameterTamperingCustomizations.qll | 15 +++ ...onfusionThroughParameterTamperingQuery.qll | 78 +++++++----- .../TypeConfusionThroughParameterTampering.ql | 6 +- ...onfusionThroughParameterTampering.expected | 113 +++++++++--------- 4 files changed, 120 insertions(+), 92 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingCustomizations.qll index ad608017115..6857ab308a4 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingCustomizations.qll @@ -23,6 +23,21 @@ module TypeConfusionThroughParameterTampering { */ abstract class Barrier extends DataFlow::Node { } + /** + * A barrier guard for type confusion for HTTP request inputs. + */ + 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() } + } + + /** 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) } + } + /** * An HTTP request parameter that the user controls the type of. * diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingQuery.qll index 9cc09987343..a490d11a429 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingQuery.qll @@ -13,19 +13,61 @@ private import semmle.javascript.dataflow.InferredTypes import TypeConfusionThroughParameterTamperingCustomizations::TypeConfusionThroughParameterTampering /** - * A taint tracking configuration for type confusion for HTTP request inputs. + * Data flow configuration for type confusion for HTTP request inputs. */ -class Configuration extends DataFlow::Configuration { - Configuration() { this = "TypeConfusionThroughParameterTampering" } +module TypeConfusionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink instanceof Sink and sink.analyze().getAType() = TTString() and sink.analyze().getAType() = TTObject() } + predicate isBarrier(DataFlow::Node node) { + node instanceof Barrier or node = DataFlow::MakeBarrierGuard::getABarrierNode() + } +} + +/** + * Data flow for type confusion for HTTP request inputs. + */ +module TypeConfusionFlow = DataFlow::Global; + +private class TypeOfTestBarrier extends BarrierGuardLegacy, DataFlow::ValueNode { + override EqualityTest astNode; + + TypeOfTestBarrier() { TaintTracking::isTypeofGuard(astNode, _, _) } + + override predicate blocksExpr(boolean outcome, Expr e) { + exists(string tag | + TaintTracking::isTypeofGuard(astNode, e, tag) and + if tag = ["string", "object"] + then outcome = [true, false] // separation between string/array removes type confusion in both branches + else outcome = astNode.getPolarity() // block flow to branch where value is neither string nor array + ) + } +} + +private class IsArrayBarrier extends BarrierGuardLegacy, DataFlow::CallNode { + IsArrayBarrier() { this = DataFlow::globalVarRef("Array").getAMemberCall("isArray") } + + override predicate blocksExpr(boolean outcome, Expr e) { + e = this.getArgument(0).asExpr() and + outcome = [true, false] // separation between string/array removes type confusion in both branches + } +} + +/** + * DEPRECATED. Use the `TypeConfusionFlow` module instead. + */ +deprecated class Configuration extends DataFlow::Configuration { + Configuration() { this = "TypeConfusionThroughParameterTampering" } + + override predicate isSource(DataFlow::Node source) { TypeConfusionConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TypeConfusionConfig::isSink(sink) } + override predicate isBarrier(DataFlow::Node node) { super.isBarrier(node) or @@ -37,27 +79,3 @@ class Configuration extends DataFlow::Configuration { guard instanceof IsArrayBarrier } } - -private class TypeOfTestBarrier extends DataFlow::BarrierGuardNode, DataFlow::ValueNode { - override EqualityTest astNode; - - TypeOfTestBarrier() { TaintTracking::isTypeofGuard(astNode, _, _) } - - override predicate blocks(boolean outcome, Expr e) { - exists(string tag | - TaintTracking::isTypeofGuard(astNode, e, tag) and - if tag = ["string", "object"] - then outcome = [true, false] // separation between string/array removes type confusion in both branches - else outcome = astNode.getPolarity() // block flow to branch where value is neither string nor array - ) - } -} - -private class IsArrayBarrier extends DataFlow::BarrierGuardNode, DataFlow::CallNode { - IsArrayBarrier() { this = DataFlow::globalVarRef("Array").getAMemberCall("isArray") } - - override predicate blocks(boolean outcome, Expr e) { - e = this.getArgument(0).asExpr() and - outcome = [true, false] // separation between string/array removes type confusion in both branches - } -} diff --git a/javascript/ql/src/Security/CWE-843/TypeConfusionThroughParameterTampering.ql b/javascript/ql/src/Security/CWE-843/TypeConfusionThroughParameterTampering.ql index 795ad48409c..5887cb1db37 100644 --- a/javascript/ql/src/Security/CWE-843/TypeConfusionThroughParameterTampering.ql +++ b/javascript/ql/src/Security/CWE-843/TypeConfusionThroughParameterTampering.ql @@ -12,10 +12,10 @@ import javascript import semmle.javascript.security.dataflow.TypeConfusionThroughParameterTamperingQuery -import DataFlow::PathGraph +import TypeConfusionFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from TypeConfusionFlow::PathNode source, TypeConfusionFlow::PathNode sink +where TypeConfusionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Potential type confusion as $@ may be either an array or a string.", source.getNode(), "this HTTP request parameter" diff --git a/javascript/ql/test/query-tests/Security/CWE-843/TypeConfusionThroughParameterTampering.expected b/javascript/ql/test/query-tests/Security/CWE-843/TypeConfusionThroughParameterTampering.expected index 13c97e3f327..d0234ead079 100644 --- a/javascript/ql/test/query-tests/Security/CWE-843/TypeConfusionThroughParameterTampering.expected +++ b/javascript/ql/test/query-tests/Security/CWE-843/TypeConfusionThroughParameterTampering.expected @@ -1,81 +1,76 @@ -nodes -| tst.js:5:9:5:27 | foo | -| tst.js:5:15:5:27 | req.query.foo | -| tst.js:5:15:5:27 | req.query.foo | -| tst.js:6:5:6:7 | foo | -| tst.js:6:5:6:7 | foo | -| tst.js:8:5:8:7 | foo | -| tst.js:8:5:8:7 | foo | -| tst.js:11:9:11:11 | foo | -| tst.js:11:9:11:11 | foo | -| tst.js:14:16:14:18 | bar | -| tst.js:15:9:15:11 | bar | -| tst.js:15:9:15:11 | bar | -| tst.js:17:7:17:9 | foo | -| tst.js:27:5:27:7 | foo | -| tst.js:27:5:27:7 | foo | -| tst.js:28:5:28:7 | foo | -| tst.js:28:5:28:7 | foo | -| tst.js:45:9:45:35 | foo | -| tst.js:45:15:45:35 | ctx.req ... ery.foo | -| tst.js:45:15:45:35 | ctx.req ... ery.foo | -| tst.js:46:5:46:7 | foo | -| tst.js:46:5:46:7 | foo | -| tst.js:77:25:77:38 | req.query.path | -| tst.js:77:25:77:38 | req.query.path | -| tst.js:80:23:80:23 | p | -| tst.js:81:9:81:9 | p | -| tst.js:81:9:81:9 | p | -| tst.js:82:9:82:9 | p | -| tst.js:82:9:82:9 | p | -| tst.js:90:5:90:12 | data.foo | -| tst.js:90:5:90:12 | data.foo | -| tst.js:90:5:90:12 | data.foo | -| tst.js:92:9:92:16 | data.foo | -| tst.js:92:9:92:16 | data.foo | -| tst.js:92:9:92:16 | data.foo | -| tst.js:98:9:98:16 | data.foo | -| tst.js:98:9:98:16 | data.foo | -| tst.js:98:9:98:16 | data.foo | -| tst.js:103:9:103:29 | data | -| tst.js:103:16:103:29 | req.query.data | -| tst.js:103:16:103:29 | req.query.data | -| tst.js:104:5:104:8 | data | -| tst.js:104:5:104:8 | data | edges | tst.js:5:9:5:27 | foo | tst.js:6:5:6:7 | foo | | tst.js:5:9:5:27 | foo | tst.js:6:5:6:7 | foo | | tst.js:5:9:5:27 | foo | tst.js:8:5:8:7 | foo | | tst.js:5:9:5:27 | foo | tst.js:8:5:8:7 | foo | -| tst.js:5:9:5:27 | foo | tst.js:11:9:11:11 | foo | -| tst.js:5:9:5:27 | foo | tst.js:11:9:11:11 | foo | | tst.js:5:9:5:27 | foo | tst.js:17:7:17:9 | foo | +| tst.js:5:9:5:27 | foo | tst.js:21:5:21:7 | foo | +| tst.js:5:9:5:27 | foo | tst.js:22:5:22:7 | foo | +| tst.js:5:9:5:27 | foo | tst.js:23:5:23:7 | foo | +| tst.js:5:9:5:27 | foo | tst.js:25:5:25:7 | foo | | tst.js:5:9:5:27 | foo | tst.js:27:5:27:7 | foo | | tst.js:5:9:5:27 | foo | tst.js:27:5:27:7 | foo | | tst.js:5:9:5:27 | foo | tst.js:28:5:28:7 | foo | -| tst.js:5:9:5:27 | foo | tst.js:28:5:28:7 | foo | | tst.js:5:15:5:27 | req.query.foo | tst.js:5:9:5:27 | foo | -| tst.js:5:15:5:27 | req.query.foo | tst.js:5:9:5:27 | foo | -| tst.js:14:16:14:18 | bar | tst.js:15:9:15:11 | bar | +| tst.js:6:5:6:7 | foo | tst.js:8:5:8:7 | foo | +| tst.js:6:5:6:7 | foo | tst.js:8:5:8:7 | foo | +| tst.js:8:5:8:7 | foo | tst.js:10:5:12:5 | functio ... K\\n } [foo] | +| tst.js:8:5:8:7 | foo | tst.js:17:7:17:9 | foo | +| tst.js:10:5:12:5 | functio ... K\\n } [foo] | tst.js:10:14:10:14 | f [foo] | +| tst.js:10:5:12:5 | functio ... K\\n } [foo] | tst.js:11:9:11:11 | foo | +| tst.js:10:14:10:14 | f [foo] | tst.js:39:12:39:12 | f [foo] | | tst.js:14:16:14:18 | bar | tst.js:15:9:15:11 | bar | | tst.js:17:7:17:9 | foo | tst.js:14:16:14:18 | bar | -| tst.js:45:9:45:35 | foo | tst.js:46:5:46:7 | foo | +| tst.js:17:7:17:9 | foo | tst.js:21:5:21:7 | foo | +| tst.js:21:5:21:7 | foo | tst.js:22:5:22:7 | foo | +| tst.js:22:5:22:7 | foo | tst.js:23:5:23:7 | foo | +| tst.js:23:5:23:7 | foo | tst.js:25:5:25:7 | foo | +| tst.js:25:5:25:7 | foo | tst.js:27:5:27:7 | foo | +| tst.js:25:5:25:7 | foo | tst.js:27:5:27:7 | foo | +| tst.js:27:5:27:7 | foo | tst.js:28:5:28:7 | foo | +| tst.js:39:12:39:12 | f [foo] | tst.js:11:9:11:11 | foo | | tst.js:45:9:45:35 | foo | tst.js:46:5:46:7 | foo | | tst.js:45:15:45:35 | ctx.req ... ery.foo | tst.js:45:9:45:35 | foo | -| tst.js:45:15:45:35 | ctx.req ... ery.foo | tst.js:45:9:45:35 | foo | -| tst.js:77:25:77:38 | req.query.path | tst.js:80:23:80:23 | p | | tst.js:77:25:77:38 | req.query.path | tst.js:80:23:80:23 | p | | tst.js:80:23:80:23 | p | tst.js:81:9:81:9 | p | -| tst.js:80:23:80:23 | p | tst.js:81:9:81:9 | p | | tst.js:80:23:80:23 | p | tst.js:82:9:82:9 | p | -| tst.js:80:23:80:23 | p | tst.js:82:9:82:9 | p | -| tst.js:90:5:90:12 | data.foo | tst.js:90:5:90:12 | data.foo | -| tst.js:92:9:92:16 | data.foo | tst.js:92:9:92:16 | data.foo | -| tst.js:98:9:98:16 | data.foo | tst.js:98:9:98:16 | data.foo | -| tst.js:103:9:103:29 | data | tst.js:104:5:104:8 | data | | tst.js:103:9:103:29 | data | tst.js:104:5:104:8 | data | | tst.js:103:16:103:29 | req.query.data | tst.js:103:9:103:29 | data | -| tst.js:103:16:103:29 | req.query.data | tst.js:103:9:103:29 | data | +nodes +| tst.js:5:9:5:27 | foo | semmle.label | foo | +| tst.js:5:15:5:27 | req.query.foo | semmle.label | req.query.foo | +| tst.js:6:5:6:7 | foo | semmle.label | foo | +| tst.js:6:5:6:7 | foo | semmle.label | foo | +| tst.js:8:5:8:7 | foo | semmle.label | foo | +| tst.js:8:5:8:7 | foo | semmle.label | foo | +| tst.js:10:5:12:5 | functio ... K\\n } [foo] | semmle.label | functio ... K\\n } [foo] | +| tst.js:10:14:10:14 | f [foo] | semmle.label | f [foo] | +| tst.js:11:9:11:11 | foo | semmle.label | foo | +| tst.js:14:16:14:18 | bar | semmle.label | bar | +| tst.js:15:9:15:11 | bar | semmle.label | bar | +| tst.js:17:7:17:9 | foo | semmle.label | foo | +| tst.js:21:5:21:7 | foo | semmle.label | foo | +| tst.js:22:5:22:7 | foo | semmle.label | foo | +| tst.js:23:5:23:7 | foo | semmle.label | foo | +| tst.js:25:5:25:7 | foo | semmle.label | foo | +| tst.js:27:5:27:7 | foo | semmle.label | foo | +| tst.js:27:5:27:7 | foo | semmle.label | foo | +| tst.js:28:5:28:7 | foo | semmle.label | foo | +| tst.js:39:12:39:12 | f [foo] | semmle.label | f [foo] | +| tst.js:45:9:45:35 | foo | semmle.label | foo | +| tst.js:45:15:45:35 | ctx.req ... ery.foo | semmle.label | ctx.req ... ery.foo | +| tst.js:46:5:46:7 | foo | semmle.label | foo | +| tst.js:77:25:77:38 | req.query.path | semmle.label | req.query.path | +| tst.js:80:23:80:23 | p | semmle.label | p | +| tst.js:81:9:81:9 | p | semmle.label | p | +| tst.js:82:9:82:9 | p | semmle.label | p | +| tst.js:90:5:90:12 | data.foo | semmle.label | data.foo | +| tst.js:92:9:92:16 | data.foo | semmle.label | data.foo | +| tst.js:98:9:98:16 | data.foo | semmle.label | data.foo | +| tst.js:103:9:103:29 | data | semmle.label | data | +| tst.js:103:16:103:29 | req.query.data | semmle.label | req.query.data | +| tst.js:104:5:104:8 | data | semmle.label | data | +subpaths #select | tst.js:6:5:6:7 | foo | tst.js:5:15:5:27 | req.query.foo | tst.js:6:5:6:7 | foo | Potential type confusion as $@ may be either an array or a string. | tst.js:5:15:5:27 | req.query.foo | this HTTP request parameter | | tst.js:8:5:8:7 | foo | tst.js:5:15:5:27 | req.query.foo | tst.js:8:5:8:7 | foo | Potential type confusion as $@ may be either an array or a string. | tst.js:5:15:5:27 | req.query.foo | this HTTP request parameter | From 32022ccbdaebbeb9f744f5c86c9b38eb88769d94 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:24:48 +0200 Subject: [PATCH 095/514] JS: Port UnsafeCodeConstruction --- .../dataflow/UnsafeCodeConstruction.qll | 29 +++- .../CWE-094/UnsafeCodeConstruction.ql | 8 +- .../UnsafeCodeConstruction.expected | 127 ++---------------- 3 files changed, 43 insertions(+), 121 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeCodeConstruction.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeCodeConstruction.qll index 2c45483f0db..5e2c3d8f195 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeCodeConstruction.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeCodeConstruction.qll @@ -19,7 +19,34 @@ module UnsafeCodeConstruction { /** * A taint-tracking configuration for reasoning about unsafe code constructed from library input. */ - class Configuration extends TaintTracking::Configuration { + module UnsafeCodeConstructionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof CodeInjection::Sanitizer } + + predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg) { + // HTML sanitizers are insufficient protection against code injection + src = trg.(HtmlSanitizerCall).getInput() + or + none() + // TODO: localFieldStep is too expensive with dataflow2 + // DataFlow::localFieldStep(pred, succ) + } + + DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext } + } + + /** + * Taint-tracking for reasoning about unsafe code constructed from library input. + */ + module UnsafeCodeConstructionFlow = TaintTracking::Global; + + /** + * DEPRECATED. Use the `UnsafeCodeConstructionFlow` module instead. + */ + deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "UnsafeCodeConstruction" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-094/UnsafeCodeConstruction.ql b/javascript/ql/src/Security/CWE-094/UnsafeCodeConstruction.ql index 2adf02114b9..e68a482f8d2 100644 --- a/javascript/ql/src/Security/CWE-094/UnsafeCodeConstruction.ql +++ b/javascript/ql/src/Security/CWE-094/UnsafeCodeConstruction.ql @@ -14,11 +14,13 @@ */ import javascript -import DataFlow::PathGraph import semmle.javascript.security.dataflow.UnsafeCodeConstruction::UnsafeCodeConstruction +import UnsafeCodeConstructionFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Sink sinkNode -where cfg.hasFlowPath(source, sink) and sinkNode = sink.getNode() +from + UnsafeCodeConstructionFlow::PathNode source, UnsafeCodeConstructionFlow::PathNode sink, + Sink sinkNode +where UnsafeCodeConstructionFlow::flowPath(source, sink) and sinkNode = sink.getNode() select sink.getNode(), source, sink, "This " + sinkNode.getSinkType() + " which depends on $@ is later $@.", source.getNode(), "library input", sinkNode.getCodeSink(), "interpreted as code" diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected index 725c600ecaa..a54acabbb64 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected @@ -1,127 +1,20 @@ -nodes -| lib/index.js:1:35:1:38 | data | -| lib/index.js:1:35:1:38 | data | -| lib/index.js:2:21:2:24 | data | -| lib/index.js:2:21:2:24 | data | -| lib/index.js:5:35:5:38 | name | -| lib/index.js:5:35:5:38 | name | -| lib/index.js:6:26:6:29 | name | -| lib/index.js:6:26:6:29 | name | -| lib/index.js:13:38:13:41 | data | -| lib/index.js:13:38:13:41 | data | -| lib/index.js:14:21:14:24 | data | -| lib/index.js:14:21:14:24 | data | -| lib/index.js:19:26:19:29 | data | -| lib/index.js:19:26:19:29 | data | -| lib/index.js:22:7:22:10 | data | -| lib/index.js:22:7:22:10 | data | -| lib/index.js:41:32:41:35 | opts | -| lib/index.js:41:32:41:35 | opts | -| lib/index.js:42:3:42:19 | opts | -| lib/index.js:42:10:42:13 | opts | -| lib/index.js:42:10:42:19 | opts \|\| {} | -| lib/index.js:44:21:44:24 | opts | -| lib/index.js:44:21:44:32 | opts.varName | -| lib/index.js:51:21:51:32 | opts.varName | -| lib/index.js:51:21:51:32 | opts.varName | -| lib/index.js:51:21:51:32 | opts.varName | -| lib/index.js:86:15:86:19 | taint | -| lib/index.js:86:15:86:19 | taint | -| lib/index.js:87:18:87:22 | taint | -| lib/index.js:89:36:89:40 | taint | -| lib/index.js:93:32:93:36 | taint | -| lib/index.js:98:30:98:34 | taint | -| lib/index.js:103:21:103:47 | this.op ... dOption | -| lib/index.js:103:21:103:47 | this.op ... dOption | -| lib/index.js:104:21:104:47 | this.op ... dOption | -| lib/index.js:104:21:104:47 | this.op ... dOption | -| lib/index.js:105:21:105:47 | this.op ... dOption | -| lib/index.js:105:21:105:47 | this.op ... dOption | -| lib/index.js:106:21:106:30 | this.taint | -| lib/index.js:106:21:106:30 | this.taint | -| lib/index.js:112:17:112:21 | taint | -| lib/index.js:112:17:112:21 | taint | -| lib/index.js:113:20:113:24 | taint | -| lib/index.js:115:38:115:42 | taint | -| lib/index.js:121:34:121:38 | taint | -| lib/index.js:129:32:129:36 | taint | -| lib/index.js:135:23:135:49 | this.op ... dOption | -| lib/index.js:135:23:135:49 | this.op ... dOption | -| lib/index.js:136:23:136:49 | this.op ... dOption | -| lib/index.js:136:23:136:49 | this.op ... dOption | -| lib/index.js:137:23:137:49 | this.op ... dOption | -| lib/index.js:137:23:137:49 | this.op ... dOption | -| lib/index.js:138:23:138:32 | this.taint | -| lib/index.js:138:23:138:32 | this.taint | edges | lib/index.js:1:35:1:38 | data | lib/index.js:2:21:2:24 | data | -| lib/index.js:1:35:1:38 | data | lib/index.js:2:21:2:24 | data | -| lib/index.js:1:35:1:38 | data | lib/index.js:2:21:2:24 | data | -| lib/index.js:1:35:1:38 | data | lib/index.js:2:21:2:24 | data | -| lib/index.js:5:35:5:38 | name | lib/index.js:6:26:6:29 | name | -| lib/index.js:5:35:5:38 | name | lib/index.js:6:26:6:29 | name | -| lib/index.js:5:35:5:38 | name | lib/index.js:6:26:6:29 | name | | lib/index.js:5:35:5:38 | name | lib/index.js:6:26:6:29 | name | | lib/index.js:13:38:13:41 | data | lib/index.js:14:21:14:24 | data | -| lib/index.js:13:38:13:41 | data | lib/index.js:14:21:14:24 | data | -| lib/index.js:13:38:13:41 | data | lib/index.js:14:21:14:24 | data | -| lib/index.js:13:38:13:41 | data | lib/index.js:14:21:14:24 | data | | lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | -| lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | -| lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | -| lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | -| lib/index.js:41:32:41:35 | opts | lib/index.js:42:10:42:13 | opts | -| lib/index.js:41:32:41:35 | opts | lib/index.js:42:10:42:13 | opts | -| lib/index.js:42:3:42:19 | opts | lib/index.js:44:21:44:24 | opts | -| lib/index.js:42:10:42:13 | opts | lib/index.js:42:10:42:19 | opts \|\| {} | -| lib/index.js:42:10:42:19 | opts \|\| {} | lib/index.js:42:3:42:19 | opts | -| lib/index.js:44:21:44:24 | opts | lib/index.js:44:21:44:32 | opts.varName | -| lib/index.js:44:21:44:32 | opts.varName | lib/index.js:51:21:51:32 | opts.varName | -| lib/index.js:44:21:44:32 | opts.varName | lib/index.js:51:21:51:32 | opts.varName | -| lib/index.js:44:21:44:32 | opts.varName | lib/index.js:51:21:51:32 | opts.varName | -| lib/index.js:86:15:86:19 | taint | lib/index.js:87:18:87:22 | taint | -| lib/index.js:86:15:86:19 | taint | lib/index.js:87:18:87:22 | taint | -| lib/index.js:86:15:86:19 | taint | lib/index.js:89:36:89:40 | taint | -| lib/index.js:86:15:86:19 | taint | lib/index.js:89:36:89:40 | taint | -| lib/index.js:86:15:86:19 | taint | lib/index.js:93:32:93:36 | taint | -| lib/index.js:86:15:86:19 | taint | lib/index.js:93:32:93:36 | taint | -| lib/index.js:86:15:86:19 | taint | lib/index.js:98:30:98:34 | taint | -| lib/index.js:86:15:86:19 | taint | lib/index.js:98:30:98:34 | taint | -| lib/index.js:87:18:87:22 | taint | lib/index.js:106:21:106:30 | this.taint | -| lib/index.js:87:18:87:22 | taint | lib/index.js:106:21:106:30 | this.taint | -| lib/index.js:89:36:89:40 | taint | lib/index.js:103:21:103:47 | this.op ... dOption | -| lib/index.js:89:36:89:40 | taint | lib/index.js:103:21:103:47 | this.op ... dOption | -| lib/index.js:93:32:93:36 | taint | lib/index.js:104:21:104:47 | this.op ... dOption | -| lib/index.js:93:32:93:36 | taint | lib/index.js:104:21:104:47 | this.op ... dOption | -| lib/index.js:98:30:98:34 | taint | lib/index.js:105:21:105:47 | this.op ... dOption | -| lib/index.js:98:30:98:34 | taint | lib/index.js:105:21:105:47 | this.op ... dOption | -| lib/index.js:112:17:112:21 | taint | lib/index.js:113:20:113:24 | taint | -| lib/index.js:112:17:112:21 | taint | lib/index.js:113:20:113:24 | taint | -| lib/index.js:112:17:112:21 | taint | lib/index.js:115:38:115:42 | taint | -| lib/index.js:112:17:112:21 | taint | lib/index.js:115:38:115:42 | taint | -| lib/index.js:112:17:112:21 | taint | lib/index.js:121:34:121:38 | taint | -| lib/index.js:112:17:112:21 | taint | lib/index.js:121:34:121:38 | taint | -| lib/index.js:112:17:112:21 | taint | lib/index.js:129:32:129:36 | taint | -| lib/index.js:112:17:112:21 | taint | lib/index.js:129:32:129:36 | taint | -| lib/index.js:113:20:113:24 | taint | lib/index.js:138:23:138:32 | this.taint | -| lib/index.js:113:20:113:24 | taint | lib/index.js:138:23:138:32 | this.taint | -| lib/index.js:115:38:115:42 | taint | lib/index.js:135:23:135:49 | this.op ... dOption | -| lib/index.js:115:38:115:42 | taint | lib/index.js:135:23:135:49 | this.op ... dOption | -| lib/index.js:121:34:121:38 | taint | lib/index.js:136:23:136:49 | this.op ... dOption | -| lib/index.js:121:34:121:38 | taint | lib/index.js:136:23:136:49 | this.op ... dOption | -| lib/index.js:129:32:129:36 | taint | lib/index.js:137:23:137:49 | this.op ... dOption | -| lib/index.js:129:32:129:36 | taint | lib/index.js:137:23:137:49 | this.op ... dOption | +nodes +| lib/index.js:1:35:1:38 | data | semmle.label | data | +| lib/index.js:2:21:2:24 | data | semmle.label | data | +| lib/index.js:5:35:5:38 | name | semmle.label | name | +| lib/index.js:6:26:6:29 | name | semmle.label | name | +| lib/index.js:13:38:13:41 | data | semmle.label | data | +| lib/index.js:14:21:14:24 | data | semmle.label | data | +| lib/index.js:19:26:19:29 | data | semmle.label | data | +| lib/index.js:22:7:22:10 | data | semmle.label | data | +subpaths #select | lib/index.js:2:21:2:24 | data | lib/index.js:1:35:1:38 | data | lib/index.js:2:21:2:24 | data | This string concatenation which depends on $@ is later $@. | lib/index.js:1:35:1:38 | data | library input | lib/index.js:2:15:2:30 | "(" + data + ")" | interpreted as code | | lib/index.js:6:26:6:29 | name | lib/index.js:5:35:5:38 | name | lib/index.js:6:26:6:29 | name | This string concatenation which depends on $@ is later $@. | lib/index.js:5:35:5:38 | name | library input | lib/index.js:6:17:6:29 | "obj." + name | interpreted as code | | lib/index.js:14:21:14:24 | data | lib/index.js:13:38:13:41 | data | lib/index.js:14:21:14:24 | data | This string concatenation which depends on $@ is later $@. | lib/index.js:13:38:13:41 | data | library input | lib/index.js:14:15:14:30 | "(" + data + ")" | interpreted as code | | lib/index.js:22:7:22:10 | data | lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | This string concatenation which depends on $@ is later $@. | lib/index.js:19:26:19:29 | data | library input | lib/index.js:25:24:25:26 | str | interpreted as code | -| lib/index.js:51:21:51:32 | opts.varName | lib/index.js:41:32:41:35 | opts | lib/index.js:51:21:51:32 | opts.varName | This string concatenation which depends on $@ is later $@. | lib/index.js:41:32:41:35 | opts | library input | lib/index.js:51:10:51:52 | " var ... ing();" | interpreted as code | -| lib/index.js:103:21:103:47 | this.op ... dOption | lib/index.js:86:15:86:19 | taint | lib/index.js:103:21:103:47 | this.op ... dOption | This string concatenation which depends on $@ is later $@. | lib/index.js:86:15:86:19 | taint | library input | lib/index.js:103:10:103:67 | " var ... ing();" | interpreted as code | -| lib/index.js:104:21:104:47 | this.op ... dOption | lib/index.js:86:15:86:19 | taint | lib/index.js:104:21:104:47 | this.op ... dOption | This string concatenation which depends on $@ is later $@. | lib/index.js:86:15:86:19 | taint | library input | lib/index.js:104:10:104:67 | " var ... ing();" | interpreted as code | -| lib/index.js:105:21:105:47 | this.op ... dOption | lib/index.js:86:15:86:19 | taint | lib/index.js:105:21:105:47 | this.op ... dOption | This string concatenation which depends on $@ is later $@. | lib/index.js:86:15:86:19 | taint | library input | lib/index.js:105:10:105:67 | " var ... ing();" | interpreted as code | -| lib/index.js:106:21:106:30 | this.taint | lib/index.js:86:15:86:19 | taint | lib/index.js:106:21:106:30 | this.taint | This string concatenation which depends on $@ is later $@. | lib/index.js:86:15:86:19 | taint | library input | lib/index.js:106:10:106:50 | " var ... ing();" | interpreted as code | -| lib/index.js:135:23:135:49 | this.op ... dOption | lib/index.js:112:17:112:21 | taint | lib/index.js:135:23:135:49 | this.op ... dOption | This string concatenation which depends on $@ is later $@. | lib/index.js:112:17:112:21 | taint | library input | lib/index.js:135:12:135:69 | " var ... ing();" | interpreted as code | -| lib/index.js:136:23:136:49 | this.op ... dOption | lib/index.js:112:17:112:21 | taint | lib/index.js:136:23:136:49 | this.op ... dOption | This string concatenation which depends on $@ is later $@. | lib/index.js:112:17:112:21 | taint | library input | lib/index.js:136:12:136:69 | " var ... ing();" | interpreted as code | -| lib/index.js:137:23:137:49 | this.op ... dOption | lib/index.js:112:17:112:21 | taint | lib/index.js:137:23:137:49 | this.op ... dOption | This string concatenation which depends on $@ is later $@. | lib/index.js:112:17:112:21 | taint | library input | lib/index.js:137:12:137:69 | " var ... ing();" | interpreted as code | -| lib/index.js:138:23:138:32 | this.taint | lib/index.js:112:17:112:21 | taint | lib/index.js:138:23:138:32 | this.taint | This string concatenation which depends on $@ is later $@. | lib/index.js:112:17:112:21 | taint | library input | lib/index.js:138:12:138:52 | " var ... ing();" | interpreted as code | From 758f42495cc8091e260d83d4f580a1f1b212467f Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:25:16 +0200 Subject: [PATCH 096/514] JS: Port UnsafeDeserialization --- .../dataflow/UnsafeDeserializationQuery.qll | 18 +++++++- .../Security/CWE-502/UnsafeDeserialization.ql | 6 +-- .../CWE-502/UnsafeDeserialization.expected | 43 +++++-------------- 3 files changed, 30 insertions(+), 37 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDeserializationQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDeserializationQuery.qll index f8afff17b3a..edb3f93fa1b 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDeserializationQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDeserializationQuery.qll @@ -12,7 +12,23 @@ import UnsafeDeserializationCustomizations::UnsafeDeserialization /** * A taint-tracking configuration for reasoning about unsafe deserialization. */ -class Configuration extends TaintTracking::Configuration { +module UnsafeDeserializationConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint-tracking for reasoning about unsafe deserialization. + */ +module UnsafeDeserializationFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `UnsafeDeserializationFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "UnsafeDeserialization" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-502/UnsafeDeserialization.ql b/javascript/ql/src/Security/CWE-502/UnsafeDeserialization.ql index 35ae85130c9..e940ddff338 100644 --- a/javascript/ql/src/Security/CWE-502/UnsafeDeserialization.ql +++ b/javascript/ql/src/Security/CWE-502/UnsafeDeserialization.ql @@ -13,9 +13,9 @@ import javascript import semmle.javascript.security.dataflow.UnsafeDeserializationQuery -import DataFlow::PathGraph +import UnsafeDeserializationFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from UnsafeDeserializationFlow::PathNode source, UnsafeDeserializationFlow::PathNode sink +where UnsafeDeserializationFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Unsafe deserialization depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected b/javascript/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected index 7abe0b7f559..dbd2e399114 100644 --- a/javascript/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected +++ b/javascript/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected @@ -1,37 +1,14 @@ -nodes -| tst.js:13:22:13:36 | req.params.data | -| tst.js:13:22:13:36 | req.params.data | -| tst.js:13:22:13:36 | req.params.data | -| tst.js:14:25:14:39 | req.params.data | -| tst.js:14:25:14:39 | req.params.data | -| tst.js:14:25:14:39 | req.params.data | -| tst.js:15:26:15:40 | req.params.data | -| tst.js:15:26:15:40 | req.params.data | -| tst.js:15:26:15:40 | req.params.data | -| tst.js:16:29:16:43 | req.params.data | -| tst.js:16:29:16:43 | req.params.data | -| tst.js:16:29:16:43 | req.params.data | -| tst.js:20:22:20:36 | req.params.data | -| tst.js:20:22:20:36 | req.params.data | -| tst.js:20:22:20:36 | req.params.data | -| tst.js:21:22:21:36 | req.params.data | -| tst.js:21:22:21:36 | req.params.data | -| tst.js:21:22:21:36 | req.params.data | -| tst.js:24:22:24:36 | req.params.data | -| tst.js:24:22:24:36 | req.params.data | -| tst.js:24:22:24:36 | req.params.data | -| tst.js:25:22:25:36 | req.params.data | -| tst.js:25:22:25:36 | req.params.data | -| tst.js:25:22:25:36 | req.params.data | edges -| tst.js:13:22:13:36 | req.params.data | tst.js:13:22:13:36 | req.params.data | -| tst.js:14:25:14:39 | req.params.data | tst.js:14:25:14:39 | req.params.data | -| tst.js:15:26:15:40 | req.params.data | tst.js:15:26:15:40 | req.params.data | -| tst.js:16:29:16:43 | req.params.data | tst.js:16:29:16:43 | req.params.data | -| tst.js:20:22:20:36 | req.params.data | tst.js:20:22:20:36 | req.params.data | -| tst.js:21:22:21:36 | req.params.data | tst.js:21:22:21:36 | req.params.data | -| tst.js:24:22:24:36 | req.params.data | tst.js:24:22:24:36 | req.params.data | -| tst.js:25:22:25:36 | req.params.data | tst.js:25:22:25:36 | req.params.data | +nodes +| tst.js:13:22:13:36 | req.params.data | semmle.label | req.params.data | +| tst.js:14:25:14:39 | req.params.data | semmle.label | req.params.data | +| tst.js:15:26:15:40 | req.params.data | semmle.label | req.params.data | +| tst.js:16:29:16:43 | req.params.data | semmle.label | req.params.data | +| tst.js:20:22:20:36 | req.params.data | semmle.label | req.params.data | +| tst.js:21:22:21:36 | req.params.data | semmle.label | req.params.data | +| tst.js:24:22:24:36 | req.params.data | semmle.label | req.params.data | +| tst.js:25:22:25:36 | req.params.data | semmle.label | req.params.data | +subpaths #select | tst.js:13:22:13:36 | req.params.data | tst.js:13:22:13:36 | req.params.data | tst.js:13:22:13:36 | req.params.data | Unsafe deserialization depends on a $@. | tst.js:13:22:13:36 | req.params.data | user-provided value | | tst.js:14:25:14:39 | req.params.data | tst.js:14:25:14:39 | req.params.data | tst.js:14:25:14:39 | req.params.data | Unsafe deserialization depends on a $@. | tst.js:14:25:14:39 | req.params.data | user-provided value | From 7f4d42ddcde6db10023806458b805323704b121f Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:25:26 +0200 Subject: [PATCH 097/514] JS: Port UnsafeDynamicMethodAccess --- .../UnsafeDynamicMethodAccessQuery.qll | 61 ++++++++++++++- .../CWE-094/UnsafeDynamicMethodAccess.ql | 6 +- .../UnsafeDynamicMethodAccess.expected | 76 ++++++++----------- 3 files changed, 93 insertions(+), 50 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccessQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccessQuery.qll index 9ebe36a7cb8..556204375df 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccessQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccessQuery.qll @@ -20,7 +20,66 @@ private class ConcreteUnsafeFunction extends UnsafeFunction { /** * A taint-tracking configuration for reasoning about unsafe dynamic method access. */ -class Configuration extends TaintTracking::Configuration { +module UnsafeDynamicMethodAccessConfig 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) { + node instanceof Sanitizer + or + exists(StringConcatenation::getOperand(node, _)) and + not StringConcatenation::isCoercion(node) + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel label) { + TaintTracking::defaultSanitizer(node) and + label.isTaint() + } + + predicate isAdditionalFlowStep( + DataFlow::Node src, DataFlow::FlowLabel srclabel, DataFlow::Node dst, + DataFlow::FlowLabel dstlabel + ) { + // Reading a property of the global object or of a function + exists(DataFlow::PropRead read | + PropertyInjection::hasUnsafeMethods(read.getBase().getALocalSource()) and + src = read.getPropertyNameExpr().flow() and + dst = read and + srclabel.isTaint() and + dstlabel = unsafeFunction() + ) + or + // Reading a chain of properties from any object with a prototype can lead to Function + exists(PropertyProjection proj | + not PropertyInjection::isPrototypeLessObject(proj.getObject().getALocalSource()) and + src = proj.getASelector() and + dst = proj and + srclabel.isTaint() and + dstlabel = unsafeFunction() + ) + or + srclabel.isTaint() and + TaintTracking::defaultTaintStep(src, dst) and + srclabel = dstlabel + } +} + +/** + * Taint-tracking for reasoning about unsafe dynamic method access. + */ +module UnsafeDynamicMethodAccessFlow = DataFlow::GlobalWithState; + +/** + * DEPRECATED. Use the `UnsafeDynamicMethodAccessFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "UnsafeDynamicMethodAccess" } override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { diff --git a/javascript/ql/src/Security/CWE-094/UnsafeDynamicMethodAccess.ql b/javascript/ql/src/Security/CWE-094/UnsafeDynamicMethodAccess.ql index 4659ce89178..3a108a79132 100644 --- a/javascript/ql/src/Security/CWE-094/UnsafeDynamicMethodAccess.ql +++ b/javascript/ql/src/Security/CWE-094/UnsafeDynamicMethodAccess.ql @@ -12,10 +12,10 @@ import javascript import semmle.javascript.security.dataflow.UnsafeDynamicMethodAccessQuery -import DataFlow::PathGraph +import UnsafeDynamicMethodAccessFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from UnsafeDynamicMethodAccessFlow::PathNode source, UnsafeDynamicMethodAccessFlow::PathNode sink +where UnsafeDynamicMethodAccessFlow::flowPath(source, sink) select sink, source, sink, "This method is invoked using a $@, which may allow remote code execution.", source.getNode(), "user-controlled value" diff --git a/javascript/ql/test/query-tests/Security/CWE-094/UnsafeDynamicMethodAccess/UnsafeDynamicMethodAccess.expected b/javascript/ql/test/query-tests/Security/CWE-094/UnsafeDynamicMethodAccess/UnsafeDynamicMethodAccess.expected index 4005bd32dba..4a5f9141a99 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/UnsafeDynamicMethodAccess/UnsafeDynamicMethodAccess.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/UnsafeDynamicMethodAccess/UnsafeDynamicMethodAccess.expected @@ -1,53 +1,12 @@ -nodes -| example.js:9:37:9:38 | ev | -| example.js:9:37:9:38 | ev | -| example.js:10:9:10:37 | message | -| example.js:10:19:10:37 | JSON.parse(ev.data) | -| example.js:10:30:10:31 | ev | -| example.js:10:30:10:36 | ev.data | -| example.js:13:5:13:24 | window[message.name] | -| example.js:13:5:13:24 | window[message.name] | -| example.js:13:12:13:18 | message | -| example.js:13:12:13:23 | message.name | -| tst.js:3:37:3:38 | ev | -| tst.js:3:37:3:38 | ev | -| tst.js:4:9:4:37 | message | -| tst.js:4:19:4:37 | JSON.parse(ev.data) | -| tst.js:4:30:4:31 | ev | -| tst.js:4:30:4:36 | ev.data | -| tst.js:5:5:5:24 | window[message.name] | -| tst.js:5:5:5:24 | window[message.name] | -| tst.js:5:12:5:18 | message | -| tst.js:5:12:5:23 | message.name | -| tst.js:6:9:6:28 | window[message.name] | -| tst.js:6:9:6:28 | window[message.name] | -| tst.js:6:16:6:22 | message | -| tst.js:6:16:6:27 | message.name | -| tst.js:11:5:11:19 | f[message.name] | -| tst.js:11:5:11:19 | f[message.name] | -| tst.js:11:7:11:13 | message | -| tst.js:11:7:11:18 | message.name | -| tst.js:15:5:15:14 | window[ev] | -| tst.js:15:5:15:14 | window[ev] | -| tst.js:15:12:15:13 | ev | -| tst.js:21:5:21:29 | window[ ... e.name] | -| tst.js:21:5:21:29 | window[ ... e.name] | -| tst.js:21:12:21:28 | '' + message.name | -| tst.js:21:17:21:23 | message | -| tst.js:21:17:21:28 | message.name | edges | example.js:9:37:9:38 | ev | example.js:10:30:10:31 | ev | -| example.js:9:37:9:38 | ev | example.js:10:30:10:31 | ev | | example.js:10:9:10:37 | message | example.js:13:12:13:18 | message | | example.js:10:19:10:37 | JSON.parse(ev.data) | example.js:10:9:10:37 | message | | example.js:10:30:10:31 | ev | example.js:10:30:10:36 | ev.data | | example.js:10:30:10:36 | ev.data | example.js:10:19:10:37 | JSON.parse(ev.data) | | example.js:13:12:13:18 | message | example.js:13:12:13:23 | message.name | | example.js:13:12:13:23 | message.name | example.js:13:5:13:24 | window[message.name] | -| example.js:13:12:13:23 | message.name | example.js:13:5:13:24 | window[message.name] | | tst.js:3:37:3:38 | ev | tst.js:4:30:4:31 | ev | -| tst.js:3:37:3:38 | ev | tst.js:4:30:4:31 | ev | -| tst.js:3:37:3:38 | ev | tst.js:15:12:15:13 | ev | | tst.js:3:37:3:38 | ev | tst.js:15:12:15:13 | ev | | tst.js:4:9:4:37 | message | tst.js:5:12:5:18 | message | | tst.js:4:9:4:37 | message | tst.js:6:16:6:22 | message | @@ -58,19 +17,44 @@ edges | tst.js:4:30:4:36 | ev.data | tst.js:4:19:4:37 | JSON.parse(ev.data) | | tst.js:5:12:5:18 | message | tst.js:5:12:5:23 | message.name | | tst.js:5:12:5:23 | message.name | tst.js:5:5:5:24 | window[message.name] | -| tst.js:5:12:5:23 | message.name | tst.js:5:5:5:24 | window[message.name] | | tst.js:6:16:6:22 | message | tst.js:6:16:6:27 | message.name | | tst.js:6:16:6:27 | message.name | tst.js:6:9:6:28 | window[message.name] | -| tst.js:6:16:6:27 | message.name | tst.js:6:9:6:28 | window[message.name] | | tst.js:11:7:11:13 | message | tst.js:11:7:11:18 | message.name | | tst.js:11:7:11:18 | message.name | tst.js:11:5:11:19 | f[message.name] | -| tst.js:11:7:11:18 | message.name | tst.js:11:5:11:19 | f[message.name] | | tst.js:15:12:15:13 | ev | tst.js:15:5:15:14 | window[ev] | -| tst.js:15:12:15:13 | ev | tst.js:15:5:15:14 | window[ev] | -| tst.js:21:12:21:28 | '' + message.name | tst.js:21:5:21:29 | window[ ... e.name] | | tst.js:21:12:21:28 | '' + message.name | tst.js:21:5:21:29 | window[ ... e.name] | | tst.js:21:17:21:23 | message | tst.js:21:17:21:28 | message.name | | tst.js:21:17:21:28 | message.name | tst.js:21:12:21:28 | '' + message.name | +nodes +| example.js:9:37:9:38 | ev | semmle.label | ev | +| example.js:10:9:10:37 | message | semmle.label | message | +| example.js:10:19:10:37 | JSON.parse(ev.data) | semmle.label | JSON.parse(ev.data) | +| example.js:10:30:10:31 | ev | semmle.label | ev | +| example.js:10:30:10:36 | ev.data | semmle.label | ev.data | +| example.js:13:5:13:24 | window[message.name] | semmle.label | window[message.name] | +| example.js:13:12:13:18 | message | semmle.label | message | +| example.js:13:12:13:23 | message.name | semmle.label | message.name | +| tst.js:3:37:3:38 | ev | semmle.label | ev | +| tst.js:4:9:4:37 | message | semmle.label | message | +| tst.js:4:19:4:37 | JSON.parse(ev.data) | semmle.label | JSON.parse(ev.data) | +| tst.js:4:30:4:31 | ev | semmle.label | ev | +| tst.js:4:30:4:36 | ev.data | semmle.label | ev.data | +| tst.js:5:5:5:24 | window[message.name] | semmle.label | window[message.name] | +| tst.js:5:12:5:18 | message | semmle.label | message | +| tst.js:5:12:5:23 | message.name | semmle.label | message.name | +| tst.js:6:9:6:28 | window[message.name] | semmle.label | window[message.name] | +| tst.js:6:16:6:22 | message | semmle.label | message | +| tst.js:6:16:6:27 | message.name | semmle.label | message.name | +| tst.js:11:5:11:19 | f[message.name] | semmle.label | f[message.name] | +| tst.js:11:7:11:13 | message | semmle.label | message | +| tst.js:11:7:11:18 | message.name | semmle.label | message.name | +| tst.js:15:5:15:14 | window[ev] | semmle.label | window[ev] | +| tst.js:15:12:15:13 | ev | semmle.label | ev | +| tst.js:21:5:21:29 | window[ ... e.name] | semmle.label | window[ ... e.name] | +| tst.js:21:12:21:28 | '' + message.name | semmle.label | '' + message.name | +| tst.js:21:17:21:23 | message | semmle.label | message | +| tst.js:21:17:21:28 | message.name | semmle.label | message.name | +subpaths #select | example.js:13:5:13:24 | window[message.name] | example.js:9:37:9:38 | ev | example.js:13:5:13:24 | window[message.name] | This method is invoked using a $@, which may allow remote code execution. | example.js:9:37:9:38 | ev | user-controlled value | | tst.js:5:5:5:24 | window[message.name] | tst.js:3:37:3:38 | ev | tst.js:5:5:5:24 | window[message.name] | This method is invoked using a $@, which may allow remote code execution. | tst.js:3:37:3:38 | ev | user-controlled value | From 6e3f4bd7d8645efbc0eb7844553927fdc6481b16 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:25:35 +0200 Subject: [PATCH 098/514] JS: Port UnsafeHtmlConstruction --- .../UnsafeHtmlConstructionCustomizations.qll | 28 +- .../dataflow/UnsafeHtmlConstructionQuery.qll | 66 +++- .../CWE-079/UnsafeHtmlConstruction.ql | 8 +- .../UnsafeHtmlConstruction.expected | 301 ++++-------------- 4 files changed, 150 insertions(+), 253 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll index 90579211a3f..47535107bd8 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll @@ -61,6 +61,30 @@ module UnsafeHtmlConstruction { abstract string describe(); } + /** + * A barrier guard for unsafe HTML constructed from library input vulnerabilities. + */ + 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 sink for `js/html-constructed-from-input` that constructs some HTML where * that HTML is later used in `xssSink`. @@ -176,14 +200,14 @@ module UnsafeHtmlConstruction { } /** A test for the value of `typeof x`, restricting the potential types of `x`. */ - class TypeTestGuard extends TaintTracking::LabeledSanitizerGuardNode, DataFlow::ValueNode { + class TypeTestGuard extends BarrierGuardLegacy, DataFlow::ValueNode { override EqualityTest astNode; Expr operand; boolean polarity; TypeTestGuard() { TaintTracking::isStringTypeGuard(astNode, operand, polarity) } - override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { + override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { polarity = outcome and e = operand and lbl.isTaint() diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionQuery.qll index ed655e60412..2bd2dad9cd2 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionQuery.qll @@ -12,7 +12,66 @@ import semmle.javascript.security.TaintedObject /** * A taint-tracking configuration for reasoning about unsafe HTML constructed from library input vulnerabilities. */ -class Configration extends TaintTracking::Configuration { +module UnsafeHtmlConstructionConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; + + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { + source instanceof Source and + label = [TaintedObject::label(), DataFlow::FlowLabel::taint(), DataFlow::FlowLabel::data()] + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { + sink instanceof Sink and + label = DataFlow::FlowLabel::taint() + } + + predicate isBarrier(DataFlow::Node node) { + node instanceof DomBasedXss::Sanitizer + or + node instanceof UnsafeJQueryPlugin::Sanitizer + or + DomBasedXss::isOptionallySanitizedNode(node) + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel label) { + TaintTracking::defaultSanitizer(node) and label.isTaint() + or + node = DataFlow::MakeLabeledBarrierGuard::getABarrierNode(label) + } + + predicate isAdditionalFlowStep( + DataFlow::Node pred, DataFlow::FlowLabel inlbl, DataFlow::Node succ, DataFlow::FlowLabel outlbl + ) { + // TODO: localFieldStep is too expensive with dataflow2 + // DataFlow::localFieldStep(pred, succ) and + // inlbl.isTaint() and + // outlbl.isTaint() + none() + or + TaintedObject::step(pred, succ, inlbl, outlbl) + or + // property read from a tainted object is considered tainted + succ.(DataFlow::PropRead).getBase() = pred and + inlbl = TaintedObject::label() and + outlbl = DataFlow::FlowLabel::taint() + or + TaintTracking::defaultTaintStep(pred, succ) and + inlbl.isTaint() and + outlbl = inlbl + } + + DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext } +} + +/** + * Taint-tracking for reasoning about unsafe HTML constructed from library input vulnerabilities. + */ +module UnsafeHtmlConstructionFlow = DataFlow::GlobalWithState; + +/** + * DEPRECATED. Use the `UnsafeHtmlConstructionFlow` module instead. + */ +deprecated class Configration extends TaintTracking::Configuration { Configration() { this = "UnsafeHtmlConstruction" } override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { @@ -65,11 +124,10 @@ class Configration extends TaintTracking::Configuration { private import semmle.javascript.security.dataflow.Xss::Shared as Shared -private class QuoteGuard extends TaintTracking::SanitizerGuardNode, Shared::QuoteGuard { +private class QuoteGuard extends Shared::QuoteGuard { QuoteGuard() { this = this } } -private class ContainsHtmlGuard extends TaintTracking::SanitizerGuardNode, Shared::ContainsHtmlGuard -{ +private class ContainsHtmlGuard extends Shared::ContainsHtmlGuard { ContainsHtmlGuard() { this = this } } diff --git a/javascript/ql/src/Security/CWE-079/UnsafeHtmlConstruction.ql b/javascript/ql/src/Security/CWE-079/UnsafeHtmlConstruction.ql index 3e1818af026..9746e21334c 100644 --- a/javascript/ql/src/Security/CWE-079/UnsafeHtmlConstruction.ql +++ b/javascript/ql/src/Security/CWE-079/UnsafeHtmlConstruction.ql @@ -13,11 +13,13 @@ */ import javascript -import DataFlow::PathGraph import semmle.javascript.security.dataflow.UnsafeHtmlConstructionQuery +import DataFlow::DeduplicatePathGraph -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Sink sinkNode -where cfg.hasFlowPath(source, sink) and sink.getNode() = sinkNode +from PathNode source, PathNode sink, Sink sinkNode +where + UnsafeHtmlConstructionFlow::flowPath(source.getAnOriginalPathNode(), sink.getAnOriginalPathNode()) and + sink.getNode() = sinkNode select sinkNode, source, sink, "This " + sinkNode.describe() + " which depends on $@ might later allow $@.", source.getNode(), "library input", sinkNode.getSink(), sinkNode.getVulnerabilityKind().toLowerCase() diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected index b05425e65da..997d26fb127 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected @@ -1,287 +1,101 @@ nodes -| jquery-plugin.js:11:27:11:31 | stuff | -| jquery-plugin.js:11:27:11:31 | stuff | -| jquery-plugin.js:11:34:11:40 | options | -| jquery-plugin.js:11:34:11:40 | options | -| jquery-plugin.js:11:34:11:40 | options | -| jquery-plugin.js:11:34:11:40 | options | -| jquery-plugin.js:12:31:12:37 | options | -| jquery-plugin.js:12:31:12:37 | options | -| jquery-plugin.js:12:31:12:37 | options | -| jquery-plugin.js:12:31:12:41 | options.foo | -| jquery-plugin.js:12:31:12:41 | options.foo | -| jquery-plugin.js:12:31:12:41 | options.foo | -| jquery-plugin.js:12:31:12:41 | options.foo | -| jquery-plugin.js:14:31:14:35 | stuff | -| jquery-plugin.js:14:31:14:35 | stuff | -| lib2/index.ts:1:28:1:28 | s | -| lib2/index.ts:1:28:1:28 | s | -| lib2/index.ts:2:27:2:27 | s | -| lib2/index.ts:2:27:2:27 | s | -| lib2/index.ts:6:29:6:36 | settings | -| lib2/index.ts:6:29:6:36 | settings | -| lib2/index.ts:6:29:6:36 | settings | -| lib2/index.ts:7:58:7:65 | settings | -| lib2/index.ts:7:58:7:65 | settings | -| lib2/index.ts:13:9:13:41 | name | -| lib2/index.ts:13:16:13:23 | settings | -| lib2/index.ts:13:16:13:33 | settings.mySetting | -| lib2/index.ts:13:16:13:36 | setting ... ting[i] | -| lib2/index.ts:13:16:13:41 | setting ... i].name | -| lib2/index.ts:18:62:18:65 | name | -| lib2/index.ts:18:62:18:65 | name | -| lib2/src/MyNode.ts:1:28:1:28 | s | -| lib2/src/MyNode.ts:1:28:1:28 | s | -| lib2/src/MyNode.ts:2:29:2:29 | s | -| lib2/src/MyNode.ts:2:29:2:29 | s | -| lib/src/MyNode.ts:1:28:1:28 | s | -| lib/src/MyNode.ts:1:28:1:28 | s | -| lib/src/MyNode.ts:2:29:2:29 | s | -| lib/src/MyNode.ts:2:29:2:29 | s | -| main.js:1:55:1:55 | s | -| main.js:1:55:1:55 | s | -| main.js:2:29:2:29 | s | -| main.js:2:29:2:29 | s | -| main.js:6:49:6:49 | s | -| main.js:6:49:6:49 | s | -| main.js:7:49:7:49 | s | -| main.js:7:49:7:49 | s | -| main.js:11:60:11:60 | s | -| main.js:11:60:11:60 | s | -| main.js:12:49:12:49 | s | -| main.js:12:49:12:49 | s | -| main.js:21:47:21:47 | s | -| main.js:21:47:21:47 | s | -| main.js:22:34:22:34 | s | -| main.js:22:34:22:34 | s | -| main.js:41:17:41:17 | s | -| main.js:42:21:42:21 | s | -| main.js:47:65:47:73 | this.step | -| main.js:47:65:47:73 | this.step | -| main.js:52:41:52:41 | s | -| main.js:52:41:52:41 | s | -| main.js:53:20:53:20 | s | -| main.js:56:28:56:34 | options | -| main.js:56:28:56:34 | options | -| main.js:56:28:56:34 | options | -| main.js:56:28:56:34 | options | -| main.js:57:11:59:5 | defaults | -| main.js:57:11:59:5 | defaults | -| main.js:57:11:59:5 | defaults | -| main.js:57:22:59:5 | {\\n ... "\\n } | -| main.js:57:22:59:5 | {\\n ... "\\n } | -| main.js:57:22:59:5 | {\\n ... "\\n } | -| main.js:60:11:60:48 | settings | -| main.js:60:11:60:48 | settings | -| main.js:60:11:60:48 | settings | -| main.js:60:22:60:48 | $.exten ... ptions) | -| main.js:60:22:60:48 | $.exten ... ptions) | -| main.js:60:22:60:48 | $.exten ... ptions) | -| main.js:60:31:60:38 | defaults | -| main.js:60:31:60:38 | defaults | -| main.js:60:31:60:38 | defaults | -| main.js:60:41:60:47 | options | -| main.js:60:41:60:47 | options | -| main.js:60:41:60:47 | options | -| main.js:62:19:62:26 | settings | -| main.js:62:19:62:26 | settings | -| main.js:62:19:62:26 | settings | -| main.js:62:19:62:31 | settings.name | -| main.js:62:19:62:31 | settings.name | -| main.js:62:19:62:31 | settings.name | -| main.js:62:19:62:31 | settings.name | -| main.js:66:35:66:41 | attrVal | -| main.js:66:35:66:41 | attrVal | -| main.js:67:63:67:69 | attrVal | -| main.js:67:63:67:69 | attrVal | -| main.js:79:34:79:36 | val | -| main.js:79:34:79:36 | val | -| main.js:81:35:81:37 | val | -| main.js:81:35:81:37 | val | -| main.js:89:21:89:21 | x | -| main.js:90:23:90:23 | x | -| main.js:90:23:90:23 | x | -| main.js:93:43:93:43 | x | -| main.js:93:43:93:43 | x | -| main.js:94:31:94:31 | x | -| main.js:98:43:98:43 | x | -| main.js:98:43:98:43 | x | -| main.js:99:28:99:28 | x | -| main.js:99:28:99:28 | x | -| main.js:103:43:103:43 | x | -| main.js:103:43:103:43 | x | -| main.js:105:26:105:26 | x | -| main.js:105:26:105:26 | x | -| main.js:109:41:109:41 | x | -| main.js:109:41:109:41 | x | -| main.js:111:37:111:37 | x | -| main.js:111:37:111:37 | x | -| main.js:116:47:116:47 | s | -| main.js:116:47:116:47 | s | -| main.js:117:34:117:34 | s | -| main.js:117:34:117:34 | s | -| typed.ts:1:39:1:39 | s | -| typed.ts:1:39:1:39 | s | -| typed.ts:2:29:2:29 | s | -| typed.ts:2:29:2:29 | s | -| typed.ts:6:43:6:43 | s | -| typed.ts:6:43:6:43 | s | -| typed.ts:8:40:8:40 | s | -| typed.ts:8:40:8:40 | s | -| typed.ts:11:20:11:20 | s | -| typed.ts:11:20:11:20 | s | -| typed.ts:12:12:12:12 | s | -| typed.ts:16:11:16:21 | s | -| typed.ts:16:15:16:21 | id("x") | -| typed.ts:17:29:17:29 | s | -| typed.ts:17:29:17:29 | s | +| jquery-plugin.js:11:27:11:31 | stuff | semmle.label | stuff | +| jquery-plugin.js:11:34:11:40 | options | semmle.label | options | +| jquery-plugin.js:12:31:12:37 | options | semmle.label | options | +| jquery-plugin.js:12:31:12:41 | options.foo | semmle.label | options.foo | +| jquery-plugin.js:14:31:14:35 | stuff | semmle.label | stuff | +| lib2/index.ts:1:28:1:28 | s | semmle.label | s | +| lib2/index.ts:2:27:2:27 | s | semmle.label | s | +| lib2/index.ts:6:29:6:36 | settings | semmle.label | settings | +| lib2/index.ts:7:58:7:65 | settings | semmle.label | settings | +| lib2/index.ts:13:9:13:41 | name | semmle.label | name | +| lib2/index.ts:13:16:13:23 | settings | semmle.label | settings | +| lib2/index.ts:13:16:13:33 | settings.mySetting | semmle.label | settings.mySetting | +| lib2/index.ts:13:16:13:36 | setting ... ting[i] | semmle.label | setting ... ting[i] | +| lib2/index.ts:13:16:13:41 | setting ... i].name | semmle.label | setting ... i].name | +| lib2/index.ts:18:62:18:65 | name | semmle.label | name | +| lib2/src/MyNode.ts:1:28:1:28 | s | semmle.label | s | +| lib2/src/MyNode.ts:2:29:2:29 | s | semmle.label | s | +| lib/src/MyNode.ts:1:28:1:28 | s | semmle.label | s | +| lib/src/MyNode.ts:2:29:2:29 | s | semmle.label | s | +| main.js:1:55:1:55 | s | semmle.label | s | +| main.js:2:29:2:29 | s | semmle.label | s | +| main.js:6:49:6:49 | s | semmle.label | s | +| main.js:7:49:7:49 | s | semmle.label | s | +| main.js:11:60:11:60 | s | semmle.label | s | +| main.js:12:49:12:49 | s | semmle.label | s | +| main.js:21:47:21:47 | s | semmle.label | s | +| main.js:22:34:22:34 | s | semmle.label | s | +| main.js:56:28:56:34 | options | semmle.label | options | +| main.js:57:11:59:5 | defaults | semmle.label | defaults | +| main.js:57:22:59:5 | {\\n ... "\\n } | semmle.label | {\\n ... "\\n } | +| main.js:60:11:60:48 | settings | semmle.label | settings | +| main.js:60:22:60:48 | $.exten ... ptions) | semmle.label | $.exten ... ptions) | +| main.js:60:31:60:38 | defaults | semmle.label | defaults | +| main.js:60:41:60:47 | options | semmle.label | options | +| main.js:62:19:62:26 | settings | semmle.label | settings | +| main.js:62:19:62:31 | settings.name | semmle.label | settings.name | +| main.js:66:35:66:41 | attrVal | semmle.label | attrVal | +| main.js:67:63:67:69 | attrVal | semmle.label | attrVal | +| main.js:79:34:79:36 | val | semmle.label | val | +| main.js:81:35:81:37 | val | semmle.label | val | +| main.js:89:21:89:21 | x | semmle.label | x | +| main.js:90:23:90:23 | x | semmle.label | x | +| main.js:93:43:93:43 | x | semmle.label | x | +| main.js:94:31:94:31 | x | semmle.label | x | +| main.js:98:43:98:43 | x | semmle.label | x | +| main.js:99:28:99:28 | x | semmle.label | x | +| main.js:103:43:103:43 | x | semmle.label | x | +| main.js:105:26:105:26 | x | semmle.label | x | +| main.js:109:41:109:41 | x | semmle.label | x | +| main.js:111:37:111:37 | x | semmle.label | x | +| main.js:116:47:116:47 | s | semmle.label | s | +| main.js:117:34:117:34 | s | semmle.label | s | +| typed.ts:1:39:1:39 | s | semmle.label | s | +| typed.ts:2:29:2:29 | s | semmle.label | s | +| typed.ts:6:43:6:43 | s | semmle.label | s | +| typed.ts:8:40:8:40 | s | semmle.label | s | edges | jquery-plugin.js:11:27:11:31 | stuff | jquery-plugin.js:14:31:14:35 | stuff | -| jquery-plugin.js:11:27:11:31 | stuff | jquery-plugin.js:14:31:14:35 | stuff | -| jquery-plugin.js:11:27:11:31 | stuff | jquery-plugin.js:14:31:14:35 | stuff | -| jquery-plugin.js:11:27:11:31 | stuff | jquery-plugin.js:14:31:14:35 | stuff | | jquery-plugin.js:11:34:11:40 | options | jquery-plugin.js:12:31:12:37 | options | -| jquery-plugin.js:11:34:11:40 | options | jquery-plugin.js:12:31:12:37 | options | -| jquery-plugin.js:11:34:11:40 | options | jquery-plugin.js:12:31:12:37 | options | -| jquery-plugin.js:11:34:11:40 | options | jquery-plugin.js:12:31:12:37 | options | -| jquery-plugin.js:11:34:11:40 | options | jquery-plugin.js:12:31:12:37 | options | -| jquery-plugin.js:11:34:11:40 | options | jquery-plugin.js:12:31:12:37 | options | -| jquery-plugin.js:12:31:12:37 | options | jquery-plugin.js:12:31:12:41 | options.foo | -| jquery-plugin.js:12:31:12:37 | options | jquery-plugin.js:12:31:12:41 | options.foo | -| jquery-plugin.js:12:31:12:37 | options | jquery-plugin.js:12:31:12:41 | options.foo | -| jquery-plugin.js:12:31:12:37 | options | jquery-plugin.js:12:31:12:41 | options.foo | -| jquery-plugin.js:12:31:12:37 | options | jquery-plugin.js:12:31:12:41 | options.foo | | jquery-plugin.js:12:31:12:37 | options | jquery-plugin.js:12:31:12:41 | options.foo | | lib2/index.ts:1:28:1:28 | s | lib2/index.ts:2:27:2:27 | s | -| lib2/index.ts:1:28:1:28 | s | lib2/index.ts:2:27:2:27 | s | -| lib2/index.ts:1:28:1:28 | s | lib2/index.ts:2:27:2:27 | s | -| lib2/index.ts:1:28:1:28 | s | lib2/index.ts:2:27:2:27 | s | -| lib2/index.ts:6:29:6:36 | settings | lib2/index.ts:7:58:7:65 | settings | -| lib2/index.ts:6:29:6:36 | settings | lib2/index.ts:7:58:7:65 | settings | -| lib2/index.ts:6:29:6:36 | settings | lib2/index.ts:7:58:7:65 | settings | | lib2/index.ts:6:29:6:36 | settings | lib2/index.ts:7:58:7:65 | settings | | lib2/index.ts:6:29:6:36 | settings | lib2/index.ts:13:16:13:23 | settings | -| lib2/index.ts:6:29:6:36 | settings | lib2/index.ts:13:16:13:23 | settings | -| lib2/index.ts:13:9:13:41 | name | lib2/index.ts:18:62:18:65 | name | | lib2/index.ts:13:9:13:41 | name | lib2/index.ts:18:62:18:65 | name | | lib2/index.ts:13:16:13:23 | settings | lib2/index.ts:13:16:13:33 | settings.mySetting | | lib2/index.ts:13:16:13:33 | settings.mySetting | lib2/index.ts:13:16:13:36 | setting ... ting[i] | | lib2/index.ts:13:16:13:36 | setting ... ting[i] | lib2/index.ts:13:16:13:41 | setting ... i].name | | lib2/index.ts:13:16:13:41 | setting ... i].name | lib2/index.ts:13:9:13:41 | name | | lib2/src/MyNode.ts:1:28:1:28 | s | lib2/src/MyNode.ts:2:29:2:29 | s | -| lib2/src/MyNode.ts:1:28:1:28 | s | lib2/src/MyNode.ts:2:29:2:29 | s | -| lib2/src/MyNode.ts:1:28:1:28 | s | lib2/src/MyNode.ts:2:29:2:29 | s | -| lib2/src/MyNode.ts:1:28:1:28 | s | lib2/src/MyNode.ts:2:29:2:29 | s | -| lib/src/MyNode.ts:1:28:1:28 | s | lib/src/MyNode.ts:2:29:2:29 | s | -| lib/src/MyNode.ts:1:28:1:28 | s | lib/src/MyNode.ts:2:29:2:29 | s | -| lib/src/MyNode.ts:1:28:1:28 | s | lib/src/MyNode.ts:2:29:2:29 | s | | lib/src/MyNode.ts:1:28:1:28 | s | lib/src/MyNode.ts:2:29:2:29 | s | | main.js:1:55:1:55 | s | main.js:2:29:2:29 | s | -| main.js:1:55:1:55 | s | main.js:2:29:2:29 | s | -| main.js:1:55:1:55 | s | main.js:2:29:2:29 | s | -| main.js:1:55:1:55 | s | main.js:2:29:2:29 | s | -| main.js:6:49:6:49 | s | main.js:7:49:7:49 | s | -| main.js:6:49:6:49 | s | main.js:7:49:7:49 | s | -| main.js:6:49:6:49 | s | main.js:7:49:7:49 | s | | main.js:6:49:6:49 | s | main.js:7:49:7:49 | s | | main.js:11:60:11:60 | s | main.js:12:49:12:49 | s | -| main.js:11:60:11:60 | s | main.js:12:49:12:49 | s | -| main.js:11:60:11:60 | s | main.js:12:49:12:49 | s | -| main.js:11:60:11:60 | s | main.js:12:49:12:49 | s | | main.js:21:47:21:47 | s | main.js:22:34:22:34 | s | -| main.js:21:47:21:47 | s | main.js:22:34:22:34 | s | -| main.js:21:47:21:47 | s | main.js:22:34:22:34 | s | -| main.js:21:47:21:47 | s | main.js:22:34:22:34 | s | -| main.js:41:17:41:17 | s | main.js:42:21:42:21 | s | -| main.js:42:21:42:21 | s | main.js:47:65:47:73 | this.step | -| main.js:42:21:42:21 | s | main.js:47:65:47:73 | this.step | -| main.js:52:41:52:41 | s | main.js:53:20:53:20 | s | -| main.js:52:41:52:41 | s | main.js:53:20:53:20 | s | -| main.js:53:20:53:20 | s | main.js:41:17:41:17 | s | -| main.js:56:28:56:34 | options | main.js:60:41:60:47 | options | -| main.js:56:28:56:34 | options | main.js:60:41:60:47 | options | -| main.js:56:28:56:34 | options | main.js:60:41:60:47 | options | -| main.js:56:28:56:34 | options | main.js:60:41:60:47 | options | -| main.js:56:28:56:34 | options | main.js:60:41:60:47 | options | | main.js:56:28:56:34 | options | main.js:60:41:60:47 | options | | main.js:57:11:59:5 | defaults | main.js:60:31:60:38 | defaults | -| main.js:57:11:59:5 | defaults | main.js:60:31:60:38 | defaults | -| main.js:57:11:59:5 | defaults | main.js:60:31:60:38 | defaults | -| main.js:57:22:59:5 | {\\n ... "\\n } | main.js:57:11:59:5 | defaults | -| main.js:57:22:59:5 | {\\n ... "\\n } | main.js:57:11:59:5 | defaults | | main.js:57:22:59:5 | {\\n ... "\\n } | main.js:57:11:59:5 | defaults | | main.js:60:11:60:48 | settings | main.js:62:19:62:26 | settings | -| main.js:60:11:60:48 | settings | main.js:62:19:62:26 | settings | -| main.js:60:11:60:48 | settings | main.js:62:19:62:26 | settings | -| main.js:60:22:60:48 | $.exten ... ptions) | main.js:60:11:60:48 | settings | -| main.js:60:22:60:48 | $.exten ... ptions) | main.js:60:11:60:48 | settings | | main.js:60:22:60:48 | $.exten ... ptions) | main.js:60:11:60:48 | settings | | main.js:60:31:60:38 | defaults | main.js:60:22:60:48 | $.exten ... ptions) | -| main.js:60:31:60:38 | defaults | main.js:60:22:60:48 | $.exten ... ptions) | -| main.js:60:31:60:38 | defaults | main.js:60:22:60:48 | $.exten ... ptions) | -| main.js:60:41:60:47 | options | main.js:57:22:59:5 | {\\n ... "\\n } | -| main.js:60:41:60:47 | options | main.js:57:22:59:5 | {\\n ... "\\n } | | main.js:60:41:60:47 | options | main.js:57:22:59:5 | {\\n ... "\\n } | | main.js:60:41:60:47 | options | main.js:60:22:60:48 | $.exten ... ptions) | -| main.js:60:41:60:47 | options | main.js:60:22:60:48 | $.exten ... ptions) | -| main.js:60:41:60:47 | options | main.js:60:22:60:48 | $.exten ... ptions) | -| main.js:62:19:62:26 | settings | main.js:62:19:62:31 | settings.name | -| main.js:62:19:62:26 | settings | main.js:62:19:62:31 | settings.name | -| main.js:62:19:62:26 | settings | main.js:62:19:62:31 | settings.name | -| main.js:62:19:62:26 | settings | main.js:62:19:62:31 | settings.name | -| main.js:62:19:62:26 | settings | main.js:62:19:62:31 | settings.name | | main.js:62:19:62:26 | settings | main.js:62:19:62:31 | settings.name | | main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | -| main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | -| main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | -| main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | -| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | -| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | -| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | | main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | | main.js:89:21:89:21 | x | main.js:90:23:90:23 | x | -| main.js:89:21:89:21 | x | main.js:90:23:90:23 | x | -| main.js:93:43:93:43 | x | main.js:94:31:94:31 | x | | main.js:93:43:93:43 | x | main.js:94:31:94:31 | x | | main.js:94:31:94:31 | x | main.js:89:21:89:21 | x | | main.js:98:43:98:43 | x | main.js:99:28:99:28 | x | -| main.js:98:43:98:43 | x | main.js:99:28:99:28 | x | -| main.js:98:43:98:43 | x | main.js:99:28:99:28 | x | -| main.js:98:43:98:43 | x | main.js:99:28:99:28 | x | -| main.js:98:43:98:43 | x | main.js:103:43:103:43 | x | -| main.js:98:43:98:43 | x | main.js:103:43:103:43 | x | -| main.js:98:43:98:43 | x | main.js:103:43:103:43 | x | | main.js:98:43:98:43 | x | main.js:103:43:103:43 | x | | main.js:98:43:98:43 | x | main.js:105:26:105:26 | x | -| main.js:98:43:98:43 | x | main.js:105:26:105:26 | x | -| main.js:98:43:98:43 | x | main.js:105:26:105:26 | x | -| main.js:98:43:98:43 | x | main.js:105:26:105:26 | x | -| main.js:98:43:98:43 | x | main.js:109:41:109:41 | x | -| main.js:98:43:98:43 | x | main.js:109:41:109:41 | x | -| main.js:98:43:98:43 | x | main.js:109:41:109:41 | x | | main.js:98:43:98:43 | x | main.js:109:41:109:41 | x | | main.js:98:43:98:43 | x | main.js:111:37:111:37 | x | -| main.js:98:43:98:43 | x | main.js:111:37:111:37 | x | -| main.js:98:43:98:43 | x | main.js:111:37:111:37 | x | -| main.js:98:43:98:43 | x | main.js:111:37:111:37 | x | -| main.js:116:47:116:47 | s | main.js:117:34:117:34 | s | -| main.js:116:47:116:47 | s | main.js:117:34:117:34 | s | -| main.js:116:47:116:47 | s | main.js:117:34:117:34 | s | | main.js:116:47:116:47 | s | main.js:117:34:117:34 | s | | typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | -| typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | -| typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | -| typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | | typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s | -| typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s | -| typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s | -| typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s | -| typed.ts:11:20:11:20 | s | typed.ts:12:12:12:12 | s | -| typed.ts:11:20:11:20 | s | typed.ts:12:12:12:12 | s | -| typed.ts:12:12:12:12 | s | typed.ts:16:15:16:21 | id("x") | -| typed.ts:16:11:16:21 | s | typed.ts:17:29:17:29 | s | -| typed.ts:16:11:16:21 | s | typed.ts:17:29:17:29 | s | -| typed.ts:16:15:16:21 | id("x") | typed.ts:16:11:16:21 | s | +subpaths #select | jquery-plugin.js:12:31:12:41 | options.foo | jquery-plugin.js:11:34:11:40 | options | jquery-plugin.js:12:31:12:41 | options.foo | This HTML construction which depends on $@ might later allow $@. | jquery-plugin.js:11:34:11:40 | options | library input | jquery-plugin.js:12:20:12:53 | " ... /span>" | cross-site scripting | | jquery-plugin.js:14:31:14:35 | stuff | jquery-plugin.js:11:27:11:31 | stuff | jquery-plugin.js:14:31:14:35 | stuff | This HTML construction which depends on $@ might later allow $@. | jquery-plugin.js:11:27:11:31 | stuff | library input | jquery-plugin.js:14:20:14:47 | " ... /span>" | cross-site scripting | @@ -295,7 +109,6 @@ edges | main.js:12:49:12:49 | s | main.js:11:60:11:60 | s | main.js:12:49:12:49 | s | This XML parsing which depends on $@ might later allow $@. | main.js:11:60:11:60 | s | library input | main.js:16:21:16:35 | xml.cloneNode() | cross-site scripting | | main.js:12:49:12:49 | s | main.js:11:60:11:60 | s | main.js:12:49:12:49 | s | This XML parsing which depends on $@ might later allow $@. | main.js:11:60:11:60 | s | library input | main.js:17:48:17:50 | tmp | cross-site scripting | | main.js:22:34:22:34 | s | main.js:21:47:21:47 | s | main.js:22:34:22:34 | s | This markdown rendering which depends on $@ might later allow $@. | main.js:21:47:21:47 | s | library input | main.js:23:53:23:56 | html | cross-site scripting | -| main.js:47:65:47:73 | this.step | main.js:52:41:52:41 | s | main.js:47:65:47:73 | this.step | This HTML construction which depends on $@ might later allow $@. | main.js:52:41:52:41 | s | library input | main.js:47:54:47:85 | " ... /span>" | cross-site scripting | | main.js:62:19:62:31 | settings.name | main.js:56:28:56:34 | options | main.js:62:19:62:31 | settings.name | This HTML construction which depends on $@ might later allow $@. | main.js:56:28:56:34 | options | library input | main.js:62:11:62:40 | "" + ... "" | cross-site scripting | | main.js:67:63:67:69 | attrVal | main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | This HTML construction which depends on $@ might later allow $@. | main.js:66:35:66:41 | attrVal | library input | main.js:67:47:67:78 | "" | cross-site scripting | | main.js:81:35:81:37 | val | main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | This HTML construction which depends on $@ might later allow $@. | main.js:79:34:79:36 | val | library input | main.js:81:24:81:49 | " ... /span>" | cross-site scripting | From d08e4504ff741602eea7d598eaa6b89e95a19b0a Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:25:48 +0200 Subject: [PATCH 099/514] JS: Port UnsafeJQueryPlugin --- .../UnsafeJQueryPluginCustomizations.qll | 27 +- .../dataflow/UnsafeJQueryPluginQuery.qll | 41 ++- .../Security/CWE-079/UnsafeJQueryPlugin.ql | 6 +- .../UnsafeJQueryPlugin.expected | 277 +++++------------- 4 files changed, 136 insertions(+), 215 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll index d1e35a91c26..9209a7b1f8a 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll @@ -31,6 +31,21 @@ module UnsafeJQueryPlugin { */ abstract class Sanitizer extends DataFlow::Node { } + /** + * A barrier guard for XSS in unsafe jQuery plugins. + */ + 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() } + } + + /** 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) } + } + /** * The receiver of a function, seen as a sanitizer. * @@ -110,7 +125,7 @@ module UnsafeJQueryPlugin { /** * An expression of form `isElement(x)`, which sanitizes `x`. */ - class IsElementSanitizer extends TaintTracking::SanitizerGuardNode, DataFlow::CallNode { + class IsElementSanitizer extends BarrierGuardLegacy, DataFlow::CallNode { IsElementSanitizer() { // common ad hoc sanitizing calls exists(string name | this.getCalleeName() = name | @@ -118,7 +133,7 @@ module UnsafeJQueryPlugin { ) } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = this.getArgument(0).asExpr() } } @@ -126,7 +141,7 @@ module UnsafeJQueryPlugin { /** * An expression like `typeof x. !== "undefined"` or `x.`, which sanitizes `x`, as it is unlikely to be a string afterwards. */ - class PropertyPresenceSanitizer extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode { + class PropertyPresenceSanitizer extends BarrierGuardLegacy, DataFlow::ValueNode { DataFlow::Node input; boolean polarity; @@ -155,20 +170,20 @@ module UnsafeJQueryPlugin { */ DataFlow::PropRead getPropRead() { result = this } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { outcome = polarity and e = input.asExpr() } } /** 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 } } /** diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginQuery.qll index e4b70c176cc..1860ffa3be6 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginQuery.qll @@ -10,7 +10,46 @@ import UnsafeJQueryPluginCustomizations::UnsafeJQueryPlugin /** * A taint-tracking configuration for reasoning about XSS in unsafe jQuery plugins. */ -class Configuration extends TaintTracking::Configuration { +module UnsafeJQueryPluginConfig implements DataFlow::ConfigSig { + // TODO: PropertyPresenceSanitizer should not block values in a content. + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { + node instanceof DomBasedXss::Sanitizer or + node instanceof Sanitizer or + node = DataFlow::MakeBarrierGuard::getABarrierNode() + } + + predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node sink) { + // jQuery plugins tend to be implemented as classes that store data in fields initialized by the constructor. + // TODO: localFieldStep is too expensive with dataflow2 + // DataFlow::localFieldStep(pred, succ) + none() + or + aliasPropertyPresenceStep(src, sink) + } + + predicate isBarrierOut(DataFlow::Node node) { + // prefixing prevents forced html/css confusion: + // prefixing through concatenation: + StringConcatenation::taintStep(node, _, _, any(int i | i >= 1)) + or + // prefixing through a poor-mans templating system: + node = any(StringReplaceCall call).getRawReplacement() + } +} + +/** + * Taint-tracking for reasoning about XSS in unsafe jQuery plugins. + */ +module UnsafeJQueryPluginFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `UnsafeJQueryPluginFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "UnsafeJQueryPlugin" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql b/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql index 0cd8312a8cd..5bb2abb2564 100644 --- a/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql +++ b/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql @@ -14,13 +14,13 @@ import javascript import semmle.javascript.security.dataflow.UnsafeJQueryPluginQuery -import DataFlow::PathGraph +import UnsafeJQueryPluginFlow::PathGraph from - Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, + UnsafeJQueryPluginFlow::PathNode source, UnsafeJQueryPluginFlow::PathNode sink, JQuery::JQueryPluginMethod plugin where - cfg.hasFlowPath(source, sink) and + UnsafeJQueryPluginFlow::flowPath(source, sink) and source.getNode().(Source).getPlugin() = plugin select sink.getNode(), source, sink, "Potential XSS vulnerability in the $@.", plugin, "'$.fn." + plugin.getPluginName() + "' plugin" diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/UnsafeJQueryPlugin.expected b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/UnsafeJQueryPlugin.expected index 23a7d82ca14..296f89e05af 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/UnsafeJQueryPlugin.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/UnsafeJQueryPlugin.expected @@ -1,142 +1,7 @@ -nodes -| unsafe-jquery-plugin.js:2:38:2:44 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | -| unsafe-jquery-plugin.js:3:5:3:11 | options | -| unsafe-jquery-plugin.js:3:5:3:11 | options | -| unsafe-jquery-plugin.js:5:5:5:11 | options | -| unsafe-jquery-plugin.js:5:5:5:18 | options.target | -| unsafe-jquery-plugin.js:5:5:5:18 | options.target | -| unsafe-jquery-plugin.js:7:17:7:23 | options | -| unsafe-jquery-plugin.js:7:17:7:30 | options.target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | -| unsafe-jquery-plugin.js:11:16:11:22 | options | -| unsafe-jquery-plugin.js:11:16:11:29 | options.target | -| unsafe-jquery-plugin.js:22:6:22:11 | target | -| unsafe-jquery-plugin.js:22:6:22:11 | target | -| unsafe-jquery-plugin.js:30:6:30:11 | target | -| unsafe-jquery-plugin.js:30:6:30:11 | target | -| unsafe-jquery-plugin.js:36:6:36:11 | target | -| unsafe-jquery-plugin.js:36:6:36:11 | target | -| unsafe-jquery-plugin.js:40:6:40:11 | target | -| unsafe-jquery-plugin.js:40:6:40:11 | target | -| unsafe-jquery-plugin.js:48:6:48:11 | target | -| unsafe-jquery-plugin.js:48:6:48:11 | target | -| unsafe-jquery-plugin.js:52:6:52:11 | target | -| unsafe-jquery-plugin.js:52:6:52:11 | target | -| unsafe-jquery-plugin.js:60:6:60:11 | target | -| unsafe-jquery-plugin.js:60:6:60:11 | target | -| unsafe-jquery-plugin.js:65:47:65:53 | options | -| unsafe-jquery-plugin.js:65:47:65:53 | options | -| unsafe-jquery-plugin.js:67:24:67:44 | $.exten ... ptions) | -| unsafe-jquery-plugin.js:67:33:67:34 | {} | -| unsafe-jquery-plugin.js:67:37:67:43 | options | -| unsafe-jquery-plugin.js:68:7:68:18 | this.options | -| unsafe-jquery-plugin.js:68:7:68:25 | this.options.parent | -| unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | -| unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | -| unsafe-jquery-plugin.js:71:38:71:44 | options | -| unsafe-jquery-plugin.js:71:38:71:44 | options | -| unsafe-jquery-plugin.js:72:5:72:11 | options | -| unsafe-jquery-plugin.js:72:5:72:15 | options.foo | -| unsafe-jquery-plugin.js:72:5:72:19 | options.foo.bar | -| unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | -| unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | -| unsafe-jquery-plugin.js:76:38:76:44 | options | -| unsafe-jquery-plugin.js:76:38:76:44 | options | -| unsafe-jquery-plugin.js:77:17:77:23 | options | -| unsafe-jquery-plugin.js:77:17:77:27 | options.foo | -| unsafe-jquery-plugin.js:77:17:77:31 | options.foo.bar | -| unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | -| unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | -| unsafe-jquery-plugin.js:84:38:84:44 | options | -| unsafe-jquery-plugin.js:84:38:84:44 | options | -| unsafe-jquery-plugin.js:85:14:85:14 | o | -| unsafe-jquery-plugin.js:86:13:86:27 | $.extend({}, o) | -| unsafe-jquery-plugin.js:86:22:86:23 | {} | -| unsafe-jquery-plugin.js:86:26:86:26 | o | -| unsafe-jquery-plugin.js:87:8:87:24 | t | -| unsafe-jquery-plugin.js:87:12:87:17 | this.o | -| unsafe-jquery-plugin.js:87:12:87:24 | this.o.target | -| unsafe-jquery-plugin.js:90:6:90:6 | t | -| unsafe-jquery-plugin.js:90:6:90:6 | t | -| unsafe-jquery-plugin.js:92:5:92:11 | options | -| unsafe-jquery-plugin.js:101:38:101:44 | options | -| unsafe-jquery-plugin.js:101:38:101:44 | options | -| unsafe-jquery-plugin.js:102:3:105:13 | options | -| unsafe-jquery-plugin.js:102:13:105:13 | $.exten ... ptions) | -| unsafe-jquery-plugin.js:102:22:105:3 | {\\n\\t\\t\\tme ... in'\\n\\t\\t} | -| unsafe-jquery-plugin.js:105:6:105:12 | options | -| unsafe-jquery-plugin.js:107:5:107:11 | options | -| unsafe-jquery-plugin.js:107:5:107:18 | options.target | -| unsafe-jquery-plugin.js:107:5:107:18 | options.target | -| unsafe-jquery-plugin.js:114:38:114:44 | options | -| unsafe-jquery-plugin.js:114:38:114:44 | options | -| unsafe-jquery-plugin.js:115:3:115:58 | options | -| unsafe-jquery-plugin.js:115:13:115:58 | $.exten ... ptions) | -| unsafe-jquery-plugin.js:115:22:115:23 | {} | -| unsafe-jquery-plugin.js:115:51:115:57 | options | -| unsafe-jquery-plugin.js:117:5:117:11 | options | -| unsafe-jquery-plugin.js:117:5:117:18 | options.target | -| unsafe-jquery-plugin.js:117:5:117:18 | options.target | -| unsafe-jquery-plugin.js:121:40:121:46 | options | -| unsafe-jquery-plugin.js:121:40:121:46 | options | -| unsafe-jquery-plugin.js:122:5:122:11 | options | -| unsafe-jquery-plugin.js:122:5:122:18 | options.target | -| unsafe-jquery-plugin.js:122:5:122:18 | options.target | -| unsafe-jquery-plugin.js:126:33:126:39 | options | -| unsafe-jquery-plugin.js:126:33:126:39 | options | -| unsafe-jquery-plugin.js:127:6:127:12 | options | -| unsafe-jquery-plugin.js:127:6:127:19 | options.target | -| unsafe-jquery-plugin.js:127:6:127:19 | options.target | -| unsafe-jquery-plugin.js:131:34:131:40 | options | -| unsafe-jquery-plugin.js:131:34:131:40 | options | -| unsafe-jquery-plugin.js:132:5:132:11 | options | -| unsafe-jquery-plugin.js:132:5:132:18 | options.target | -| unsafe-jquery-plugin.js:132:5:132:18 | options.target | -| unsafe-jquery-plugin.js:135:36:135:42 | options | -| unsafe-jquery-plugin.js:135:36:135:42 | options | -| unsafe-jquery-plugin.js:136:5:136:11 | options | -| unsafe-jquery-plugin.js:136:5:136:20 | options.viewport | -| unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | -| unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | -| unsafe-jquery-plugin.js:153:38:153:44 | options | -| unsafe-jquery-plugin.js:153:38:153:44 | options | -| unsafe-jquery-plugin.js:154:16:154:22 | options | -| unsafe-jquery-plugin.js:154:16:154:29 | options.target | -| unsafe-jquery-plugin.js:156:3:156:9 | options | -| unsafe-jquery-plugin.js:156:3:156:16 | options.target | -| unsafe-jquery-plugin.js:157:44:157:50 | options | -| unsafe-jquery-plugin.js:157:44:157:57 | options.target | -| unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | -| unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | -| unsafe-jquery-plugin.js:160:38:160:44 | options | -| unsafe-jquery-plugin.js:160:38:160:44 | options | -| unsafe-jquery-plugin.js:165:7:165:29 | target | -| unsafe-jquery-plugin.js:165:16:165:22 | options | -| unsafe-jquery-plugin.js:165:16:165:29 | options.target | -| unsafe-jquery-plugin.js:170:6:170:11 | target | -| unsafe-jquery-plugin.js:170:6:170:11 | target | -| unsafe-jquery-plugin.js:178:27:178:33 | options | -| unsafe-jquery-plugin.js:178:27:178:33 | options | -| unsafe-jquery-plugin.js:179:5:179:11 | options | -| unsafe-jquery-plugin.js:179:5:179:18 | options.target | -| unsafe-jquery-plugin.js:179:5:179:18 | options.target | -| unsafe-jquery-plugin.js:185:28:185:34 | options | -| unsafe-jquery-plugin.js:185:28:185:34 | options | -| unsafe-jquery-plugin.js:186:21:186:27 | options | -| unsafe-jquery-plugin.js:186:21:186:30 | options.of | -| unsafe-jquery-plugin.js:192:19:192:28 | options.of | -| unsafe-jquery-plugin.js:192:19:192:28 | options.of | edges | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:3:5:3:11 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:3:5:3:11 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:3:5:3:11 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:3:5:3:11 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:5:5:5:11 | options | | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:5:5:5:11 | options | | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:7:17:7:23 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:7:17:7:23 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:11:16:11:22 | options | | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:11:16:11:22 | options | | unsafe-jquery-plugin.js:5:5:5:11 | options | unsafe-jquery-plugin.js:5:5:5:18 | options.target | | unsafe-jquery-plugin.js:5:5:5:11 | options | unsafe-jquery-plugin.js:5:5:5:18 | options.target | @@ -144,94 +9,38 @@ edges | unsafe-jquery-plugin.js:7:17:7:23 | options | unsafe-jquery-plugin.js:7:17:7:30 | options.target | | unsafe-jquery-plugin.js:7:17:7:30 | options.target | unsafe-jquery-plugin.js:11:16:11:29 | options.target | | unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:22:6:22:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:22:6:22:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:30:6:30:11 | target | | unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:30:6:30:11 | target | | unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:36:6:36:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:36:6:36:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:40:6:40:11 | target | | unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:40:6:40:11 | target | | unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:48:6:48:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:48:6:48:11 | target | | unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:52:6:52:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:52:6:52:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:60:6:60:11 | target | | unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:60:6:60:11 | target | | unsafe-jquery-plugin.js:11:16:11:22 | options | unsafe-jquery-plugin.js:11:16:11:29 | options.target | | unsafe-jquery-plugin.js:11:16:11:29 | options.target | unsafe-jquery-plugin.js:11:7:11:29 | target | -| unsafe-jquery-plugin.js:65:47:65:53 | options | unsafe-jquery-plugin.js:67:37:67:43 | options | -| unsafe-jquery-plugin.js:65:47:65:53 | options | unsafe-jquery-plugin.js:67:37:67:43 | options | -| unsafe-jquery-plugin.js:67:24:67:44 | $.exten ... ptions) | unsafe-jquery-plugin.js:68:7:68:18 | this.options | -| unsafe-jquery-plugin.js:67:33:67:34 | {} | unsafe-jquery-plugin.js:67:24:67:44 | $.exten ... ptions) | -| unsafe-jquery-plugin.js:67:37:67:43 | options | unsafe-jquery-plugin.js:67:24:67:44 | $.exten ... ptions) | -| unsafe-jquery-plugin.js:67:37:67:43 | options | unsafe-jquery-plugin.js:67:33:67:34 | {} | -| unsafe-jquery-plugin.js:68:7:68:18 | this.options | unsafe-jquery-plugin.js:68:7:68:25 | this.options.parent | -| unsafe-jquery-plugin.js:68:7:68:25 | this.options.parent | unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | -| unsafe-jquery-plugin.js:68:7:68:25 | this.options.parent | unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | | unsafe-jquery-plugin.js:71:38:71:44 | options | unsafe-jquery-plugin.js:72:5:72:11 | options | -| unsafe-jquery-plugin.js:71:38:71:44 | options | unsafe-jquery-plugin.js:72:5:72:11 | options | -| unsafe-jquery-plugin.js:72:5:72:11 | options | unsafe-jquery-plugin.js:72:5:72:15 | options.foo | -| unsafe-jquery-plugin.js:72:5:72:15 | options.foo | unsafe-jquery-plugin.js:72:5:72:19 | options.foo.bar | -| unsafe-jquery-plugin.js:72:5:72:19 | options.foo.bar | unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | -| unsafe-jquery-plugin.js:72:5:72:19 | options.foo.bar | unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | +| unsafe-jquery-plugin.js:72:5:72:11 | options | unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | | unsafe-jquery-plugin.js:76:38:76:44 | options | unsafe-jquery-plugin.js:77:17:77:23 | options | -| unsafe-jquery-plugin.js:76:38:76:44 | options | unsafe-jquery-plugin.js:77:17:77:23 | options | -| unsafe-jquery-plugin.js:77:17:77:23 | options | unsafe-jquery-plugin.js:77:17:77:27 | options.foo | -| unsafe-jquery-plugin.js:77:17:77:27 | options.foo | unsafe-jquery-plugin.js:77:17:77:31 | options.foo.bar | -| unsafe-jquery-plugin.js:77:17:77:31 | options.foo.bar | unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | -| unsafe-jquery-plugin.js:77:17:77:31 | options.foo.bar | unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | -| unsafe-jquery-plugin.js:84:38:84:44 | options | unsafe-jquery-plugin.js:92:5:92:11 | options | -| unsafe-jquery-plugin.js:84:38:84:44 | options | unsafe-jquery-plugin.js:92:5:92:11 | options | -| unsafe-jquery-plugin.js:85:14:85:14 | o | unsafe-jquery-plugin.js:86:26:86:26 | o | -| unsafe-jquery-plugin.js:86:13:86:27 | $.extend({}, o) | unsafe-jquery-plugin.js:87:12:87:17 | this.o | -| unsafe-jquery-plugin.js:86:22:86:23 | {} | unsafe-jquery-plugin.js:86:13:86:27 | $.extend({}, o) | -| unsafe-jquery-plugin.js:86:26:86:26 | o | unsafe-jquery-plugin.js:86:13:86:27 | $.extend({}, o) | -| unsafe-jquery-plugin.js:86:26:86:26 | o | unsafe-jquery-plugin.js:86:22:86:23 | {} | -| unsafe-jquery-plugin.js:87:8:87:24 | t | unsafe-jquery-plugin.js:90:6:90:6 | t | -| unsafe-jquery-plugin.js:87:8:87:24 | t | unsafe-jquery-plugin.js:90:6:90:6 | t | -| unsafe-jquery-plugin.js:87:12:87:17 | this.o | unsafe-jquery-plugin.js:87:12:87:24 | this.o.target | -| unsafe-jquery-plugin.js:87:12:87:24 | this.o.target | unsafe-jquery-plugin.js:87:8:87:24 | t | -| unsafe-jquery-plugin.js:92:5:92:11 | options | unsafe-jquery-plugin.js:85:14:85:14 | o | -| unsafe-jquery-plugin.js:101:38:101:44 | options | unsafe-jquery-plugin.js:105:6:105:12 | options | +| unsafe-jquery-plugin.js:77:17:77:23 | options | unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | | unsafe-jquery-plugin.js:101:38:101:44 | options | unsafe-jquery-plugin.js:105:6:105:12 | options | | unsafe-jquery-plugin.js:102:3:105:13 | options | unsafe-jquery-plugin.js:107:5:107:11 | options | | unsafe-jquery-plugin.js:102:13:105:13 | $.exten ... ptions) | unsafe-jquery-plugin.js:102:3:105:13 | options | -| unsafe-jquery-plugin.js:102:22:105:3 | {\\n\\t\\t\\tme ... in'\\n\\t\\t} | unsafe-jquery-plugin.js:102:13:105:13 | $.exten ... ptions) | | unsafe-jquery-plugin.js:105:6:105:12 | options | unsafe-jquery-plugin.js:102:13:105:13 | $.exten ... ptions) | -| unsafe-jquery-plugin.js:105:6:105:12 | options | unsafe-jquery-plugin.js:102:22:105:3 | {\\n\\t\\t\\tme ... in'\\n\\t\\t} | | unsafe-jquery-plugin.js:107:5:107:11 | options | unsafe-jquery-plugin.js:107:5:107:18 | options.target | -| unsafe-jquery-plugin.js:107:5:107:11 | options | unsafe-jquery-plugin.js:107:5:107:18 | options.target | -| unsafe-jquery-plugin.js:114:38:114:44 | options | unsafe-jquery-plugin.js:115:51:115:57 | options | | unsafe-jquery-plugin.js:114:38:114:44 | options | unsafe-jquery-plugin.js:115:51:115:57 | options | | unsafe-jquery-plugin.js:115:3:115:58 | options | unsafe-jquery-plugin.js:117:5:117:11 | options | | unsafe-jquery-plugin.js:115:13:115:58 | $.exten ... ptions) | unsafe-jquery-plugin.js:115:3:115:58 | options | -| unsafe-jquery-plugin.js:115:22:115:23 | {} | unsafe-jquery-plugin.js:115:13:115:58 | $.exten ... ptions) | | unsafe-jquery-plugin.js:115:51:115:57 | options | unsafe-jquery-plugin.js:115:13:115:58 | $.exten ... ptions) | -| unsafe-jquery-plugin.js:115:51:115:57 | options | unsafe-jquery-plugin.js:115:22:115:23 | {} | -| unsafe-jquery-plugin.js:117:5:117:11 | options | unsafe-jquery-plugin.js:117:5:117:18 | options.target | | unsafe-jquery-plugin.js:117:5:117:11 | options | unsafe-jquery-plugin.js:117:5:117:18 | options.target | | unsafe-jquery-plugin.js:121:40:121:46 | options | unsafe-jquery-plugin.js:122:5:122:11 | options | -| unsafe-jquery-plugin.js:121:40:121:46 | options | unsafe-jquery-plugin.js:122:5:122:11 | options | -| unsafe-jquery-plugin.js:122:5:122:11 | options | unsafe-jquery-plugin.js:122:5:122:18 | options.target | | unsafe-jquery-plugin.js:122:5:122:11 | options | unsafe-jquery-plugin.js:122:5:122:18 | options.target | | unsafe-jquery-plugin.js:126:33:126:39 | options | unsafe-jquery-plugin.js:127:6:127:12 | options | -| unsafe-jquery-plugin.js:126:33:126:39 | options | unsafe-jquery-plugin.js:127:6:127:12 | options | -| unsafe-jquery-plugin.js:127:6:127:12 | options | unsafe-jquery-plugin.js:127:6:127:19 | options.target | | unsafe-jquery-plugin.js:127:6:127:12 | options | unsafe-jquery-plugin.js:127:6:127:19 | options.target | | unsafe-jquery-plugin.js:131:34:131:40 | options | unsafe-jquery-plugin.js:132:5:132:11 | options | -| unsafe-jquery-plugin.js:131:34:131:40 | options | unsafe-jquery-plugin.js:132:5:132:11 | options | -| unsafe-jquery-plugin.js:132:5:132:11 | options | unsafe-jquery-plugin.js:132:5:132:18 | options.target | | unsafe-jquery-plugin.js:132:5:132:11 | options | unsafe-jquery-plugin.js:132:5:132:18 | options.target | | unsafe-jquery-plugin.js:135:36:135:42 | options | unsafe-jquery-plugin.js:136:5:136:11 | options | -| unsafe-jquery-plugin.js:135:36:135:42 | options | unsafe-jquery-plugin.js:136:5:136:11 | options | -| unsafe-jquery-plugin.js:136:5:136:11 | options | unsafe-jquery-plugin.js:136:5:136:20 | options.viewport | -| unsafe-jquery-plugin.js:136:5:136:20 | options.viewport | unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | -| unsafe-jquery-plugin.js:136:5:136:20 | options.viewport | unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | -| unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:154:16:154:22 | options | +| unsafe-jquery-plugin.js:136:5:136:11 | options | unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:154:16:154:22 | options | | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:156:3:156:9 | options | -| unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:156:3:156:9 | options | -| unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:157:44:157:50 | options | | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:157:44:157:50 | options | | unsafe-jquery-plugin.js:154:16:154:22 | options | unsafe-jquery-plugin.js:154:16:154:29 | options.target | | unsafe-jquery-plugin.js:154:16:154:29 | options.target | unsafe-jquery-plugin.js:156:3:156:16 | options.target | @@ -240,22 +49,82 @@ edges | unsafe-jquery-plugin.js:156:3:156:16 | options.target | unsafe-jquery-plugin.js:157:44:157:57 | options.target | | unsafe-jquery-plugin.js:157:44:157:50 | options | unsafe-jquery-plugin.js:157:44:157:57 | options.target | | unsafe-jquery-plugin.js:157:44:157:57 | options.target | unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | -| unsafe-jquery-plugin.js:157:44:157:57 | options.target | unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | -| unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:165:16:165:22 | options | | unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:165:16:165:22 | options | | unsafe-jquery-plugin.js:165:7:165:29 | target | unsafe-jquery-plugin.js:170:6:170:11 | target | -| unsafe-jquery-plugin.js:165:7:165:29 | target | unsafe-jquery-plugin.js:170:6:170:11 | target | -| unsafe-jquery-plugin.js:165:16:165:22 | options | unsafe-jquery-plugin.js:165:16:165:29 | options.target | -| unsafe-jquery-plugin.js:165:16:165:29 | options.target | unsafe-jquery-plugin.js:165:7:165:29 | target | -| unsafe-jquery-plugin.js:178:27:178:33 | options | unsafe-jquery-plugin.js:179:5:179:11 | options | +| unsafe-jquery-plugin.js:165:16:165:22 | options | unsafe-jquery-plugin.js:165:7:165:29 | target | | unsafe-jquery-plugin.js:178:27:178:33 | options | unsafe-jquery-plugin.js:179:5:179:11 | options | | unsafe-jquery-plugin.js:179:5:179:11 | options | unsafe-jquery-plugin.js:179:5:179:18 | options.target | -| unsafe-jquery-plugin.js:179:5:179:11 | options | unsafe-jquery-plugin.js:179:5:179:18 | options.target | -| unsafe-jquery-plugin.js:185:28:185:34 | options | unsafe-jquery-plugin.js:186:21:186:27 | options | | unsafe-jquery-plugin.js:185:28:185:34 | options | unsafe-jquery-plugin.js:186:21:186:27 | options | | unsafe-jquery-plugin.js:186:21:186:27 | options | unsafe-jquery-plugin.js:186:21:186:30 | options.of | | unsafe-jquery-plugin.js:186:21:186:30 | options.of | unsafe-jquery-plugin.js:192:19:192:28 | options.of | -| unsafe-jquery-plugin.js:186:21:186:30 | options.of | unsafe-jquery-plugin.js:192:19:192:28 | options.of | +nodes +| unsafe-jquery-plugin.js:2:38:2:44 | options | semmle.label | options | +| unsafe-jquery-plugin.js:3:5:3:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:5:5:5:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:5:5:5:18 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:5:5:5:18 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:7:17:7:23 | options | semmle.label | options | +| unsafe-jquery-plugin.js:7:17:7:30 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:11:7:11:29 | target | semmle.label | target | +| unsafe-jquery-plugin.js:11:16:11:22 | options | semmle.label | options | +| unsafe-jquery-plugin.js:11:16:11:29 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:22:6:22:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:30:6:30:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:36:6:36:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:40:6:40:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:48:6:48:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:52:6:52:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:60:6:60:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:71:38:71:44 | options | semmle.label | options | +| unsafe-jquery-plugin.js:72:5:72:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | semmle.label | options.foo.bar.baz | +| unsafe-jquery-plugin.js:76:38:76:44 | options | semmle.label | options | +| unsafe-jquery-plugin.js:77:17:77:23 | options | semmle.label | options | +| unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | semmle.label | options.foo.bar.baz | +| unsafe-jquery-plugin.js:101:38:101:44 | options | semmle.label | options | +| unsafe-jquery-plugin.js:102:3:105:13 | options | semmle.label | options | +| unsafe-jquery-plugin.js:102:13:105:13 | $.exten ... ptions) | semmle.label | $.exten ... ptions) | +| unsafe-jquery-plugin.js:105:6:105:12 | options | semmle.label | options | +| unsafe-jquery-plugin.js:107:5:107:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:107:5:107:18 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:114:38:114:44 | options | semmle.label | options | +| unsafe-jquery-plugin.js:115:3:115:58 | options | semmle.label | options | +| unsafe-jquery-plugin.js:115:13:115:58 | $.exten ... ptions) | semmle.label | $.exten ... ptions) | +| unsafe-jquery-plugin.js:115:51:115:57 | options | semmle.label | options | +| unsafe-jquery-plugin.js:117:5:117:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:117:5:117:18 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:121:40:121:46 | options | semmle.label | options | +| unsafe-jquery-plugin.js:122:5:122:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:122:5:122:18 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:126:33:126:39 | options | semmle.label | options | +| unsafe-jquery-plugin.js:127:6:127:12 | options | semmle.label | options | +| unsafe-jquery-plugin.js:127:6:127:19 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:131:34:131:40 | options | semmle.label | options | +| unsafe-jquery-plugin.js:132:5:132:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:132:5:132:18 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:135:36:135:42 | options | semmle.label | options | +| unsafe-jquery-plugin.js:136:5:136:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | semmle.label | options ... elector | +| unsafe-jquery-plugin.js:153:38:153:44 | options | semmle.label | options | +| unsafe-jquery-plugin.js:154:16:154:22 | options | semmle.label | options | +| unsafe-jquery-plugin.js:154:16:154:29 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:156:3:156:9 | options | semmle.label | options | +| unsafe-jquery-plugin.js:156:3:156:16 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:157:44:157:50 | options | semmle.label | options | +| unsafe-jquery-plugin.js:157:44:157:57 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | semmle.label | options.target.a | +| unsafe-jquery-plugin.js:160:38:160:44 | options | semmle.label | options | +| unsafe-jquery-plugin.js:165:7:165:29 | target | semmle.label | target | +| unsafe-jquery-plugin.js:165:16:165:22 | options | semmle.label | options | +| unsafe-jquery-plugin.js:170:6:170:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:178:27:178:33 | options | semmle.label | options | +| unsafe-jquery-plugin.js:179:5:179:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:179:5:179:18 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:185:28:185:34 | options | semmle.label | options | +| unsafe-jquery-plugin.js:186:21:186:27 | options | semmle.label | options | +| unsafe-jquery-plugin.js:186:21:186:30 | options.of | semmle.label | options.of | +| unsafe-jquery-plugin.js:192:19:192:28 | options.of | semmle.label | options.of | +subpaths #select | unsafe-jquery-plugin.js:3:5:3:11 | options | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:3:5:3:11 | options | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:2:19:63:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:5:5:5:18 | options.target | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:5:5:5:18 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:2:19:63:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin | @@ -266,10 +135,8 @@ edges | unsafe-jquery-plugin.js:48:6:48:11 | target | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:48:6:48:11 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:2:19:63:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:52:6:52:11 | target | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:52:6:52:11 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:2:19:63:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:60:6:60:11 | target | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:60:6:60:11 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:2:19:63:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin | -| unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | unsafe-jquery-plugin.js:65:47:65:53 | options | unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:65:19:69:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | unsafe-jquery-plugin.js:71:38:71:44 | options | unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:71:19:74:2 | functio ... / OK\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | unsafe-jquery-plugin.js:76:38:76:44 | options | unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:76:19:78:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin | -| unsafe-jquery-plugin.js:90:6:90:6 | t | unsafe-jquery-plugin.js:84:38:84:44 | options | unsafe-jquery-plugin.js:90:6:90:6 | t | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:84:19:93:2 | functio ... ns);\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:107:5:107:18 | options.target | unsafe-jquery-plugin.js:101:38:101:44 | options | unsafe-jquery-plugin.js:107:5:107:18 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:101:19:108:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:117:5:117:18 | options.target | unsafe-jquery-plugin.js:114:38:114:44 | options | unsafe-jquery-plugin.js:117:5:117:18 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:114:19:118:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:122:5:122:18 | options.target | unsafe-jquery-plugin.js:121:40:121:46 | options | unsafe-jquery-plugin.js:122:5:122:18 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:121:21:123:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin | From ba9edb4e549f140104c5209b3bf9cd2fa00e8665 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:26:09 +0200 Subject: [PATCH 100/514] JS: Port UnsafeShellCommandConstruction --- ...ShellCommandConstructionCustomizations.qll | 27 +- .../UnsafeShellCommandConstructionQuery.qll | 33 +- .../CWE-078/UnsafeShellCommandConstruction.ql | 8 +- .../UnsafeShellCommandConstruction.expected | 885 +++++------------- 4 files changed, 280 insertions(+), 673 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll index 77625874df9..9a6710217e5 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll @@ -46,6 +46,21 @@ module UnsafeShellCommandConstruction { */ abstract class Sanitizer extends DataFlow::Node { } + /** + * A barrier guard for shell command constructed from library input vulnerabilities. + */ + 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() } + } + + /** 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) } + } + /** * A parameter of an exported function, seen as a source for shell command constructed from library input. */ @@ -270,13 +285,13 @@ module UnsafeShellCommandConstruction { * A sanitizer that sanitizers paths that exist in the file-system. * For example: `x` is sanitized in `fs.existsSync(x)` or `fs.existsSync(x + "/suffix/path")`. */ - class PathExistsSanitizerGuard extends TaintTracking::SanitizerGuardNode, DataFlow::CallNode { + class PathExistsSanitizerGuard extends BarrierGuardLegacy, DataFlow::CallNode { PathExistsSanitizerGuard() { this = DataFlow::moduleMember("path", "exist").getACall() or this = DataFlow::moduleMember("fs", "existsSync").getACall() } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { outcome = true and ( e = this.getArgument(0).asExpr() or @@ -289,26 +304,26 @@ module UnsafeShellCommandConstruction { * A guard of the form `typeof x === ""`, where `` is "number", or "boolean", * which sanitizes `x` in its "then" branch. */ - class TypeOfSanitizer extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode { + class TypeOfSanitizer extends BarrierGuardLegacy, DataFlow::ValueNode { Expr x; override EqualityTest astNode; TypeOfSanitizer() { TaintTracking::isTypeofGuard(astNode, x, ["number", "boolean"]) } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { outcome = astNode.getPolarity() and e = x } } /** 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 } } private import semmle.javascript.dataflow.internal.AccessPaths diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionQuery.qll index 7d5dae90209..1704bf3e3e6 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionQuery.qll @@ -13,7 +13,38 @@ import UnsafeShellCommandConstructionCustomizations::UnsafeShellCommandConstruct /** * A taint-tracking configuration for reasoning about shell command constructed from library input vulnerabilities. */ -class Configuration extends TaintTracking::Configuration { +module UnsafeShellCommandConstructionConfig implements DataFlow::ConfigSig { + // TODO: we get a FP in the test case due to SanitizingRegExpTest not being able to generate a barrier edge + // for an edge into a phi node. + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { + node instanceof Sanitizer or + node = DataFlow::MakeBarrierGuard::getABarrierNode() or + node = TaintTracking::AdHocWhitelistCheckSanitizer::getABarrierNode() + } + + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { + none() + // TODO: localFieldStep is too expensive with dataflow2 + // DataFlow::localFieldStep(pred, succ) + } + + DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext } +} + +/** + * Taint-tracking for reasoning about shell command constructed from library input vulnerabilities. + */ +module UnsafeShellCommandConstructionFlow = + TaintTracking::Global; + +/** + * DEPRECATED. Use the `UnsafeShellCommandConstructionFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "UnsafeShellCommandConstruction" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-078/UnsafeShellCommandConstruction.ql b/javascript/ql/src/Security/CWE-078/UnsafeShellCommandConstruction.ql index 3b96b6beffb..4b866c9cfff 100644 --- a/javascript/ql/src/Security/CWE-078/UnsafeShellCommandConstruction.ql +++ b/javascript/ql/src/Security/CWE-078/UnsafeShellCommandConstruction.ql @@ -15,10 +15,12 @@ import javascript import semmle.javascript.security.dataflow.UnsafeShellCommandConstructionQuery -import DataFlow::PathGraph +import UnsafeShellCommandConstructionFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Sink sinkNode -where cfg.hasFlowPath(source, sink) and sinkNode = sink.getNode() +from + UnsafeShellCommandConstructionFlow::PathNode source, + UnsafeShellCommandConstructionFlow::PathNode sink, Sink sinkNode +where UnsafeShellCommandConstructionFlow::flowPath(source, sink) and sinkNode = sink.getNode() select sinkNode.getAlertLocation(), source, sink, "This " + sinkNode.getSinkType() + " which depends on $@ is later used in a $@.", source.getNode(), "library input", sinkNode.getCommandExecution(), "shell command" diff --git a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected index b4022c8550c..4755cc2a0ae 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected @@ -1,787 +1,346 @@ -nodes -| lib/isImported.js:5:49:5:52 | name | -| lib/isImported.js:5:49:5:52 | name | -| lib/isImported.js:6:22:6:25 | name | -| lib/isImported.js:6:22:6:25 | name | -| lib/lib2.js:3:28:3:31 | name | -| lib/lib2.js:3:28:3:31 | name | -| lib/lib2.js:4:22:4:25 | name | -| lib/lib2.js:4:22:4:25 | name | -| lib/lib2.js:7:32:7:35 | name | -| lib/lib2.js:7:32:7:35 | name | -| lib/lib2.js:8:22:8:25 | name | -| lib/lib2.js:8:22:8:25 | name | -| lib/lib.js:3:28:3:31 | name | -| lib/lib.js:3:28:3:31 | name | -| lib/lib.js:4:22:4:25 | name | -| lib/lib.js:4:22:4:25 | name | -| lib/lib.js:10:32:10:35 | name | -| lib/lib.js:10:32:10:35 | name | -| lib/lib.js:11:22:11:25 | name | -| lib/lib.js:11:22:11:25 | name | -| lib/lib.js:14:36:14:39 | name | -| lib/lib.js:14:36:14:39 | name | -| lib/lib.js:15:22:15:25 | name | -| lib/lib.js:15:22:15:25 | name | -| lib/lib.js:19:34:19:37 | name | -| lib/lib.js:19:34:19:37 | name | -| lib/lib.js:20:22:20:25 | name | -| lib/lib.js:20:22:20:25 | name | -| lib/lib.js:26:35:26:38 | name | -| lib/lib.js:26:35:26:38 | name | -| lib/lib.js:27:22:27:25 | name | -| lib/lib.js:27:22:27:25 | name | -| lib/lib.js:34:14:34:17 | name | -| lib/lib.js:34:14:34:17 | name | -| lib/lib.js:35:23:35:26 | name | -| lib/lib.js:35:23:35:26 | name | -| lib/lib.js:37:13:37:16 | name | -| lib/lib.js:37:13:37:16 | name | -| lib/lib.js:38:23:38:26 | name | -| lib/lib.js:38:23:38:26 | name | -| lib/lib.js:40:6:40:9 | name | -| lib/lib.js:40:6:40:9 | name | -| lib/lib.js:41:23:41:26 | name | -| lib/lib.js:41:23:41:26 | name | -| lib/lib.js:49:31:49:34 | name | -| lib/lib.js:49:31:49:34 | name | -| lib/lib.js:50:47:50:50 | name | -| lib/lib.js:50:47:50:50 | name | -| lib/lib.js:53:33:53:36 | name | -| lib/lib.js:53:33:53:36 | name | -| lib/lib.js:54:25:54:28 | name | -| lib/lib.js:54:25:54:28 | name | -| lib/lib.js:57:25:57:28 | name | -| lib/lib.js:57:25:57:28 | name | -| lib/lib.js:64:41:64:44 | name | -| lib/lib.js:64:41:64:44 | name | -| lib/lib.js:65:22:65:25 | name | -| lib/lib.js:65:22:65:25 | name | -| lib/lib.js:69:27:69:30 | name | -| lib/lib.js:69:27:69:30 | name | -| lib/lib.js:71:28:71:31 | name | -| lib/lib.js:71:28:71:31 | name | -| lib/lib.js:73:21:73:24 | name | -| lib/lib.js:73:21:73:24 | name | -| lib/lib.js:75:20:75:23 | name | -| lib/lib.js:75:20:75:23 | name | -| lib/lib.js:77:28:77:31 | name | -| lib/lib.js:77:28:77:31 | name | -| lib/lib.js:82:35:82:38 | name | -| lib/lib.js:82:35:82:38 | name | -| lib/lib.js:83:22:83:25 | name | -| lib/lib.js:83:22:83:25 | name | -| lib/lib.js:86:13:86:16 | name | -| lib/lib.js:86:13:86:16 | name | -| lib/lib.js:89:21:89:24 | name | -| lib/lib.js:89:21:89:24 | name | -| lib/lib.js:91:21:91:38 | "\\"" + name + "\\"" | -| lib/lib.js:91:21:91:38 | "\\"" + name + "\\"" | -| lib/lib.js:91:28:91:31 | name | -| lib/lib.js:97:35:97:38 | name | -| lib/lib.js:97:35:97:38 | name | -| lib/lib.js:98:35:98:38 | name | -| lib/lib.js:98:35:98:38 | name | -| lib/lib.js:100:37:100:40 | name | -| lib/lib.js:100:37:100:40 | name | -| lib/lib.js:102:46:102:49 | name | -| lib/lib.js:102:46:102:49 | name | -| lib/lib.js:108:41:108:44 | name | -| lib/lib.js:108:41:108:44 | name | -| lib/lib.js:111:34:111:37 | name | -| lib/lib.js:111:34:111:37 | name | -| lib/lib.js:112:22:112:25 | name | -| lib/lib.js:112:22:112:25 | name | -| lib/lib.js:120:33:120:36 | name | -| lib/lib.js:120:33:120:36 | name | -| lib/lib.js:121:22:121:25 | name | -| lib/lib.js:121:22:121:25 | name | -| lib/lib.js:130:6:130:9 | name | -| lib/lib.js:130:6:130:9 | name | -| lib/lib.js:131:23:131:26 | name | -| lib/lib.js:131:23:131:26 | name | -| lib/lib.js:148:37:148:40 | name | -| lib/lib.js:148:37:148:40 | name | -| lib/lib.js:149:24:149:27 | name | -| lib/lib.js:149:24:149:27 | name | -| lib/lib.js:155:38:155:41 | name | -| lib/lib.js:155:38:155:41 | name | -| lib/lib.js:161:25:161:28 | name | -| lib/lib.js:161:25:161:28 | name | -| lib/lib.js:170:41:170:44 | name | -| lib/lib.js:170:41:170:44 | name | -| lib/lib.js:173:20:173:23 | name | -| lib/lib.js:173:20:173:23 | name | -| lib/lib.js:177:38:177:41 | name | -| lib/lib.js:177:38:177:41 | name | -| lib/lib.js:181:6:181:52 | broken | -| lib/lib.js:181:15:181:52 | "'" + n ... ) + "'" | -| lib/lib.js:181:21:181:24 | name | -| lib/lib.js:181:21:181:46 | name.re ... "'\\''") | -| lib/lib.js:181:21:181:46 | name.re ... "'\\''") | -| lib/lib.js:182:22:182:27 | broken | -| lib/lib.js:182:22:182:27 | broken | -| lib/lib.js:186:34:186:37 | name | -| lib/lib.js:186:34:186:37 | name | -| lib/lib.js:187:22:187:25 | name | -| lib/lib.js:187:22:187:25 | name | -| lib/lib.js:190:23:190:26 | name | -| lib/lib.js:190:23:190:26 | name | -| lib/lib.js:196:45:196:48 | name | -| lib/lib.js:196:45:196:48 | name | -| lib/lib.js:197:22:197:25 | name | -| lib/lib.js:197:22:197:25 | name | -| lib/lib.js:200:23:200:26 | name | -| lib/lib.js:200:23:200:26 | name | -| lib/lib.js:206:45:206:48 | name | -| lib/lib.js:206:45:206:48 | name | -| lib/lib.js:207:22:207:25 | name | -| lib/lib.js:207:22:207:25 | name | -| lib/lib.js:212:23:212:26 | name | -| lib/lib.js:212:23:212:26 | name | -| lib/lib.js:216:39:216:42 | name | -| lib/lib.js:216:39:216:42 | name | -| lib/lib.js:217:22:217:25 | name | -| lib/lib.js:217:22:217:25 | name | -| lib/lib.js:220:23:220:26 | name | -| lib/lib.js:220:23:220:26 | name | -| lib/lib.js:224:22:224:25 | name | -| lib/lib.js:224:22:224:25 | name | -| lib/lib.js:227:39:227:42 | name | -| lib/lib.js:227:39:227:42 | name | -| lib/lib.js:228:22:228:25 | name | -| lib/lib.js:228:22:228:25 | name | -| lib/lib.js:236:22:236:25 | name | -| lib/lib.js:236:22:236:25 | name | -| lib/lib.js:248:42:248:45 | name | -| lib/lib.js:248:42:248:45 | name | -| lib/lib.js:249:22:249:25 | name | -| lib/lib.js:249:22:249:25 | name | -| lib/lib.js:257:35:257:38 | name | -| lib/lib.js:257:35:257:38 | name | -| lib/lib.js:258:22:258:25 | name | -| lib/lib.js:258:22:258:25 | name | -| lib/lib.js:261:30:261:33 | name | -| lib/lib.js:261:30:261:33 | name | -| lib/lib.js:267:46:267:48 | obj | -| lib/lib.js:267:46:267:48 | obj | -| lib/lib.js:268:22:268:24 | obj | -| lib/lib.js:268:22:268:32 | obj.version | -| lib/lib.js:268:22:268:32 | obj.version | -| lib/lib.js:276:8:276:11 | opts | -| lib/lib.js:276:8:276:11 | opts | -| lib/lib.js:277:23:277:26 | opts | -| lib/lib.js:277:23:277:30 | opts.bla | -| lib/lib.js:277:23:277:30 | opts.bla | -| lib/lib.js:279:19:279:22 | opts | -| lib/lib.js:279:19:279:26 | opts.bla | -| lib/lib.js:281:23:281:35 | this.opts.bla | -| lib/lib.js:281:23:281:35 | this.opts.bla | -| lib/lib.js:307:39:307:42 | name | -| lib/lib.js:307:39:307:42 | name | -| lib/lib.js:308:23:308:26 | name | -| lib/lib.js:308:23:308:26 | name | -| lib/lib.js:314:40:314:43 | name | -| lib/lib.js:314:40:314:43 | name | -| lib/lib.js:315:22:315:25 | name | -| lib/lib.js:315:22:315:25 | name | -| lib/lib.js:320:23:320:26 | name | -| lib/lib.js:320:23:320:26 | name | -| lib/lib.js:324:40:324:42 | arg | -| lib/lib.js:324:40:324:42 | arg | -| lib/lib.js:325:49:325:51 | arg | -| lib/lib.js:325:49:325:51 | arg | -| lib/lib.js:329:13:329:13 | x | -| lib/lib.js:329:13:329:13 | x | -| lib/lib.js:330:9:330:9 | x | -| lib/lib.js:336:22:336:31 | id("test") | -| lib/lib.js:336:22:336:31 | id("test") | -| lib/lib.js:339:39:339:39 | n | -| lib/lib.js:339:39:339:39 | n | -| lib/lib.js:340:22:340:26 | id(n) | -| lib/lib.js:340:22:340:26 | id(n) | -| lib/lib.js:340:22:340:26 | id(n) | -| lib/lib.js:340:25:340:25 | n | -| lib/lib.js:349:29:349:34 | unsafe | -| lib/lib.js:349:29:349:34 | unsafe | -| lib/lib.js:351:22:351:27 | unsafe | -| lib/lib.js:351:22:351:27 | unsafe | -| lib/lib.js:360:20:360:23 | opts | -| lib/lib.js:360:20:360:23 | opts | -| lib/lib.js:361:20:361:23 | opts | -| lib/lib.js:361:20:361:34 | opts.learn_args | -| lib/lib.js:366:28:366:42 | this.learn_args | -| lib/lib.js:366:28:366:42 | this.learn_args | -| lib/lib.js:405:39:405:42 | name | -| lib/lib.js:405:39:405:42 | name | -| lib/lib.js:406:22:406:25 | name | -| lib/lib.js:406:22:406:25 | name | -| lib/lib.js:414:40:414:43 | name | -| lib/lib.js:414:40:414:43 | name | -| lib/lib.js:415:22:415:25 | name | -| lib/lib.js:415:22:415:25 | name | -| lib/lib.js:417:28:417:31 | name | -| lib/lib.js:417:28:417:31 | name | -| lib/lib.js:418:25:418:28 | name | -| lib/lib.js:418:25:418:28 | name | -| lib/lib.js:419:32:419:35 | name | -| lib/lib.js:419:32:419:35 | name | -| lib/lib.js:420:29:420:32 | name | -| lib/lib.js:420:29:420:32 | name | -| lib/lib.js:424:24:424:27 | name | -| lib/lib.js:424:24:424:27 | name | -| lib/lib.js:425:6:425:13 | arr | -| lib/lib.js:425:12:425:13 | [] | -| lib/lib.js:426:11:426:14 | name | -| lib/lib.js:426:11:426:14 | name | -| lib/lib.js:427:14:427:16 | arr | -| lib/lib.js:427:14:427:16 | arr | -| lib/lib.js:428:14:428:58 | build(" ... + '-') | -| lib/lib.js:428:14:428:58 | build(" ... + '-') | -| lib/lib.js:428:28:428:51 | (name ? ... ' : '') | -| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | -| lib/lib.js:428:29:428:50 | name ? ... :' : '' | -| lib/lib.js:428:36:428:39 | name | -| lib/lib.js:428:36:428:45 | name + ':' | -| lib/lib.js:431:23:431:26 | last | -| lib/lib.js:436:19:436:22 | last | -| lib/lib.js:436:19:436:22 | last | -| lib/lib.js:441:39:441:42 | name | -| lib/lib.js:441:39:441:42 | name | -| lib/lib.js:442:24:442:27 | name | -| lib/lib.js:442:24:442:27 | name | -| lib/lib.js:446:20:446:23 | name | -| lib/lib.js:446:20:446:23 | name | -| lib/lib.js:447:25:447:28 | name | -| lib/lib.js:447:25:447:28 | name | -| lib/lib.js:477:33:477:38 | config | -| lib/lib.js:477:33:477:38 | config | -| lib/lib.js:478:27:478:32 | config | -| lib/lib.js:478:27:478:46 | config.installedPath | -| lib/lib.js:478:27:478:46 | config.installedPath | -| lib/lib.js:482:40:482:43 | name | -| lib/lib.js:482:40:482:43 | name | -| lib/lib.js:483:30:483:33 | name | -| lib/lib.js:483:30:483:33 | name | -| lib/lib.js:498:45:498:48 | name | -| lib/lib.js:498:45:498:48 | name | -| lib/lib.js:499:31:499:34 | name | -| lib/lib.js:499:31:499:34 | name | -| lib/lib.js:509:39:509:42 | name | -| lib/lib.js:509:39:509:42 | name | -| lib/lib.js:510:22:510:25 | name | -| lib/lib.js:510:22:510:25 | name | -| lib/lib.js:513:23:513:26 | name | -| lib/lib.js:513:23:513:26 | name | -| lib/lib.js:519:23:519:26 | name | -| lib/lib.js:519:23:519:26 | name | -| lib/lib.js:525:23:525:26 | name | -| lib/lib.js:525:23:525:26 | name | -| lib/lib.js:531:23:531:26 | name | -| lib/lib.js:531:23:531:26 | name | -| lib/lib.js:537:23:537:26 | name | -| lib/lib.js:537:23:537:26 | name | -| lib/lib.js:543:23:543:26 | name | -| lib/lib.js:543:23:543:26 | name | -| lib/lib.js:545:23:545:26 | name | -| lib/lib.js:545:23:545:26 | name | -| lib/lib.js:550:39:550:42 | name | -| lib/lib.js:550:39:550:42 | name | -| lib/lib.js:551:33:551:36 | args | -| lib/lib.js:552:23:552:26 | args | -| lib/lib.js:552:23:552:26 | args | -| lib/lib.js:555:25:555:37 | ["-rf", name] | -| lib/lib.js:555:33:555:36 | name | -| lib/lib.js:555:33:555:36 | name | -| lib/lib.js:558:41:558:44 | name | -| lib/lib.js:558:41:558:44 | name | -| lib/lib.js:560:26:560:29 | name | -| lib/lib.js:560:26:560:29 | name | -| lib/lib.js:562:26:562:29 | name | -| lib/lib.js:562:26:562:29 | name | -| lib/lib.js:566:26:566:29 | name | -| lib/lib.js:566:26:566:29 | name | -| lib/lib.js:572:41:572:44 | name | -| lib/lib.js:572:41:572:44 | name | -| lib/lib.js:573:22:573:25 | name | -| lib/lib.js:573:22:573:25 | name | -| lib/lib.js:579:25:579:28 | name | -| lib/lib.js:579:25:579:28 | name | -| lib/lib.js:590:29:590:32 | name | -| lib/lib.js:590:29:590:32 | name | -| lib/lib.js:593:25:593:28 | name | -| lib/lib.js:593:25:593:28 | name | -| lib/lib.js:608:42:608:45 | name | -| lib/lib.js:608:42:608:45 | name | -| lib/lib.js:609:22:609:25 | name | -| lib/lib.js:609:22:609:25 | name | -| lib/lib.js:626:29:626:32 | name | -| lib/lib.js:626:29:626:32 | name | -| lib/lib.js:629:25:629:28 | name | -| lib/lib.js:629:25:629:28 | name | -| lib/subLib2/compiled-file.ts:3:26:3:29 | name | -| lib/subLib2/compiled-file.ts:3:26:3:29 | name | -| lib/subLib2/compiled-file.ts:4:25:4:28 | name | -| lib/subLib2/compiled-file.ts:4:25:4:28 | name | -| lib/subLib2/special-file.js:3:28:3:31 | name | -| lib/subLib2/special-file.js:3:28:3:31 | name | -| lib/subLib2/special-file.js:4:22:4:25 | name | -| lib/subLib2/special-file.js:4:22:4:25 | name | -| lib/subLib3/my-file.ts:3:28:3:31 | name | -| lib/subLib3/my-file.ts:3:28:3:31 | name | -| lib/subLib3/my-file.ts:4:22:4:25 | name | -| lib/subLib3/my-file.ts:4:22:4:25 | name | -| lib/subLib4/index.js:6:32:6:35 | name | -| lib/subLib4/index.js:6:32:6:35 | name | -| lib/subLib4/index.js:7:18:7:21 | name | -| lib/subLib4/subsub.js:3:28:3:31 | name | -| lib/subLib4/subsub.js:4:22:4:25 | name | -| lib/subLib4/subsub.js:4:22:4:25 | name | -| lib/subLib/amdSub.js:3:28:3:31 | name | -| lib/subLib/amdSub.js:3:28:3:31 | name | -| lib/subLib/amdSub.js:4:22:4:25 | name | -| lib/subLib/amdSub.js:4:22:4:25 | name | -| lib/subLib/index.js:3:28:3:31 | name | -| lib/subLib/index.js:3:28:3:31 | name | -| lib/subLib/index.js:4:22:4:25 | name | -| lib/subLib/index.js:4:22:4:25 | name | -| lib/subLib/index.js:7:32:7:35 | name | -| lib/subLib/index.js:7:32:7:35 | name | -| lib/subLib/index.js:8:22:8:25 | name | -| lib/subLib/index.js:8:22:8:25 | name | -| lib/subLib/index.js:13:44:13:46 | arr | -| lib/subLib/index.js:13:44:13:46 | arr | -| lib/subLib/index.js:14:22:14:24 | arr | -| lib/subLib/index.js:14:22:14:24 | arr | edges | lib/isImported.js:5:49:5:52 | name | lib/isImported.js:6:22:6:25 | name | -| lib/isImported.js:5:49:5:52 | name | lib/isImported.js:6:22:6:25 | name | -| lib/isImported.js:5:49:5:52 | name | lib/isImported.js:6:22:6:25 | name | -| lib/isImported.js:5:49:5:52 | name | lib/isImported.js:6:22:6:25 | name | -| lib/lib2.js:3:28:3:31 | name | lib/lib2.js:4:22:4:25 | name | -| lib/lib2.js:3:28:3:31 | name | lib/lib2.js:4:22:4:25 | name | -| lib/lib2.js:3:28:3:31 | name | lib/lib2.js:4:22:4:25 | name | | lib/lib2.js:3:28:3:31 | name | lib/lib2.js:4:22:4:25 | name | | lib/lib2.js:7:32:7:35 | name | lib/lib2.js:8:22:8:25 | name | -| lib/lib2.js:7:32:7:35 | name | lib/lib2.js:8:22:8:25 | name | -| lib/lib2.js:7:32:7:35 | name | lib/lib2.js:8:22:8:25 | name | -| lib/lib2.js:7:32:7:35 | name | lib/lib2.js:8:22:8:25 | name | -| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:22:4:25 | name | -| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:22:4:25 | name | -| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:22:4:25 | name | | lib/lib.js:3:28:3:31 | name | lib/lib.js:4:22:4:25 | name | | lib/lib.js:10:32:10:35 | name | lib/lib.js:11:22:11:25 | name | -| lib/lib.js:10:32:10:35 | name | lib/lib.js:11:22:11:25 | name | -| lib/lib.js:10:32:10:35 | name | lib/lib.js:11:22:11:25 | name | -| lib/lib.js:10:32:10:35 | name | lib/lib.js:11:22:11:25 | name | -| lib/lib.js:14:36:14:39 | name | lib/lib.js:15:22:15:25 | name | -| lib/lib.js:14:36:14:39 | name | lib/lib.js:15:22:15:25 | name | -| lib/lib.js:14:36:14:39 | name | lib/lib.js:15:22:15:25 | name | | lib/lib.js:14:36:14:39 | name | lib/lib.js:15:22:15:25 | name | | lib/lib.js:19:34:19:37 | name | lib/lib.js:20:22:20:25 | name | -| lib/lib.js:19:34:19:37 | name | lib/lib.js:20:22:20:25 | name | -| lib/lib.js:19:34:19:37 | name | lib/lib.js:20:22:20:25 | name | -| lib/lib.js:19:34:19:37 | name | lib/lib.js:20:22:20:25 | name | -| lib/lib.js:26:35:26:38 | name | lib/lib.js:27:22:27:25 | name | -| lib/lib.js:26:35:26:38 | name | lib/lib.js:27:22:27:25 | name | -| lib/lib.js:26:35:26:38 | name | lib/lib.js:27:22:27:25 | name | | lib/lib.js:26:35:26:38 | name | lib/lib.js:27:22:27:25 | name | | lib/lib.js:34:14:34:17 | name | lib/lib.js:35:23:35:26 | name | -| lib/lib.js:34:14:34:17 | name | lib/lib.js:35:23:35:26 | name | -| lib/lib.js:34:14:34:17 | name | lib/lib.js:35:23:35:26 | name | -| lib/lib.js:34:14:34:17 | name | lib/lib.js:35:23:35:26 | name | -| lib/lib.js:37:13:37:16 | name | lib/lib.js:38:23:38:26 | name | -| lib/lib.js:37:13:37:16 | name | lib/lib.js:38:23:38:26 | name | -| lib/lib.js:37:13:37:16 | name | lib/lib.js:38:23:38:26 | name | | lib/lib.js:37:13:37:16 | name | lib/lib.js:38:23:38:26 | name | | lib/lib.js:40:6:40:9 | name | lib/lib.js:41:23:41:26 | name | -| lib/lib.js:40:6:40:9 | name | lib/lib.js:41:23:41:26 | name | -| lib/lib.js:40:6:40:9 | name | lib/lib.js:41:23:41:26 | name | -| lib/lib.js:40:6:40:9 | name | lib/lib.js:41:23:41:26 | name | -| lib/lib.js:49:31:49:34 | name | lib/lib.js:50:47:50:50 | name | -| lib/lib.js:49:31:49:34 | name | lib/lib.js:50:47:50:50 | name | -| lib/lib.js:49:31:49:34 | name | lib/lib.js:50:47:50:50 | name | | lib/lib.js:49:31:49:34 | name | lib/lib.js:50:47:50:50 | name | | lib/lib.js:53:33:53:36 | name | lib/lib.js:54:25:54:28 | name | -| lib/lib.js:53:33:53:36 | name | lib/lib.js:54:25:54:28 | name | -| lib/lib.js:53:33:53:36 | name | lib/lib.js:54:25:54:28 | name | -| lib/lib.js:53:33:53:36 | name | lib/lib.js:54:25:54:28 | name | -| lib/lib.js:53:33:53:36 | name | lib/lib.js:57:25:57:28 | name | -| lib/lib.js:53:33:53:36 | name | lib/lib.js:57:25:57:28 | name | -| lib/lib.js:53:33:53:36 | name | lib/lib.js:57:25:57:28 | name | | lib/lib.js:53:33:53:36 | name | lib/lib.js:57:25:57:28 | name | | lib/lib.js:64:41:64:44 | name | lib/lib.js:65:22:65:25 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:65:22:65:25 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:65:22:65:25 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:65:22:65:25 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:69:27:69:30 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:69:27:69:30 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:69:27:69:30 | name | | lib/lib.js:64:41:64:44 | name | lib/lib.js:69:27:69:30 | name | | lib/lib.js:64:41:64:44 | name | lib/lib.js:71:28:71:31 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:71:28:71:31 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:71:28:71:31 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:71:28:71:31 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:73:21:73:24 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:73:21:73:24 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:73:21:73:24 | name | | lib/lib.js:64:41:64:44 | name | lib/lib.js:73:21:73:24 | name | | lib/lib.js:64:41:64:44 | name | lib/lib.js:75:20:75:23 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:75:20:75:23 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:75:20:75:23 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:75:20:75:23 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:77:28:77:31 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:77:28:77:31 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:77:28:77:31 | name | | lib/lib.js:64:41:64:44 | name | lib/lib.js:77:28:77:31 | name | | lib/lib.js:82:35:82:38 | name | lib/lib.js:83:22:83:25 | name | -| lib/lib.js:82:35:82:38 | name | lib/lib.js:83:22:83:25 | name | -| lib/lib.js:82:35:82:38 | name | lib/lib.js:83:22:83:25 | name | -| lib/lib.js:82:35:82:38 | name | lib/lib.js:83:22:83:25 | name | | lib/lib.js:82:35:82:38 | name | lib/lib.js:86:13:86:16 | name | -| lib/lib.js:82:35:82:38 | name | lib/lib.js:86:13:86:16 | name | -| lib/lib.js:82:35:82:38 | name | lib/lib.js:86:13:86:16 | name | -| lib/lib.js:82:35:82:38 | name | lib/lib.js:86:13:86:16 | name | -| lib/lib.js:82:35:82:38 | name | lib/lib.js:89:21:89:24 | name | -| lib/lib.js:82:35:82:38 | name | lib/lib.js:89:21:89:24 | name | -| lib/lib.js:82:35:82:38 | name | lib/lib.js:89:21:89:24 | name | | lib/lib.js:82:35:82:38 | name | lib/lib.js:89:21:89:24 | name | | lib/lib.js:82:35:82:38 | name | lib/lib.js:91:28:91:31 | name | -| lib/lib.js:82:35:82:38 | name | lib/lib.js:91:28:91:31 | name | -| lib/lib.js:91:28:91:31 | name | lib/lib.js:91:21:91:38 | "\\"" + name + "\\"" | | lib/lib.js:91:28:91:31 | name | lib/lib.js:91:21:91:38 | "\\"" + name + "\\"" | | lib/lib.js:97:35:97:38 | name | lib/lib.js:98:35:98:38 | name | -| lib/lib.js:97:35:97:38 | name | lib/lib.js:98:35:98:38 | name | -| lib/lib.js:97:35:97:38 | name | lib/lib.js:98:35:98:38 | name | -| lib/lib.js:97:35:97:38 | name | lib/lib.js:98:35:98:38 | name | -| lib/lib.js:97:35:97:38 | name | lib/lib.js:100:37:100:40 | name | -| lib/lib.js:97:35:97:38 | name | lib/lib.js:100:37:100:40 | name | -| lib/lib.js:97:35:97:38 | name | lib/lib.js:100:37:100:40 | name | | lib/lib.js:97:35:97:38 | name | lib/lib.js:100:37:100:40 | name | | lib/lib.js:97:35:97:38 | name | lib/lib.js:102:46:102:49 | name | -| lib/lib.js:97:35:97:38 | name | lib/lib.js:102:46:102:49 | name | -| lib/lib.js:97:35:97:38 | name | lib/lib.js:102:46:102:49 | name | -| lib/lib.js:97:35:97:38 | name | lib/lib.js:102:46:102:49 | name | -| lib/lib.js:97:35:97:38 | name | lib/lib.js:108:41:108:44 | name | -| lib/lib.js:97:35:97:38 | name | lib/lib.js:108:41:108:44 | name | -| lib/lib.js:97:35:97:38 | name | lib/lib.js:108:41:108:44 | name | | lib/lib.js:97:35:97:38 | name | lib/lib.js:108:41:108:44 | name | | lib/lib.js:111:34:111:37 | name | lib/lib.js:112:22:112:25 | name | -| lib/lib.js:111:34:111:37 | name | lib/lib.js:112:22:112:25 | name | -| lib/lib.js:111:34:111:37 | name | lib/lib.js:112:22:112:25 | name | -| lib/lib.js:111:34:111:37 | name | lib/lib.js:112:22:112:25 | name | -| lib/lib.js:120:33:120:36 | name | lib/lib.js:121:22:121:25 | name | -| lib/lib.js:120:33:120:36 | name | lib/lib.js:121:22:121:25 | name | -| lib/lib.js:120:33:120:36 | name | lib/lib.js:121:22:121:25 | name | | lib/lib.js:120:33:120:36 | name | lib/lib.js:121:22:121:25 | name | | lib/lib.js:130:6:130:9 | name | lib/lib.js:131:23:131:26 | name | -| lib/lib.js:130:6:130:9 | name | lib/lib.js:131:23:131:26 | name | -| lib/lib.js:130:6:130:9 | name | lib/lib.js:131:23:131:26 | name | -| lib/lib.js:130:6:130:9 | name | lib/lib.js:131:23:131:26 | name | -| lib/lib.js:148:37:148:40 | name | lib/lib.js:149:24:149:27 | name | -| lib/lib.js:148:37:148:40 | name | lib/lib.js:149:24:149:27 | name | -| lib/lib.js:148:37:148:40 | name | lib/lib.js:149:24:149:27 | name | | lib/lib.js:148:37:148:40 | name | lib/lib.js:149:24:149:27 | name | | lib/lib.js:155:38:155:41 | name | lib/lib.js:161:25:161:28 | name | -| lib/lib.js:155:38:155:41 | name | lib/lib.js:161:25:161:28 | name | -| lib/lib.js:155:38:155:41 | name | lib/lib.js:161:25:161:28 | name | -| lib/lib.js:155:38:155:41 | name | lib/lib.js:161:25:161:28 | name | -| lib/lib.js:170:41:170:44 | name | lib/lib.js:173:20:173:23 | name | -| lib/lib.js:170:41:170:44 | name | lib/lib.js:173:20:173:23 | name | -| lib/lib.js:170:41:170:44 | name | lib/lib.js:173:20:173:23 | name | | lib/lib.js:170:41:170:44 | name | lib/lib.js:173:20:173:23 | name | | lib/lib.js:177:38:177:41 | name | lib/lib.js:181:21:181:24 | name | -| lib/lib.js:177:38:177:41 | name | lib/lib.js:181:21:181:24 | name | | lib/lib.js:181:6:181:52 | broken | lib/lib.js:182:22:182:27 | broken | -| lib/lib.js:181:6:181:52 | broken | lib/lib.js:182:22:182:27 | broken | -| lib/lib.js:181:15:181:52 | "'" + n ... ) + "'" | lib/lib.js:181:6:181:52 | broken | | lib/lib.js:181:21:181:24 | name | lib/lib.js:181:21:181:46 | name.re ... "'\\''") | | lib/lib.js:181:21:181:24 | name | lib/lib.js:181:21:181:46 | name.re ... "'\\''") | -| lib/lib.js:181:21:181:46 | name.re ... "'\\''") | lib/lib.js:181:15:181:52 | "'" + n ... ) + "'" | -| lib/lib.js:186:34:186:37 | name | lib/lib.js:187:22:187:25 | name | -| lib/lib.js:186:34:186:37 | name | lib/lib.js:187:22:187:25 | name | -| lib/lib.js:186:34:186:37 | name | lib/lib.js:187:22:187:25 | name | +| lib/lib.js:181:21:181:46 | name.re ... "'\\''") | lib/lib.js:181:6:181:52 | broken | | lib/lib.js:186:34:186:37 | name | lib/lib.js:187:22:187:25 | name | | lib/lib.js:186:34:186:37 | name | lib/lib.js:190:23:190:26 | name | -| lib/lib.js:186:34:186:37 | name | lib/lib.js:190:23:190:26 | name | -| lib/lib.js:186:34:186:37 | name | lib/lib.js:190:23:190:26 | name | -| lib/lib.js:186:34:186:37 | name | lib/lib.js:190:23:190:26 | name | -| lib/lib.js:196:45:196:48 | name | lib/lib.js:197:22:197:25 | name | -| lib/lib.js:196:45:196:48 | name | lib/lib.js:197:22:197:25 | name | -| lib/lib.js:196:45:196:48 | name | lib/lib.js:197:22:197:25 | name | | lib/lib.js:196:45:196:48 | name | lib/lib.js:197:22:197:25 | name | | lib/lib.js:196:45:196:48 | name | lib/lib.js:200:23:200:26 | name | -| lib/lib.js:196:45:196:48 | name | lib/lib.js:200:23:200:26 | name | -| lib/lib.js:196:45:196:48 | name | lib/lib.js:200:23:200:26 | name | -| lib/lib.js:196:45:196:48 | name | lib/lib.js:200:23:200:26 | name | -| lib/lib.js:206:45:206:48 | name | lib/lib.js:207:22:207:25 | name | -| lib/lib.js:206:45:206:48 | name | lib/lib.js:207:22:207:25 | name | -| lib/lib.js:206:45:206:48 | name | lib/lib.js:207:22:207:25 | name | | lib/lib.js:206:45:206:48 | name | lib/lib.js:207:22:207:25 | name | | lib/lib.js:206:45:206:48 | name | lib/lib.js:212:23:212:26 | name | -| lib/lib.js:206:45:206:48 | name | lib/lib.js:212:23:212:26 | name | -| lib/lib.js:206:45:206:48 | name | lib/lib.js:212:23:212:26 | name | -| lib/lib.js:206:45:206:48 | name | lib/lib.js:212:23:212:26 | name | -| lib/lib.js:216:39:216:42 | name | lib/lib.js:217:22:217:25 | name | -| lib/lib.js:216:39:216:42 | name | lib/lib.js:217:22:217:25 | name | -| lib/lib.js:216:39:216:42 | name | lib/lib.js:217:22:217:25 | name | | lib/lib.js:216:39:216:42 | name | lib/lib.js:217:22:217:25 | name | | lib/lib.js:216:39:216:42 | name | lib/lib.js:220:23:220:26 | name | -| lib/lib.js:216:39:216:42 | name | lib/lib.js:220:23:220:26 | name | -| lib/lib.js:216:39:216:42 | name | lib/lib.js:220:23:220:26 | name | -| lib/lib.js:216:39:216:42 | name | lib/lib.js:220:23:220:26 | name | -| lib/lib.js:216:39:216:42 | name | lib/lib.js:224:22:224:25 | name | -| lib/lib.js:216:39:216:42 | name | lib/lib.js:224:22:224:25 | name | -| lib/lib.js:216:39:216:42 | name | lib/lib.js:224:22:224:25 | name | | lib/lib.js:216:39:216:42 | name | lib/lib.js:224:22:224:25 | name | | lib/lib.js:227:39:227:42 | name | lib/lib.js:228:22:228:25 | name | -| lib/lib.js:227:39:227:42 | name | lib/lib.js:228:22:228:25 | name | -| lib/lib.js:227:39:227:42 | name | lib/lib.js:228:22:228:25 | name | -| lib/lib.js:227:39:227:42 | name | lib/lib.js:228:22:228:25 | name | -| lib/lib.js:227:39:227:42 | name | lib/lib.js:236:22:236:25 | name | -| lib/lib.js:227:39:227:42 | name | lib/lib.js:236:22:236:25 | name | -| lib/lib.js:227:39:227:42 | name | lib/lib.js:236:22:236:25 | name | | lib/lib.js:227:39:227:42 | name | lib/lib.js:236:22:236:25 | name | +| lib/lib.js:239:28:239:28 | s | lib/lib.js:245:9:245:9 | s | | lib/lib.js:248:42:248:45 | name | lib/lib.js:249:22:249:25 | name | -| lib/lib.js:248:42:248:45 | name | lib/lib.js:249:22:249:25 | name | -| lib/lib.js:248:42:248:45 | name | lib/lib.js:249:22:249:25 | name | -| lib/lib.js:248:42:248:45 | name | lib/lib.js:249:22:249:25 | name | +| lib/lib.js:248:42:248:45 | name | lib/lib.js:251:27:251:30 | name | +| lib/lib.js:251:6:251:31 | cleaned | lib/lib.js:253:22:253:28 | cleaned | +| lib/lib.js:251:16:251:31 | cleanInput(name) | lib/lib.js:251:6:251:31 | cleaned | +| lib/lib.js:251:27:251:30 | name | lib/lib.js:239:28:239:28 | s | +| lib/lib.js:251:27:251:30 | name | lib/lib.js:251:16:251:31 | cleanInput(name) | | lib/lib.js:257:35:257:38 | name | lib/lib.js:258:22:258:25 | name | -| lib/lib.js:257:35:257:38 | name | lib/lib.js:258:22:258:25 | name | -| lib/lib.js:257:35:257:38 | name | lib/lib.js:258:22:258:25 | name | -| lib/lib.js:257:35:257:38 | name | lib/lib.js:258:22:258:25 | name | -| lib/lib.js:257:35:257:38 | name | lib/lib.js:261:30:261:33 | name | -| lib/lib.js:257:35:257:38 | name | lib/lib.js:261:30:261:33 | name | -| lib/lib.js:257:35:257:38 | name | lib/lib.js:261:30:261:33 | name | | lib/lib.js:257:35:257:38 | name | lib/lib.js:261:30:261:33 | name | | lib/lib.js:267:46:267:48 | obj | lib/lib.js:268:22:268:24 | obj | -| lib/lib.js:267:46:267:48 | obj | lib/lib.js:268:22:268:24 | obj | -| lib/lib.js:268:22:268:24 | obj | lib/lib.js:268:22:268:32 | obj.version | | lib/lib.js:268:22:268:24 | obj | lib/lib.js:268:22:268:32 | obj.version | | lib/lib.js:276:8:276:11 | opts | lib/lib.js:277:23:277:26 | opts | -| lib/lib.js:276:8:276:11 | opts | lib/lib.js:277:23:277:26 | opts | -| lib/lib.js:276:8:276:11 | opts | lib/lib.js:279:19:279:22 | opts | | lib/lib.js:276:8:276:11 | opts | lib/lib.js:279:19:279:22 | opts | | lib/lib.js:277:23:277:26 | opts | lib/lib.js:277:23:277:30 | opts.bla | -| lib/lib.js:277:23:277:26 | opts | lib/lib.js:277:23:277:30 | opts.bla | +| lib/lib.js:279:3:279:6 | [post update] this [opts, bla] | lib/lib.js:281:23:281:26 | this [opts, bla] | +| lib/lib.js:279:3:279:11 | [post update] this.opts [bla] | lib/lib.js:279:3:279:6 | [post update] this [opts, bla] | | lib/lib.js:279:19:279:22 | opts | lib/lib.js:279:19:279:26 | opts.bla | -| lib/lib.js:279:19:279:26 | opts.bla | lib/lib.js:281:23:281:35 | this.opts.bla | -| lib/lib.js:279:19:279:26 | opts.bla | lib/lib.js:281:23:281:35 | this.opts.bla | -| lib/lib.js:307:39:307:42 | name | lib/lib.js:308:23:308:26 | name | -| lib/lib.js:307:39:307:42 | name | lib/lib.js:308:23:308:26 | name | -| lib/lib.js:307:39:307:42 | name | lib/lib.js:308:23:308:26 | name | +| lib/lib.js:279:19:279:26 | opts.bla | lib/lib.js:279:3:279:11 | [post update] this.opts [bla] | +| lib/lib.js:281:23:281:26 | this [opts, bla] | lib/lib.js:281:23:281:31 | this.opts [bla] | +| lib/lib.js:281:23:281:31 | this.opts [bla] | lib/lib.js:281:23:281:35 | this.opts.bla | | lib/lib.js:307:39:307:42 | name | lib/lib.js:308:23:308:26 | name | | lib/lib.js:314:40:314:43 | name | lib/lib.js:315:22:315:25 | name | -| lib/lib.js:314:40:314:43 | name | lib/lib.js:315:22:315:25 | name | -| lib/lib.js:314:40:314:43 | name | lib/lib.js:315:22:315:25 | name | -| lib/lib.js:314:40:314:43 | name | lib/lib.js:315:22:315:25 | name | | lib/lib.js:314:40:314:43 | name | lib/lib.js:320:23:320:26 | name | -| lib/lib.js:314:40:314:43 | name | lib/lib.js:320:23:320:26 | name | -| lib/lib.js:314:40:314:43 | name | lib/lib.js:320:23:320:26 | name | -| lib/lib.js:314:40:314:43 | name | lib/lib.js:320:23:320:26 | name | -| lib/lib.js:324:40:324:42 | arg | lib/lib.js:325:49:325:51 | arg | -| lib/lib.js:324:40:324:42 | arg | lib/lib.js:325:49:325:51 | arg | -| lib/lib.js:324:40:324:42 | arg | lib/lib.js:325:49:325:51 | arg | | lib/lib.js:324:40:324:42 | arg | lib/lib.js:325:49:325:51 | arg | | lib/lib.js:329:13:329:13 | x | lib/lib.js:330:9:330:9 | x | -| lib/lib.js:329:13:329:13 | x | lib/lib.js:330:9:330:9 | x | -| lib/lib.js:330:9:330:9 | x | lib/lib.js:336:22:336:31 | id("test") | -| lib/lib.js:330:9:330:9 | x | lib/lib.js:336:22:336:31 | id("test") | -| lib/lib.js:330:9:330:9 | x | lib/lib.js:340:22:340:26 | id(n) | -| lib/lib.js:330:9:330:9 | x | lib/lib.js:340:22:340:26 | id(n) | | lib/lib.js:339:39:339:39 | n | lib/lib.js:340:25:340:25 | n | -| lib/lib.js:339:39:339:39 | n | lib/lib.js:340:25:340:25 | n | -| lib/lib.js:340:25:340:25 | n | lib/lib.js:340:22:340:26 | id(n) | +| lib/lib.js:340:25:340:25 | n | lib/lib.js:329:13:329:13 | x | | lib/lib.js:340:25:340:25 | n | lib/lib.js:340:22:340:26 | id(n) | | lib/lib.js:349:29:349:34 | unsafe | lib/lib.js:351:22:351:27 | unsafe | -| lib/lib.js:349:29:349:34 | unsafe | lib/lib.js:351:22:351:27 | unsafe | -| lib/lib.js:349:29:349:34 | unsafe | lib/lib.js:351:22:351:27 | unsafe | -| lib/lib.js:349:29:349:34 | unsafe | lib/lib.js:351:22:351:27 | unsafe | -| lib/lib.js:360:20:360:23 | opts | lib/lib.js:361:20:361:23 | opts | -| lib/lib.js:360:20:360:23 | opts | lib/lib.js:361:20:361:23 | opts | -| lib/lib.js:361:20:361:23 | opts | lib/lib.js:361:20:361:34 | opts.learn_args | -| lib/lib.js:361:20:361:34 | opts.learn_args | lib/lib.js:366:28:366:42 | this.learn_args | -| lib/lib.js:361:20:361:34 | opts.learn_args | lib/lib.js:366:28:366:42 | this.learn_args | -| lib/lib.js:405:39:405:42 | name | lib/lib.js:406:22:406:25 | name | -| lib/lib.js:405:39:405:42 | name | lib/lib.js:406:22:406:25 | name | -| lib/lib.js:405:39:405:42 | name | lib/lib.js:406:22:406:25 | name | | lib/lib.js:405:39:405:42 | name | lib/lib.js:406:22:406:25 | name | | lib/lib.js:414:40:414:43 | name | lib/lib.js:415:22:415:25 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:415:22:415:25 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:415:22:415:25 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:415:22:415:25 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:417:28:417:31 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:417:28:417:31 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:417:28:417:31 | name | | lib/lib.js:414:40:414:43 | name | lib/lib.js:417:28:417:31 | name | | lib/lib.js:414:40:414:43 | name | lib/lib.js:418:25:418:28 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:418:25:418:28 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:418:25:418:28 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:418:25:418:28 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:419:32:419:35 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:419:32:419:35 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:419:32:419:35 | name | | lib/lib.js:414:40:414:43 | name | lib/lib.js:419:32:419:35 | name | | lib/lib.js:414:40:414:43 | name | lib/lib.js:420:29:420:32 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:420:29:420:32 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:420:29:420:32 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:420:29:420:32 | name | | lib/lib.js:414:40:414:43 | name | lib/lib.js:424:24:424:27 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:424:24:424:27 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:424:24:424:27 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:424:24:424:27 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:426:11:426:14 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:426:11:426:14 | name | | lib/lib.js:414:40:414:43 | name | lib/lib.js:426:11:426:14 | name | | lib/lib.js:414:40:414:43 | name | lib/lib.js:426:11:426:14 | name | | lib/lib.js:414:40:414:43 | name | lib/lib.js:428:36:428:39 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:428:36:428:39 | name | | lib/lib.js:425:6:425:13 | arr | lib/lib.js:427:14:427:16 | arr | -| lib/lib.js:425:6:425:13 | arr | lib/lib.js:427:14:427:16 | arr | -| lib/lib.js:425:12:425:13 | [] | lib/lib.js:425:6:425:13 | arr | -| lib/lib.js:426:11:426:14 | name | lib/lib.js:425:12:425:13 | [] | -| lib/lib.js:428:28:428:51 | (name ? ... ' : '') | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | -| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:428:14:428:58 | build(" ... + '-') | +| lib/lib.js:426:2:426:4 | [post update] arr | lib/lib.js:425:6:425:13 | arr | +| lib/lib.js:426:11:426:14 | name | lib/lib.js:426:2:426:4 | [post update] arr | | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:428:14:428:58 | build(" ... + '-') | | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:431:23:431:26 | last | -| lib/lib.js:428:29:428:50 | name ? ... :' : '' | lib/lib.js:428:28:428:51 | (name ? ... ' : '') | -| lib/lib.js:428:36:428:39 | name | lib/lib.js:428:36:428:45 | name + ':' | -| lib/lib.js:428:36:428:45 | name + ':' | lib/lib.js:428:29:428:50 | name ? ... :' : '' | +| lib/lib.js:428:36:428:39 | name | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | | lib/lib.js:431:23:431:26 | last | lib/lib.js:436:19:436:22 | last | | lib/lib.js:431:23:431:26 | last | lib/lib.js:436:19:436:22 | last | +| lib/lib.js:432:6:432:13 | arr | lib/lib.js:437:9:437:11 | arr | +| lib/lib.js:436:10:436:12 | [post update] arr | lib/lib.js:432:6:432:13 | arr | +| lib/lib.js:436:19:436:22 | last | lib/lib.js:436:10:436:12 | [post update] arr | | lib/lib.js:441:39:441:42 | name | lib/lib.js:442:24:442:27 | name | -| lib/lib.js:441:39:441:42 | name | lib/lib.js:442:24:442:27 | name | -| lib/lib.js:441:39:441:42 | name | lib/lib.js:442:24:442:27 | name | -| lib/lib.js:441:39:441:42 | name | lib/lib.js:442:24:442:27 | name | -| lib/lib.js:446:20:446:23 | name | lib/lib.js:447:25:447:28 | name | -| lib/lib.js:446:20:446:23 | name | lib/lib.js:447:25:447:28 | name | -| lib/lib.js:446:20:446:23 | name | lib/lib.js:447:25:447:28 | name | | lib/lib.js:446:20:446:23 | name | lib/lib.js:447:25:447:28 | name | | lib/lib.js:477:33:477:38 | config | lib/lib.js:478:27:478:32 | config | -| lib/lib.js:477:33:477:38 | config | lib/lib.js:478:27:478:32 | config | -| lib/lib.js:478:27:478:32 | config | lib/lib.js:478:27:478:46 | config.installedPath | | lib/lib.js:478:27:478:32 | config | lib/lib.js:478:27:478:46 | config.installedPath | | lib/lib.js:482:40:482:43 | name | lib/lib.js:483:30:483:33 | name | -| lib/lib.js:482:40:482:43 | name | lib/lib.js:483:30:483:33 | name | -| lib/lib.js:482:40:482:43 | name | lib/lib.js:483:30:483:33 | name | -| lib/lib.js:482:40:482:43 | name | lib/lib.js:483:30:483:33 | name | -| lib/lib.js:498:45:498:48 | name | lib/lib.js:499:31:499:34 | name | -| lib/lib.js:498:45:498:48 | name | lib/lib.js:499:31:499:34 | name | -| lib/lib.js:498:45:498:48 | name | lib/lib.js:499:31:499:34 | name | | lib/lib.js:498:45:498:48 | name | lib/lib.js:499:31:499:34 | name | | lib/lib.js:509:39:509:42 | name | lib/lib.js:510:22:510:25 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:510:22:510:25 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:510:22:510:25 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:510:22:510:25 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:513:23:513:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:513:23:513:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:513:23:513:26 | name | | lib/lib.js:509:39:509:42 | name | lib/lib.js:513:23:513:26 | name | | lib/lib.js:509:39:509:42 | name | lib/lib.js:519:23:519:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:519:23:519:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:519:23:519:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:519:23:519:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:525:23:525:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:525:23:525:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:525:23:525:26 | name | | lib/lib.js:509:39:509:42 | name | lib/lib.js:525:23:525:26 | name | | lib/lib.js:509:39:509:42 | name | lib/lib.js:531:23:531:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:531:23:531:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:531:23:531:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:531:23:531:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:537:23:537:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:537:23:537:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:537:23:537:26 | name | | lib/lib.js:509:39:509:42 | name | lib/lib.js:537:23:537:26 | name | | lib/lib.js:509:39:509:42 | name | lib/lib.js:543:23:543:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:543:23:543:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:543:23:543:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:543:23:543:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:545:23:545:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:545:23:545:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:545:23:545:26 | name | | lib/lib.js:509:39:509:42 | name | lib/lib.js:545:23:545:26 | name | | lib/lib.js:550:39:550:42 | name | lib/lib.js:555:33:555:36 | name | | lib/lib.js:550:39:550:42 | name | lib/lib.js:555:33:555:36 | name | -| lib/lib.js:550:39:550:42 | name | lib/lib.js:555:33:555:36 | name | -| lib/lib.js:550:39:550:42 | name | lib/lib.js:555:33:555:36 | name | -| lib/lib.js:551:33:551:36 | args | lib/lib.js:552:23:552:26 | args | | lib/lib.js:551:33:551:36 | args | lib/lib.js:552:23:552:26 | args | | lib/lib.js:555:25:555:37 | ["-rf", name] | lib/lib.js:551:33:551:36 | args | | lib/lib.js:555:33:555:36 | name | lib/lib.js:555:25:555:37 | ["-rf", name] | | lib/lib.js:558:41:558:44 | name | lib/lib.js:560:26:560:29 | name | -| lib/lib.js:558:41:558:44 | name | lib/lib.js:560:26:560:29 | name | -| lib/lib.js:558:41:558:44 | name | lib/lib.js:560:26:560:29 | name | -| lib/lib.js:558:41:558:44 | name | lib/lib.js:560:26:560:29 | name | -| lib/lib.js:558:41:558:44 | name | lib/lib.js:562:26:562:29 | name | -| lib/lib.js:558:41:558:44 | name | lib/lib.js:562:26:562:29 | name | -| lib/lib.js:558:41:558:44 | name | lib/lib.js:562:26:562:29 | name | | lib/lib.js:558:41:558:44 | name | lib/lib.js:562:26:562:29 | name | | lib/lib.js:558:41:558:44 | name | lib/lib.js:566:26:566:29 | name | -| lib/lib.js:558:41:558:44 | name | lib/lib.js:566:26:566:29 | name | -| lib/lib.js:558:41:558:44 | name | lib/lib.js:566:26:566:29 | name | -| lib/lib.js:558:41:558:44 | name | lib/lib.js:566:26:566:29 | name | -| lib/lib.js:572:41:572:44 | name | lib/lib.js:573:22:573:25 | name | -| lib/lib.js:572:41:572:44 | name | lib/lib.js:573:22:573:25 | name | -| lib/lib.js:572:41:572:44 | name | lib/lib.js:573:22:573:25 | name | | lib/lib.js:572:41:572:44 | name | lib/lib.js:573:22:573:25 | name | | lib/lib.js:572:41:572:44 | name | lib/lib.js:579:25:579:28 | name | -| lib/lib.js:572:41:572:44 | name | lib/lib.js:579:25:579:28 | name | -| lib/lib.js:572:41:572:44 | name | lib/lib.js:579:25:579:28 | name | -| lib/lib.js:572:41:572:44 | name | lib/lib.js:579:25:579:28 | name | -| lib/lib.js:572:41:572:44 | name | lib/lib.js:590:29:590:32 | name | -| lib/lib.js:572:41:572:44 | name | lib/lib.js:590:29:590:32 | name | -| lib/lib.js:572:41:572:44 | name | lib/lib.js:590:29:590:32 | name | | lib/lib.js:572:41:572:44 | name | lib/lib.js:590:29:590:32 | name | | lib/lib.js:572:41:572:44 | name | lib/lib.js:593:25:593:28 | name | -| lib/lib.js:572:41:572:44 | name | lib/lib.js:593:25:593:28 | name | -| lib/lib.js:572:41:572:44 | name | lib/lib.js:593:25:593:28 | name | -| lib/lib.js:572:41:572:44 | name | lib/lib.js:593:25:593:28 | name | -| lib/lib.js:608:42:608:45 | name | lib/lib.js:609:22:609:25 | name | -| lib/lib.js:608:42:608:45 | name | lib/lib.js:609:22:609:25 | name | -| lib/lib.js:608:42:608:45 | name | lib/lib.js:609:22:609:25 | name | | lib/lib.js:608:42:608:45 | name | lib/lib.js:609:22:609:25 | name | | lib/lib.js:608:42:608:45 | name | lib/lib.js:626:29:626:32 | name | -| lib/lib.js:608:42:608:45 | name | lib/lib.js:626:29:626:32 | name | -| lib/lib.js:608:42:608:45 | name | lib/lib.js:626:29:626:32 | name | -| lib/lib.js:608:42:608:45 | name | lib/lib.js:626:29:626:32 | name | -| lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | -| lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | -| lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | | lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | | lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | -| lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | -| lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | -| lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | -| lib/subLib2/special-file.js:3:28:3:31 | name | lib/subLib2/special-file.js:4:22:4:25 | name | -| lib/subLib2/special-file.js:3:28:3:31 | name | lib/subLib2/special-file.js:4:22:4:25 | name | -| lib/subLib2/special-file.js:3:28:3:31 | name | lib/subLib2/special-file.js:4:22:4:25 | name | | lib/subLib2/special-file.js:3:28:3:31 | name | lib/subLib2/special-file.js:4:22:4:25 | name | | lib/subLib3/my-file.ts:3:28:3:31 | name | lib/subLib3/my-file.ts:4:22:4:25 | name | -| lib/subLib3/my-file.ts:3:28:3:31 | name | lib/subLib3/my-file.ts:4:22:4:25 | name | -| lib/subLib3/my-file.ts:3:28:3:31 | name | lib/subLib3/my-file.ts:4:22:4:25 | name | -| lib/subLib3/my-file.ts:3:28:3:31 | name | lib/subLib3/my-file.ts:4:22:4:25 | name | -| lib/subLib4/index.js:6:32:6:35 | name | lib/subLib4/index.js:7:18:7:21 | name | | lib/subLib4/index.js:6:32:6:35 | name | lib/subLib4/index.js:7:18:7:21 | name | | lib/subLib4/index.js:7:18:7:21 | name | lib/subLib4/subsub.js:3:28:3:31 | name | | lib/subLib4/subsub.js:3:28:3:31 | name | lib/subLib4/subsub.js:4:22:4:25 | name | -| lib/subLib4/subsub.js:3:28:3:31 | name | lib/subLib4/subsub.js:4:22:4:25 | name | -| lib/subLib/amdSub.js:3:28:3:31 | name | lib/subLib/amdSub.js:4:22:4:25 | name | -| lib/subLib/amdSub.js:3:28:3:31 | name | lib/subLib/amdSub.js:4:22:4:25 | name | -| lib/subLib/amdSub.js:3:28:3:31 | name | lib/subLib/amdSub.js:4:22:4:25 | name | | lib/subLib/amdSub.js:3:28:3:31 | name | lib/subLib/amdSub.js:4:22:4:25 | name | | lib/subLib/index.js:3:28:3:31 | name | lib/subLib/index.js:4:22:4:25 | name | -| lib/subLib/index.js:3:28:3:31 | name | lib/subLib/index.js:4:22:4:25 | name | -| lib/subLib/index.js:3:28:3:31 | name | lib/subLib/index.js:4:22:4:25 | name | -| lib/subLib/index.js:3:28:3:31 | name | lib/subLib/index.js:4:22:4:25 | name | -| lib/subLib/index.js:7:32:7:35 | name | lib/subLib/index.js:8:22:8:25 | name | -| lib/subLib/index.js:7:32:7:35 | name | lib/subLib/index.js:8:22:8:25 | name | -| lib/subLib/index.js:7:32:7:35 | name | lib/subLib/index.js:8:22:8:25 | name | | lib/subLib/index.js:7:32:7:35 | name | lib/subLib/index.js:8:22:8:25 | name | | lib/subLib/index.js:13:44:13:46 | arr | lib/subLib/index.js:14:22:14:24 | arr | -| lib/subLib/index.js:13:44:13:46 | arr | lib/subLib/index.js:14:22:14:24 | arr | -| lib/subLib/index.js:13:44:13:46 | arr | lib/subLib/index.js:14:22:14:24 | arr | -| lib/subLib/index.js:13:44:13:46 | arr | lib/subLib/index.js:14:22:14:24 | arr | +nodes +| lib/isImported.js:5:49:5:52 | name | semmle.label | name | +| lib/isImported.js:6:22:6:25 | name | semmle.label | name | +| lib/lib2.js:3:28:3:31 | name | semmle.label | name | +| lib/lib2.js:4:22:4:25 | name | semmle.label | name | +| lib/lib2.js:7:32:7:35 | name | semmle.label | name | +| lib/lib2.js:8:22:8:25 | name | semmle.label | name | +| lib/lib.js:3:28:3:31 | name | semmle.label | name | +| lib/lib.js:4:22:4:25 | name | semmle.label | name | +| lib/lib.js:10:32:10:35 | name | semmle.label | name | +| lib/lib.js:11:22:11:25 | name | semmle.label | name | +| lib/lib.js:14:36:14:39 | name | semmle.label | name | +| lib/lib.js:15:22:15:25 | name | semmle.label | name | +| lib/lib.js:19:34:19:37 | name | semmle.label | name | +| lib/lib.js:20:22:20:25 | name | semmle.label | name | +| lib/lib.js:26:35:26:38 | name | semmle.label | name | +| lib/lib.js:27:22:27:25 | name | semmle.label | name | +| lib/lib.js:34:14:34:17 | name | semmle.label | name | +| lib/lib.js:35:23:35:26 | name | semmle.label | name | +| lib/lib.js:37:13:37:16 | name | semmle.label | name | +| lib/lib.js:38:23:38:26 | name | semmle.label | name | +| lib/lib.js:40:6:40:9 | name | semmle.label | name | +| lib/lib.js:41:23:41:26 | name | semmle.label | name | +| lib/lib.js:49:31:49:34 | name | semmle.label | name | +| lib/lib.js:50:47:50:50 | name | semmle.label | name | +| lib/lib.js:53:33:53:36 | name | semmle.label | name | +| lib/lib.js:54:25:54:28 | name | semmle.label | name | +| lib/lib.js:57:25:57:28 | name | semmle.label | name | +| lib/lib.js:64:41:64:44 | name | semmle.label | name | +| lib/lib.js:65:22:65:25 | name | semmle.label | name | +| lib/lib.js:69:27:69:30 | name | semmle.label | name | +| lib/lib.js:71:28:71:31 | name | semmle.label | name | +| lib/lib.js:73:21:73:24 | name | semmle.label | name | +| lib/lib.js:75:20:75:23 | name | semmle.label | name | +| lib/lib.js:77:28:77:31 | name | semmle.label | name | +| lib/lib.js:82:35:82:38 | name | semmle.label | name | +| lib/lib.js:83:22:83:25 | name | semmle.label | name | +| lib/lib.js:86:13:86:16 | name | semmle.label | name | +| lib/lib.js:89:21:89:24 | name | semmle.label | name | +| lib/lib.js:91:21:91:38 | "\\"" + name + "\\"" | semmle.label | "\\"" + name + "\\"" | +| lib/lib.js:91:28:91:31 | name | semmle.label | name | +| lib/lib.js:97:35:97:38 | name | semmle.label | name | +| lib/lib.js:98:35:98:38 | name | semmle.label | name | +| lib/lib.js:100:37:100:40 | name | semmle.label | name | +| lib/lib.js:102:46:102:49 | name | semmle.label | name | +| lib/lib.js:108:41:108:44 | name | semmle.label | name | +| lib/lib.js:111:34:111:37 | name | semmle.label | name | +| lib/lib.js:112:22:112:25 | name | semmle.label | name | +| lib/lib.js:120:33:120:36 | name | semmle.label | name | +| lib/lib.js:121:22:121:25 | name | semmle.label | name | +| lib/lib.js:130:6:130:9 | name | semmle.label | name | +| lib/lib.js:131:23:131:26 | name | semmle.label | name | +| lib/lib.js:148:37:148:40 | name | semmle.label | name | +| lib/lib.js:149:24:149:27 | name | semmle.label | name | +| lib/lib.js:155:38:155:41 | name | semmle.label | name | +| lib/lib.js:161:25:161:28 | name | semmle.label | name | +| lib/lib.js:170:41:170:44 | name | semmle.label | name | +| lib/lib.js:173:20:173:23 | name | semmle.label | name | +| lib/lib.js:177:38:177:41 | name | semmle.label | name | +| lib/lib.js:181:6:181:52 | broken | semmle.label | broken | +| lib/lib.js:181:21:181:24 | name | semmle.label | name | +| lib/lib.js:181:21:181:46 | name.re ... "'\\''") | semmle.label | name.re ... "'\\''") | +| lib/lib.js:181:21:181:46 | name.re ... "'\\''") | semmle.label | name.re ... "'\\''") | +| lib/lib.js:182:22:182:27 | broken | semmle.label | broken | +| lib/lib.js:186:34:186:37 | name | semmle.label | name | +| lib/lib.js:187:22:187:25 | name | semmle.label | name | +| lib/lib.js:190:23:190:26 | name | semmle.label | name | +| lib/lib.js:196:45:196:48 | name | semmle.label | name | +| lib/lib.js:197:22:197:25 | name | semmle.label | name | +| lib/lib.js:200:23:200:26 | name | semmle.label | name | +| lib/lib.js:206:45:206:48 | name | semmle.label | name | +| lib/lib.js:207:22:207:25 | name | semmle.label | name | +| lib/lib.js:212:23:212:26 | name | semmle.label | name | +| lib/lib.js:216:39:216:42 | name | semmle.label | name | +| lib/lib.js:217:22:217:25 | name | semmle.label | name | +| lib/lib.js:220:23:220:26 | name | semmle.label | name | +| lib/lib.js:224:22:224:25 | name | semmle.label | name | +| lib/lib.js:227:39:227:42 | name | semmle.label | name | +| lib/lib.js:228:22:228:25 | name | semmle.label | name | +| lib/lib.js:236:22:236:25 | name | semmle.label | name | +| lib/lib.js:239:28:239:28 | s | semmle.label | s | +| lib/lib.js:245:9:245:9 | s | semmle.label | s | +| lib/lib.js:248:42:248:45 | name | semmle.label | name | +| lib/lib.js:249:22:249:25 | name | semmle.label | name | +| lib/lib.js:251:6:251:31 | cleaned | semmle.label | cleaned | +| lib/lib.js:251:16:251:31 | cleanInput(name) | semmle.label | cleanInput(name) | +| lib/lib.js:251:27:251:30 | name | semmle.label | name | +| lib/lib.js:253:22:253:28 | cleaned | semmle.label | cleaned | +| lib/lib.js:257:35:257:38 | name | semmle.label | name | +| lib/lib.js:258:22:258:25 | name | semmle.label | name | +| lib/lib.js:261:30:261:33 | name | semmle.label | name | +| lib/lib.js:267:46:267:48 | obj | semmle.label | obj | +| lib/lib.js:268:22:268:24 | obj | semmle.label | obj | +| lib/lib.js:268:22:268:32 | obj.version | semmle.label | obj.version | +| lib/lib.js:276:8:276:11 | opts | semmle.label | opts | +| lib/lib.js:277:23:277:26 | opts | semmle.label | opts | +| lib/lib.js:277:23:277:30 | opts.bla | semmle.label | opts.bla | +| lib/lib.js:279:3:279:6 | [post update] this [opts, bla] | semmle.label | [post update] this [opts, bla] | +| lib/lib.js:279:3:279:11 | [post update] this.opts [bla] | semmle.label | [post update] this.opts [bla] | +| lib/lib.js:279:19:279:22 | opts | semmle.label | opts | +| lib/lib.js:279:19:279:26 | opts.bla | semmle.label | opts.bla | +| lib/lib.js:281:23:281:26 | this [opts, bla] | semmle.label | this [opts, bla] | +| lib/lib.js:281:23:281:31 | this.opts [bla] | semmle.label | this.opts [bla] | +| lib/lib.js:281:23:281:35 | this.opts.bla | semmle.label | this.opts.bla | +| lib/lib.js:307:39:307:42 | name | semmle.label | name | +| lib/lib.js:308:23:308:26 | name | semmle.label | name | +| lib/lib.js:314:40:314:43 | name | semmle.label | name | +| lib/lib.js:315:22:315:25 | name | semmle.label | name | +| lib/lib.js:320:23:320:26 | name | semmle.label | name | +| lib/lib.js:324:40:324:42 | arg | semmle.label | arg | +| lib/lib.js:325:49:325:51 | arg | semmle.label | arg | +| lib/lib.js:329:13:329:13 | x | semmle.label | x | +| lib/lib.js:330:9:330:9 | x | semmle.label | x | +| lib/lib.js:339:39:339:39 | n | semmle.label | n | +| lib/lib.js:340:22:340:26 | id(n) | semmle.label | id(n) | +| lib/lib.js:340:25:340:25 | n | semmle.label | n | +| lib/lib.js:349:29:349:34 | unsafe | semmle.label | unsafe | +| lib/lib.js:351:22:351:27 | unsafe | semmle.label | unsafe | +| lib/lib.js:405:39:405:42 | name | semmle.label | name | +| lib/lib.js:406:22:406:25 | name | semmle.label | name | +| lib/lib.js:414:40:414:43 | name | semmle.label | name | +| lib/lib.js:415:22:415:25 | name | semmle.label | name | +| lib/lib.js:417:28:417:31 | name | semmle.label | name | +| lib/lib.js:418:25:418:28 | name | semmle.label | name | +| lib/lib.js:419:32:419:35 | name | semmle.label | name | +| lib/lib.js:420:29:420:32 | name | semmle.label | name | +| lib/lib.js:424:24:424:27 | name | semmle.label | name | +| lib/lib.js:425:6:425:13 | arr | semmle.label | arr | +| lib/lib.js:426:2:426:4 | [post update] arr | semmle.label | [post update] arr | +| lib/lib.js:426:11:426:14 | name | semmle.label | name | +| lib/lib.js:426:11:426:14 | name | semmle.label | name | +| lib/lib.js:427:14:427:16 | arr | semmle.label | arr | +| lib/lib.js:428:14:428:58 | build(" ... + '-') | semmle.label | build(" ... + '-') | +| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | semmle.label | (name ? ... ) + '-' | +| lib/lib.js:428:36:428:39 | name | semmle.label | name | +| lib/lib.js:431:23:431:26 | last | semmle.label | last | +| lib/lib.js:432:6:432:13 | arr | semmle.label | arr | +| lib/lib.js:436:10:436:12 | [post update] arr | semmle.label | [post update] arr | +| lib/lib.js:436:19:436:22 | last | semmle.label | last | +| lib/lib.js:436:19:436:22 | last | semmle.label | last | +| lib/lib.js:437:9:437:11 | arr | semmle.label | arr | +| lib/lib.js:441:39:441:42 | name | semmle.label | name | +| lib/lib.js:442:24:442:27 | name | semmle.label | name | +| lib/lib.js:446:20:446:23 | name | semmle.label | name | +| lib/lib.js:447:25:447:28 | name | semmle.label | name | +| lib/lib.js:477:33:477:38 | config | semmle.label | config | +| lib/lib.js:478:27:478:32 | config | semmle.label | config | +| lib/lib.js:478:27:478:46 | config.installedPath | semmle.label | config.installedPath | +| lib/lib.js:482:40:482:43 | name | semmle.label | name | +| lib/lib.js:483:30:483:33 | name | semmle.label | name | +| lib/lib.js:498:45:498:48 | name | semmle.label | name | +| lib/lib.js:499:31:499:34 | name | semmle.label | name | +| lib/lib.js:509:39:509:42 | name | semmle.label | name | +| lib/lib.js:510:22:510:25 | name | semmle.label | name | +| lib/lib.js:513:23:513:26 | name | semmle.label | name | +| lib/lib.js:519:23:519:26 | name | semmle.label | name | +| lib/lib.js:525:23:525:26 | name | semmle.label | name | +| lib/lib.js:531:23:531:26 | name | semmle.label | name | +| lib/lib.js:537:23:537:26 | name | semmle.label | name | +| lib/lib.js:543:23:543:26 | name | semmle.label | name | +| lib/lib.js:545:23:545:26 | name | semmle.label | name | +| lib/lib.js:550:39:550:42 | name | semmle.label | name | +| lib/lib.js:551:33:551:36 | args | semmle.label | args | +| lib/lib.js:552:23:552:26 | args | semmle.label | args | +| lib/lib.js:555:25:555:37 | ["-rf", name] | semmle.label | ["-rf", name] | +| lib/lib.js:555:33:555:36 | name | semmle.label | name | +| lib/lib.js:555:33:555:36 | name | semmle.label | name | +| lib/lib.js:558:41:558:44 | name | semmle.label | name | +| lib/lib.js:560:26:560:29 | name | semmle.label | name | +| lib/lib.js:562:26:562:29 | name | semmle.label | name | +| lib/lib.js:566:26:566:29 | name | semmle.label | name | +| lib/lib.js:572:41:572:44 | name | semmle.label | name | +| lib/lib.js:573:22:573:25 | name | semmle.label | name | +| lib/lib.js:579:25:579:28 | name | semmle.label | name | +| lib/lib.js:590:29:590:32 | name | semmle.label | name | +| lib/lib.js:593:25:593:28 | name | semmle.label | name | +| lib/lib.js:608:42:608:45 | name | semmle.label | name | +| lib/lib.js:609:22:609:25 | name | semmle.label | name | +| lib/lib.js:626:29:626:32 | name | semmle.label | name | +| lib/lib.js:629:25:629:28 | name | semmle.label | name | +| lib/subLib2/compiled-file.ts:3:26:3:29 | name | semmle.label | name | +| lib/subLib2/compiled-file.ts:4:25:4:28 | name | semmle.label | name | +| lib/subLib2/special-file.js:3:28:3:31 | name | semmle.label | name | +| lib/subLib2/special-file.js:4:22:4:25 | name | semmle.label | name | +| lib/subLib3/my-file.ts:3:28:3:31 | name | semmle.label | name | +| lib/subLib3/my-file.ts:4:22:4:25 | name | semmle.label | name | +| lib/subLib4/index.js:6:32:6:35 | name | semmle.label | name | +| lib/subLib4/index.js:7:18:7:21 | name | semmle.label | name | +| lib/subLib4/subsub.js:3:28:3:31 | name | semmle.label | name | +| lib/subLib4/subsub.js:4:22:4:25 | name | semmle.label | name | +| lib/subLib/amdSub.js:3:28:3:31 | name | semmle.label | name | +| lib/subLib/amdSub.js:4:22:4:25 | name | semmle.label | name | +| lib/subLib/index.js:3:28:3:31 | name | semmle.label | name | +| lib/subLib/index.js:4:22:4:25 | name | semmle.label | name | +| lib/subLib/index.js:7:32:7:35 | name | semmle.label | name | +| lib/subLib/index.js:8:22:8:25 | name | semmle.label | name | +| lib/subLib/index.js:13:44:13:46 | arr | semmle.label | arr | +| lib/subLib/index.js:14:22:14:24 | arr | semmle.label | arr | +subpaths +| lib/lib.js:251:27:251:30 | name | lib/lib.js:239:28:239:28 | s | lib/lib.js:245:9:245:9 | s | lib/lib.js:251:16:251:31 | cleanInput(name) | +| lib/lib.js:340:25:340:25 | n | lib/lib.js:329:13:329:13 | x | lib/lib.js:330:9:330:9 | x | lib/lib.js:340:22:340:26 | id(n) | +| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:431:23:431:26 | last | lib/lib.js:437:9:437:11 | arr | lib/lib.js:428:14:428:58 | build(" ... + '-') | #select | lib/isImported.js:6:10:6:25 | "rm -rf " + name | lib/isImported.js:5:49:5:52 | name | lib/isImported.js:6:22:6:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/isImported.js:5:49:5:52 | name | library input | lib/isImported.js:6:2:6:26 | cp.exec ... + name) | shell command | | lib/lib2.js:4:10:4:25 | "rm -rf " + name | lib/lib2.js:3:28:3:31 | name | lib/lib2.js:4:22:4:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib2.js:3:28:3:31 | name | library input | lib/lib2.js:4:2:4:26 | cp.exec ... + name) | shell command | @@ -831,6 +390,7 @@ edges | lib/lib.js:228:10:228:25 | "rm -rf " + name | lib/lib.js:227:39:227:42 | name | lib/lib.js:228:22:228:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:227:39:227:42 | name | library input | lib/lib.js:228:2:228:26 | cp.exec ... + name) | shell command | | lib/lib.js:236:10:236:25 | "rm -rf " + name | lib/lib.js:227:39:227:42 | name | lib/lib.js:236:22:236:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:227:39:227:42 | name | library input | lib/lib.js:236:2:236:26 | cp.exec ... + name) | shell command | | lib/lib.js:249:10:249:25 | "rm -rf " + name | lib/lib.js:248:42:248:45 | name | lib/lib.js:249:22:249:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:248:42:248:45 | name | library input | lib/lib.js:249:2:249:26 | cp.exec ... + name) | shell command | +| lib/lib.js:253:10:253:28 | "rm -rf " + cleaned | lib/lib.js:248:42:248:45 | name | lib/lib.js:253:22:253:28 | cleaned | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:248:42:248:45 | name | library input | lib/lib.js:253:2:253:29 | cp.exec ... leaned) | shell command | | lib/lib.js:258:10:258:25 | "rm -rf " + name | lib/lib.js:257:35:257:38 | name | lib/lib.js:258:22:258:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:257:35:257:38 | name | library input | lib/lib.js:258:2:258:26 | cp.exec ... + name) | shell command | | lib/lib.js:261:11:261:33 | "rm -rf ... + name | lib/lib.js:257:35:257:38 | name | lib/lib.js:261:30:261:33 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:257:35:257:38 | name | library input | lib/lib.js:261:3:261:34 | cp.exec ... + name) | shell command | | lib/lib.js:268:10:268:32 | "rm -rf ... version | lib/lib.js:267:46:267:48 | obj | lib/lib.js:268:22:268:32 | obj.version | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:267:46:267:48 | obj | library input | lib/lib.js:268:2:268:33 | cp.exec ... ersion) | shell command | @@ -842,7 +402,6 @@ edges | lib/lib.js:325:12:325:51 | "MyWind ... " + arg | lib/lib.js:324:40:324:42 | arg | lib/lib.js:325:49:325:51 | arg | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:324:40:324:42 | arg | library input | lib/lib.js:326:2:326:13 | cp.exec(cmd) | shell command | | lib/lib.js:340:10:340:26 | "rm -rf " + id(n) | lib/lib.js:339:39:339:39 | n | lib/lib.js:340:22:340:26 | id(n) | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:339:39:339:39 | n | library input | lib/lib.js:340:2:340:27 | cp.exec ... id(n)) | shell command | | lib/lib.js:351:10:351:27 | "rm -rf " + unsafe | lib/lib.js:349:29:349:34 | unsafe | lib/lib.js:351:22:351:27 | unsafe | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:349:29:349:34 | unsafe | library input | lib/lib.js:351:2:351:28 | cp.exec ... unsafe) | shell command | -| lib/lib.js:366:17:366:56 | "learn ... + model | lib/lib.js:360:20:360:23 | opts | lib/lib.js:366:28:366:42 | this.learn_args | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:360:20:360:23 | opts | library input | lib/lib.js:367:3:367:18 | cp.exec(command) | shell command | | lib/lib.js:406:10:406:25 | "rm -rf " + name | lib/lib.js:405:39:405:42 | name | lib/lib.js:406:22:406:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:405:39:405:42 | name | library input | lib/lib.js:406:2:406:26 | cp.exec ... + name) | shell command | | lib/lib.js:415:10:415:25 | "rm -rf " + name | lib/lib.js:414:40:414:43 | name | lib/lib.js:415:22:415:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:414:40:414:43 | name | library input | lib/lib.js:415:2:415:26 | cp.exec ... + name) | shell command | | lib/lib.js:417:28:417:31 | name | lib/lib.js:414:40:414:43 | name | lib/lib.js:417:28:417:31 | name | This shell argument which depends on $@ is later used in a $@. | lib/lib.js:414:40:414:43 | name | library input | lib/lib.js:417:2:417:66 | cp.exec ... => {}) | shell command | From 83095535f9590d221b60143503954202e9a00dba Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:26:19 +0200 Subject: [PATCH 101/514] JS: Port UnvalidatedDynamicMethodCall --- ...lidatedDynamicMethodCallCustomizations.qll | 32 ++- .../UnvalidatedDynamicMethodCallQuery.qll | 89 ++++++-- .../CWE-754/UnvalidatedDynamicMethodCall.ql | 8 +- .../UnvalidatedDynamicMethodCall.expected | 191 ++++++------------ 4 files changed, 161 insertions(+), 159 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallCustomizations.qll index d81227bcd68..139ddf880b4 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallCustomizations.qll @@ -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 } } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallQuery.qll index 921ab7f88e2..e964770437d 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallQuery.qll @@ -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::getABarrierNode(label) + } + + predicate isBarrier(DataFlow::Node node) { + node = DataFlow::MakeBarrierGuard::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; + +/** + * 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) } } diff --git a/javascript/ql/src/Security/CWE-754/UnvalidatedDynamicMethodCall.ql b/javascript/ql/src/Security/CWE-754/UnvalidatedDynamicMethodCall.ql index c2841c5e902..df84c62edf7 100644 --- a/javascript/ql/src/Security/CWE-754/UnvalidatedDynamicMethodCall.ql +++ b/javascript/ql/src/Security/CWE-754/UnvalidatedDynamicMethodCall.ql @@ -13,10 +13,12 @@ import javascript import semmle.javascript.security.dataflow.UnvalidatedDynamicMethodCallQuery -import DataFlow::PathGraph +import DataFlow::DeduplicatePathGraph -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" diff --git a/javascript/ql/test/query-tests/Security/CWE-754/UnvalidatedDynamicMethodCall.expected b/javascript/ql/test/query-tests/Security/CWE-754/UnvalidatedDynamicMethodCall.expected index cd3f5d60a35..55d4ce16510 100644 --- a/javascript/ql/test/query-tests/Security/CWE-754/UnvalidatedDynamicMethodCall.expected +++ b/javascript/ql/test/query-tests/Security/CWE-754/UnvalidatedDynamicMethodCall.expected @@ -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 | From 03f8c0fc5ef9551660fcd24f7915d2951cb6803a Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:26:25 +0200 Subject: [PATCH 102/514] JS: Port XmlBomb --- .../security/dataflow/XmlBombQuery.qll | 18 ++++- javascript/ql/src/Security/CWE-776/XmlBomb.ql | 6 +- .../Security/CWE-776/XmlBomb.expected | 66 +++++-------------- 3 files changed, 38 insertions(+), 52 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XmlBombQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XmlBombQuery.qll index 951b927f86e..e6ff29f81c5 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XmlBombQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XmlBombQuery.qll @@ -13,7 +13,23 @@ import XmlBombCustomizations::XmlBomb /** * A taint-tracking configuration for reasoning about XML-bomb vulnerabilities. */ -class Configuration extends TaintTracking::Configuration { +module XmlBombConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint-tracking for reasoning about XML-bomb vulnerabilities. + */ +module XmlBombFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `XmlBombFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "XmlBomb" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-776/XmlBomb.ql b/javascript/ql/src/Security/CWE-776/XmlBomb.ql index e418f329810..aa3f48c6037 100644 --- a/javascript/ql/src/Security/CWE-776/XmlBomb.ql +++ b/javascript/ql/src/Security/CWE-776/XmlBomb.ql @@ -14,10 +14,10 @@ import javascript import semmle.javascript.security.dataflow.XmlBombQuery -import DataFlow::PathGraph +import XmlBombFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from XmlBombFlow::PathNode source, XmlBombFlow::PathNode sink +where XmlBombFlow::flowPath(source, sink) select sink.getNode(), source, sink, "XML parsing depends on a $@ without guarding against uncontrolled entity expansion.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected b/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected index fb1e8e68321..be99aaf7513 100644 --- a/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected +++ b/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected @@ -1,60 +1,30 @@ -nodes -| closure.js:2:7:2:36 | src | -| closure.js:2:13:2:36 | documen ... .search | -| closure.js:2:13:2:36 | documen ... .search | -| closure.js:4:24:4:26 | src | -| closure.js:4:24:4:26 | src | -| domparser.js:2:7:2:36 | src | -| domparser.js:2:13:2:36 | documen ... .search | -| domparser.js:2:13:2:36 | documen ... .search | -| domparser.js:6:37:6:39 | src | -| domparser.js:6:37:6:39 | src | -| domparser.js:11:55:11:57 | src | -| domparser.js:11:55:11:57 | src | -| domparser.js:14:57:14:59 | src | -| domparser.js:14:57:14:59 | src | -| expat.js:6:16:6:36 | req.par ... e-xml") | -| expat.js:6:16:6:36 | req.par ... e-xml") | -| expat.js:6:16:6:36 | req.par ... e-xml") | -| jquery.js:2:7:2:36 | src | -| jquery.js:2:13:2:36 | documen ... .search | -| jquery.js:2:13:2:36 | documen ... .search | -| jquery.js:5:14:5:16 | src | -| jquery.js:5:14:5:16 | src | -| libxml.js:6:21:6:41 | req.par ... e-xml") | -| libxml.js:6:21:6:41 | req.par ... e-xml") | -| libxml.js:6:21:6:41 | req.par ... e-xml") | -| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | -| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | -| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | -| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | -| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | -| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | -| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | -| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | -| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | edges | closure.js:2:7:2:36 | src | closure.js:4:24:4:26 | src | -| closure.js:2:7:2:36 | src | closure.js:4:24:4:26 | src | -| closure.js:2:13:2:36 | documen ... .search | closure.js:2:7:2:36 | src | | closure.js:2:13:2:36 | documen ... .search | closure.js:2:7:2:36 | src | | domparser.js:2:7:2:36 | src | domparser.js:6:37:6:39 | src | -| domparser.js:2:7:2:36 | src | domparser.js:6:37:6:39 | src | -| domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src | | domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src | | domparser.js:2:7:2:36 | src | domparser.js:14:57:14:59 | src | -| domparser.js:2:7:2:36 | src | domparser.js:14:57:14:59 | src | | domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src | -| domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src | -| expat.js:6:16:6:36 | req.par ... e-xml") | expat.js:6:16:6:36 | req.par ... e-xml") | -| jquery.js:2:7:2:36 | src | jquery.js:5:14:5:16 | src | | jquery.js:2:7:2:36 | src | jquery.js:5:14:5:16 | src | | jquery.js:2:13:2:36 | documen ... .search | jquery.js:2:7:2:36 | src | -| jquery.js:2:13:2:36 | documen ... .search | jquery.js:2:7:2:36 | src | -| libxml.js:6:21:6:41 | req.par ... e-xml") | libxml.js:6:21:6:41 | req.par ... e-xml") | -| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | -| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | libxml.sax.js:6:22:6:42 | req.par ... e-xml") | -| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | +nodes +| closure.js:2:7:2:36 | src | semmle.label | src | +| closure.js:2:13:2:36 | documen ... .search | semmle.label | documen ... .search | +| closure.js:4:24:4:26 | src | semmle.label | src | +| domparser.js:2:7:2:36 | src | semmle.label | src | +| domparser.js:2:13:2:36 | documen ... .search | semmle.label | documen ... .search | +| domparser.js:6:37:6:39 | src | semmle.label | src | +| domparser.js:11:55:11:57 | src | semmle.label | src | +| domparser.js:14:57:14:59 | src | semmle.label | src | +| expat.js:6:16:6:36 | req.par ... e-xml") | semmle.label | req.par ... e-xml") | +| jquery.js:2:7:2:36 | src | semmle.label | src | +| jquery.js:2:13:2:36 | documen ... .search | semmle.label | documen ... .search | +| jquery.js:5:14:5:16 | src | semmle.label | src | +| libxml.js:6:21:6:41 | req.par ... e-xml") | semmle.label | req.par ... e-xml") | +| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | semmle.label | req.par ... e-xml") | +| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | semmle.label | req.par ... e-xml") | +| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | semmle.label | req.par ... e-xml") | +subpaths #select | closure.js:4:24:4:26 | src | closure.js:2:13:2:36 | documen ... .search | closure.js:4:24:4:26 | src | XML parsing depends on a $@ without guarding against uncontrolled entity expansion. | closure.js:2:13:2:36 | documen ... .search | user-provided value | | domparser.js:6:37:6:39 | src | domparser.js:2:13:2:36 | documen ... .search | domparser.js:6:37:6:39 | src | XML parsing depends on a $@ without guarding against uncontrolled entity expansion. | domparser.js:2:13:2:36 | documen ... .search | user-provided value | From c2d170b4fd4bad9961bc03f5b8d5f37f185b89c3 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:26:36 +0200 Subject: [PATCH 103/514] JS: Port XpathInjection --- .../security/dataflow/XpathInjectionQuery.qll | 18 ++++++- .../ql/src/Security/CWE-643/XpathInjection.ql | 6 +-- .../Security/CWE-643/XpathInjection.expected | 51 ++++++------------- 3 files changed, 36 insertions(+), 39 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XpathInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XpathInjectionQuery.qll index 08e84e834d0..9016c19bd9e 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XpathInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XpathInjectionQuery.qll @@ -14,7 +14,23 @@ import XpathInjectionCustomizations::XpathInjection /** * A taint-tracking configuration for untrusted user input used in XPath expression. */ -class Configuration extends TaintTracking::Configuration { +module XpathInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint-tracking for untrusted user input used in XPath expression. + */ +module XpathInjectionFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `XpathInjectionFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "XpathInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-643/XpathInjection.ql b/javascript/ql/src/Security/CWE-643/XpathInjection.ql index 8a5bfbd791f..c28441d8e24 100644 --- a/javascript/ql/src/Security/CWE-643/XpathInjection.ql +++ b/javascript/ql/src/Security/CWE-643/XpathInjection.ql @@ -13,9 +13,9 @@ import javascript import semmle.javascript.security.dataflow.XpathInjectionQuery -import DataFlow::PathGraph +import XpathInjectionFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from XpathInjectionFlow::PathNode source, XpathInjectionFlow::PathNode sink +where XpathInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "XPath expression depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected b/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected index f2e28eb3703..5b216204dbe 100644 --- a/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected @@ -1,50 +1,31 @@ -nodes -| XpathInjectionBad.js:6:7:6:38 | userName | -| XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | -| XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | -| XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | -| XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | -| XpathInjectionBad.js:9:66:9:73 | userName | -| tst2.js:1:13:1:34 | documen ... on.hash | -| tst2.js:1:13:1:34 | documen ... on.hash | -| tst2.js:1:13:1:47 | documen ... ring(1) | -| tst2.js:2:27:2:31 | query | -| tst2.js:2:27:2:31 | query | -| tst2.js:3:19:3:23 | query | -| tst2.js:3:19:3:23 | query | -| tst.js:6:7:6:37 | tainted | -| tst.js:6:17:6:37 | req.par ... rName") | -| tst.js:6:17:6:37 | req.par ... rName") | -| tst.js:7:15:7:21 | tainted | -| tst.js:7:15:7:21 | tainted | -| tst.js:8:16:8:22 | tainted | -| tst.js:8:16:8:22 | tainted | -| tst.js:9:17:9:23 | tainted | -| tst.js:9:17:9:23 | tainted | -| tst.js:11:8:11:14 | tainted | -| tst.js:11:8:11:14 | tainted | edges | XpathInjectionBad.js:6:7:6:38 | userName | XpathInjectionBad.js:9:66:9:73 | userName | | XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | XpathInjectionBad.js:6:7:6:38 | userName | -| XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | XpathInjectionBad.js:6:7:6:38 | userName | -| XpathInjectionBad.js:9:66:9:73 | userName | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | | XpathInjectionBad.js:9:66:9:73 | userName | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | | tst2.js:1:13:1:34 | documen ... on.hash | tst2.js:1:13:1:47 | documen ... ring(1) | -| tst2.js:1:13:1:34 | documen ... on.hash | tst2.js:1:13:1:47 | documen ... ring(1) | -| tst2.js:1:13:1:47 | documen ... ring(1) | tst2.js:2:27:2:31 | query | | tst2.js:1:13:1:47 | documen ... ring(1) | tst2.js:2:27:2:31 | query | | tst2.js:1:13:1:47 | documen ... ring(1) | tst2.js:3:19:3:23 | query | -| tst2.js:1:13:1:47 | documen ... ring(1) | tst2.js:3:19:3:23 | query | -| tst.js:6:7:6:37 | tainted | tst.js:7:15:7:21 | tainted | | tst.js:6:7:6:37 | tainted | tst.js:7:15:7:21 | tainted | | tst.js:6:7:6:37 | tainted | tst.js:8:16:8:22 | tainted | -| tst.js:6:7:6:37 | tainted | tst.js:8:16:8:22 | tainted | -| tst.js:6:7:6:37 | tainted | tst.js:9:17:9:23 | tainted | | tst.js:6:7:6:37 | tainted | tst.js:9:17:9:23 | tainted | | tst.js:6:7:6:37 | tainted | tst.js:11:8:11:14 | tainted | -| tst.js:6:7:6:37 | tainted | tst.js:11:8:11:14 | tainted | -| tst.js:6:17:6:37 | req.par ... rName") | tst.js:6:7:6:37 | tainted | | tst.js:6:17:6:37 | req.par ... rName") | tst.js:6:7:6:37 | tainted | +nodes +| XpathInjectionBad.js:6:7:6:38 | userName | semmle.label | userName | +| XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | semmle.label | req.par ... rName") | +| XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | semmle.label | "//user ... text()" | +| XpathInjectionBad.js:9:66:9:73 | userName | semmle.label | userName | +| tst2.js:1:13:1:34 | documen ... on.hash | semmle.label | documen ... on.hash | +| tst2.js:1:13:1:47 | documen ... ring(1) | semmle.label | documen ... ring(1) | +| tst2.js:2:27:2:31 | query | semmle.label | query | +| tst2.js:3:19:3:23 | query | semmle.label | query | +| tst.js:6:7:6:37 | tainted | semmle.label | tainted | +| tst.js:6:17:6:37 | req.par ... rName") | semmle.label | req.par ... rName") | +| tst.js:7:15:7:21 | tainted | semmle.label | tainted | +| tst.js:8:16:8:22 | tainted | semmle.label | tainted | +| tst.js:9:17:9:23 | tainted | semmle.label | tainted | +| tst.js:11:8:11:14 | tainted | semmle.label | tainted | +subpaths #select | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | XPath expression depends on a $@. | XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | user-provided value | | tst2.js:2:27:2:31 | query | tst2.js:1:13:1:34 | documen ... on.hash | tst2.js:2:27:2:31 | query | XPath expression depends on a $@. | tst2.js:1:13:1:34 | documen ... on.hash | user-provided value | From b8847dbc5d0328de7c7788abac52680ebf2eb8d5 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:26:42 +0200 Subject: [PATCH 104/514] JS: Port Xxe --- .../javascript/security/dataflow/XxeQuery.qll | 18 +++++- javascript/ql/src/Security/CWE-611/Xxe.ql | 6 +- .../query-tests/Security/CWE-611/Xxe.expected | 56 +++++-------------- 3 files changed, 34 insertions(+), 46 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XxeQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XxeQuery.qll index 82d3fb4f6cc..c82289b28bc 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XxeQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XxeQuery.qll @@ -13,7 +13,23 @@ import XxeCustomizations::Xxe /** * A taint-tracking configuration for reasoning about XXE vulnerabilities. */ -class Configuration extends TaintTracking::Configuration { +module XxeConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint-tracking for reasoning about XXE vulnerabilities. + */ +module XxeFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `XxeFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "Xxe" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-611/Xxe.ql b/javascript/ql/src/Security/CWE-611/Xxe.ql index 6f544f3a2e5..e1e84e36048 100644 --- a/javascript/ql/src/Security/CWE-611/Xxe.ql +++ b/javascript/ql/src/Security/CWE-611/Xxe.ql @@ -14,10 +14,10 @@ import javascript import semmle.javascript.security.dataflow.XxeQuery -import DataFlow::PathGraph +import XxeFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from XxeFlow::PathNode source, XxeFlow::PathNode sink +where XxeFlow::flowPath(source, sink) select sink.getNode(), source, sink, "XML parsing depends on a $@ without guarding against external entity expansion.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected b/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected index b625cd91449..8302bf16dd0 100644 --- a/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected +++ b/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected @@ -1,49 +1,21 @@ -nodes -| domparser.js:2:7:2:36 | src | -| domparser.js:2:13:2:36 | documen ... .search | -| domparser.js:2:13:2:36 | documen ... .search | -| domparser.js:11:55:11:57 | src | -| domparser.js:11:55:11:57 | src | -| domparser.js:14:57:14:59 | src | -| domparser.js:14:57:14:59 | src | -| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | -| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | -| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | -| libxml.noent.js:11:21:11:41 | req.par ... e-xml") | -| libxml.noent.js:11:21:11:41 | req.par ... e-xml") | -| libxml.noent.js:11:21:11:41 | req.par ... e-xml") | -| libxml.noent.js:14:27:14:47 | req.par ... e-xml") | -| libxml.noent.js:14:27:14:47 | req.par ... e-xml") | -| libxml.noent.js:14:27:14:47 | req.par ... e-xml") | -| libxml.noent.js:16:27:16:35 | req.files | -| libxml.noent.js:16:27:16:35 | req.files | -| libxml.noent.js:16:27:16:44 | req.files.products | -| libxml.noent.js:16:27:16:49 | req.fil ... ts.data | -| libxml.noent.js:16:27:16:66 | req.fil ... 'utf8') | -| libxml.noent.js:16:27:16:66 | req.fil ... 'utf8') | -| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | -| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | -| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | -| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | -| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | -| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | edges | domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src | -| domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src | -| domparser.js:2:7:2:36 | src | domparser.js:14:57:14:59 | src | | domparser.js:2:7:2:36 | src | domparser.js:14:57:14:59 | src | | domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src | -| domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src | -| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | -| libxml.noent.js:11:21:11:41 | req.par ... e-xml") | libxml.noent.js:11:21:11:41 | req.par ... e-xml") | -| libxml.noent.js:14:27:14:47 | req.par ... e-xml") | libxml.noent.js:14:27:14:47 | req.par ... e-xml") | -| libxml.noent.js:16:27:16:35 | req.files | libxml.noent.js:16:27:16:44 | req.files.products | -| libxml.noent.js:16:27:16:35 | req.files | libxml.noent.js:16:27:16:44 | req.files.products | -| libxml.noent.js:16:27:16:44 | req.files.products | libxml.noent.js:16:27:16:49 | req.fil ... ts.data | -| libxml.noent.js:16:27:16:49 | req.fil ... ts.data | libxml.noent.js:16:27:16:66 | req.fil ... 'utf8') | -| libxml.noent.js:16:27:16:49 | req.fil ... ts.data | libxml.noent.js:16:27:16:66 | req.fil ... 'utf8') | -| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | libxml.sax.js:6:22:6:42 | req.par ... e-xml") | -| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | +| libxml.noent.js:16:27:16:35 | req.files | libxml.noent.js:16:27:16:66 | req.fil ... 'utf8') | +nodes +| domparser.js:2:7:2:36 | src | semmle.label | src | +| domparser.js:2:13:2:36 | documen ... .search | semmle.label | documen ... .search | +| domparser.js:11:55:11:57 | src | semmle.label | src | +| domparser.js:14:57:14:59 | src | semmle.label | src | +| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | semmle.label | req.par ... e-xml") | +| libxml.noent.js:11:21:11:41 | req.par ... e-xml") | semmle.label | req.par ... e-xml") | +| libxml.noent.js:14:27:14:47 | req.par ... e-xml") | semmle.label | req.par ... e-xml") | +| libxml.noent.js:16:27:16:35 | req.files | semmle.label | req.files | +| libxml.noent.js:16:27:16:66 | req.fil ... 'utf8') | semmle.label | req.fil ... 'utf8') | +| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | semmle.label | req.par ... e-xml") | +| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | semmle.label | req.par ... e-xml") | +subpaths #select | domparser.js:11:55:11:57 | src | domparser.js:2:13:2:36 | documen ... .search | domparser.js:11:55:11:57 | src | XML parsing depends on a $@ without guarding against external entity expansion. | domparser.js:2:13:2:36 | documen ... .search | user-provided value | | domparser.js:14:57:14:59 | src | domparser.js:2:13:2:36 | documen ... .search | domparser.js:14:57:14:59 | src | XML parsing depends on a $@ without guarding against external entity expansion. | domparser.js:2:13:2:36 | documen ... .search | user-provided value | From c55300d4b05bcad1167530025d8d5c468b788bf9 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:26:50 +0200 Subject: [PATCH 105/514] JS: Port PolynomialReDoS --- .../regexp/PolynomialReDoSCustomizations.qll | 19 +- .../security/regexp/PolynomialReDoSQuery.qll | 26 +- .../ql/src/Performance/PolynomialReDoS.ql | 6 +- .../CWE-400/ReDoS/PolynomialReDoS.expected | 717 ++++++++++-------- 4 files changed, 444 insertions(+), 324 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSCustomizations.qll index 30bd36c124e..196bead33f1 100644 --- a/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSCustomizations.qll @@ -46,6 +46,21 @@ module PolynomialReDoS { */ abstract class Sanitizer extends DataFlow::Node { } + /** + * A barrier guard for polynomial regular expression denial-of-service attacks. + */ + 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() } + } + + /** 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) } + } + /** * A remote input to a server, seen as a source for polynomial * regular expression denial-of-service vulnerabilities. @@ -118,7 +133,7 @@ module PolynomialReDoS { /** * An check on the length of a string, seen as a sanitizer guard. */ - class LengthGuard extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode { + class LengthGuard extends BarrierGuardLegacy, DataFlow::ValueNode { DataFlow::Node input; boolean polarity; @@ -133,7 +148,7 @@ module PolynomialReDoS { ) } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { outcome = polarity and e = input.asExpr() } diff --git a/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSQuery.qll b/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSQuery.qll index f8675bde3f2..dbe45503f2c 100644 --- a/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSQuery.qll @@ -11,7 +11,31 @@ import javascript import PolynomialReDoSCustomizations::PolynomialReDoS /** A taint-tracking configuration for reasoning about polynomial regular expression denial-of-service attacks. */ -class Configuration extends TaintTracking::Configuration { +module PolynomialReDoSConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { + node instanceof Sanitizer or node = DataFlow::MakeBarrierGuard::getABarrierNode() + } + + DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext } + + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { + none() + // TODO: localFieldStep is too expensive with dataflow2 + // DataFlow::localFieldStep(pred, succ) + } +} + +/** Taint-tracking for reasoning about polynomial regular expression denial-of-service attacks. */ +module PolynomialReDoSFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `PolynomialReDoSFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "PolynomialReDoS" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Performance/PolynomialReDoS.ql b/javascript/ql/src/Performance/PolynomialReDoS.ql index befc556b033..7a4e72136f4 100644 --- a/javascript/ql/src/Performance/PolynomialReDoS.ql +++ b/javascript/ql/src/Performance/PolynomialReDoS.ql @@ -15,13 +15,13 @@ import javascript import semmle.javascript.security.regexp.PolynomialReDoSQuery -import DataFlow::PathGraph +import PolynomialReDoSFlow::PathGraph from - Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Sink sinkNode, + PolynomialReDoSFlow::PathNode source, PolynomialReDoSFlow::PathNode sink, Sink sinkNode, PolynomialBackTrackingTerm regexp where - cfg.hasFlowPath(source, sink) and + PolynomialReDoSFlow::flowPath(source, sink) and sinkNode = sink.getNode() and regexp = sinkNode.getRegExp() and not ( diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected index 4c534fffe13..e8593c903ca 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected @@ -1,341 +1,32 @@ -nodes -| lib/closure.js:3:21:3:21 | x | -| lib/closure.js:3:21:3:21 | x | -| lib/closure.js:4:16:4:16 | x | -| lib/closure.js:4:16:4:16 | x | -| lib/indirect.js:1:32:1:32 | x | -| lib/indirect.js:1:32:1:32 | x | -| lib/indirect.js:2:16:2:16 | x | -| lib/indirect.js:2:16:2:16 | x | -| lib/lib.js:3:28:3:31 | name | -| lib/lib.js:3:28:3:31 | name | -| lib/lib.js:4:14:4:17 | name | -| lib/lib.js:4:14:4:17 | name | -| lib/lib.js:7:19:7:22 | name | -| lib/lib.js:7:19:7:22 | name | -| lib/lib.js:8:13:8:16 | name | -| lib/lib.js:8:13:8:16 | name | -| lib/lib.js:21:14:21:14 | x | -| lib/lib.js:21:14:21:14 | x | -| lib/lib.js:22:9:22:9 | x | -| lib/lib.js:27:6:27:19 | y | -| lib/lib.js:27:10:27:19 | id("safe") | -| lib/lib.js:28:13:28:13 | y | -| lib/lib.js:28:13:28:13 | y | -| lib/lib.js:32:32:32:40 | arguments | -| lib/lib.js:32:32:32:40 | arguments | -| lib/lib.js:35:1:37:1 | 'arguments' object of function usedWithArguments | -| lib/lib.js:35:28:35:31 | name | -| lib/lib.js:36:13:36:16 | name | -| lib/lib.js:36:13:36:16 | name | -| lib/lib.js:41:32:41:35 | name | -| lib/lib.js:41:32:41:35 | name | -| lib/lib.js:42:17:42:20 | name | -| lib/lib.js:42:17:42:20 | name | -| lib/lib.js:44:5:44:25 | name | -| lib/lib.js:44:12:44:15 | name | -| lib/lib.js:44:12:44:25 | name.substr(1) | -| lib/lib.js:45:17:45:20 | name | -| lib/lib.js:45:17:45:20 | name | -| lib/lib.js:52:22:52:25 | name | -| lib/lib.js:52:22:52:25 | name | -| lib/lib.js:53:16:53:19 | name | -| lib/lib.js:53:16:53:19 | name | -| lib/moduleLib/moduleLib.js:1:28:1:31 | name | -| lib/moduleLib/moduleLib.js:1:28:1:31 | name | -| lib/moduleLib/moduleLib.js:2:13:2:16 | name | -| lib/moduleLib/moduleLib.js:2:13:2:16 | name | -| lib/otherLib/js/src/index.js:1:28:1:31 | name | -| lib/otherLib/js/src/index.js:1:28:1:31 | name | -| lib/otherLib/js/src/index.js:2:13:2:16 | name | -| lib/otherLib/js/src/index.js:2:13:2:16 | name | -| lib/snapdragon.js:3:34:3:38 | input | -| lib/snapdragon.js:3:34:3:38 | input | -| lib/snapdragon.js:7:15:7:18 | this | -| lib/snapdragon.js:7:15:7:18 | this | -| lib/snapdragon.js:9:12:9:16 | input | -| lib/snapdragon.js:12:34:12:38 | input | -| lib/snapdragon.js:12:34:12:38 | input | -| lib/snapdragon.js:15:13:15:16 | this | -| lib/snapdragon.js:15:13:15:16 | this | -| lib/snapdragon.js:17:20:17:24 | input | -| lib/snapdragon.js:20:34:20:38 | input | -| lib/snapdragon.js:20:34:20:38 | input | -| lib/snapdragon.js:22:44:22:47 | node | -| lib/snapdragon.js:23:5:23:8 | node | -| lib/snapdragon.js:23:5:23:12 | node.val | -| lib/snapdragon.js:23:5:23:12 | node.val | -| lib/snapdragon.js:25:22:25:26 | input | -| lib/subLib4/factory.js:7:27:7:30 | name | -| lib/subLib4/factory.js:7:27:7:30 | name | -| lib/subLib4/factory.js:8:13:8:16 | name | -| lib/subLib4/factory.js:8:13:8:16 | name | -| lib/subLib5/feature.js:1:28:1:31 | name | -| lib/subLib5/feature.js:1:28:1:31 | name | -| lib/subLib5/feature.js:2:13:2:16 | name | -| lib/subLib5/feature.js:2:13:2:16 | name | -| lib/subLib5/main.js:1:28:1:31 | name | -| lib/subLib5/main.js:1:28:1:31 | name | -| lib/subLib5/main.js:2:13:2:16 | name | -| lib/subLib5/main.js:2:13:2:16 | name | -| lib/subLib5/subclass.js:4:10:4:13 | name | -| lib/subLib5/subclass.js:4:10:4:13 | name | -| lib/subLib5/subclass.js:5:16:5:19 | name | -| lib/subLib5/subclass.js:5:16:5:19 | name | -| lib/subLib6/index.js:1:32:1:35 | name | -| lib/subLib6/index.js:1:32:1:35 | name | -| lib/subLib6/index.js:2:14:2:17 | name | -| lib/subLib6/index.js:2:14:2:17 | name | -| lib/sublib/factory.js:12:26:12:29 | name | -| lib/sublib/factory.js:12:26:12:29 | name | -| lib/sublib/factory.js:13:24:13:27 | name | -| lib/sublib/factory.js:13:24:13:27 | name | -| polynomial-redos.js:5:6:5:32 | tainted | -| polynomial-redos.js:5:16:5:32 | req.query.tainted | -| polynomial-redos.js:5:16:5:32 | req.query.tainted | -| polynomial-redos.js:7:2:7:8 | tainted | -| polynomial-redos.js:7:2:7:8 | tainted | -| polynomial-redos.js:8:2:8:8 | tainted | -| polynomial-redos.js:8:2:8:8 | tainted | -| polynomial-redos.js:9:2:9:8 | tainted | -| polynomial-redos.js:9:2:9:8 | tainted | -| polynomial-redos.js:11:2:11:8 | tainted | -| polynomial-redos.js:11:2:11:8 | tainted | -| polynomial-redos.js:12:2:12:8 | tainted | -| polynomial-redos.js:12:2:12:8 | tainted | -| polynomial-redos.js:15:2:15:8 | tainted | -| polynomial-redos.js:15:2:15:8 | tainted | -| polynomial-redos.js:16:2:16:8 | tainted | -| polynomial-redos.js:16:2:16:8 | tainted | -| polynomial-redos.js:17:23:17:29 | tainted | -| polynomial-redos.js:17:23:17:29 | tainted | -| polynomial-redos.js:18:2:18:8 | tainted | -| polynomial-redos.js:18:2:18:8 | tainted | -| polynomial-redos.js:19:2:19:8 | tainted | -| polynomial-redos.js:19:2:19:8 | tainted | -| polynomial-redos.js:20:2:20:8 | tainted | -| polynomial-redos.js:20:2:20:8 | tainted | -| polynomial-redos.js:25:2:25:8 | tainted | -| polynomial-redos.js:25:2:25:8 | tainted | -| polynomial-redos.js:30:2:30:8 | tainted | -| polynomial-redos.js:30:2:30:8 | tainted | -| polynomial-redos.js:33:2:33:8 | tainted | -| polynomial-redos.js:33:2:33:8 | tainted | -| polynomial-redos.js:36:2:36:8 | tainted | -| polynomial-redos.js:36:2:36:8 | tainted | -| polynomial-redos.js:37:2:37:8 | tainted | -| polynomial-redos.js:37:2:37:8 | tainted | -| polynomial-redos.js:38:2:38:8 | tainted | -| polynomial-redos.js:38:2:38:8 | tainted | -| polynomial-redos.js:40:2:40:8 | tainted | -| polynomial-redos.js:40:2:40:8 | tainted | -| polynomial-redos.js:43:2:43:8 | tainted | -| polynomial-redos.js:43:2:43:8 | tainted | -| polynomial-redos.js:48:2:48:8 | tainted | -| polynomial-redos.js:48:2:48:8 | tainted | -| polynomial-redos.js:50:14:50:20 | tainted | -| polynomial-redos.js:50:14:50:20 | tainted | -| polynomial-redos.js:51:26:51:32 | tainted | -| polynomial-redos.js:51:26:51:32 | tainted | -| polynomial-redos.js:52:22:52:28 | tainted | -| polynomial-redos.js:52:22:52:28 | tainted | -| polynomial-redos.js:53:21:53:27 | tainted | -| polynomial-redos.js:53:21:53:27 | tainted | -| polynomial-redos.js:54:22:54:28 | tainted | -| polynomial-redos.js:54:22:54:28 | tainted | -| polynomial-redos.js:55:23:55:29 | tainted | -| polynomial-redos.js:55:23:55:29 | tainted | -| polynomial-redos.js:56:22:56:28 | tainted | -| polynomial-redos.js:56:22:56:28 | tainted | -| polynomial-redos.js:57:25:57:31 | tainted | -| polynomial-redos.js:57:25:57:31 | tainted | -| polynomial-redos.js:58:21:58:27 | tainted | -| polynomial-redos.js:58:21:58:27 | tainted | -| polynomial-redos.js:59:23:59:29 | tainted | -| polynomial-redos.js:59:23:59:29 | tainted | -| polynomial-redos.js:62:17:62:23 | tainted | -| polynomial-redos.js:62:17:62:23 | tainted | -| polynomial-redos.js:63:21:63:27 | tainted | -| polynomial-redos.js:63:21:63:27 | tainted | -| polynomial-redos.js:64:24:64:30 | tainted | -| polynomial-redos.js:64:24:64:30 | tainted | -| polynomial-redos.js:65:24:65:30 | tainted | -| polynomial-redos.js:65:24:65:30 | tainted | -| polynomial-redos.js:66:19:66:25 | tainted | -| polynomial-redos.js:66:19:66:25 | tainted | -| polynomial-redos.js:67:18:67:24 | tainted | -| polynomial-redos.js:67:18:67:24 | tainted | -| polynomial-redos.js:68:18:68:24 | req.url | -| polynomial-redos.js:68:18:68:24 | req.url | -| polynomial-redos.js:68:18:68:24 | req.url | -| polynomial-redos.js:69:18:69:25 | req.body | -| polynomial-redos.js:69:18:69:25 | req.body | -| polynomial-redos.js:69:18:69:25 | req.body | -| polynomial-redos.js:71:2:71:8 | tainted | -| polynomial-redos.js:71:2:71:8 | tainted | -| polynomial-redos.js:73:2:73:8 | tainted | -| polynomial-redos.js:73:2:73:8 | tainted | -| polynomial-redos.js:75:2:75:8 | tainted | -| polynomial-redos.js:75:2:75:8 | tainted | -| polynomial-redos.js:77:2:77:8 | tainted | -| polynomial-redos.js:77:2:77:8 | tainted | -| polynomial-redos.js:80:2:80:8 | tainted | -| polynomial-redos.js:80:2:80:8 | tainted | -| polynomial-redos.js:81:2:81:8 | tainted | -| polynomial-redos.js:81:2:81:8 | tainted | -| polynomial-redos.js:86:2:86:8 | tainted | -| polynomial-redos.js:86:2:86:8 | tainted | -| polynomial-redos.js:88:2:88:8 | tainted | -| polynomial-redos.js:88:2:88:8 | tainted | -| polynomial-redos.js:89:2:89:8 | tainted | -| polynomial-redos.js:89:2:89:8 | tainted | -| polynomial-redos.js:90:2:90:8 | tainted | -| polynomial-redos.js:90:2:90:8 | tainted | -| polynomial-redos.js:94:2:94:8 | tainted | -| polynomial-redos.js:94:2:94:8 | tainted | -| polynomial-redos.js:95:2:95:8 | tainted | -| polynomial-redos.js:95:2:95:8 | tainted | -| polynomial-redos.js:96:2:96:8 | tainted | -| polynomial-redos.js:96:2:96:8 | tainted | -| polynomial-redos.js:98:2:98:8 | tainted | -| polynomial-redos.js:98:2:98:8 | tainted | -| polynomial-redos.js:100:2:100:8 | tainted | -| polynomial-redos.js:100:2:100:8 | tainted | -| polynomial-redos.js:101:2:101:8 | tainted | -| polynomial-redos.js:101:2:101:8 | tainted | -| polynomial-redos.js:102:2:102:8 | tainted | -| polynomial-redos.js:102:2:102:8 | tainted | -| polynomial-redos.js:103:2:103:8 | tainted | -| polynomial-redos.js:103:2:103:8 | tainted | -| polynomial-redos.js:104:2:104:8 | tainted | -| polynomial-redos.js:104:2:104:8 | tainted | -| polynomial-redos.js:107:2:107:8 | tainted | -| polynomial-redos.js:107:2:107:8 | tainted | -| polynomial-redos.js:108:2:108:8 | tainted | -| polynomial-redos.js:108:2:108:8 | tainted | -| polynomial-redos.js:109:2:109:8 | tainted | -| polynomial-redos.js:109:2:109:8 | tainted | -| polynomial-redos.js:111:2:111:8 | tainted | -| polynomial-redos.js:111:2:111:8 | tainted | -| polynomial-redos.js:112:2:112:8 | tainted | -| polynomial-redos.js:112:2:112:8 | tainted | -| polynomial-redos.js:114:2:114:8 | tainted | -| polynomial-redos.js:114:2:114:8 | tainted | -| polynomial-redos.js:116:2:116:8 | tainted | -| polynomial-redos.js:116:2:116:8 | tainted | -| polynomial-redos.js:118:2:118:8 | tainted | -| polynomial-redos.js:118:2:118:8 | tainted | -| polynomial-redos.js:121:7:121:55 | replaced | -| polynomial-redos.js:121:18:121:24 | tainted | -| polynomial-redos.js:121:18:121:55 | tainted ... /g, '') | -| polynomial-redos.js:123:3:123:20 | result | -| polynomial-redos.js:123:13:123:20 | replaced | -| polynomial-redos.js:124:12:124:17 | result | -| polynomial-redos.js:124:12:124:17 | result | -| polynomial-redos.js:129:6:129:42 | modified | -| polynomial-redos.js:129:17:129:23 | tainted | -| polynomial-redos.js:129:17:129:42 | tainted ... g, "b") | -| polynomial-redos.js:130:2:130:9 | modified | -| polynomial-redos.js:130:2:130:9 | modified | -| polynomial-redos.js:132:6:132:50 | modified2 | -| polynomial-redos.js:132:18:132:24 | tainted | -| polynomial-redos.js:132:18:132:50 | tainted ... g, "e") | -| polynomial-redos.js:133:2:133:10 | modified2 | -| polynomial-redos.js:133:2:133:10 | modified2 | -| polynomial-redos.js:135:9:135:47 | modified3 | -| polynomial-redos.js:135:21:135:27 | tainted | -| polynomial-redos.js:135:21:135:47 | tainted ... /g, "") | -| polynomial-redos.js:136:5:136:13 | modified3 | -| polynomial-redos.js:136:5:136:13 | modified3 | -| polynomial-redos.js:138:5:138:11 | tainted | -| polynomial-redos.js:138:5:138:11 | tainted | edges | lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x | -| lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x | -| lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x | -| lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x | -| lib/indirect.js:1:32:1:32 | x | lib/indirect.js:2:16:2:16 | x | -| lib/indirect.js:1:32:1:32 | x | lib/indirect.js:2:16:2:16 | x | -| lib/indirect.js:1:32:1:32 | x | lib/indirect.js:2:16:2:16 | x | | lib/indirect.js:1:32:1:32 | x | lib/indirect.js:2:16:2:16 | x | | lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name | -| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name | -| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name | -| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name | | lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name | -| lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name | -| lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name | -| lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name | -| lib/lib.js:21:14:21:14 | x | lib/lib.js:22:9:22:9 | x | -| lib/lib.js:21:14:21:14 | x | lib/lib.js:22:9:22:9 | x | -| lib/lib.js:22:9:22:9 | x | lib/lib.js:27:10:27:19 | id("safe") | -| lib/lib.js:27:6:27:19 | y | lib/lib.js:28:13:28:13 | y | -| lib/lib.js:27:6:27:19 | y | lib/lib.js:28:13:28:13 | y | -| lib/lib.js:27:10:27:19 | id("safe") | lib/lib.js:27:6:27:19 | y | -| lib/lib.js:32:32:32:40 | arguments | lib/lib.js:35:1:37:1 | 'arguments' object of function usedWithArguments | | lib/lib.js:32:32:32:40 | arguments | lib/lib.js:35:1:37:1 | 'arguments' object of function usedWithArguments | | lib/lib.js:35:1:37:1 | 'arguments' object of function usedWithArguments | lib/lib.js:35:28:35:31 | name | | lib/lib.js:35:28:35:31 | name | lib/lib.js:36:13:36:16 | name | -| lib/lib.js:35:28:35:31 | name | lib/lib.js:36:13:36:16 | name | -| lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | -| lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | -| lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | | lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | | lib/lib.js:41:32:41:35 | name | lib/lib.js:44:12:44:15 | name | -| lib/lib.js:41:32:41:35 | name | lib/lib.js:44:12:44:15 | name | -| lib/lib.js:44:5:44:25 | name | lib/lib.js:45:17:45:20 | name | | lib/lib.js:44:5:44:25 | name | lib/lib.js:45:17:45:20 | name | | lib/lib.js:44:12:44:15 | name | lib/lib.js:44:12:44:25 | name.substr(1) | | lib/lib.js:44:12:44:25 | name.substr(1) | lib/lib.js:44:5:44:25 | name | | lib/lib.js:52:22:52:25 | name | lib/lib.js:53:16:53:19 | name | -| lib/lib.js:52:22:52:25 | name | lib/lib.js:53:16:53:19 | name | -| lib/lib.js:52:22:52:25 | name | lib/lib.js:53:16:53:19 | name | -| lib/lib.js:52:22:52:25 | name | lib/lib.js:53:16:53:19 | name | | lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | -| lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | -| lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | -| lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | -| lib/otherLib/js/src/index.js:1:28:1:31 | name | lib/otherLib/js/src/index.js:2:13:2:16 | name | -| lib/otherLib/js/src/index.js:1:28:1:31 | name | lib/otherLib/js/src/index.js:2:13:2:16 | name | -| lib/otherLib/js/src/index.js:1:28:1:31 | name | lib/otherLib/js/src/index.js:2:13:2:16 | name | | lib/otherLib/js/src/index.js:1:28:1:31 | name | lib/otherLib/js/src/index.js:2:13:2:16 | name | | lib/snapdragon.js:3:34:3:38 | input | lib/snapdragon.js:9:12:9:16 | input | -| lib/snapdragon.js:3:34:3:38 | input | lib/snapdragon.js:9:12:9:16 | input | -| lib/snapdragon.js:9:12:9:16 | input | lib/snapdragon.js:7:15:7:18 | this | | lib/snapdragon.js:9:12:9:16 | input | lib/snapdragon.js:7:15:7:18 | this | | lib/snapdragon.js:12:34:12:38 | input | lib/snapdragon.js:17:20:17:24 | input | -| lib/snapdragon.js:12:34:12:38 | input | lib/snapdragon.js:17:20:17:24 | input | | lib/snapdragon.js:17:20:17:24 | input | lib/snapdragon.js:15:13:15:16 | this | -| lib/snapdragon.js:17:20:17:24 | input | lib/snapdragon.js:15:13:15:16 | this | -| lib/snapdragon.js:20:34:20:38 | input | lib/snapdragon.js:25:22:25:26 | input | | lib/snapdragon.js:20:34:20:38 | input | lib/snapdragon.js:25:22:25:26 | input | | lib/snapdragon.js:22:44:22:47 | node | lib/snapdragon.js:23:5:23:8 | node | | lib/snapdragon.js:23:5:23:8 | node | lib/snapdragon.js:23:5:23:12 | node.val | -| lib/snapdragon.js:23:5:23:8 | node | lib/snapdragon.js:23:5:23:12 | node.val | | lib/snapdragon.js:25:22:25:26 | input | lib/snapdragon.js:22:44:22:47 | node | | lib/subLib4/factory.js:7:27:7:30 | name | lib/subLib4/factory.js:8:13:8:16 | name | -| lib/subLib4/factory.js:7:27:7:30 | name | lib/subLib4/factory.js:8:13:8:16 | name | -| lib/subLib4/factory.js:7:27:7:30 | name | lib/subLib4/factory.js:8:13:8:16 | name | -| lib/subLib4/factory.js:7:27:7:30 | name | lib/subLib4/factory.js:8:13:8:16 | name | -| lib/subLib5/feature.js:1:28:1:31 | name | lib/subLib5/feature.js:2:13:2:16 | name | -| lib/subLib5/feature.js:1:28:1:31 | name | lib/subLib5/feature.js:2:13:2:16 | name | -| lib/subLib5/feature.js:1:28:1:31 | name | lib/subLib5/feature.js:2:13:2:16 | name | | lib/subLib5/feature.js:1:28:1:31 | name | lib/subLib5/feature.js:2:13:2:16 | name | | lib/subLib5/main.js:1:28:1:31 | name | lib/subLib5/main.js:2:13:2:16 | name | -| lib/subLib5/main.js:1:28:1:31 | name | lib/subLib5/main.js:2:13:2:16 | name | -| lib/subLib5/main.js:1:28:1:31 | name | lib/subLib5/main.js:2:13:2:16 | name | -| lib/subLib5/main.js:1:28:1:31 | name | lib/subLib5/main.js:2:13:2:16 | name | -| lib/subLib5/subclass.js:4:10:4:13 | name | lib/subLib5/subclass.js:5:16:5:19 | name | -| lib/subLib5/subclass.js:4:10:4:13 | name | lib/subLib5/subclass.js:5:16:5:19 | name | -| lib/subLib5/subclass.js:4:10:4:13 | name | lib/subLib5/subclass.js:5:16:5:19 | name | | lib/subLib5/subclass.js:4:10:4:13 | name | lib/subLib5/subclass.js:5:16:5:19 | name | | lib/subLib6/index.js:1:32:1:35 | name | lib/subLib6/index.js:2:14:2:17 | name | -| lib/subLib6/index.js:1:32:1:35 | name | lib/subLib6/index.js:2:14:2:17 | name | -| lib/subLib6/index.js:1:32:1:35 | name | lib/subLib6/index.js:2:14:2:17 | name | -| lib/subLib6/index.js:1:32:1:35 | name | lib/subLib6/index.js:2:14:2:17 | name | -| lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name | -| lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name | -| lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name | | lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:7:2:7:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:7:2:7:8 | tainted | @@ -343,10 +34,13 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:8:2:8:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:9:2:9:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:9:2:9:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:10:2:10:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:11:2:11:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:11:2:11:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:12:2:12:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:12:2:12:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:13:2:13:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:14:2:14:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:15:2:15:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:15:2:15:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:16:2:16:8 | tainted | @@ -359,12 +53,19 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:19:2:19:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:20:2:20:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:20:2:20:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:21:6:21:12 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:25:2:25:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:25:2:25:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:26:2:26:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:27:77:27:83 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:28:76:28:82 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:30:2:30:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:30:2:30:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:31:2:31:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:32:2:32:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:33:2:33:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:33:2:33:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:34:2:34:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:36:2:36:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:36:2:36:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:37:2:37:8 | tainted | @@ -373,8 +74,12 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:38:2:38:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:40:2:40:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:40:2:40:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:41:2:41:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:43:2:43:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:43:2:43:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:44:2:44:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:46:2:46:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:47:2:47:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:48:2:48:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:48:2:48:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:50:14:50:20 | tainted | @@ -397,6 +102,8 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:58:21:58:27 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:59:23:59:29 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:59:23:59:29 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:60:17:60:23 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:61:18:61:24 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:62:17:62:23 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:62:17:62:23 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:63:21:63:27 | tainted | @@ -421,6 +128,9 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:80:2:80:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:81:2:81:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:81:2:81:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:82:2:82:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:83:2:83:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:84:2:84:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:86:2:86:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:86:2:86:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:88:2:88:8 | tainted | @@ -429,6 +139,8 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:89:2:89:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:90:2:90:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:90:2:90:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:91:2:91:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:92:2:92:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:94:2:94:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:94:2:94:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:95:2:95:8 | tainted | @@ -447,6 +159,7 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:103:2:103:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:104:2:104:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:104:2:104:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:105:2:105:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:107:2:107:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:107:2:107:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:108:2:108:8 | tainted | @@ -463,34 +176,402 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:116:2:116:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:118:2:118:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:118:2:118:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:121:18:121:24 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:127:2:127:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:129:17:129:23 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:132:18:132:24 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:135:21:135:27 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:138:5:138:11 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:138:5:138:11 | tainted | | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:5:6:5:32 | tainted | -| polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:5:6:5:32 | tainted | -| polynomial-redos.js:68:18:68:24 | req.url | polynomial-redos.js:68:18:68:24 | req.url | -| polynomial-redos.js:69:18:69:25 | req.body | polynomial-redos.js:69:18:69:25 | req.body | +| polynomial-redos.js:7:2:7:8 | tainted | polynomial-redos.js:8:2:8:8 | tainted | +| polynomial-redos.js:7:2:7:8 | tainted | polynomial-redos.js:8:2:8:8 | tainted | +| polynomial-redos.js:8:2:8:8 | tainted | polynomial-redos.js:9:2:9:8 | tainted | +| polynomial-redos.js:8:2:8:8 | tainted | polynomial-redos.js:9:2:9:8 | tainted | +| polynomial-redos.js:9:2:9:8 | tainted | polynomial-redos.js:10:2:10:8 | tainted | +| polynomial-redos.js:10:2:10:8 | tainted | polynomial-redos.js:11:2:11:8 | tainted | +| polynomial-redos.js:10:2:10:8 | tainted | polynomial-redos.js:11:2:11:8 | tainted | +| polynomial-redos.js:11:2:11:8 | tainted | polynomial-redos.js:12:2:12:8 | tainted | +| polynomial-redos.js:11:2:11:8 | tainted | polynomial-redos.js:12:2:12:8 | tainted | +| polynomial-redos.js:12:2:12:8 | tainted | polynomial-redos.js:13:2:13:8 | tainted | +| polynomial-redos.js:13:2:13:8 | tainted | polynomial-redos.js:14:2:14:8 | tainted | +| polynomial-redos.js:14:2:14:8 | tainted | polynomial-redos.js:15:2:15:8 | tainted | +| polynomial-redos.js:14:2:14:8 | tainted | polynomial-redos.js:15:2:15:8 | tainted | +| polynomial-redos.js:15:2:15:8 | tainted | polynomial-redos.js:16:2:16:8 | tainted | +| polynomial-redos.js:15:2:15:8 | tainted | polynomial-redos.js:16:2:16:8 | tainted | +| polynomial-redos.js:16:2:16:8 | tainted | polynomial-redos.js:17:23:17:29 | tainted | +| polynomial-redos.js:16:2:16:8 | tainted | polynomial-redos.js:17:23:17:29 | tainted | +| polynomial-redos.js:17:23:17:29 | tainted | polynomial-redos.js:18:2:18:8 | tainted | +| polynomial-redos.js:17:23:17:29 | tainted | polynomial-redos.js:18:2:18:8 | tainted | +| polynomial-redos.js:18:2:18:8 | tainted | polynomial-redos.js:19:2:19:8 | tainted | +| polynomial-redos.js:18:2:18:8 | tainted | polynomial-redos.js:19:2:19:8 | tainted | +| polynomial-redos.js:19:2:19:8 | tainted | polynomial-redos.js:20:2:20:8 | tainted | +| polynomial-redos.js:19:2:19:8 | tainted | polynomial-redos.js:20:2:20:8 | tainted | +| polynomial-redos.js:20:2:20:8 | tainted | polynomial-redos.js:21:6:21:12 | tainted | +| polynomial-redos.js:21:6:21:12 | tainted | polynomial-redos.js:25:2:25:8 | tainted | +| polynomial-redos.js:21:6:21:12 | tainted | polynomial-redos.js:25:2:25:8 | tainted | +| polynomial-redos.js:25:2:25:8 | tainted | polynomial-redos.js:26:2:26:8 | tainted | +| polynomial-redos.js:26:2:26:8 | tainted | polynomial-redos.js:27:77:27:83 | tainted | +| polynomial-redos.js:27:77:27:83 | tainted | polynomial-redos.js:28:76:28:82 | tainted | +| polynomial-redos.js:28:76:28:82 | tainted | polynomial-redos.js:30:2:30:8 | tainted | +| polynomial-redos.js:28:76:28:82 | tainted | polynomial-redos.js:30:2:30:8 | tainted | +| polynomial-redos.js:30:2:30:8 | tainted | polynomial-redos.js:31:2:31:8 | tainted | +| polynomial-redos.js:31:2:31:8 | tainted | polynomial-redos.js:32:2:32:8 | tainted | +| polynomial-redos.js:32:2:32:8 | tainted | polynomial-redos.js:33:2:33:8 | tainted | +| polynomial-redos.js:32:2:32:8 | tainted | polynomial-redos.js:33:2:33:8 | tainted | +| polynomial-redos.js:33:2:33:8 | tainted | polynomial-redos.js:34:2:34:8 | tainted | +| polynomial-redos.js:34:2:34:8 | tainted | polynomial-redos.js:36:2:36:8 | tainted | +| polynomial-redos.js:34:2:34:8 | tainted | polynomial-redos.js:36:2:36:8 | tainted | +| polynomial-redos.js:36:2:36:8 | tainted | polynomial-redos.js:37:2:37:8 | tainted | +| polynomial-redos.js:36:2:36:8 | tainted | polynomial-redos.js:37:2:37:8 | tainted | +| polynomial-redos.js:37:2:37:8 | tainted | polynomial-redos.js:38:2:38:8 | tainted | +| polynomial-redos.js:37:2:37:8 | tainted | polynomial-redos.js:38:2:38:8 | tainted | +| polynomial-redos.js:38:2:38:8 | tainted | polynomial-redos.js:40:2:40:8 | tainted | +| polynomial-redos.js:38:2:38:8 | tainted | polynomial-redos.js:40:2:40:8 | tainted | +| polynomial-redos.js:40:2:40:8 | tainted | polynomial-redos.js:41:2:41:8 | tainted | +| polynomial-redos.js:41:2:41:8 | tainted | polynomial-redos.js:43:2:43:8 | tainted | +| polynomial-redos.js:41:2:41:8 | tainted | polynomial-redos.js:43:2:43:8 | tainted | +| polynomial-redos.js:43:2:43:8 | tainted | polynomial-redos.js:44:2:44:8 | tainted | +| polynomial-redos.js:44:2:44:8 | tainted | polynomial-redos.js:46:2:46:8 | tainted | +| polynomial-redos.js:46:2:46:8 | tainted | polynomial-redos.js:47:2:47:8 | tainted | +| polynomial-redos.js:47:2:47:8 | tainted | polynomial-redos.js:48:2:48:8 | tainted | +| polynomial-redos.js:47:2:47:8 | tainted | polynomial-redos.js:48:2:48:8 | tainted | +| polynomial-redos.js:48:2:48:8 | tainted | polynomial-redos.js:50:14:50:20 | tainted | +| polynomial-redos.js:48:2:48:8 | tainted | polynomial-redos.js:50:14:50:20 | tainted | +| polynomial-redos.js:50:14:50:20 | tainted | polynomial-redos.js:51:26:51:32 | tainted | +| polynomial-redos.js:50:14:50:20 | tainted | polynomial-redos.js:51:26:51:32 | tainted | +| polynomial-redos.js:51:26:51:32 | tainted | polynomial-redos.js:52:22:52:28 | tainted | +| polynomial-redos.js:51:26:51:32 | tainted | polynomial-redos.js:52:22:52:28 | tainted | +| polynomial-redos.js:52:22:52:28 | tainted | polynomial-redos.js:53:21:53:27 | tainted | +| polynomial-redos.js:52:22:52:28 | tainted | polynomial-redos.js:53:21:53:27 | tainted | +| polynomial-redos.js:53:21:53:27 | tainted | polynomial-redos.js:54:22:54:28 | tainted | +| polynomial-redos.js:53:21:53:27 | tainted | polynomial-redos.js:54:22:54:28 | tainted | +| polynomial-redos.js:54:22:54:28 | tainted | polynomial-redos.js:55:23:55:29 | tainted | +| polynomial-redos.js:54:22:54:28 | tainted | polynomial-redos.js:55:23:55:29 | tainted | +| polynomial-redos.js:55:23:55:29 | tainted | polynomial-redos.js:56:22:56:28 | tainted | +| polynomial-redos.js:55:23:55:29 | tainted | polynomial-redos.js:56:22:56:28 | tainted | +| polynomial-redos.js:56:22:56:28 | tainted | polynomial-redos.js:57:25:57:31 | tainted | +| polynomial-redos.js:56:22:56:28 | tainted | polynomial-redos.js:57:25:57:31 | tainted | +| polynomial-redos.js:57:25:57:31 | tainted | polynomial-redos.js:58:21:58:27 | tainted | +| polynomial-redos.js:57:25:57:31 | tainted | polynomial-redos.js:58:21:58:27 | tainted | +| polynomial-redos.js:58:21:58:27 | tainted | polynomial-redos.js:59:23:59:29 | tainted | +| polynomial-redos.js:58:21:58:27 | tainted | polynomial-redos.js:59:23:59:29 | tainted | +| polynomial-redos.js:59:23:59:29 | tainted | polynomial-redos.js:60:17:60:23 | tainted | +| polynomial-redos.js:60:17:60:23 | tainted | polynomial-redos.js:61:18:61:24 | tainted | +| polynomial-redos.js:61:18:61:24 | tainted | polynomial-redos.js:62:17:62:23 | tainted | +| polynomial-redos.js:61:18:61:24 | tainted | polynomial-redos.js:62:17:62:23 | tainted | +| polynomial-redos.js:62:17:62:23 | tainted | polynomial-redos.js:63:21:63:27 | tainted | +| polynomial-redos.js:62:17:62:23 | tainted | polynomial-redos.js:63:21:63:27 | tainted | +| polynomial-redos.js:63:21:63:27 | tainted | polynomial-redos.js:64:24:64:30 | tainted | +| polynomial-redos.js:63:21:63:27 | tainted | polynomial-redos.js:64:24:64:30 | tainted | +| polynomial-redos.js:64:24:64:30 | tainted | polynomial-redos.js:65:24:65:30 | tainted | +| polynomial-redos.js:64:24:64:30 | tainted | polynomial-redos.js:65:24:65:30 | tainted | +| polynomial-redos.js:65:24:65:30 | tainted | polynomial-redos.js:66:19:66:25 | tainted | +| polynomial-redos.js:65:24:65:30 | tainted | polynomial-redos.js:66:19:66:25 | tainted | +| polynomial-redos.js:66:19:66:25 | tainted | polynomial-redos.js:67:18:67:24 | tainted | +| polynomial-redos.js:66:19:66:25 | tainted | polynomial-redos.js:67:18:67:24 | tainted | +| polynomial-redos.js:67:18:67:24 | tainted | polynomial-redos.js:71:2:71:8 | tainted | +| polynomial-redos.js:67:18:67:24 | tainted | polynomial-redos.js:71:2:71:8 | tainted | +| polynomial-redos.js:71:2:71:8 | tainted | polynomial-redos.js:73:2:73:8 | tainted | +| polynomial-redos.js:71:2:71:8 | tainted | polynomial-redos.js:73:2:73:8 | tainted | +| polynomial-redos.js:73:2:73:8 | tainted | polynomial-redos.js:75:2:75:8 | tainted | +| polynomial-redos.js:73:2:73:8 | tainted | polynomial-redos.js:75:2:75:8 | tainted | +| polynomial-redos.js:75:2:75:8 | tainted | polynomial-redos.js:77:2:77:8 | tainted | +| polynomial-redos.js:75:2:75:8 | tainted | polynomial-redos.js:77:2:77:8 | tainted | +| polynomial-redos.js:77:2:77:8 | tainted | polynomial-redos.js:80:2:80:8 | tainted | +| polynomial-redos.js:77:2:77:8 | tainted | polynomial-redos.js:80:2:80:8 | tainted | +| polynomial-redos.js:80:2:80:8 | tainted | polynomial-redos.js:81:2:81:8 | tainted | +| polynomial-redos.js:80:2:80:8 | tainted | polynomial-redos.js:81:2:81:8 | tainted | +| polynomial-redos.js:81:2:81:8 | tainted | polynomial-redos.js:82:2:82:8 | tainted | +| polynomial-redos.js:82:2:82:8 | tainted | polynomial-redos.js:83:2:83:8 | tainted | +| polynomial-redos.js:83:2:83:8 | tainted | polynomial-redos.js:84:2:84:8 | tainted | +| polynomial-redos.js:84:2:84:8 | tainted | polynomial-redos.js:86:2:86:8 | tainted | +| polynomial-redos.js:84:2:84:8 | tainted | polynomial-redos.js:86:2:86:8 | tainted | +| polynomial-redos.js:86:2:86:8 | tainted | polynomial-redos.js:88:2:88:8 | tainted | +| polynomial-redos.js:86:2:86:8 | tainted | polynomial-redos.js:88:2:88:8 | tainted | +| polynomial-redos.js:88:2:88:8 | tainted | polynomial-redos.js:89:2:89:8 | tainted | +| polynomial-redos.js:88:2:88:8 | tainted | polynomial-redos.js:89:2:89:8 | tainted | +| polynomial-redos.js:89:2:89:8 | tainted | polynomial-redos.js:90:2:90:8 | tainted | +| polynomial-redos.js:89:2:89:8 | tainted | polynomial-redos.js:90:2:90:8 | tainted | +| polynomial-redos.js:90:2:90:8 | tainted | polynomial-redos.js:91:2:91:8 | tainted | +| polynomial-redos.js:91:2:91:8 | tainted | polynomial-redos.js:92:2:92:8 | tainted | +| polynomial-redos.js:92:2:92:8 | tainted | polynomial-redos.js:94:2:94:8 | tainted | +| polynomial-redos.js:92:2:92:8 | tainted | polynomial-redos.js:94:2:94:8 | tainted | +| polynomial-redos.js:94:2:94:8 | tainted | polynomial-redos.js:95:2:95:8 | tainted | +| polynomial-redos.js:94:2:94:8 | tainted | polynomial-redos.js:95:2:95:8 | tainted | +| polynomial-redos.js:95:2:95:8 | tainted | polynomial-redos.js:96:2:96:8 | tainted | +| polynomial-redos.js:95:2:95:8 | tainted | polynomial-redos.js:96:2:96:8 | tainted | +| polynomial-redos.js:96:2:96:8 | tainted | polynomial-redos.js:98:2:98:8 | tainted | +| polynomial-redos.js:96:2:96:8 | tainted | polynomial-redos.js:98:2:98:8 | tainted | +| polynomial-redos.js:98:2:98:8 | tainted | polynomial-redos.js:100:2:100:8 | tainted | +| polynomial-redos.js:98:2:98:8 | tainted | polynomial-redos.js:100:2:100:8 | tainted | +| polynomial-redos.js:100:2:100:8 | tainted | polynomial-redos.js:101:2:101:8 | tainted | +| polynomial-redos.js:100:2:100:8 | tainted | polynomial-redos.js:101:2:101:8 | tainted | +| polynomial-redos.js:101:2:101:8 | tainted | polynomial-redos.js:102:2:102:8 | tainted | +| polynomial-redos.js:101:2:101:8 | tainted | polynomial-redos.js:102:2:102:8 | tainted | +| polynomial-redos.js:102:2:102:8 | tainted | polynomial-redos.js:103:2:103:8 | tainted | +| polynomial-redos.js:102:2:102:8 | tainted | polynomial-redos.js:103:2:103:8 | tainted | +| polynomial-redos.js:103:2:103:8 | tainted | polynomial-redos.js:104:2:104:8 | tainted | +| polynomial-redos.js:103:2:103:8 | tainted | polynomial-redos.js:104:2:104:8 | tainted | +| polynomial-redos.js:104:2:104:8 | tainted | polynomial-redos.js:105:2:105:8 | tainted | +| polynomial-redos.js:105:2:105:8 | tainted | polynomial-redos.js:107:2:107:8 | tainted | +| polynomial-redos.js:105:2:105:8 | tainted | polynomial-redos.js:107:2:107:8 | tainted | +| polynomial-redos.js:107:2:107:8 | tainted | polynomial-redos.js:108:2:108:8 | tainted | +| polynomial-redos.js:107:2:107:8 | tainted | polynomial-redos.js:108:2:108:8 | tainted | +| polynomial-redos.js:108:2:108:8 | tainted | polynomial-redos.js:109:2:109:8 | tainted | +| polynomial-redos.js:108:2:108:8 | tainted | polynomial-redos.js:109:2:109:8 | tainted | +| polynomial-redos.js:109:2:109:8 | tainted | polynomial-redos.js:111:2:111:8 | tainted | +| polynomial-redos.js:109:2:109:8 | tainted | polynomial-redos.js:111:2:111:8 | tainted | +| polynomial-redos.js:111:2:111:8 | tainted | polynomial-redos.js:112:2:112:8 | tainted | +| polynomial-redos.js:111:2:111:8 | tainted | polynomial-redos.js:112:2:112:8 | tainted | +| polynomial-redos.js:112:2:112:8 | tainted | polynomial-redos.js:114:2:114:8 | tainted | +| polynomial-redos.js:112:2:112:8 | tainted | polynomial-redos.js:114:2:114:8 | tainted | +| polynomial-redos.js:114:2:114:8 | tainted | polynomial-redos.js:116:2:116:8 | tainted | +| polynomial-redos.js:114:2:114:8 | tainted | polynomial-redos.js:116:2:116:8 | tainted | +| polynomial-redos.js:116:2:116:8 | tainted | polynomial-redos.js:118:2:118:8 | tainted | +| polynomial-redos.js:116:2:116:8 | tainted | polynomial-redos.js:118:2:118:8 | tainted | +| polynomial-redos.js:118:2:118:8 | tainted | polynomial-redos.js:120:2:125:3 | (functi ... OK\\n\\t}) [tainted] | +| polynomial-redos.js:118:2:118:8 | tainted | polynomial-redos.js:121:18:121:24 | tainted | +| polynomial-redos.js:118:2:118:8 | tainted | polynomial-redos.js:127:2:127:8 | tainted | +| polynomial-redos.js:120:2:125:3 | (functi ... OK\\n\\t}) [tainted] | polynomial-redos.js:121:18:121:24 | tainted | | polynomial-redos.js:121:7:121:55 | replaced | polynomial-redos.js:123:13:123:20 | replaced | | polynomial-redos.js:121:18:121:24 | tainted | polynomial-redos.js:121:18:121:55 | tainted ... /g, '') | | polynomial-redos.js:121:18:121:55 | tainted ... /g, '') | polynomial-redos.js:121:7:121:55 | replaced | | polynomial-redos.js:123:3:123:20 | result | polynomial-redos.js:124:12:124:17 | result | -| polynomial-redos.js:123:3:123:20 | result | polynomial-redos.js:124:12:124:17 | result | | polynomial-redos.js:123:13:123:20 | replaced | polynomial-redos.js:123:3:123:20 | result | -| polynomial-redos.js:129:6:129:42 | modified | polynomial-redos.js:130:2:130:9 | modified | +| polynomial-redos.js:127:2:127:8 | tainted | polynomial-redos.js:129:17:129:23 | tainted | | polynomial-redos.js:129:6:129:42 | modified | polynomial-redos.js:130:2:130:9 | modified | | polynomial-redos.js:129:17:129:23 | tainted | polynomial-redos.js:129:17:129:42 | tainted ... g, "b") | +| polynomial-redos.js:129:17:129:23 | tainted | polynomial-redos.js:132:18:132:24 | tainted | | polynomial-redos.js:129:17:129:42 | tainted ... g, "b") | polynomial-redos.js:129:6:129:42 | modified | | polynomial-redos.js:132:6:132:50 | modified2 | polynomial-redos.js:133:2:133:10 | modified2 | -| polynomial-redos.js:132:6:132:50 | modified2 | polynomial-redos.js:133:2:133:10 | modified2 | | polynomial-redos.js:132:18:132:24 | tainted | polynomial-redos.js:132:18:132:50 | tainted ... g, "e") | +| polynomial-redos.js:132:18:132:24 | tainted | polynomial-redos.js:135:21:135:27 | tainted | | polynomial-redos.js:132:18:132:50 | tainted ... g, "e") | polynomial-redos.js:132:6:132:50 | modified2 | | polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:136:5:136:13 | modified3 | -| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:136:5:136:13 | modified3 | | polynomial-redos.js:135:21:135:27 | tainted | polynomial-redos.js:135:21:135:47 | tainted ... /g, "") | +| polynomial-redos.js:135:21:135:27 | tainted | polynomial-redos.js:138:5:138:11 | tainted | | polynomial-redos.js:135:21:135:47 | tainted ... /g, "") | polynomial-redos.js:135:9:135:47 | modified3 | +nodes +| lib/closure.js:3:21:3:21 | x | semmle.label | x | +| lib/closure.js:4:16:4:16 | x | semmle.label | x | +| lib/indirect.js:1:32:1:32 | x | semmle.label | x | +| lib/indirect.js:2:16:2:16 | x | semmle.label | x | +| lib/lib.js:3:28:3:31 | name | semmle.label | name | +| lib/lib.js:4:14:4:17 | name | semmle.label | name | +| lib/lib.js:7:19:7:22 | name | semmle.label | name | +| lib/lib.js:8:13:8:16 | name | semmle.label | name | +| lib/lib.js:32:32:32:40 | arguments | semmle.label | arguments | +| lib/lib.js:35:1:37:1 | 'arguments' object of function usedWithArguments | semmle.label | 'arguments' object of function usedWithArguments | +| lib/lib.js:35:28:35:31 | name | semmle.label | name | +| lib/lib.js:36:13:36:16 | name | semmle.label | name | +| lib/lib.js:41:32:41:35 | name | semmle.label | name | +| lib/lib.js:42:17:42:20 | name | semmle.label | name | +| lib/lib.js:44:5:44:25 | name | semmle.label | name | +| lib/lib.js:44:12:44:15 | name | semmle.label | name | +| lib/lib.js:44:12:44:25 | name.substr(1) | semmle.label | name.substr(1) | +| lib/lib.js:45:17:45:20 | name | semmle.label | name | +| lib/lib.js:52:22:52:25 | name | semmle.label | name | +| lib/lib.js:53:16:53:19 | name | semmle.label | name | +| lib/moduleLib/moduleLib.js:1:28:1:31 | name | semmle.label | name | +| lib/moduleLib/moduleLib.js:2:13:2:16 | name | semmle.label | name | +| lib/otherLib/js/src/index.js:1:28:1:31 | name | semmle.label | name | +| lib/otherLib/js/src/index.js:2:13:2:16 | name | semmle.label | name | +| lib/snapdragon.js:3:34:3:38 | input | semmle.label | input | +| lib/snapdragon.js:7:15:7:18 | this | semmle.label | this | +| lib/snapdragon.js:9:12:9:16 | input | semmle.label | input | +| lib/snapdragon.js:12:34:12:38 | input | semmle.label | input | +| lib/snapdragon.js:15:13:15:16 | this | semmle.label | this | +| lib/snapdragon.js:17:20:17:24 | input | semmle.label | input | +| lib/snapdragon.js:20:34:20:38 | input | semmle.label | input | +| lib/snapdragon.js:22:44:22:47 | node | semmle.label | node | +| lib/snapdragon.js:23:5:23:8 | node | semmle.label | node | +| lib/snapdragon.js:23:5:23:12 | node.val | semmle.label | node.val | +| lib/snapdragon.js:25:22:25:26 | input | semmle.label | input | +| lib/subLib4/factory.js:7:27:7:30 | name | semmle.label | name | +| lib/subLib4/factory.js:8:13:8:16 | name | semmle.label | name | +| lib/subLib5/feature.js:1:28:1:31 | name | semmle.label | name | +| lib/subLib5/feature.js:2:13:2:16 | name | semmle.label | name | +| lib/subLib5/main.js:1:28:1:31 | name | semmle.label | name | +| lib/subLib5/main.js:2:13:2:16 | name | semmle.label | name | +| lib/subLib5/subclass.js:4:10:4:13 | name | semmle.label | name | +| lib/subLib5/subclass.js:5:16:5:19 | name | semmle.label | name | +| lib/subLib6/index.js:1:32:1:35 | name | semmle.label | name | +| lib/subLib6/index.js:2:14:2:17 | name | semmle.label | name | +| lib/sublib/factory.js:12:26:12:29 | name | semmle.label | name | +| lib/sublib/factory.js:13:24:13:27 | name | semmle.label | name | +| polynomial-redos.js:5:6:5:32 | tainted | semmle.label | tainted | +| polynomial-redos.js:5:16:5:32 | req.query.tainted | semmle.label | req.query.tainted | +| polynomial-redos.js:7:2:7:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:7:2:7:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:8:2:8:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:8:2:8:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:9:2:9:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:9:2:9:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:10:2:10:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:11:2:11:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:11:2:11:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:12:2:12:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:12:2:12:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:13:2:13:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:14:2:14:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:15:2:15:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:15:2:15:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:16:2:16:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:16:2:16:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:17:23:17:29 | tainted | semmle.label | tainted | +| polynomial-redos.js:17:23:17:29 | tainted | semmle.label | tainted | +| polynomial-redos.js:18:2:18:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:18:2:18:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:19:2:19:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:19:2:19:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:20:2:20:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:20:2:20:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:21:6:21:12 | tainted | semmle.label | tainted | +| polynomial-redos.js:25:2:25:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:25:2:25:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:26:2:26:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:27:77:27:83 | tainted | semmle.label | tainted | +| polynomial-redos.js:28:76:28:82 | tainted | semmle.label | tainted | +| polynomial-redos.js:30:2:30:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:30:2:30:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:31:2:31:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:32:2:32:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:33:2:33:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:33:2:33:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:34:2:34:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:36:2:36:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:36:2:36:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:37:2:37:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:37:2:37:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:38:2:38:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:38:2:38:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:40:2:40:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:40:2:40:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:41:2:41:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:43:2:43:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:43:2:43:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:44:2:44:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:46:2:46:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:47:2:47:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:48:2:48:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:48:2:48:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:50:14:50:20 | tainted | semmle.label | tainted | +| polynomial-redos.js:50:14:50:20 | tainted | semmle.label | tainted | +| polynomial-redos.js:51:26:51:32 | tainted | semmle.label | tainted | +| polynomial-redos.js:51:26:51:32 | tainted | semmle.label | tainted | +| polynomial-redos.js:52:22:52:28 | tainted | semmle.label | tainted | +| polynomial-redos.js:52:22:52:28 | tainted | semmle.label | tainted | +| polynomial-redos.js:53:21:53:27 | tainted | semmle.label | tainted | +| polynomial-redos.js:53:21:53:27 | tainted | semmle.label | tainted | +| polynomial-redos.js:54:22:54:28 | tainted | semmle.label | tainted | +| polynomial-redos.js:54:22:54:28 | tainted | semmle.label | tainted | +| polynomial-redos.js:55:23:55:29 | tainted | semmle.label | tainted | +| polynomial-redos.js:55:23:55:29 | tainted | semmle.label | tainted | +| polynomial-redos.js:56:22:56:28 | tainted | semmle.label | tainted | +| polynomial-redos.js:56:22:56:28 | tainted | semmle.label | tainted | +| polynomial-redos.js:57:25:57:31 | tainted | semmle.label | tainted | +| polynomial-redos.js:57:25:57:31 | tainted | semmle.label | tainted | +| polynomial-redos.js:58:21:58:27 | tainted | semmle.label | tainted | +| polynomial-redos.js:58:21:58:27 | tainted | semmle.label | tainted | +| polynomial-redos.js:59:23:59:29 | tainted | semmle.label | tainted | +| polynomial-redos.js:59:23:59:29 | tainted | semmle.label | tainted | +| polynomial-redos.js:60:17:60:23 | tainted | semmle.label | tainted | +| polynomial-redos.js:61:18:61:24 | tainted | semmle.label | tainted | +| polynomial-redos.js:62:17:62:23 | tainted | semmle.label | tainted | +| polynomial-redos.js:62:17:62:23 | tainted | semmle.label | tainted | +| polynomial-redos.js:63:21:63:27 | tainted | semmle.label | tainted | +| polynomial-redos.js:63:21:63:27 | tainted | semmle.label | tainted | +| polynomial-redos.js:64:24:64:30 | tainted | semmle.label | tainted | +| polynomial-redos.js:64:24:64:30 | tainted | semmle.label | tainted | +| polynomial-redos.js:65:24:65:30 | tainted | semmle.label | tainted | +| polynomial-redos.js:65:24:65:30 | tainted | semmle.label | tainted | +| polynomial-redos.js:66:19:66:25 | tainted | semmle.label | tainted | +| polynomial-redos.js:66:19:66:25 | tainted | semmle.label | tainted | +| polynomial-redos.js:67:18:67:24 | tainted | semmle.label | tainted | +| polynomial-redos.js:67:18:67:24 | tainted | semmle.label | tainted | +| polynomial-redos.js:68:18:68:24 | req.url | semmle.label | req.url | +| polynomial-redos.js:69:18:69:25 | req.body | semmle.label | req.body | +| polynomial-redos.js:71:2:71:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:71:2:71:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:73:2:73:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:73:2:73:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:75:2:75:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:75:2:75:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:77:2:77:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:77:2:77:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:80:2:80:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:80:2:80:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:81:2:81:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:81:2:81:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:82:2:82:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:83:2:83:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:84:2:84:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:86:2:86:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:86:2:86:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:88:2:88:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:88:2:88:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:89:2:89:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:89:2:89:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:90:2:90:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:90:2:90:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:91:2:91:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:92:2:92:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:94:2:94:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:94:2:94:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:95:2:95:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:95:2:95:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:96:2:96:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:96:2:96:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:98:2:98:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:98:2:98:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:100:2:100:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:100:2:100:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:101:2:101:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:101:2:101:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:102:2:102:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:102:2:102:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:103:2:103:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:103:2:103:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:104:2:104:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:104:2:104:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:105:2:105:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:107:2:107:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:107:2:107:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:108:2:108:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:108:2:108:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:109:2:109:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:109:2:109:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:111:2:111:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:111:2:111:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:112:2:112:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:112:2:112:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:114:2:114:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:114:2:114:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:116:2:116:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:116:2:116:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:118:2:118:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:118:2:118:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:120:2:125:3 | (functi ... OK\\n\\t}) [tainted] | semmle.label | (functi ... OK\\n\\t}) [tainted] | +| polynomial-redos.js:121:7:121:55 | replaced | semmle.label | replaced | +| polynomial-redos.js:121:18:121:24 | tainted | semmle.label | tainted | +| polynomial-redos.js:121:18:121:55 | tainted ... /g, '') | semmle.label | tainted ... /g, '') | +| polynomial-redos.js:123:3:123:20 | result | semmle.label | result | +| polynomial-redos.js:123:13:123:20 | replaced | semmle.label | replaced | +| polynomial-redos.js:124:12:124:17 | result | semmle.label | result | +| polynomial-redos.js:127:2:127:8 | tainted | semmle.label | tainted | +| polynomial-redos.js:129:6:129:42 | modified | semmle.label | modified | +| polynomial-redos.js:129:17:129:23 | tainted | semmle.label | tainted | +| polynomial-redos.js:129:17:129:42 | tainted ... g, "b") | semmle.label | tainted ... g, "b") | +| polynomial-redos.js:130:2:130:9 | modified | semmle.label | modified | +| polynomial-redos.js:132:6:132:50 | modified2 | semmle.label | modified2 | +| polynomial-redos.js:132:18:132:24 | tainted | semmle.label | tainted | +| polynomial-redos.js:132:18:132:50 | tainted ... g, "e") | semmle.label | tainted ... g, "e") | +| polynomial-redos.js:133:2:133:10 | modified2 | semmle.label | modified2 | +| polynomial-redos.js:135:9:135:47 | modified3 | semmle.label | modified3 | +| polynomial-redos.js:135:21:135:27 | tainted | semmle.label | tainted | +| polynomial-redos.js:135:21:135:47 | tainted ... /g, "") | semmle.label | tainted ... /g, "") | +| polynomial-redos.js:136:5:136:13 | modified3 | semmle.label | modified3 | +| polynomial-redos.js:138:5:138:11 | tainted | semmle.label | tainted | +subpaths #select | lib/closure.js:4:5:4:17 | /u*o/.test(x) | lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x | This $@ that depends on $@ may run slow on strings with many repetitions of 'u'. | lib/closure.js:4:6:4:7 | u* | regular expression | lib/closure.js:3:21:3:21 | x | library input | | lib/indirect.js:2:5:2:17 | /k*h/.test(x) | lib/indirect.js:1:32:1:32 | x | lib/indirect.js:2:16:2:16 | x | This $@ that depends on $@ may run slow on strings with many repetitions of 'k'. | lib/indirect.js:2:6:2:7 | k* | regular expression | lib/indirect.js:1:32:1:32 | x | library input | From 43be45207dea8322b8e1ab91a6bc1b16313afc22 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:28:27 +0200 Subject: [PATCH 106/514] JS: Port meta queries --- javascript/ql/src/meta/alerts/TaintedNodes.ql | 14 +++++++------- .../SanitizersReachableFromSource.ql | 12 ++++++------ .../SinksReachableFromSanitizer.ql | 12 ++++++------ .../ql/src/meta/analysis-quality/TaintedNodes.ql | 12 ++++++------ 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/javascript/ql/src/meta/alerts/TaintedNodes.ql b/javascript/ql/src/meta/alerts/TaintedNodes.ql index 6bdd0a6bc30..da9f7bab6f4 100644 --- a/javascript/ql/src/meta/alerts/TaintedNodes.ql +++ b/javascript/ql/src/meta/alerts/TaintedNodes.ql @@ -12,20 +12,20 @@ import javascript import meta.internal.TaintMetrics -class BasicTaintConfiguration extends TaintTracking::Configuration { - BasicTaintConfiguration() { this = "BasicTaintConfiguration" } +module BasicTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node = relevantTaintSource() } - override predicate isSource(DataFlow::Node node) { node = relevantTaintSource() } - - override predicate isSink(DataFlow::Node node) { + predicate isSink(DataFlow::Node node) { // To reduce noise from synthetic nodes, only count value nodes node instanceof DataFlow::ValueNode and not node.getFile() instanceof IgnoredFile } } +module BasicTaintFlow = TaintTracking::Global; + // Avoid linking to the source as this would upset the statistics: nodes reachable -// from multiple sources would be counted multilpe times, and that's not what we intend to measure. +// from multiple sources would be counted multiple times, and that's not what we intend to measure. from DataFlow::Node node -where any(BasicTaintConfiguration cfg).hasFlow(_, node) +where BasicTaintFlow::flowTo(node) select node, "Tainted node" diff --git a/javascript/ql/src/meta/analysis-quality/SanitizersReachableFromSource.ql b/javascript/ql/src/meta/analysis-quality/SanitizersReachableFromSource.ql index a477c8af8a9..f99d3b9a391 100644 --- a/javascript/ql/src/meta/analysis-quality/SanitizersReachableFromSource.ql +++ b/javascript/ql/src/meta/analysis-quality/SanitizersReachableFromSource.ql @@ -11,12 +11,12 @@ import javascript import meta.internal.TaintMetrics -class BasicTaintConfiguration extends TaintTracking::Configuration { - BasicTaintConfiguration() { this = "BasicTaintConfiguration" } +module BasicTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node = relevantTaintSource() } - override predicate isSource(DataFlow::Node node) { node = relevantTaintSource() } - - override predicate isSink(DataFlow::Node node) { node = relevantSanitizerInput() } + predicate isSink(DataFlow::Node node) { node = relevantSanitizerInput() } } -select projectRoot(), count(DataFlow::Node node | any(BasicTaintConfiguration cfg).hasFlow(_, node)) +module BasicTaintFlow = TaintTracking::Global; + +select projectRoot(), count(DataFlow::Node node | BasicTaintFlow::flowTo(node)) diff --git a/javascript/ql/src/meta/analysis-quality/SinksReachableFromSanitizer.ql b/javascript/ql/src/meta/analysis-quality/SinksReachableFromSanitizer.ql index e57d562aebb..7786fce5ece 100644 --- a/javascript/ql/src/meta/analysis-quality/SinksReachableFromSanitizer.ql +++ b/javascript/ql/src/meta/analysis-quality/SinksReachableFromSanitizer.ql @@ -11,12 +11,12 @@ import javascript import meta.internal.TaintMetrics -class BasicTaintConfiguration extends TaintTracking::Configuration { - BasicTaintConfiguration() { this = "BasicTaintConfiguration" } +module BasicTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node = relevantSanitizerOutput() } - override predicate isSource(DataFlow::Node node) { node = relevantSanitizerOutput() } - - override predicate isSink(DataFlow::Node node) { node = relevantTaintSink() } + predicate isSink(DataFlow::Node node) { node = relevantTaintSink() } } -select projectRoot(), count(DataFlow::Node node | any(BasicTaintConfiguration cfg).hasFlow(_, node)) +module BasicTaintFlow = TaintTracking::Global; + +select projectRoot(), count(DataFlow::Node node | BasicTaintFlow::flowTo(node)) diff --git a/javascript/ql/src/meta/analysis-quality/TaintedNodes.ql b/javascript/ql/src/meta/analysis-quality/TaintedNodes.ql index 208a39b9ab1..7b2dfbbf642 100644 --- a/javascript/ql/src/meta/analysis-quality/TaintedNodes.ql +++ b/javascript/ql/src/meta/analysis-quality/TaintedNodes.ql @@ -12,16 +12,16 @@ import javascript import meta.internal.TaintMetrics -class BasicTaintConfiguration extends TaintTracking::Configuration { - BasicTaintConfiguration() { this = "BasicTaintConfiguration" } +module BasicTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node = relevantTaintSource() } - override predicate isSource(DataFlow::Node node) { node = relevantTaintSource() } - - override predicate isSink(DataFlow::Node node) { + predicate isSink(DataFlow::Node node) { // To reduce noise from synthetic nodes, only count value nodes node instanceof DataFlow::ValueNode and not node.getFile() instanceof IgnoredFile } } -select projectRoot(), count(DataFlow::Node node | any(BasicTaintConfiguration cfg).hasFlow(_, node)) +module BasicTaintFlow = TaintTracking::Global; + +select projectRoot(), count(DataFlow::Node node | BasicTaintFlow::flowTo(node)) From d35959a09820341ac5ba51475a982200623c1b8e Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:29:42 +0200 Subject: [PATCH 107/514] JS: Add utility for comparing results in tests --- .../test/testUtilities/LegacyDataFlowDiff.qll | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 javascript/ql/test/testUtilities/LegacyDataFlowDiff.qll diff --git a/javascript/ql/test/testUtilities/LegacyDataFlowDiff.qll b/javascript/ql/test/testUtilities/LegacyDataFlowDiff.qll new file mode 100644 index 00000000000..00fd8217c21 --- /dev/null +++ b/javascript/ql/test/testUtilities/LegacyDataFlowDiff.qll @@ -0,0 +1,17 @@ +private import javascript + +private signature class LegacyConfigSig extends DataFlow::Configuration; + +module DataFlowDiff { + query predicate legacyDataFlowDifference( + DataFlow::Node source, DataFlow::Node sink, string message + ) { + NewFlow::flow(source, sink) and + not any(LegacyConfig cfg).hasFlow(source, sink) and + message = "only flow with NEW data flow library" + or + not NewFlow::flow(source, sink) and + any(LegacyConfig cfg).hasFlow(source, sink) and + message = "only flow with OLD data flow library" + } +} From ff086377cb4620e8506e1adc2979ad3b97b56dbc Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 14:48:34 +0200 Subject: [PATCH 108/514] JS: Port Arrays test --- .../library-tests/Arrays/DataFlow.expected | 2 ++ .../ql/test/library-tests/Arrays/DataFlow.ql | 24 ++++++++++++------- .../library-tests/Arrays/TaintFlow.expected | 2 ++ .../ql/test/library-tests/Arrays/TaintFlow.ql | 24 ++++++++++++------- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/javascript/ql/test/library-tests/Arrays/DataFlow.expected b/javascript/ql/test/library-tests/Arrays/DataFlow.expected index 2f5179075cf..042acffde4b 100644 --- a/javascript/ql/test/library-tests/Arrays/DataFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/DataFlow.expected @@ -1,3 +1,5 @@ +legacyDataFlowDifference +flow | arrays.js:2:16:2:23 | "source" | arrays.js:5:8:5:14 | obj.foo | | arrays.js:2:16:2:23 | "source" | arrays.js:11:10:11:15 | arr[i] | | arrays.js:2:16:2:23 | "source" | arrays.js:15:27:15:27 | e | diff --git a/javascript/ql/test/library-tests/Arrays/DataFlow.ql b/javascript/ql/test/library-tests/Arrays/DataFlow.ql index 80c9f068a10..dab899b56b0 100644 --- a/javascript/ql/test/library-tests/Arrays/DataFlow.ql +++ b/javascript/ql/test/library-tests/Arrays/DataFlow.ql @@ -1,15 +1,23 @@ import javascript -class ArrayFlowConfig extends DataFlow::Configuration { - ArrayFlowConfig() { this = "ArrayFlowConfig" } +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr().getStringValue() = "source" } - override predicate isSource(DataFlow::Node source) { source.asExpr().getStringValue() = "source" } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink = any(DataFlow::CallNode call | call.getCalleeName() = "sink").getAnArgument() } } -from ArrayFlowConfig config, DataFlow::Node src, DataFlow::Node snk -where config.hasFlow(src, snk) -select src, snk +module TestFlow = DataFlow::Global; + +class LegacyConfig extends DataFlow::Configuration { + LegacyConfig() { this = "LegacyConfig" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } +} + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff + +query predicate flow = TestFlow::flow/2; diff --git a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected index 20dbaa46ae2..b3628576a39 100644 --- a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected @@ -1,3 +1,5 @@ +legacyDataFlowDifference +flow | arrays.js:2:16:2:23 | "source" | arrays.js:5:8:5:14 | obj.foo | | arrays.js:2:16:2:23 | "source" | arrays.js:11:10:11:15 | arr[i] | | arrays.js:2:16:2:23 | "source" | arrays.js:15:27:15:27 | e | diff --git a/javascript/ql/test/library-tests/Arrays/TaintFlow.ql b/javascript/ql/test/library-tests/Arrays/TaintFlow.ql index cee2f294a34..8e0763c8a39 100644 --- a/javascript/ql/test/library-tests/Arrays/TaintFlow.ql +++ b/javascript/ql/test/library-tests/Arrays/TaintFlow.ql @@ -1,15 +1,23 @@ import javascript -class ArrayTaintFlowConfig extends TaintTracking::Configuration { - ArrayTaintFlowConfig() { this = "ArrayTaintFlowConfig" } +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr().getStringValue() = "source" } - override predicate isSource(DataFlow::Node source) { source.asExpr().getStringValue() = "source" } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink = any(DataFlow::CallNode call | call.getCalleeName() = "sink").getAnArgument() } } -from ArrayTaintFlowConfig config, DataFlow::Node src, DataFlow::Node snk -where config.hasFlow(src, snk) -select src, snk +module TestFlow = TaintTracking::Global; + +class LegacyConfig extends TaintTracking::Configuration { + LegacyConfig() { this = "LegacyConfig" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } +} + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff + +query predicate flow = TestFlow::flow/2; From 9a15a557b4eba6e309693ec0602302ccf0d8ad8d Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 14:48:52 +0200 Subject: [PATCH 109/514] JS: Port SimpleBarrierGuard test --- .../Barriers/SimpleBarrierGuard.expected | 8 +++-- .../Barriers/SimpleBarrierGuard.ql | 36 +++++++++++++------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/javascript/ql/test/library-tests/Barriers/SimpleBarrierGuard.expected b/javascript/ql/test/library-tests/Barriers/SimpleBarrierGuard.expected index 437c60684f8..ef95465e01a 100644 --- a/javascript/ql/test/library-tests/Barriers/SimpleBarrierGuard.expected +++ b/javascript/ql/test/library-tests/Barriers/SimpleBarrierGuard.expected @@ -1,3 +1,5 @@ -| tst.js:4:10:4:10 | x | tst.js:2:13:2:20 | SOURCE() | -| tst.js:9:14:9:14 | x | tst.js:2:13:2:20 | SOURCE() | -| tst.js:12:10:12:10 | x | tst.js:2:13:2:20 | SOURCE() | +legacyDataFlowDifference +flow +| tst.js:2:13:2:20 | SOURCE() | tst.js:4:10:4:10 | x | +| tst.js:2:13:2:20 | SOURCE() | tst.js:9:14:9:14 | x | +| tst.js:2:13:2:20 | SOURCE() | tst.js:12:10:12:10 | x | diff --git a/javascript/ql/test/library-tests/Barriers/SimpleBarrierGuard.ql b/javascript/ql/test/library-tests/Barriers/SimpleBarrierGuard.ql index 595d7797d36..a548e99a1ff 100644 --- a/javascript/ql/test/library-tests/Barriers/SimpleBarrierGuard.ql +++ b/javascript/ql/test/library-tests/Barriers/SimpleBarrierGuard.ql @@ -1,33 +1,47 @@ import javascript -class Configuration extends DataFlow::Configuration { - Configuration() { this = "SimpleBarrierGuard" } - - override predicate isSource(DataFlow::Node source) { +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.(DataFlow::InvokeNode).getCalleeName() = "SOURCE" } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(DataFlow::InvokeNode call | call.getCalleeName() = "SINK" and sink = call.getArgument(0) ) } - override predicate isBarrierGuard(DataFlow::BarrierGuardNode guard) { - guard instanceof SimpleBarrierGuardNode + predicate isBarrier(DataFlow::Node node) { + node = DataFlow::MakeBarrierGuard::getABarrierNode() } } +module TestFlow = DataFlow::Global; + class SimpleBarrierGuardNode extends DataFlow::BarrierGuardNode, DataFlow::InvokeNode { SimpleBarrierGuardNode() { this.getCalleeName() = "BARRIER" } - override predicate blocks(boolean outcome, Expr e) { + override predicate blocks(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = this.getArgument(0).asExpr() } } -from Configuration cfg, DataFlow::Node source, DataFlow::Node sink -where cfg.hasFlow(source, sink) -select sink, source +class LegacyConfig extends DataFlow::Configuration { + LegacyConfig() { this = "LegacyConfig" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } + + override predicate isBarrierGuard(DataFlow::BarrierGuardNode guard) { + guard instanceof SimpleBarrierGuardNode + } +} + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff + +query predicate flow = TestFlow::flow/2; From 1a95961bac5327a74def2c59c23072bce81a1e3a Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 14:49:04 +0200 Subject: [PATCH 110/514] JS: Port Classes test --- .../test/library-tests/Classes/tests.expected | 7 +++--- .../ql/test/library-tests/Classes/tests.ql | 22 +++++++++++++------ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/javascript/ql/test/library-tests/Classes/tests.expected b/javascript/ql/test/library-tests/Classes/tests.expected index 1d4cce399de..aadd449349c 100644 --- a/javascript/ql/test/library-tests/Classes/tests.expected +++ b/javascript/ql/test/library-tests/Classes/tests.expected @@ -1,3 +1,4 @@ +legacyDataFlowDifference test_FieldInits | dataflow.js:5:3:5:17 | #priv = source; | dataflow.js:5:11:5:16 | source | | fields.js:3:3:3:8 | y = 42 | fields.js:3:7:3:8 | 42 | @@ -287,9 +288,6 @@ getAccessModifier | tst.js:12:3:12:8 | m() {} | tst.js:12:3:12:3 | m | Public | | tst.js:13:3:13:10 | [m]() {} | tst.js:13:4:13:4 | m | Public | | tst.js:17:3:17:20 | m() { return 42; } | tst.js:17:3:17:3 | m | Public | -dataflow -| dataflow.js:2:15:2:22 | "source" | dataflow.js:14:7:14:25 | new Foo().getPriv() | -| dataflow.js:2:15:2:22 | "source" | dataflow.js:16:7:16:33 | new Foo ... ivate() | staticInitializer | staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | staticInitializer.js:6:10:8:3 | {\\n M ... 3;\\n } | | staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | staticInitializer.js:15:10:17:3 | {\\n t ... 6;\\n } | @@ -312,3 +310,6 @@ privateIdentifier | privateFields.js:37:12:37:17 | #brand | | privateFields.js:37:29:37:35 | #method | | privateFields.js:37:47:37:53 | #getter | +dataflow +| dataflow.js:2:15:2:22 | "source" | dataflow.js:14:7:14:25 | new Foo().getPriv() | +| dataflow.js:2:15:2:22 | "source" | dataflow.js:16:7:16:33 | new Foo ... ivate() | diff --git a/javascript/ql/test/library-tests/Classes/tests.ql b/javascript/ql/test/library-tests/Classes/tests.ql index cd236367152..d01f8f6f640 100644 --- a/javascript/ql/test/library-tests/Classes/tests.ql +++ b/javascript/ql/test/library-tests/Classes/tests.ql @@ -57,22 +57,30 @@ query string getAccessModifier(DataFlow::PropRef ref, Expr prop) { if ref.isPrivateField() then result = "Private" else result = "Public" } -class Configuration extends DataFlow::Configuration { - Configuration() { this = "ClassDataFlowTestingConfig" } - - override predicate isSource(DataFlow::Node source) { +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.getEnclosingExpr().(StringLiteral).getValue().toLowerCase() = "source" } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { any(DataFlow::CallNode call | call.getCalleeName() = "sink").getAnArgument() = sink } } -query predicate dataflow(DataFlow::Node pred, DataFlow::Node succ) { - any(Configuration c).hasFlow(pred, succ) +module TestFlow = DataFlow::Global; + +class LegacyConfig extends DataFlow::Configuration { + LegacyConfig() { this = "LegacyConfig" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } +import testUtilities.LegacyDataFlowDiff::DataFlowDiff + +query predicate dataflow = TestFlow::flow/2; + query BlockStmt staticInitializer(ClassDefinition cd) { result = cd.getAStaticInitializerBlock() } query Identifier privateIdentifier() { result.getName().matches("#%") } From c652470e2f9fcd01f33787f175a3c8bb22efb331 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 14:49:18 +0200 Subject: [PATCH 111/514] JS: Do not port CustomLoadStoreStep test --- javascript/ql/test/library-tests/CustomLoadStoreSteps/test.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/javascript/ql/test/library-tests/CustomLoadStoreSteps/test.ql b/javascript/ql/test/library-tests/CustomLoadStoreSteps/test.ql index 2c56d41ab4d..c6721b52217 100644 --- a/javascript/ql/test/library-tests/CustomLoadStoreSteps/test.ql +++ b/javascript/ql/test/library-tests/CustomLoadStoreSteps/test.ql @@ -1,5 +1,6 @@ import javascript +// Note: this test has not been ported to ConfigSig, because isAdditionalLoadStep has no equivalent there class Configuration extends TaintTracking::Configuration { Configuration() { this = "PromiseFlowTestingConfig" } From af05789cbf7c9a09cc688f67639bf010c5c81c85 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 9 Oct 2023 10:36:17 +0200 Subject: [PATCH 112/514] JS: Remove noise from data flow test --- .../library-tests/DataFlow/tests.expected | 21 ++++++++++++++++++- .../ql/test/library-tests/DataFlow/tests.ql | 5 ++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/javascript/ql/test/library-tests/DataFlow/tests.expected b/javascript/ql/test/library-tests/DataFlow/tests.expected index 02bfbe09e2d..c0e1edf1d3f 100644 --- a/javascript/ql/test/library-tests/DataFlow/tests.expected +++ b/javascript/ql/test/library-tests/DataFlow/tests.expected @@ -16,12 +16,14 @@ basicBlock | arguments.js:1:1:12:4 | exceptional return of (functi ... );\\n})() | arguments.js:1:1:1:0 | entry node of | | arguments.js:1:2:1:1 | this | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} | | arguments.js:1:2:12:1 | 'arguments' object of anonymous function | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} | +| arguments.js:1:2:12:1 | [function self-reference] functio ... , 3);\\n} | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} | | arguments.js:1:2:12:1 | exceptional return of anonymous function | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} | | arguments.js:1:2:12:1 | functio ... , 3);\\n} | arguments.js:1:1:1:0 | entry node of | | arguments.js:1:2:12:1 | return of anonymous function | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} | | arguments.js:2:5:2:4 | this | arguments.js:2:5:2:4 | entry node of functio ... ;\\n } | | arguments.js:2:5:2:5 | arguments | arguments.js:2:5:2:4 | entry node of functio ... ;\\n } | | arguments.js:2:5:10:5 | 'arguments' object of function f | arguments.js:2:5:2:4 | entry node of functio ... ;\\n } | +| arguments.js:2:5:10:5 | [function self-reference] functio ... ;\\n } | arguments.js:2:5:2:4 | entry node of functio ... ;\\n } | | arguments.js:2:5:10:5 | exceptional return of function f | arguments.js:2:5:2:4 | entry node of functio ... ;\\n } | | arguments.js:2:5:10:5 | functio ... ;\\n } | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} | | arguments.js:2:5:10:5 | return of function f | arguments.js:2:5:2:4 | entry node of functio ... ;\\n } | @@ -69,6 +71,7 @@ basicBlock | eval.js:1:1:1:0 | this | eval.js:1:1:1:0 | entry node of | | eval.js:1:1:1:0 | this | eval.js:1:1:1:0 | entry node of functio ... eval`\\n} | | eval.js:1:1:5:1 | 'arguments' object of function k | eval.js:1:1:1:0 | entry node of functio ... eval`\\n} | +| eval.js:1:1:5:1 | [function self-reference] functio ... eval`\\n} | eval.js:1:1:1:0 | entry node of functio ... eval`\\n} | | eval.js:1:1:5:1 | exceptional return of function k | eval.js:1:1:1:0 | entry node of functio ... eval`\\n} | | eval.js:1:1:5:1 | functio ... eval`\\n} | eval.js:1:1:1:0 | entry node of | | eval.js:1:1:5:1 | return of function k | eval.js:1:1:1:0 | entry node of functio ... eval`\\n} | @@ -89,6 +92,7 @@ basicBlock | sources.js:1:6:1:6 | x | sources.js:1:6:1:5 | entry node of x => x | | sources.js:1:6:1:6 | x | sources.js:1:6:1:5 | entry node of x => x | | sources.js:1:6:1:11 | 'arguments' object of anonymous function | sources.js:1:6:1:5 | entry node of x => x | +| sources.js:1:6:1:11 | [function self-reference] x => x | sources.js:1:6:1:5 | entry node of x => x | | sources.js:1:6:1:11 | exceptional return of anonymous function | sources.js:1:6:1:5 | entry node of x => x | | sources.js:1:6:1:11 | return of anonymous function | sources.js:1:6:1:5 | entry node of x => x | | sources.js:1:6:1:11 | x => x | sources.js:1:1:1:0 | entry node of | @@ -98,6 +102,7 @@ basicBlock | sources.js:3:1:5:6 | exceptional return of (functi ... \\n})(23) | sources.js:1:1:1:0 | entry node of | | sources.js:3:2:3:1 | this | sources.js:3:2:3:1 | entry node of functio ... x+19;\\n} | | sources.js:3:2:5:1 | 'arguments' object of anonymous function | sources.js:3:2:3:1 | entry node of functio ... x+19;\\n} | +| sources.js:3:2:5:1 | [function self-reference] functio ... x+19;\\n} | sources.js:3:2:3:1 | entry node of functio ... x+19;\\n} | | sources.js:3:2:5:1 | exceptional return of anonymous function | sources.js:3:2:3:1 | entry node of functio ... x+19;\\n} | | sources.js:3:2:5:1 | functio ... x+19;\\n} | sources.js:1:1:1:0 | entry node of | | sources.js:3:2:5:1 | return of anonymous function | sources.js:3:2:3:1 | entry node of functio ... x+19;\\n} | @@ -110,6 +115,7 @@ basicBlock | sources.js:7:1:7:3 | /x/ | sources.js:1:1:1:0 | entry node of | | sources.js:9:1:9:0 | this | sources.js:9:1:9:0 | entry node of functio ... ey; }\\n} | | sources.js:9:1:12:1 | 'arguments' object of function foo | sources.js:9:1:9:0 | entry node of functio ... ey; }\\n} | +| sources.js:9:1:12:1 | [function self-reference] functio ... ey; }\\n} | sources.js:9:1:9:0 | entry node of functio ... ey; }\\n} | | sources.js:9:1:12:1 | exceptional return of function foo | sources.js:12:2:12:1 | exit node of functio ... ey; }\\n} | | sources.js:9:1:12:1 | functio ... ey; }\\n} | sources.js:1:1:1:0 | entry node of | | sources.js:9:1:12:1 | return of function foo | sources.js:12:2:12:1 | exit node of functio ... ey; }\\n} | @@ -147,6 +153,7 @@ basicBlock | tst2.ts:7:1:7:0 | A | tst2.ts:7:1:7:0 | entry node of functio ... = 23;\\n} | | tst2.ts:7:1:7:0 | this | tst2.ts:7:1:7:0 | entry node of functio ... = 23;\\n} | | tst2.ts:7:1:9:1 | 'arguments' object of function setX | tst2.ts:7:1:7:0 | entry node of functio ... = 23;\\n} | +| tst2.ts:7:1:9:1 | [function self-reference] functio ... = 23;\\n} | tst2.ts:7:1:7:0 | entry node of functio ... = 23;\\n} | | tst2.ts:7:1:9:1 | exceptional return of function setX | tst2.ts:7:1:7:0 | entry node of functio ... = 23;\\n} | | tst2.ts:7:1:9:1 | functio ... = 23;\\n} | tst2.ts:1:1:1:0 | entry node of | | tst2.ts:7:1:9:1 | return of function setX | tst2.ts:7:1:7:0 | entry node of functio ... = 23;\\n} | @@ -170,6 +177,7 @@ basicBlock | tst2.ts:13:39:13:38 | 'arguments' object of default constructor of class StringList | tst2.ts:13:39:13:38 | entry node of (...arg ... rgs); } | | tst2.ts:13:39:13:38 | (...arg ... rgs); } | tst2.ts:1:1:1:0 | entry node of | | tst2.ts:13:39:13:38 | ...args | tst2.ts:13:39:13:38 | entry node of (...arg ... rgs); } | +| tst2.ts:13:39:13:38 | [function self-reference] (...arg ... rgs); } | tst2.ts:13:39:13:38 | entry node of (...arg ... rgs); } | | tst2.ts:13:39:13:38 | args | tst2.ts:13:39:13:38 | entry node of (...arg ... rgs); } | | tst2.ts:13:39:13:38 | args | tst2.ts:13:39:13:38 | entry node of (...arg ... rgs); } | | tst2.ts:13:39:13:38 | args | tst2.ts:13:39:13:38 | entry node of (...arg ... rgs); } | @@ -236,6 +244,7 @@ basicBlock | tst.js:16:1:20:9 | exceptional return of (functi ... ("arg") | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:16:2:16:1 | this | tst.js:16:2:16:1 | entry node of functio ... n "";\\n} | | tst.js:16:2:20:1 | 'arguments' object of function f | tst.js:16:2:16:1 | entry node of functio ... n "";\\n} | +| tst.js:16:2:20:1 | [function self-reference] functio ... n "";\\n} | tst.js:16:2:16:1 | entry node of functio ... n "";\\n} | | tst.js:16:2:20:1 | exceptional return of function f | tst.js:20:2:20:1 | exit node of functio ... n "";\\n} | | tst.js:16:2:20:1 | functio ... n "";\\n} | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:16:2:20:1 | return of function f | tst.js:20:2:20:1 | exit node of functio ... n "";\\n} | @@ -271,12 +280,14 @@ basicBlock | tst.js:28:2:28:1 | x | tst.js:28:2:28:1 | entry node of () =>\\n x | | tst.js:28:2:29:3 | 'arguments' object of anonymous function | tst.js:28:2:28:1 | entry node of () =>\\n x | | tst.js:28:2:29:3 | () =>\\n x | tst.js:16:1:20:10 | (functi ... "arg"); | +| tst.js:28:2:29:3 | [function self-reference] () =>\\n x | tst.js:28:2:28:1 | entry node of () =>\\n x | | tst.js:28:2:29:3 | exceptional return of anonymous function | tst.js:28:2:28:1 | entry node of () =>\\n x | | tst.js:28:2:29:3 | return of anonymous function | tst.js:28:2:28:1 | entry node of () =>\\n x | | tst.js:29:3:29:3 | x | tst.js:28:2:28:1 | entry node of () =>\\n x | | tst.js:32:1:32:0 | this | tst.js:32:1:32:0 | entry node of functio ... ables\\n} | | tst.js:32:1:32:0 | x | tst.js:32:1:32:0 | entry node of functio ... ables\\n} | | tst.js:32:1:34:1 | 'arguments' object of function g | tst.js:32:1:32:0 | entry node of functio ... ables\\n} | +| tst.js:32:1:34:1 | [function self-reference] functio ... ables\\n} | tst.js:32:1:32:0 | entry node of functio ... ables\\n} | | tst.js:32:1:34:1 | exceptional return of function g | tst.js:32:1:32:0 | entry node of functio ... ables\\n} | | tst.js:32:1:34:1 | functio ... ables\\n} | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:32:1:34:1 | return of function g | tst.js:32:1:32:0 | entry node of functio ... ables\\n} | @@ -302,6 +313,7 @@ basicBlock | tst.js:39:4:39:3 | this | tst.js:39:4:39:3 | entry node of () {\\n this;\\n } | | tst.js:39:4:41:3 | 'arguments' object of method m | tst.js:39:4:39:3 | entry node of () {\\n this;\\n } | | tst.js:39:4:41:3 | () {\\n this;\\n } | tst.js:16:1:20:10 | (functi ... "arg"); | +| tst.js:39:4:41:3 | [function self-reference] () {\\n this;\\n } | tst.js:39:4:39:3 | entry node of () {\\n this;\\n } | | tst.js:39:4:41:3 | exceptional return of method m | tst.js:39:4:39:3 | entry node of () {\\n this;\\n } | | tst.js:39:4:41:3 | return of method m | tst.js:39:4:39:3 | entry node of () {\\n this;\\n } | | tst.js:40:5:40:8 | this | tst.js:39:4:39:3 | entry node of () {\\n this;\\n } | @@ -327,6 +339,7 @@ basicBlock | tst.js:50:14:50:13 | this | tst.js:50:14:50:13 | entry node of () {\\n ... et`\\n } | | tst.js:50:14:53:3 | 'arguments' object of constructor of class A | tst.js:50:14:50:13 | entry node of () {\\n ... et`\\n } | | tst.js:50:14:53:3 | () {\\n ... et`\\n } | tst.js:16:1:20:10 | (functi ... "arg"); | +| tst.js:50:14:53:3 | [function self-reference] () {\\n ... et`\\n } | tst.js:50:14:50:13 | entry node of () {\\n ... et`\\n } | | tst.js:50:14:53:3 | exceptional return of constructor of class A | tst.js:50:14:50:13 | entry node of () {\\n ... et`\\n } | | tst.js:50:14:53:3 | return of constructor of class A | tst.js:50:14:50:13 | entry node of () {\\n ... et`\\n } | | tst.js:51:5:51:9 | super | tst.js:50:14:50:13 | entry node of () {\\n ... et`\\n } | @@ -353,6 +366,7 @@ basicBlock | tst.js:62:4:62:4 | g | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:64:1:64:0 | this | tst.js:64:1:64:0 | entry node of functio ... lysed\\n} | | tst.js:64:1:67:1 | 'arguments' object of function h | tst.js:64:1:64:0 | entry node of functio ... lysed\\n} | +| tst.js:64:1:67:1 | [function self-reference] functio ... lysed\\n} | tst.js:64:1:64:0 | entry node of functio ... lysed\\n} | | tst.js:64:1:67:1 | exceptional return of function h | tst.js:64:1:64:0 | entry node of functio ... lysed\\n} | | tst.js:64:1:67:1 | functio ... lysed\\n} | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:64:1:67:1 | return of function h | tst.js:64:1:64:0 | entry node of functio ... lysed\\n} | @@ -377,6 +391,7 @@ basicBlock | tst.js:69:11:69:12 | 23 | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:71:1:71:0 | this | tst.js:71:1:71:0 | entry node of async f ... lysed\\n} | | tst.js:71:1:73:1 | 'arguments' object of function k | tst.js:71:1:71:0 | entry node of async f ... lysed\\n} | +| tst.js:71:1:73:1 | [function self-reference] async f ... lysed\\n} | tst.js:71:1:71:0 | entry node of async f ... lysed\\n} | | tst.js:71:1:73:1 | async f ... lysed\\n} | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:71:1:73:1 | exceptional return of function k | tst.js:71:1:71:0 | entry node of async f ... lysed\\n} | | tst.js:71:1:73:1 | return of function k | tst.js:71:1:71:0 | entry node of async f ... lysed\\n} | @@ -420,6 +435,7 @@ basicBlock | tst.js:87:1:96:2 | exceptional return of (functi ... r: 0\\n}) | tst.js:85:5:85:28 | vs2 = ( ... o) v ) | | tst.js:87:2:87:1 | this | tst.js:87:2:87:1 | entry node of functio ... + z;\\n} | | tst.js:87:2:92:1 | 'arguments' object of anonymous function | tst.js:87:2:87:1 | entry node of functio ... + z;\\n} | +| tst.js:87:2:92:1 | [function self-reference] functio ... + z;\\n} | tst.js:87:2:87:1 | entry node of functio ... + z;\\n} | | tst.js:87:2:92:1 | exceptional return of anonymous function | tst.js:87:2:87:1 | entry node of functio ... + z;\\n} | | tst.js:87:2:92:1 | functio ... + z;\\n} | tst.js:85:5:85:28 | vs2 = ( ... o) v ) | | tst.js:87:2:92:1 | return of anonymous function | tst.js:87:2:87:1 | entry node of functio ... + z;\\n} | @@ -474,6 +490,7 @@ basicBlock | tst.js:98:1:103:17 | exceptional return of (functi ... 3, 0 ]) | tst.js:85:5:85:28 | vs2 = ( ... o) v ) | | tst.js:98:2:98:1 | this | tst.js:98:2:98:1 | entry node of functio ... + z;\\n} | | tst.js:98:2:103:1 | 'arguments' object of anonymous function | tst.js:98:2:98:1 | entry node of functio ... + z;\\n} | +| tst.js:98:2:103:1 | [function self-reference] functio ... + z;\\n} | tst.js:98:2:98:1 | entry node of functio ... + z;\\n} | | tst.js:98:2:103:1 | exceptional return of anonymous function | tst.js:98:2:98:1 | entry node of functio ... + z;\\n} | | tst.js:98:2:103:1 | functio ... + z;\\n} | tst.js:85:5:85:28 | vs2 = ( ... o) v ) | | tst.js:98:2:103:1 | return of anonymous function | tst.js:98:2:98:1 | entry node of functio ... + z;\\n} | @@ -516,6 +533,7 @@ basicBlock | tst.js:107:1:113:2 | (functi ... v2c;\\n}) | tst.js:107:1:113:3 | (functi ... 2c;\\n}); | | tst.js:107:2:107:1 | this | tst.js:107:2:107:1 | entry node of functio ... v2c;\\n} | | tst.js:107:2:113:1 | 'arguments' object of anonymous function | tst.js:107:2:107:1 | entry node of functio ... v2c;\\n} | +| tst.js:107:2:113:1 | [function self-reference] functio ... v2c;\\n} | tst.js:107:2:107:1 | entry node of functio ... v2c;\\n} | | tst.js:107:2:113:1 | exceptional return of anonymous function | tst.js:107:2:107:1 | entry node of functio ... v2c;\\n} | | tst.js:107:2:113:1 | functio ... v2c;\\n} | tst.js:107:1:113:3 | (functi ... 2c;\\n}); | | tst.js:107:2:113:1 | return of anonymous function | tst.js:107:2:107:1 | entry node of functio ... v2c;\\n} | @@ -998,6 +1016,7 @@ flowStep | tst2.ts:13:26:13:29 | List | tst2.ts:13:26:13:37 | List | | tst2.ts:13:39:13:38 | args | tst2.ts:13:39:13:38 | args | | tst2.ts:13:39:13:38 | args | tst2.ts:13:39:13:38 | args | +| tst2.ts:13:39:13:38 | this | tst2.ts:13:39:13:38 | implicit 'this' argument of super(...args) | | tst2.ts:15:11:15:13 | A.x | tst2.ts:15:11:15:30 | A.x satisfies number | | tst.js:1:1:1:1 | x | tst.js:3:5:3:5 | x | | tst.js:1:10:1:11 | fs | tst.js:1:10:1:11 | fs | @@ -1079,6 +1098,7 @@ flowStep | tst.js:46:10:46:11 | "" | tst.js:46:1:46:11 | global = "" | | tst.js:49:1:54:1 | A | tst.js:55:1:55:1 | A | | tst.js:49:1:54:1 | class A ... `\\n }\\n} | tst.js:49:1:54:1 | A | +| tst.js:50:14:50:13 | this | tst.js:51:5:51:13 | implicit 'this' argument of super(42) | | tst.js:64:1:67:1 | functio ... lysed\\n} | tst.js:64:11:64:11 | h | | tst.js:64:11:64:11 | h | tst.js:68:12:68:12 | h | | tst.js:68:5:68:14 | iter | tst.js:69:1:69:4 | iter | @@ -1443,7 +1463,6 @@ incomplete | tst.js:117:10:117:24 | exceptional return of Object.seal(x1) | call | | tst.js:117:22:117:23 | x1 | global | noBasicBlock -| file://:0:0:0:0 | global access path | | tst.js:1:10:1:11 | fs | | tst.js:1:10:1:11 | fs | | tst.js:1:20:1:23 | 'fs' | diff --git a/javascript/ql/test/library-tests/DataFlow/tests.ql b/javascript/ql/test/library-tests/DataFlow/tests.ql index 14a3635b534..8fd5fd694a1 100644 --- a/javascript/ql/test/library-tests/DataFlow/tests.ql +++ b/javascript/ql/test/library-tests/DataFlow/tests.ql @@ -23,7 +23,10 @@ query predicate incomplete(DataFlow::Node dfn, DataFlow::Incompleteness cause) { dfn.isIncomplete(cause) } -query predicate noBasicBlock(DataFlow::Node node) { not exists(node.getBasicBlock()) } +query predicate noBasicBlock(DataFlow::Node node) { + (node instanceof DataFlow::ValueNode or node instanceof DataFlow::SsaDefinitionNode) and + not exists(node.getBasicBlock()) +} query predicate parameters(DataFlow::ParameterNode param) { any() } From 92812eee78b35d5fe085b039819d9d9083caabed Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 14:54:41 +0200 Subject: [PATCH 113/514] JS: Add test for flow summaries --- .../FlowSummary/CaptureConsistency.expected | 17 ++ .../FlowSummary/CaptureConsistency.ql | 1 + .../FlowSummary/DataFlowConsistency.expected | 230 +++++++++++++++ .../FlowSummary/DataFlowConsistency.ql | 2 + .../library-tests/FlowSummary/Summaries.qll | 37 +++ .../library-tests/FlowSummary/test.expected | 0 .../ql/test/library-tests/FlowSummary/test.ql | 36 +++ .../ql/test/library-tests/FlowSummary/tst.js | 270 ++++++++++++++++++ 8 files changed, 593 insertions(+) create mode 100644 javascript/ql/test/library-tests/FlowSummary/CaptureConsistency.expected create mode 100644 javascript/ql/test/library-tests/FlowSummary/CaptureConsistency.ql create mode 100644 javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected create mode 100644 javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.ql create mode 100644 javascript/ql/test/library-tests/FlowSummary/Summaries.qll create mode 100644 javascript/ql/test/library-tests/FlowSummary/test.expected create mode 100644 javascript/ql/test/library-tests/FlowSummary/test.ql create mode 100644 javascript/ql/test/library-tests/FlowSummary/tst.js diff --git a/javascript/ql/test/library-tests/FlowSummary/CaptureConsistency.expected b/javascript/ql/test/library-tests/FlowSummary/CaptureConsistency.expected new file mode 100644 index 00000000000..35f4edcf1fb --- /dev/null +++ b/javascript/ql/test/library-tests/FlowSummary/CaptureConsistency.expected @@ -0,0 +1,17 @@ +uniqueToString +uniqueEnclosingCallable +uniqueDominator +localDominator +localSuccessor +uniqueDefiningScope +variableIsCaptured +uniqueLocation +uniqueCfgNode +uniqueWriteTarget +uniqueWriteCfgNode +uniqueReadVariable +closureMustHaveBody +closureAliasMustBeInSameScope +variableAccessAstNesting +uniqueCallableLocation +consistencyOverview diff --git a/javascript/ql/test/library-tests/FlowSummary/CaptureConsistency.ql b/javascript/ql/test/library-tests/FlowSummary/CaptureConsistency.ql new file mode 100644 index 00000000000..1134eee1f2b --- /dev/null +++ b/javascript/ql/test/library-tests/FlowSummary/CaptureConsistency.ql @@ -0,0 +1 @@ +import semmle.javascript.dataflow.internal.VariableCapture::VariableCaptureOutput::ConsistencyChecks diff --git a/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected b/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected new file mode 100644 index 00000000000..79c66aa0381 --- /dev/null +++ b/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected @@ -0,0 +1,230 @@ +uniqueEnclosingCallable +uniqueCallEnclosingCallable +uniqueType +uniqueNodeLocation +missingLocation +uniqueNodeToString +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | +parameterCallable +localFlowIsLocal +readStepIsLocal +storeStepIsLocal +compatibleTypesReflexive +unreachableNodeCCtx +localCallNodes +postIsNotPre +postHasUniquePre +uniquePostUpdate +postIsInSameCallable +reverseRead +| tst.js:109:11:113:3 | 'arguments' object of anonymous function | Origin of readStep is missing a PostUpdateNode. | +| tst.js:267:28:267:31 | map3 | Origin of readStep is missing a PostUpdateNode. | +argHasPostUpdate +| tst.js:219:18:219:27 | [source()] | ArgumentNode is missing PostUpdateNode. | +postWithInFlow +| file://:0:0:0:0 | [summary] to write: Argument[1] in Array method with flow into callback | PostUpdateNode should not be the target of local flow. | +| file://:0:0:0:0 | [summary] to write: Argument[1] in Array#filter | PostUpdateNode should not be the target of local flow. | +| file://:0:0:0:0 | [summary] to write: Argument[1] in Array#find / Array#findLast | PostUpdateNode should not be the target of local flow. | +| file://:0:0:0:0 | [summary] to write: Argument[1] in Array#flatMap | PostUpdateNode should not be the target of local flow. | +| file://:0:0:0:0 | [summary] to write: Argument[1] in Array#forEach / Map#forEach / Set#forEach | PostUpdateNode should not be the target of local flow. | +| file://:0:0:0:0 | [summary] to write: Argument[1] in Array#map | PostUpdateNode should not be the target of local flow. | +| file://:0:0:0:0 | [summary] to write: Argument[1] in Array#reduce / Array#reduceRight | PostUpdateNode should not be the target of local flow. | +| file://:0:0:0:0 | [summary] to write: Argument[2] in 'array.prototype.find' / 'array-find' | PostUpdateNode should not be the target of local flow. | +| file://:0:0:0:0 | [summary] to write: Argument[2] in Array.from(arg, callback, [thisArg]) | PostUpdateNode should not be the target of local flow. | +| file://:0:0:0:0 | [summary] to write: Argument[this] in Array#flatMap | PostUpdateNode should not be the target of local flow. | +| file://:0:0:0:0 | [summary] to write: Argument[this] in Array#forEach / Map#forEach / Set#forEach | PostUpdateNode should not be the target of local flow. | +| file://:0:0:0:0 | [summary] to write: Argument[this] in Array#map | PostUpdateNode should not be the target of local flow. | +| file://:0:0:0:0 | [summary] to write: Argument[this] in Array#reduce / Array#reduceRight | PostUpdateNode should not be the target of local flow. | +| tst.js:97:24:97:74 | new Pro ... rce())) | PostUpdateNode should not be the target of local flow. | +| tst.js:100:3:100:53 | new Pro ... rce())) | PostUpdateNode should not be the target of local flow. | +| tst.js:101:3:101:53 | new Pro ... rce())) | PostUpdateNode should not be the target of local flow. | +| tst.js:102:3:102:52 | new Pro ... rce())) | PostUpdateNode should not be the target of local flow. | +| tst.js:103:3:103:52 | new Pro ... rce())) | PostUpdateNode should not be the target of local flow. | +| tst.js:250:15:250:23 | new Map() | PostUpdateNode should not be the target of local flow. | +| tst.js:258:16:258:24 | new Map() | PostUpdateNode should not be the target of local flow. | +| tst.js:264:16:264:24 | new Map() | PostUpdateNode should not be the target of local flow. | +viableImplInCallContextTooLarge +uniqueParameterNodeAtPosition +uniqueParameterNodePosition +uniqueContentApprox +identityLocalStep +missingArgumentCall +multipleArgumentCall +| tst.js:30:8:30:37 | flowInt ... urce()) | tst.js:30:8:30:41 | flowInt ... ()).pop (as accessor call) | Multiple calls for argument node. | +| tst.js:30:8:30:37 | flowInt ... urce()) | tst.js:30:8:30:43 | flowInt ... ).pop() | Multiple calls for argument node. | +| tst.js:32:39:32:42 | Math | tst.js:32:39:32:49 | Math.random (as accessor call) | Multiple calls for argument node. | +| tst.js:32:39:32:42 | Math | tst.js:32:39:32:51 | Math.random() | Multiple calls for argument node. | +| tst.js:54:25:54:31 | Promise | tst.js:54:25:54:39 | Promise.resolve (as accessor call) | Multiple calls for argument node. | +| tst.js:54:25:54:31 | Promise | tst.js:54:25:54:49 | Promise ... urce()) | Multiple calls for argument node. | +| tst.js:55:25:55:31 | Promise | tst.js:55:25:55:39 | Promise.resolve (as accessor call) | Multiple calls for argument node. | +| tst.js:55:25:55:31 | Promise | tst.js:55:25:55:47 | Promise ... "safe") | Multiple calls for argument node. | +| tst.js:55:25:55:47 | Promise ... "safe") | tst.js:55:25:55:52 | Promise ... ").then (as accessor call) | Multiple calls for argument node. | +| tst.js:55:25:55:47 | Promise ... "safe") | tst.js:55:25:55:67 | Promise ... urce()) | Multiple calls for argument node. | +| tst.js:56:25:56:31 | Promise | tst.js:56:25:56:39 | Promise.resolve (as accessor call) | Multiple calls for argument node. | +| tst.js:56:25:56:31 | Promise | tst.js:56:25:56:47 | Promise ... "safe") | Multiple calls for argument node. | +| tst.js:56:25:56:47 | Promise ... "safe") | tst.js:56:25:56:52 | Promise ... ").then (as accessor call) | Multiple calls for argument node. | +| tst.js:56:25:56:47 | Promise ... "safe") | tst.js:56:25:56:65 | Promise ... "safe") | Multiple calls for argument node. | +| tst.js:57:25:57:31 | Promise | tst.js:57:25:57:39 | Promise.resolve (as accessor call) | Multiple calls for argument node. | +| tst.js:57:25:57:31 | Promise | tst.js:57:25:57:49 | Promise ... urce()) | Multiple calls for argument node. | +| tst.js:57:25:57:49 | Promise ... urce()) | tst.js:57:25:57:54 | Promise ... )).then (as accessor call) | Multiple calls for argument node. | +| tst.js:57:25:57:49 | Promise ... urce()) | tst.js:57:25:57:67 | Promise ... "safe") | Multiple calls for argument node. | +| tst.js:59:25:59:31 | Promise | tst.js:59:25:59:38 | Promise.reject (as accessor call) | Multiple calls for argument node. | +| tst.js:59:25:59:31 | Promise | tst.js:59:25:59:48 | Promise ... urce()) | Multiple calls for argument node. | +| tst.js:60:25:60:31 | Promise | tst.js:60:25:60:38 | Promise.reject (as accessor call) | Multiple calls for argument node. | +| tst.js:60:25:60:31 | Promise | tst.js:60:25:60:48 | Promise ... urce()) | Multiple calls for argument node. | +| tst.js:60:25:60:48 | Promise ... urce()) | tst.js:60:25:60:53 | Promise ... )).then (as accessor call) | Multiple calls for argument node. | +| tst.js:60:25:60:48 | Promise ... urce()) | tst.js:60:25:60:74 | Promise ... y => y) | Multiple calls for argument node. | +| tst.js:61:25:61:31 | Promise | tst.js:61:25:61:38 | Promise.reject (as accessor call) | Multiple calls for argument node. | +| tst.js:61:25:61:31 | Promise | tst.js:61:25:61:48 | Promise ... urce()) | Multiple calls for argument node. | +| tst.js:61:25:61:48 | Promise ... urce()) | tst.js:61:25:61:53 | Promise ... )).then (as accessor call) | Multiple calls for argument node. | +| tst.js:61:25:61:48 | Promise ... urce()) | tst.js:61:25:61:74 | Promise ... "safe") | Multiple calls for argument node. | +| tst.js:62:25:62:31 | Promise | tst.js:62:25:62:38 | Promise.reject (as accessor call) | Multiple calls for argument node. | +| tst.js:62:25:62:31 | Promise | tst.js:62:25:62:46 | Promise ... "safe") | Multiple calls for argument node. | +| tst.js:62:25:62:46 | Promise ... "safe") | tst.js:62:25:62:51 | Promise ... ").then (as accessor call) | Multiple calls for argument node. | +| tst.js:62:25:62:46 | Promise ... "safe") | tst.js:62:25:62:67 | Promise ... y => y) | Multiple calls for argument node. | +| tst.js:64:25:64:31 | Promise | tst.js:64:25:64:38 | Promise.reject (as accessor call) | Multiple calls for argument node. | +| tst.js:64:25:64:31 | Promise | tst.js:64:25:64:48 | Promise ... urce()) | Multiple calls for argument node. | +| tst.js:65:25:65:31 | Promise | tst.js:65:25:65:38 | Promise.reject (as accessor call) | Multiple calls for argument node. | +| tst.js:65:25:65:31 | Promise | tst.js:65:25:65:48 | Promise ... urce()) | Multiple calls for argument node. | +| tst.js:65:25:65:48 | Promise ... urce()) | tst.js:65:25:65:54 | Promise ... ).catch (as accessor call) | Multiple calls for argument node. | +| tst.js:65:25:65:48 | Promise ... urce()) | tst.js:65:25:65:66 | Promise ... => err) | Multiple calls for argument node. | +| tst.js:66:25:66:31 | Promise | tst.js:66:25:66:38 | Promise.reject (as accessor call) | Multiple calls for argument node. | +| tst.js:66:25:66:31 | Promise | tst.js:66:25:66:48 | Promise ... urce()) | Multiple calls for argument node. | +| tst.js:66:25:66:48 | Promise ... urce()) | tst.js:66:25:66:54 | Promise ... ).catch (as accessor call) | Multiple calls for argument node. | +| tst.js:66:25:66:48 | Promise ... urce()) | tst.js:66:25:66:69 | Promise ... "safe") | Multiple calls for argument node. | +| tst.js:67:25:67:31 | Promise | tst.js:67:25:67:38 | Promise.reject (as accessor call) | Multiple calls for argument node. | +| tst.js:67:25:67:31 | Promise | tst.js:67:25:67:46 | Promise ... "safe") | Multiple calls for argument node. | +| tst.js:67:25:67:46 | Promise ... "safe") | tst.js:67:25:67:52 | Promise ... ).catch (as accessor call) | Multiple calls for argument node. | +| tst.js:67:25:67:46 | Promise ... "safe") | tst.js:67:25:67:64 | Promise ... => err) | Multiple calls for argument node. | +| tst.js:69:25:69:31 | Promise | tst.js:69:25:69:38 | Promise.reject (as accessor call) | Multiple calls for argument node. | +| tst.js:69:25:69:31 | Promise | tst.js:69:25:69:48 | Promise ... urce()) | Multiple calls for argument node. | +| tst.js:69:25:69:48 | Promise ... urce()) | tst.js:69:25:69:53 | Promise ... )).then (as accessor call) | Multiple calls for argument node. | +| tst.js:69:25:69:48 | Promise ... urce()) | tst.js:69:25:69:66 | Promise ... "safe") | Multiple calls for argument node. | +| tst.js:69:25:69:66 | Promise ... "safe") | tst.js:69:25:69:72 | Promise ... ).catch (as accessor call) | Multiple calls for argument node. | +| tst.js:69:25:69:66 | Promise ... "safe") | tst.js:69:25:69:84 | Promise ... => err) | Multiple calls for argument node. | +| tst.js:71:25:71:31 | Promise | tst.js:71:25:71:38 | Promise.reject (as accessor call) | Multiple calls for argument node. | +| tst.js:71:25:71:31 | Promise | tst.js:71:25:71:48 | Promise ... urce()) | Multiple calls for argument node. | +| tst.js:71:25:71:48 | Promise ... urce()) | tst.js:71:25:71:56 | Promise ... finally (as accessor call) | Multiple calls for argument node. | +| tst.js:71:25:71:48 | Promise ... urce()) | tst.js:71:25:71:70 | Promise ... "safe") | Multiple calls for argument node. | +| tst.js:71:25:71:70 | Promise ... "safe") | tst.js:71:25:71:76 | Promise ... ).catch (as accessor call) | Multiple calls for argument node. | +| tst.js:71:25:71:70 | Promise ... "safe") | tst.js:71:25:71:88 | Promise ... => err) | Multiple calls for argument node. | +| tst.js:72:25:72:31 | Promise | tst.js:72:25:72:39 | Promise.resolve (as accessor call) | Multiple calls for argument node. | +| tst.js:72:25:72:31 | Promise | tst.js:72:25:72:49 | Promise ... urce()) | Multiple calls for argument node. | +| tst.js:72:25:72:49 | Promise ... urce()) | tst.js:72:25:72:57 | Promise ... finally (as accessor call) | Multiple calls for argument node. | +| tst.js:72:25:72:49 | Promise ... urce()) | tst.js:72:25:72:71 | Promise ... "safe") | Multiple calls for argument node. | +| tst.js:72:25:72:71 | Promise ... "safe") | tst.js:72:25:72:76 | Promise ... ").then (as accessor call) | Multiple calls for argument node. | +| tst.js:72:25:72:71 | Promise ... "safe") | tst.js:72:25:72:88 | Promise ... => err) | Multiple calls for argument node. | +| tst.js:73:25:73:31 | Promise | tst.js:73:25:73:38 | Promise.reject (as accessor call) | Multiple calls for argument node. | +| tst.js:73:25:73:31 | Promise | tst.js:73:25:73:46 | Promise ... "safe") | Multiple calls for argument node. | +| tst.js:73:25:73:46 | Promise ... "safe") | tst.js:73:25:73:54 | Promise ... finally (as accessor call) | Multiple calls for argument node. | +| tst.js:73:25:73:46 | Promise ... "safe") | tst.js:73:25:73:80 | Promise ... ce() }) | Multiple calls for argument node. | +| tst.js:73:25:73:80 | Promise ... ce() }) | tst.js:73:25:73:86 | Promise ... ).catch (as accessor call) | Multiple calls for argument node. | +| tst.js:73:25:73:80 | Promise ... ce() }) | tst.js:73:25:73:98 | Promise ... => err) | Multiple calls for argument node. | +| tst.js:75:3:75:9 | Promise | tst.js:75:3:75:17 | Promise.resolve (as accessor call) | Multiple calls for argument node. | +| tst.js:75:3:75:9 | Promise | tst.js:75:3:75:25 | Promise ... "safe") | Multiple calls for argument node. | +| tst.js:75:3:75:25 | Promise ... "safe") | tst.js:75:3:76:9 | Promise ... .then (as accessor call) | Multiple calls for argument node. | +| tst.js:75:3:75:25 | Promise ... "safe") | tst.js:75:3:76:35 | Promise ... e(); }) | Multiple calls for argument node. | +| tst.js:75:3:76:35 | Promise ... e(); }) | tst.js:75:3:77:10 | Promise ... .catch (as accessor call) | Multiple calls for argument node. | +| tst.js:75:3:76:35 | Promise ... e(); }) | tst.js:75:3:79:6 | Promise ... \\n }) | Multiple calls for argument node. | +| tst.js:81:3:81:9 | Promise | tst.js:81:3:81:17 | Promise.resolve (as accessor call) | Multiple calls for argument node. | +| tst.js:81:3:81:9 | Promise | tst.js:81:3:81:25 | Promise ... "safe") | Multiple calls for argument node. | +| tst.js:81:3:81:25 | Promise ... "safe") | tst.js:81:3:82:9 | Promise ... .then (as accessor call) | Multiple calls for argument node. | +| tst.js:81:3:81:25 | Promise ... "safe") | tst.js:81:3:82:35 | Promise ... e(); }) | Multiple calls for argument node. | +| tst.js:81:3:82:35 | Promise ... e(); }) | tst.js:81:3:83:9 | Promise ... .then (as accessor call) | Multiple calls for argument node. | +| tst.js:81:3:82:35 | Promise ... e(); }) | tst.js:81:3:83:22 | Promise ... "safe") | Multiple calls for argument node. | +| tst.js:81:3:83:22 | Promise ... "safe") | tst.js:81:3:84:10 | Promise ... .catch (as accessor call) | Multiple calls for argument node. | +| tst.js:81:3:83:22 | Promise ... "safe") | tst.js:81:3:86:6 | Promise ... \\n }) | Multiple calls for argument node. | +| tst.js:89:3:89:27 | flowInt ... urce()) | tst.js:89:3:89:32 | flowInt ... )).then (as accessor call) | Multiple calls for argument node. | +| tst.js:89:3:89:27 | flowInt ... urce()) | tst.js:89:3:89:54 | flowInt ... value)) | Multiple calls for argument node. | +| tst.js:100:3:100:53 | new Pro ... rce())) | tst.js:100:3:100:58 | new Pro ... )).then (as accessor call) | Multiple calls for argument node. | +| tst.js:100:3:100:53 | new Pro ... rce())) | tst.js:100:3:100:72 | new Pro ... ink(x)) | Multiple calls for argument node. | +| tst.js:101:3:101:53 | new Pro ... rce())) | tst.js:101:3:101:59 | new Pro ... ).catch (as accessor call) | Multiple calls for argument node. | +| tst.js:101:3:101:53 | new Pro ... rce())) | tst.js:101:3:101:77 | new Pro ... k(err)) | Multiple calls for argument node. | +| tst.js:102:3:102:52 | new Pro ... rce())) | tst.js:102:3:102:57 | new Pro ... )).then (as accessor call) | Multiple calls for argument node. | +| tst.js:102:3:102:52 | new Pro ... rce())) | tst.js:102:3:102:71 | new Pro ... ink(x)) | Multiple calls for argument node. | +| tst.js:103:3:103:52 | new Pro ... rce())) | tst.js:103:3:103:58 | new Pro ... ).catch (as accessor call) | Multiple calls for argument node. | +| tst.js:103:3:103:52 | new Pro ... rce())) | tst.js:103:3:103:76 | new Pro ... k(err)) | Multiple calls for argument node. | +| tst.js:105:3:105:9 | Promise | tst.js:105:3:105:13 | Promise.all (as accessor call) | Multiple calls for argument node. | +| tst.js:105:3:105:9 | Promise | tst.js:105:3:109:4 | Promise ... e"\\n ]) | Multiple calls for argument node. | +| tst.js:105:3:109:4 | Promise ... e"\\n ]) | tst.js:105:3:109:9 | Promise ... ]).then (as accessor call) | Multiple calls for argument node. | +| tst.js:105:3:109:4 | Promise ... e"\\n ]) | tst.js:105:3:113:4 | Promise ... OK\\n }) | Multiple calls for argument node. | +| tst.js:170:19:170:25 | Promise | tst.js:170:19:170:33 | Promise.resolve (as accessor call) | Multiple calls for argument node. | +| tst.js:170:19:170:25 | Promise | tst.js:170:19:170:38 | Promise.resolve(obj) | Multiple calls for argument node. | +| tst.js:209:3:209:7 | array | tst.js:209:3:209:12 | array.push (as accessor call) | Multiple calls for argument node. | +| tst.js:209:3:209:7 | array | tst.js:209:3:209:38 | array.p ... urce()) | Multiple calls for argument node. | +| tst.js:210:8:210:12 | array | tst.js:210:8:210:16 | array.pop (as accessor call) | Multiple calls for argument node. | +| tst.js:210:8:210:12 | array | tst.js:210:8:210:18 | array.pop() | Multiple calls for argument node. | +| tst.js:213:3:213:8 | array2 | tst.js:213:3:213:13 | array2.push (as accessor call) | Multiple calls for argument node. | +| tst.js:213:3:213:8 | array2 | tst.js:213:3:213:23 | array2. ... urce()) | Multiple calls for argument node. | +| tst.js:214:3:214:8 | array2 | tst.js:214:3:214:13 | array2.push (as accessor call) | Multiple calls for argument node. | +| tst.js:214:3:214:8 | array2 | tst.js:214:3:214:21 | array2.push("safe") | Multiple calls for argument node. | +| tst.js:215:3:215:8 | array2 | tst.js:215:3:215:13 | array2.push (as accessor call) | Multiple calls for argument node. | +| tst.js:215:3:215:8 | array2 | tst.js:215:3:215:21 | array2.push("safe") | Multiple calls for argument node. | +| tst.js:216:3:216:8 | array2 | tst.js:216:3:216:16 | array2.forEach (as accessor call) | Multiple calls for argument node. | +| tst.js:216:3:216:8 | array2 | tst.js:216:3:216:30 | array2. ... ink(x)) | Multiple calls for argument node. | +| tst.js:219:3:219:8 | array3 | tst.js:219:3:219:13 | array3.push (as accessor call) | Multiple calls for argument node. | +| tst.js:219:3:219:8 | array3 | tst.js:219:3:219:28 | array3. ... rce()]) | Multiple calls for argument node. | +| tst.js:220:3:220:8 | array3 | tst.js:220:3:220:16 | array3.forEach (as accessor call) | Multiple calls for argument node. | +| tst.js:220:3:220:8 | array3 | tst.js:220:3:220:30 | array3. ... ink(x)) | Multiple calls for argument node. | +| tst.js:223:12:223:32 | Array.p ... e.slice | tst.js:223:12:223:37 | Array.p ... ce.call (as accessor call) | Multiple calls for argument node. | +| tst.js:223:12:223:32 | Array.p ... e.slice | tst.js:223:12:223:45 | Array.p ... array4) | Multiple calls for argument node. | +| tst.js:223:12:223:32 | Array.p ... e.slice | tst.js:223:12:223:45 | reflective call | Multiple calls for argument node. | +| tst.js:223:39:223:44 | array4 | tst.js:223:12:223:45 | Array.p ... array4) | Multiple calls for argument node. | +| tst.js:223:39:223:44 | array4 | tst.js:223:12:223:45 | reflective call | Multiple calls for argument node. | +| tst.js:224:8:224:13 | array4 | tst.js:224:8:224:17 | array4.pop (as accessor call) | Multiple calls for argument node. | +| tst.js:224:8:224:13 | array4 | tst.js:224:8:224:19 | array4.pop() | Multiple calls for argument node. | +| tst.js:226:3:226:12 | [source()] | tst.js:226:3:226:20 | [source()].forEach (as accessor call) | Multiple calls for argument node. | +| tst.js:226:3:226:12 | [source()] | tst.js:226:3:226:68 | [source ... p()) }) | Multiple calls for argument node. | +| tst.js:226:54:226:58 | array | tst.js:226:54:226:62 | array.pop (as accessor call) | Multiple calls for argument node. | +| tst.js:226:54:226:58 | array | tst.js:226:54:226:64 | array.pop() | Multiple calls for argument node. | +| tst.js:228:3:228:8 | array5 | tst.js:228:3:228:16 | array5.forEach (as accessor call) | Multiple calls for argument node. | +| tst.js:228:3:228:8 | array5 | tst.js:228:3:228:64 | array5. ... p()) }) | Multiple calls for argument node. | +| tst.js:228:50:228:54 | array | tst.js:228:50:228:58 | array.pop (as accessor call) | Multiple calls for argument node. | +| tst.js:228:50:228:54 | array | tst.js:228:50:228:60 | array.pop() | Multiple calls for argument node. | +| tst.js:229:3:229:10 | ["safe"] | tst.js:229:3:229:18 | ["safe"].forEach (as accessor call) | Multiple calls for argument node. | +| tst.js:229:3:229:10 | ["safe"] | tst.js:229:3:229:66 | ["safe" ... p()) }) | Multiple calls for argument node. | +| tst.js:229:52:229:56 | array | tst.js:229:52:229:60 | array.pop (as accessor call) | Multiple calls for argument node. | +| tst.js:229:52:229:56 | array | tst.js:229:52:229:62 | array.pop() | Multiple calls for argument node. | +| tst.js:251:3:251:5 | map | tst.js:251:3:251:9 | map.set (as accessor call) | Multiple calls for argument node. | +| tst.js:251:3:251:5 | map | tst.js:251:3:251:26 | map.set ... urce()) | Multiple calls for argument node. | +| tst.js:252:3:252:5 | map | tst.js:252:3:252:9 | map.set (as accessor call) | Multiple calls for argument node. | +| tst.js:252:3:252:5 | map | tst.js:252:3:252:24 | map.set ... 'safe') | Multiple calls for argument node. | +| tst.js:254:8:254:10 | map | tst.js:254:8:254:14 | map.get (as accessor call) | Multiple calls for argument node. | +| tst.js:254:8:254:10 | map | tst.js:254:8:254:21 | map.get('foo') | Multiple calls for argument node. | +| tst.js:255:8:255:10 | map | tst.js:255:8:255:14 | map.get (as accessor call) | Multiple calls for argument node. | +| tst.js:255:8:255:10 | map | tst.js:255:8:255:21 | map.get('bar') | Multiple calls for argument node. | +| tst.js:256:8:256:10 | map | tst.js:256:8:256:14 | map.get (as accessor call) | Multiple calls for argument node. | +| tst.js:256:8:256:10 | map | tst.js:256:8:256:27 | map.get(getUnkown()) | Multiple calls for argument node. | +| tst.js:259:3:259:6 | map2 | tst.js:259:3:259:10 | map2.set (as accessor call) | Multiple calls for argument node. | +| tst.js:259:3:259:6 | map2 | tst.js:259:3:259:33 | map2.se ... urce()) | Multiple calls for argument node. | +| tst.js:260:8:260:11 | map2 | tst.js:260:8:260:15 | map2.get (as accessor call) | Multiple calls for argument node. | +| tst.js:260:8:260:11 | map2 | tst.js:260:8:260:22 | map2.get('foo') | Multiple calls for argument node. | +| tst.js:261:8:261:11 | map2 | tst.js:261:8:261:15 | map2.get (as accessor call) | Multiple calls for argument node. | +| tst.js:261:8:261:11 | map2 | tst.js:261:8:261:22 | map2.get('bar') | Multiple calls for argument node. | +| tst.js:262:8:262:11 | map2 | tst.js:262:8:262:15 | map2.get (as accessor call) | Multiple calls for argument node. | +| tst.js:262:8:262:11 | map2 | tst.js:262:8:262:28 | map2.ge ... kown()) | Multiple calls for argument node. | +| tst.js:265:3:265:6 | map3 | tst.js:265:3:265:10 | map3.set (as accessor call) | Multiple calls for argument node. | +| tst.js:265:3:265:6 | map3 | tst.js:265:3:265:27 | map3.se ... urce()) | Multiple calls for argument node. | +| tst.js:266:3:266:6 | map3 | tst.js:266:3:266:14 | map3.forEach (as accessor call) | Multiple calls for argument node. | +| tst.js:266:3:266:6 | map3 | tst.js:266:3:266:36 | map3.fo ... value)) | Multiple calls for argument node. | diff --git a/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.ql b/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.ql new file mode 100644 index 00000000000..02dd5540b6f --- /dev/null +++ b/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.ql @@ -0,0 +1,2 @@ +import javascript +import semmle.javascript.dataflow.internal.DataFlowImplConsistency::Consistency diff --git a/javascript/ql/test/library-tests/FlowSummary/Summaries.qll b/javascript/ql/test/library-tests/FlowSummary/Summaries.qll new file mode 100644 index 00000000000..e6037cb814b --- /dev/null +++ b/javascript/ql/test/library-tests/FlowSummary/Summaries.qll @@ -0,0 +1,37 @@ +import javascript +import semmle.javascript.dataflow.FlowSummary + +class MkSummary extends SummarizedCallable { + private CallExpr mkSummary; + + MkSummary() { + mkSummary.getCalleeName() = "mkSummary" and + this = + "mkSummary at " + mkSummary.getFile().getRelativePath() + ":" + + mkSummary.getLocation().getStartLine() + } + + override DataFlow::InvokeNode getACall() { + result = mkSummary.flow().(DataFlow::CallNode).getAnInvocation() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + ( + // mkSummary(input, output) + input = mkSummary.getArgument(0).getStringValue() and + output = mkSummary.getArgument(1).getStringValue() + or + // mkSummary([ + // [input1, output1], + // [input2, output2], + // ... + // ]) + exists(ArrayExpr pair | + pair = mkSummary.getArgument(0).(ArrayExpr).getAnElement() and + input = pair.getElement(0).getStringValue() and + output = pair.getElement(1).getStringValue() + ) + ) + } +} diff --git a/javascript/ql/test/library-tests/FlowSummary/test.expected b/javascript/ql/test/library-tests/FlowSummary/test.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/javascript/ql/test/library-tests/FlowSummary/test.ql b/javascript/ql/test/library-tests/FlowSummary/test.ql new file mode 100644 index 00000000000..3b300bbe19b --- /dev/null +++ b/javascript/ql/test/library-tests/FlowSummary/test.ql @@ -0,0 +1,36 @@ +import javascript +import testUtilities.ConsistencyChecking +import Summaries + +DataFlow::CallNode getACall(string name) { + result.getCalleeName() = name + or + result.getCalleeNode().getALocalSource() = DataFlow::globalVarRef(name) +} + +module ConfigArg implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node = getACall("source") } + + predicate isSink(DataFlow::Node node) { node = getACall("sink").getAnArgument() } + + predicate isBarrier(DataFlow::Node node) { + node.(DataFlow::InvokeNode).getCalleeName().matches("sanitizer_%") or + node = DataFlow::MakeBarrierGuard::getABarrierNode() + } +} + +module Configuration = DataFlow::Global; + +class BasicBarrierGuard extends DataFlow::CallNode { + BasicBarrierGuard() { this = getACall("isSafe") } + + predicate blocksExpr(boolean outcome, Expr e) { + outcome = true and e = this.getArgument(0).asExpr() + } +} + +class ConsistencyConfig extends ConsistencyConfiguration { + ConsistencyConfig() { this = "ConsistencyConfig" } + + override DataFlow::Node getAnAlert() { Configuration::flow(_, result) } +} diff --git a/javascript/ql/test/library-tests/FlowSummary/tst.js b/javascript/ql/test/library-tests/FlowSummary/tst.js new file mode 100644 index 00000000000..aea6cf4f6fa --- /dev/null +++ b/javascript/ql/test/library-tests/FlowSummary/tst.js @@ -0,0 +1,270 @@ +function m1() { + const flowThrough = mkSummary("Argument[0]", "ReturnValue"); + sink(flowThrough(source())); // NOT OK + sink(flowThrough(source() + "x")); // OK - we are not tracking taint in this test + sink(flowThrough("x")); // OK +} + +function m2() { + const flowIntoProp = mkSummary("Argument[0]", "ReturnValue.Member[prop]"); + sink(flowIntoProp(source()).prop); // NOT OK + sink(flowIntoProp(source()).prop2); // OK + sink(flowIntoProp(source())); // OK +} + +function m3() { + const flowOutOfProp = mkSummary("Argument[0].Member[prop]", "ReturnValue"); + sink(flowOutOfProp({ prop: source() })); // NOT OK + sink(flowOutOfProp({ prop2: source() })); // OK + sink(flowOutOfProp(source())); // OK + + const obj = {}; + obj.prop = source(); + sink(flowOutOfProp(obj)); // NOT OK + sink(obj); // OK + sink(obj.prop); // NOT OK +} + +function m4() { + const flowIntoArrayElement = mkSummary("Argument[0]", "ReturnValue.ArrayElement"); + sink(flowIntoArrayElement(source()).pop()); // NOT OK + sink(flowIntoArrayElement(source())[0]); // NOT OK [INCONSISTENCY] + sink(flowIntoArrayElement(source())[Math.random()]); // NOT OK + sink(flowIntoArrayElement(source()).prop); // OK +} + +function m5() { + const flowOutOfInnerCallback = mkSummary("Argument[0].Parameter[0].Argument[0]", "ReturnValue"); + sink(flowOutOfInnerCallback(cb => { cb(source()); })); // NOT OK [INCONSISTENCY] +} + +async function m6() { + const flowOutOfPromise = mkSummary("Argument[0].Awaited", "ReturnValue"); + const flowIntoPromise = mkSummary("Argument[0]", "ReturnValue.Awaited"); + + sink(flowOutOfPromise(flowIntoPromise(source()))); // NOT OK (although the synchronous flow is technically not possible) + + let data = { prop: source() }; + sink(flowOutOfPromise(flowIntoPromise(data)).prop); // NOT OK + sink(flowOutOfPromise(flowIntoPromise(flowIntoPromise(data))).prop); // NOT OK + sink(flowOutOfPromise(flowOutOfPromise(flowIntoPromise(data))).prop); // NOT OK + sink(flowOutOfPromise(data).prop); // NOT OK - because Awaited allows pass-through of a non-promise value + sink(flowIntoPromise(data).prop); // OK - promise object does not have the 'prop' property + + sink(flowOutOfPromise(Promise.resolve(source()))); // NOT OK + sink(flowOutOfPromise(Promise.resolve("safe").then(x => source()))); // NOT OK + sink(flowOutOfPromise(Promise.resolve("safe").then(x => "safe"))); // OK + sink(flowOutOfPromise(Promise.resolve(source()).then(x => "safe"))); // OK + + sink(flowOutOfPromise(Promise.reject(source()))); // OK + sink(flowOutOfPromise(Promise.reject(source()).then(x => "safe", y => y))); // NOT OK + sink(flowOutOfPromise(Promise.reject(source()).then(x => x, y => "safe"))); // OK + sink(flowOutOfPromise(Promise.reject("safe").then(x => x, y => y))); // OK + + sink(flowOutOfPromise(Promise.reject(source()))); // OK + sink(flowOutOfPromise(Promise.reject(source()).catch(err => err))); // NOT OK + sink(flowOutOfPromise(Promise.reject(source()).catch(err => "safe"))); // OK + sink(flowOutOfPromise(Promise.reject("safe").catch(err => err))); // OK + + sink(flowOutOfPromise(Promise.reject(source()).then(x => "safe").catch(err => err))); // NOT OK + + sink(flowOutOfPromise(Promise.reject(source()).finally(() => "safe").catch(err => err))); // NOT OK + sink(flowOutOfPromise(Promise.resolve(source()).finally(() => "safe").then(err => err))); // NOT OK + sink(flowOutOfPromise(Promise.reject("safe").finally(() => { throw source() }).catch(err => err))); // NOT OK + + Promise.resolve("safe") + .then(x => { throw source(); }) + .catch(err => { + sink(err); // NOT OK + }); + + Promise.resolve("safe") + .then(x => { throw source(); }) + .then(x => "safe") + .catch(err => { + sink(err); // NOT OK + }); + + sink(await flowIntoPromise(source())); // NOT OK + flowIntoPromise(source()).then(value => sink(value)); // NOT OK + sink(await flowIntoPromise(flowIntoPromise(source()))); // NOT OK + + async function makePromise() { + return source(); + } + sink(flowOutOfPromise(makePromise())); // NOT OK + + let taintedPromise = new Promise((resolve, reject) => resolve(source())); + sink(flowOutOfPromise(taintedPromise)); // NOT OK + + new Promise((resolve, reject) => resolve(source())).then(x => sink(x)); // NOT OK + new Promise((resolve, reject) => resolve(source())).catch(err => sink(err)); // OK + new Promise((resolve, reject) => reject(source())).then(x => sink(x)); // OK + new Promise((resolve, reject) => reject(source())).catch(err => sink(err)); // NOT OK + + Promise.all([ + flowIntoPromise(source()), + source(), + "safe" + ]).then(([x1, x2, x3]) => { + sink(x1); // NOT OK + sink(x2); // NOT OK + sink(x3); // OK + }); +} + +function m8() { + const flowOutOfCallback = mkSummary("Argument[0].ReturnValue", "ReturnValue"); + + sink(flowOutOfCallback(() => source())); // NOT OK + sink(flowOutOfCallback((source))); // OK + + function sourceCallback() { + return source(); + } + sink(flowOutOfCallback(sourceCallback)); // NOT OK +} + +function m9() { + const flowIntoCallback = mkSummary("Argument[0]", "Argument[1].Parameter[0]"); + + sink(flowIntoCallback(source(), x => sink(x))); // NOT OK + sink(flowIntoCallback("safe", x => sink(x))); // OK + sink(flowIntoCallback(source(), x => ignore(x))); // OK + sink(flowIntoCallback("safe", x => ignore(x))); // OK +} + +function m10() { + const flowThroughCallback = mkSummary([ + ["Argument[0]", "Argument[1].Parameter[0]"], + ["Argument[1].ReturnValue", "ReturnValue"] + ]); + + sink(flowThroughCallback(source(), x => x)); // NOT OK + sink(flowThroughCallback(source(), x => "safe")); // OK + sink(flowThroughCallback("safe", x => x)); // OK + sink(flowThroughCallback("safe", x => "safe")); // OK +} + +function m11() { + const flowFromSideEffectOnParameter = mkSummary("Argument[0].Parameter[0].Member[prop]", "ReturnValue"); + + let data = flowFromSideEffectOnParameter(param => { + param.prop = source(); + }); + sink(data); // NOT OK + + function manullyWritten(param) { + param.prop = source(); + } + let obj = {}; + manullyWritten(obj); + sink(obj.prop); // NOT OK +} + +async function m13() { + async function testStoreBack(x) { + (await x).prop = source(); + } + const obj = {}; + const promise = Promise.resolve(obj); + testStoreBack(promise); + sink(obj.prop); // NOT OK [INCONSISTENCY] + sink(promise.prop); // OK [INCONSISTENCY] + sink((await promise).prop); // NOT OK + + const obj2 = {}; + testStoreBack(obj2); + sink(obj2.prop);; // NOT OK +} + +function m14() { + const flowOutOfAnyArgument = mkSummary("Argument[0..]", "ReturnValue"); + sink(flowOutOfAnyArgument(source())); // NOT OK + sink(flowOutOfAnyArgument(source(), "safe", "safe")); // NOT OK + sink(flowOutOfAnyArgument("safe", source(), "safe")); // NOT OK + sink(flowOutOfAnyArgument("safe", "safe", source())); // NOT OK + sink(flowOutOfAnyArgument("safe", "safe", "safe")); // OK + + const flowOutOfAnyArgumentExceptFirst = mkSummary("Argument[1..]", "ReturnValue"); + sink(flowOutOfAnyArgumentExceptFirst(source())); // OK + sink(flowOutOfAnyArgumentExceptFirst(source(), "safe", "safe")); // OK + sink(flowOutOfAnyArgumentExceptFirst("safe", source(), "safe")); // NOT OK + sink(flowOutOfAnyArgumentExceptFirst("safe", "safe", source())); // NOT OK + sink(flowOutOfAnyArgumentExceptFirst("safe", "safe", "safe")); // OK + + const flowIntoAnyParameter = mkSummary("Argument[0]", "Argument[1].Parameter[0..]"); + flowIntoAnyParameter(source(), (x1, x2, x3) => sink(x1)); // NOT OK + flowIntoAnyParameter(source(), (x1, x2, x3) => sink(x2)); // NOT OK + flowIntoAnyParameter(source(), (x1, x2, x3) => sink(x3)); // NOT OK + + const flowIntoAnyParameterExceptFirst = mkSummary("Argument[0]", "Argument[1].Parameter[1..]"); + flowIntoAnyParameterExceptFirst(source(), (x1, x2, x3) => sink(x1)); // OK + flowIntoAnyParameterExceptFirst(source(), (x1, x2, x3) => sink(x2)); // NOT OK + flowIntoAnyParameterExceptFirst(source(), (x1, x2, x3) => sink(x3)); // NOT OK +} + +function m15() { + const array = []; + array.push("safe", "safe", source()); + sink(array.pop()); // NOT OK + + const array2 = []; + array2.push(source()); + array2.push("safe"); + array2.push("safe"); + array2.forEach(x => sink(x)); // NOT OK + + const array3 = []; + array3.push(...[source()]); + array3.forEach(x => sink(x)); // NOT OK + + const array4 = [source()]; + array4 = Array.prototype.slice.call(array4); + sink(array4.pop()); // NOT OK + + [source()].forEach((value, index, array) => { sink(array.pop()) }); // NOT OK + const array5 = [source()]; + array5.forEach((value, index, array) => { sink(array.pop()) }); // NOT OK + ["safe"].forEach((value, index, array) => { sink(array.pop()) }); // OK +} + +function m16() { + const array0 = [source(), 'safe', 'safe']; + sink(array0[0]); // NOT OK + sink(array0[1]); // OK + sink(array0[2]); // OK + + const array1 = ['safe', source(), 'safe']; + sink(array1[0]); // OK + sink(array1[1]); // NOT OK + sink(array1[2]); // OK + + const array2 = ['safe', 'safe', source()]; + sink(array2[0]); // OK + sink(array2[1]); // OK + sink(array2[2]); // NOT OK +} + +function m17() { + const map = new Map(); + map.set('foo', source()); + map.set('bar', 'safe'); + + sink(map.get('foo')); // NOT OK + sink(map.get('bar')); // OK + sink(map.get(getUnkown())); // NOT OK + + const map2 = new Map(); + map2.set(getUnkown(), source()); + sink(map2.get('foo')); // NOT OK + sink(map2.get('bar')); // NOT OK + sink(map2.get(getUnkown())); // NOT OK + + const map3 = new Map(); + map3.set('foo', source()); + map3.forEach(value => sink(value)); // NOT OK + for (let [key, value] of map3) { + sink(value); // NOT OK + } +} From 09b0ba0c1f60ecf5e6affd602de6263fd156f514 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 15:05:59 +0200 Subject: [PATCH 114/514] JS: Port Angular2 test --- .../frameworks/Angular2/test.expected | 1 + .../library-tests/frameworks/Angular2/test.ql | 22 ++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/javascript/ql/test/library-tests/frameworks/Angular2/test.expected b/javascript/ql/test/library-tests/frameworks/Angular2/test.expected index f09f0aed3b4..acf97ab947e 100644 --- a/javascript/ql/test/library-tests/frameworks/Angular2/test.expected +++ b/javascript/ql/test/library-tests/frameworks/Angular2/test.expected @@ -1,3 +1,4 @@ +legacyDataFlowDifference pipeRef | source.component.html:3:22:3:32 | unknownPipe | | source.component.html:4:22:4:32 | unknownPipe | diff --git a/javascript/ql/test/library-tests/frameworks/Angular2/test.ql b/javascript/ql/test/library-tests/frameworks/Angular2/test.ql index 5ff99611121..ee5dc370eee 100644 --- a/javascript/ql/test/library-tests/frameworks/Angular2/test.ql +++ b/javascript/ql/test/library-tests/frameworks/Angular2/test.ql @@ -14,21 +14,31 @@ query Angular2::PipeClass pipeClass() { any() } query DataFlow::Node pipeClassRef(Angular2::PipeClass cls) { result = cls.getAPipeRef() } -class TaintConfig extends TaintTracking::Configuration { - TaintConfig() { this = "TaintConfig" } - - override predicate isSource(DataFlow::Node source) { +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.(DataFlow::CallNode).getCalleeName() = "source" } - override predicate isSink(DataFlow::Node sink) { sink instanceof DomBasedXss::Sink } + predicate isSink(DataFlow::Node sink) { sink instanceof DomBasedXss::Sink } } +module TestFlow = TaintTracking::Global; + query predicate taintFlow(DataFlow::Node source, DataFlow::Node sink) { - any(TaintConfig c).hasFlow(source, sink) + TestFlow::flow(source, sink) } query predicate testAttrSourceLocation(HTML::Attribute attrib, Angular2::TemplateTopLevel top) { attrib.getName() = "[testAttr]" and top = attrib.getCodeInAttribute() } + +class LegacyConfig extends TaintTracking::Configuration { + LegacyConfig() { this = "LegacyConfig" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } +} + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff From 466ffdf8f500577fc3ce36d71e32188462e4462a Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 15:07:25 +0200 Subject: [PATCH 115/514] JS: Port AsyncTaintTracking test --- .../AsyncPackage/AsyncTaintTracking.expected | 2 ++ .../AsyncPackage/AsyncTaintTracking.ql | 24 +++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.expected b/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.expected index 2c2b8fec2cc..50e18f938a5 100644 --- a/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.expected +++ b/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.expected @@ -1,3 +1,5 @@ +legacyDataFlowDifference +#select | each.js:11:9:11:16 | source() | each.js:13:12:13:15 | item | | map.js:10:13:10:20 | source() | map.js:12:14:12:17 | item | | map.js:20:19:20:26 | source() | map.js:23:27:23:32 | result | diff --git a/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.ql b/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.ql index 7d591e1b48b..f3afe84d75a 100644 --- a/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.ql +++ b/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.ql @@ -2,14 +2,24 @@ import javascript DataFlow::CallNode getACall(string name) { result.getCalleeName() = name } -class BasicConfig extends TaintTracking::Configuration { - BasicConfig() { this = "BasicConfig" } +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node = getACall("source") } - override predicate isSource(DataFlow::Node node) { node = getACall("source") } - - override predicate isSink(DataFlow::Node node) { node = getACall("sink").getAnArgument() } + predicate isSink(DataFlow::Node node) { node = getACall("sink").getAnArgument() } } -from BasicConfig cfg, DataFlow::Node src, DataFlow::Node sink -where cfg.hasFlow(src, sink) +module TestFlow = TaintTracking::Global; + +class LegacyConfig extends TaintTracking::Configuration { + LegacyConfig() { this = "LegacyConfig" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } +} + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff + +from DataFlow::Node src, DataFlow::Node sink +where TestFlow::flow(src, sink) select src, sink From 09892279e64141e0b909c0d892cbe3f426631397 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 15:07:42 +0200 Subject: [PATCH 116/514] JS: Port Collections test --- .../frameworks/Collections/test.expected | 33 ++++++++++--------- .../frameworks/Collections/test.ql | 22 +++++++++---- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/javascript/ql/test/library-tests/frameworks/Collections/test.expected b/javascript/ql/test/library-tests/frameworks/Collections/test.expected index 6a026e06382..de2290b874a 100644 --- a/javascript/ql/test/library-tests/frameworks/Collections/test.expected +++ b/javascript/ql/test/library-tests/frameworks/Collections/test.expected @@ -1,19 +1,4 @@ -dataFlow -| tst.js:2:16:2:23 | source() | tst.js:7:7:7:7 | e | -| tst.js:2:16:2:23 | source() | tst.js:11:10:11:10 | e | -| tst.js:2:16:2:23 | source() | tst.js:17:10:17:10 | v | -| tst.js:2:16:2:23 | source() | tst.js:21:10:21:14 | value | -| tst.js:2:16:2:23 | source() | tst.js:26:10:26:14 | value | -| tst.js:2:16:2:23 | source() | tst.js:30:7:30:7 | e | -| tst.js:2:16:2:23 | source() | tst.js:34:7:34:7 | e | -| tst.js:2:16:2:23 | source() | tst.js:38:7:38:7 | e | -| tst.js:2:16:2:23 | source() | tst.js:42:7:42:7 | e | -| tst.js:2:16:2:23 | source() | tst.js:46:7:46:7 | e | -| tst.js:2:16:2:23 | source() | tst.js:50:10:50:10 | e | -| tst.js:2:16:2:23 | source() | tst.js:53:8:53:21 | map.get("key") | -| tst.js:2:16:2:23 | source() | tst.js:59:8:59:22 | map2.get("foo") | -| tst.js:2:16:2:23 | source() | tst.js:64:8:64:26 | map3.get(unknown()) | -| tst.js:2:16:2:23 | source() | tst.js:69:8:69:26 | map3.get(unknown()) | +legacyDataFlowDifference typeTracking | tst.js:2:16:2:23 | source() | tst.js:2:16:2:23 | source() | | tst.js:2:16:2:23 | source() | tst.js:6:14:6:14 | e | @@ -30,3 +15,19 @@ typeTracking | tst.js:2:16:2:23 | source() | tst.js:59:8:59:22 | map2.get("foo") | | tst.js:2:16:2:23 | source() | tst.js:64:8:64:26 | map3.get(unknown()) | | tst.js:2:16:2:23 | source() | tst.js:69:8:69:26 | map3.get(unknown()) | +dataFlow +| tst.js:2:16:2:23 | source() | tst.js:7:7:7:7 | e | +| tst.js:2:16:2:23 | source() | tst.js:11:10:11:10 | e | +| tst.js:2:16:2:23 | source() | tst.js:17:10:17:10 | v | +| tst.js:2:16:2:23 | source() | tst.js:21:10:21:14 | value | +| tst.js:2:16:2:23 | source() | tst.js:26:10:26:14 | value | +| tst.js:2:16:2:23 | source() | tst.js:30:7:30:7 | e | +| tst.js:2:16:2:23 | source() | tst.js:34:7:34:7 | e | +| tst.js:2:16:2:23 | source() | tst.js:38:7:38:7 | e | +| tst.js:2:16:2:23 | source() | tst.js:42:7:42:7 | e | +| tst.js:2:16:2:23 | source() | tst.js:46:7:46:7 | e | +| tst.js:2:16:2:23 | source() | tst.js:50:10:50:10 | e | +| tst.js:2:16:2:23 | source() | tst.js:53:8:53:21 | map.get("key") | +| tst.js:2:16:2:23 | source() | tst.js:59:8:59:22 | map2.get("foo") | +| tst.js:2:16:2:23 | source() | tst.js:64:8:64:26 | map3.get(unknown()) | +| tst.js:2:16:2:23 | source() | tst.js:69:8:69:26 | map3.get(unknown()) | diff --git a/javascript/ql/test/library-tests/frameworks/Collections/test.ql b/javascript/ql/test/library-tests/frameworks/Collections/test.ql index 9e3561fa844..f55cce9e035 100644 --- a/javascript/ql/test/library-tests/frameworks/Collections/test.ql +++ b/javascript/ql/test/library-tests/frameworks/Collections/test.ql @@ -1,21 +1,29 @@ import javascript -class Config extends DataFlow::Configuration { - Config() { this = "Config" } - - override predicate isSource(DataFlow::Node source) { +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.(DataFlow::CallNode).getCalleeName() = "source" } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(DataFlow::CallNode call | call.getCalleeName() = "sink" | call.getAnArgument() = sink) } } -query predicate dataFlow(DataFlow::Node pred, DataFlow::Node succ) { - any(Config c).hasFlow(pred, succ) +module TestFlow = DataFlow::Global; + +query predicate dataFlow = TestFlow::flow/2; + +class LegacyConfig extends DataFlow::Configuration { + LegacyConfig() { this = "Config" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } +import testUtilities.LegacyDataFlowDiff::DataFlowDiff + DataFlow::SourceNode trackSource(DataFlow::TypeTracker t, DataFlow::SourceNode start) { t.start() and result.(DataFlow::CallNode).getCalleeName() = "source" and From 6600fe9d51856a20bf39be5ddae8c1734e28111e Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 21:01:44 +0200 Subject: [PATCH 117/514] JS: Port ComposedFunctions test --- .../ComposedFunctions/compose.expected | 2 ++ .../frameworks/ComposedFunctions/compose.ql | 24 +++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/javascript/ql/test/library-tests/frameworks/ComposedFunctions/compose.expected b/javascript/ql/test/library-tests/frameworks/ComposedFunctions/compose.expected index 932f4ea6d43..2550bfedb05 100644 --- a/javascript/ql/test/library-tests/frameworks/ComposedFunctions/compose.expected +++ b/javascript/ql/test/library-tests/frameworks/ComposedFunctions/compose.expected @@ -1,3 +1,5 @@ +legacyDataFlowDifference +#select | tst.js:10:10:10:15 | source | | tst.js:15:10:15:13 | f1() | | tst.js:20:10:20:24 | lcompose1(f2)() | diff --git a/javascript/ql/test/library-tests/frameworks/ComposedFunctions/compose.ql b/javascript/ql/test/library-tests/frameworks/ComposedFunctions/compose.ql index d303fba17c9..dba04b72ef1 100644 --- a/javascript/ql/test/library-tests/frameworks/ComposedFunctions/compose.ql +++ b/javascript/ql/test/library-tests/frameworks/ComposedFunctions/compose.ql @@ -1,13 +1,11 @@ import javascript -class ExampleConfiguration extends TaintTracking::Configuration { - ExampleConfiguration() { this = "ExampleConfiguration" } - - override predicate isSource(DataFlow::Node source) { +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr().(CallExpr).getCalleeName() = "SOURCE" } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(CallExpr callExpr | callExpr.getCalleeName() = "SINK" and DataFlow::valueNode(callExpr.getArgument(0)) = sink @@ -15,6 +13,18 @@ class ExampleConfiguration extends TaintTracking::Configuration { } } -from ExampleConfiguration cfg, DataFlow::Node source, DataFlow::Node sink -where cfg.hasFlow(source, sink) +module TestFlow = TaintTracking::Global; + +class LegacyConfig extends TaintTracking::Configuration { + LegacyConfig() { this = "LegacyConfig" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } +} + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff + +from DataFlow::Node source, DataFlow::Node sink +where TestFlow::flow(source, sink) select sink From a2d4a03c0e567594516e1ec471c7dfcd74c93f70 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 09:47:16 +0200 Subject: [PATCH 118/514] JS: Update framework/data test --- .../frameworks/data/test.expected | 1 + .../library-tests/frameworks/data/test.ql | 28 +++++++++++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/javascript/ql/test/library-tests/frameworks/data/test.expected b/javascript/ql/test/library-tests/frameworks/data/test.expected index 28d7229789d..44e4353a9a1 100644 --- a/javascript/ql/test/library-tests/frameworks/data/test.expected +++ b/javascript/ql/test/library-tests/frameworks/data/test.expected @@ -1,3 +1,4 @@ +legacyDataFlowDifference consistencyIssue taintFlow | paramDecorator.ts:6:54:6:54 | x | paramDecorator.ts:7:10:7:10 | x | diff --git a/javascript/ql/test/library-tests/frameworks/data/test.ql b/javascript/ql/test/library-tests/frameworks/data/test.ql index 5ee8d0e3f9c..7d18ba01c55 100644 --- a/javascript/ql/test/library-tests/frameworks/data/test.ql +++ b/javascript/ql/test/library-tests/frameworks/data/test.ql @@ -84,24 +84,40 @@ class Sources extends ModelInput::SourceModelCsv { } } -class BasicTaintTracking extends TaintTracking::Configuration { - BasicTaintTracking() { this = "BasicTaintTracking" } - - override predicate isSource(DataFlow::Node source) { +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.(DataFlow::CallNode).getCalleeName() = "source" or source = ModelOutput::getASourceNode("test-source").asSource() } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink = any(DataFlow::CallNode call | call.getCalleeName() = "sink").getAnArgument() or sink = ModelOutput::getASinkNode("test-sink").asSink() } } +module TestFlow = TaintTracking::Global; + +class Consistency extends ConsistencyConfiguration { + Consistency() { this = "Consistency" } + + override DataFlow::Node getAnAlert() { TestFlow::flowTo(result) } +} + +class LegacyConfig extends TaintTracking::Configuration { + LegacyConfig() { this = "LegacyConfig" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } +} + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff + query predicate taintFlow(DataFlow::Node source, DataFlow::Node sink) { - any(BasicTaintTracking tr).hasFlow(source, sink) + TestFlow::flow(source, sink) } query predicate isSink(DataFlow::Node node, string kind) { From 644f9683b1308a554b3d2be8baadcc3e2a283016 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 09:48:45 +0200 Subject: [PATCH 119/514] JS: Update frameworks/immutable test --- .../frameworks/Immutable/tests.expected | 2 ++ .../frameworks/Immutable/tests.ql | 22 +++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/javascript/ql/test/library-tests/frameworks/Immutable/tests.expected b/javascript/ql/test/library-tests/frameworks/Immutable/tests.expected index 6edc4ee1a96..e071504bfcf 100644 --- a/javascript/ql/test/library-tests/frameworks/Immutable/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/Immutable/tests.expected @@ -1,3 +1,5 @@ +legacyDataFlowDifference +dataFlow | immutable.js:1:16:1:26 | source("a") | immutable.js:2:6:2:13 | obj["a"] | | immutable.js:1:16:1:26 | source("a") | immutable.js:11:6:11:18 | map1.get("a") | | immutable.js:1:16:1:26 | source("a") | immutable.js:12:6:12:18 | map2.get("a") | diff --git a/javascript/ql/test/library-tests/frameworks/Immutable/tests.ql b/javascript/ql/test/library-tests/frameworks/Immutable/tests.ql index 58d12ea774f..d530e770093 100644 --- a/javascript/ql/test/library-tests/frameworks/Immutable/tests.ql +++ b/javascript/ql/test/library-tests/frameworks/Immutable/tests.ql @@ -1,18 +1,26 @@ import javascript private import semmle.javascript.dataflow.internal.StepSummary -class Config extends DataFlow::Configuration { - Config() { this = "Config" } - - override predicate isSource(DataFlow::Node source) { +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.(DataFlow::CallNode).getCalleeName() = "source" } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(DataFlow::CallNode call | call.getCalleeName() = "sink" | call.getAnArgument() = sink) } } -query predicate dataFlow(DataFlow::Node pred, DataFlow::Node succ) { - any(Config c).hasFlow(pred, succ) +module TestFlow = DataFlow::Global; + +class LegacyConfig extends DataFlow::Configuration { + LegacyConfig() { this = "Config" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } + +query predicate dataFlow = TestFlow::flow/2; + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff From 2eec47b52c9d766f5ffc774340c034cfc2e3df2f Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 09:49:01 +0200 Subject: [PATCH 120/514] JS: Update frameworks/Next test --- .../frameworks/Next/tests.expected | 1 + .../library-tests/frameworks/Next/tests.ql | 22 +++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/javascript/ql/test/library-tests/frameworks/Next/tests.expected b/javascript/ql/test/library-tests/frameworks/Next/tests.expected index ced2e1f3fe1..9e9f6878b53 100644 --- a/javascript/ql/test/library-tests/frameworks/Next/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/Next/tests.expected @@ -1,3 +1,4 @@ +legacyDataFlowDifference remoteFlow | pages/[my-fallback-id].jsx:9:40:9:45 | params | | pages/secondpage.jsx:5:17:5:27 | ctx.req.url | diff --git a/javascript/ql/test/library-tests/frameworks/Next/tests.ql b/javascript/ql/test/library-tests/frameworks/Next/tests.ql index 134efa0faf1..98f4185b9ec 100644 --- a/javascript/ql/test/library-tests/frameworks/Next/tests.ql +++ b/javascript/ql/test/library-tests/frameworks/Next/tests.ql @@ -2,18 +2,26 @@ import javascript query RemoteFlowSource remoteFlow() { any() } -class Config extends DataFlow::Configuration { - Config() { this = "Config" } - - override predicate isSource(DataFlow::Node source) { +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.(DataFlow::CallNode).getCalleeName() = "source" } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(DataFlow::CallNode call | call.getCalleeName() = "sink" | call.getAnArgument() = sink) } } -query predicate dataFlow(DataFlow::Node pred, DataFlow::Node succ) { - any(Config c).hasFlow(pred, succ) +module TestFlow = DataFlow::Global; + +class LegacyConfig extends DataFlow::Configuration { + LegacyConfig() { this = "Config" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff + +query predicate dataFlow = TestFlow::flow/2; From d2053445a73b59305b8e4128e423a077e82f3904 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 09:50:15 +0200 Subject: [PATCH 121/514] JS: Update frameworks/PropertyProjection test --- .../PropertyInjectionTaint.expected | 2 ++ .../PropertyInjectionTaint.ql | 24 +++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/javascript/ql/test/library-tests/frameworks/PropertyProjection/PropertyInjectionTaint.expected b/javascript/ql/test/library-tests/frameworks/PropertyProjection/PropertyInjectionTaint.expected index 9244a0a9491..f7bcb9f8abc 100644 --- a/javascript/ql/test/library-tests/frameworks/PropertyProjection/PropertyInjectionTaint.expected +++ b/javascript/ql/test/library-tests/frameworks/PropertyProjection/PropertyInjectionTaint.expected @@ -1,3 +1,5 @@ +legacyDataFlowDifference +#select | tst.js:25:10:25:15 | source | | tst.js:32:10:32:27 | _.pick(tainted, s) | | tst.js:33:10:33:26 | _.get(tainted, s) | diff --git a/javascript/ql/test/library-tests/frameworks/PropertyProjection/PropertyInjectionTaint.ql b/javascript/ql/test/library-tests/frameworks/PropertyProjection/PropertyInjectionTaint.ql index d303fba17c9..dba04b72ef1 100644 --- a/javascript/ql/test/library-tests/frameworks/PropertyProjection/PropertyInjectionTaint.ql +++ b/javascript/ql/test/library-tests/frameworks/PropertyProjection/PropertyInjectionTaint.ql @@ -1,13 +1,11 @@ import javascript -class ExampleConfiguration extends TaintTracking::Configuration { - ExampleConfiguration() { this = "ExampleConfiguration" } - - override predicate isSource(DataFlow::Node source) { +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr().(CallExpr).getCalleeName() = "SOURCE" } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(CallExpr callExpr | callExpr.getCalleeName() = "SINK" and DataFlow::valueNode(callExpr.getArgument(0)) = sink @@ -15,6 +13,18 @@ class ExampleConfiguration extends TaintTracking::Configuration { } } -from ExampleConfiguration cfg, DataFlow::Node source, DataFlow::Node sink -where cfg.hasFlow(source, sink) +module TestFlow = TaintTracking::Global; + +class LegacyConfig extends TaintTracking::Configuration { + LegacyConfig() { this = "LegacyConfig" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } +} + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff + +from DataFlow::Node source, DataFlow::Node sink +where TestFlow::flow(source, sink) select sink From b9344134d3615bd83cd1b494dc3434fcb0f98266 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 09:51:23 +0200 Subject: [PATCH 122/514] JS: Update Redux test --- .../frameworks/Redux/test.expected | 1 + .../library-tests/frameworks/Redux/test.ql | 24 ++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/javascript/ql/test/library-tests/frameworks/Redux/test.expected b/javascript/ql/test/library-tests/frameworks/Redux/test.expected index 6a3675fea00..92c12137ad7 100644 --- a/javascript/ql/test/library-tests/frameworks/Redux/test.expected +++ b/javascript/ql/test/library-tests/frameworks/Redux/test.expected @@ -1,3 +1,4 @@ +legacyDataFlowDifference reducerArg | exportedReducer.js:12:12:12:35 | (state, ... > state | | react-redux.jsx:12:33:17:9 | (state, ... } | diff --git a/javascript/ql/test/library-tests/frameworks/Redux/test.ql b/javascript/ql/test/library-tests/frameworks/Redux/test.ql index 882aaeb616c..0cf6c7913ad 100644 --- a/javascript/ql/test/library-tests/frameworks/Redux/test.ql +++ b/javascript/ql/test/library-tests/frameworks/Redux/test.ql @@ -44,20 +44,28 @@ query predicate reducerToStateStep = Redux::reducerToStateStep/2; query Redux::StoreCreation storeCreation() { any() } -class BasicTaint extends TaintTracking::Configuration { - BasicTaint() { this = "BasicTaint" } +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node.(DataFlow::CallNode).getCalleeName() = "source" } - override predicate isSource(DataFlow::Node node) { - node.(DataFlow::CallNode).getCalleeName() = "source" - } - - override predicate isSink(DataFlow::Node node) { + predicate isSink(DataFlow::Node node) { node = any(DataFlow::CallNode call | call.getCalleeName() = "sink").getAnArgument() } } +module TestFlow = TaintTracking::Global; + +class LegacyConfig extends TaintTracking::Configuration { + LegacyConfig() { this = "LegacyConfig" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } +} + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff + query predicate taintFlow(DataFlow::Node source, DataFlow::Node sink) { - any(BasicTaint cfg).hasFlow(source, sink) + TestFlow::flow(source, sink) } query DataFlow::SourceNode reactComponentRef(ReactComponent component) { From 398353098388f3b72e85e8b68abc9dda86e8b7fe Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 09:59:09 +0200 Subject: [PATCH 123/514] JS: Update Templating/Xss test --- .../frameworks/Templating/Xss.expected | 578 ------------------ .../frameworks/Templating/Xss.qlref | 1 - .../frameworks/Templating/XssDiff.expected | 40 ++ .../frameworks/Templating/XssDiff.ql | 8 + 4 files changed, 48 insertions(+), 579 deletions(-) delete mode 100644 javascript/ql/test/library-tests/frameworks/Templating/Xss.expected delete mode 100644 javascript/ql/test/library-tests/frameworks/Templating/Xss.qlref create mode 100644 javascript/ql/test/library-tests/frameworks/Templating/XssDiff.expected create mode 100644 javascript/ql/test/library-tests/frameworks/Templating/XssDiff.ql diff --git a/javascript/ql/test/library-tests/frameworks/Templating/Xss.expected b/javascript/ql/test/library-tests/frameworks/Templating/Xss.expected deleted file mode 100644 index bc84b329dc7..00000000000 --- a/javascript/ql/test/library-tests/frameworks/Templating/Xss.expected +++ /dev/null @@ -1,578 +0,0 @@ -nodes -| app.js:8:18:8:34 | req.query.rawHtml | -| app.js:8:18:8:34 | req.query.rawHtml | -| app.js:8:18:8:34 | req.query.rawHtml | -| app.js:11:26:11:46 | req.que ... tmlProp | -| app.js:11:26:11:46 | req.que ... tmlProp | -| app.js:11:26:11:46 | req.que ... tmlProp | -| app.js:14:33:14:64 | req.que ... eralRaw | -| app.js:14:33:14:64 | req.que ... eralRaw | -| app.js:14:33:14:64 | req.que ... eralRaw | -| app.js:16:33:16:64 | req.que ... CodeRaw | -| app.js:16:33:16:64 | req.que ... CodeRaw | -| app.js:16:33:16:64 | req.que ... CodeRaw | -| app.js:20:38:20:74 | req.que ... ringRaw | -| app.js:20:38:20:74 | req.que ... ringRaw | -| app.js:20:38:20:74 | req.que ... ringRaw | -| app.js:27:18:27:34 | req.query.rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | -| app.js:30:26:30:46 | req.que ... tmlProp | -| app.js:30:26:30:46 | req.que ... tmlProp | -| app.js:30:26:30:46 | req.que ... tmlProp | -| app.js:33:33:33:64 | req.que ... eralRaw | -| app.js:33:33:33:64 | req.que ... eralRaw | -| app.js:33:33:33:64 | req.que ... eralRaw | -| app.js:35:33:35:64 | req.que ... CodeRaw | -| app.js:35:33:35:64 | req.que ... CodeRaw | -| app.js:35:33:35:64 | req.que ... CodeRaw | -| app.js:39:38:39:74 | req.que ... ringRaw | -| app.js:39:38:39:74 | req.que ... ringRaw | -| app.js:39:38:39:74 | req.que ... ringRaw | -| app.js:46:18:46:34 | req.query.rawHtml | -| app.js:46:18:46:34 | req.query.rawHtml | -| app.js:46:18:46:34 | req.query.rawHtml | -| app.js:49:26:49:46 | req.que ... tmlProp | -| app.js:49:26:49:46 | req.que ... tmlProp | -| app.js:49:26:49:46 | req.que ... tmlProp | -| app.js:52:33:52:64 | req.que ... eralRaw | -| app.js:52:33:52:64 | req.que ... eralRaw | -| app.js:52:33:52:64 | req.que ... eralRaw | -| app.js:54:33:54:64 | req.que ... CodeRaw | -| app.js:54:33:54:64 | req.que ... CodeRaw | -| app.js:54:33:54:64 | req.que ... CodeRaw | -| app.js:55:37:55:72 | req.que ... JsonRaw | -| app.js:55:37:55:72 | req.que ... JsonRaw | -| app.js:55:37:55:72 | req.que ... JsonRaw | -| app.js:59:38:59:74 | req.que ... ringRaw | -| app.js:59:38:59:74 | req.que ... ringRaw | -| app.js:59:38:59:74 | req.que ... ringRaw | -| app.js:66:18:66:34 | req.query.rawHtml | -| app.js:66:18:66:34 | req.query.rawHtml | -| app.js:66:18:66:34 | req.query.rawHtml | -| projectA/src/index.js:6:38:6:53 | req.query.taintA | -| projectA/src/index.js:6:38:6:53 | req.query.taintA | -| projectA/src/index.js:6:38:6:53 | req.query.taintA | -| projectA/src/index.js:12:16:12:30 | req.query.sinkA | -| projectA/src/index.js:12:16:12:30 | req.query.sinkA | -| projectA/src/index.js:12:16:12:30 | req.query.sinkA | -| projectA/src/index.js:17:16:17:30 | req.query.sinkA | -| projectA/src/index.js:17:16:17:30 | req.query.sinkA | -| projectA/src/index.js:17:16:17:30 | req.query.sinkA | -| projectA/src/index.js:22:16:22:30 | req.query.sinkA | -| projectA/src/index.js:22:16:22:30 | req.query.sinkA | -| projectA/src/index.js:22:16:22:30 | req.query.sinkA | -| projectA/src/index.js:37:16:37:30 | req.query.sinkA | -| projectA/src/index.js:37:16:37:30 | req.query.sinkA | -| projectA/src/index.js:37:16:37:30 | req.query.sinkA | -| projectA/src/index.js:42:16:42:30 | req.query.sinkA | -| projectA/src/index.js:42:16:42:30 | req.query.sinkA | -| projectA/src/index.js:42:16:42:30 | req.query.sinkA | -| projectA/src/index.js:47:16:47:30 | req.query.sinkA | -| projectA/src/index.js:47:16:47:30 | req.query.sinkA | -| projectA/src/index.js:47:16:47:30 | req.query.sinkA | -| projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/main.ejs:2:5:2:9 | sinkA | -| projectA/views/main.ejs:2:5:2:9 | sinkA | -| projectA/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | -| projectA/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | -| projectA/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | -| projectA/views/main.ejs:5:5:5:23 | taintedInMiddleware | -| projectA/views/main.ejs:5:5:5:23 | taintedInMiddleware | -| projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/subfolder/index.ejs:2:5:2:9 | sinkA | -| projectA/views/subfolder/index.ejs:2:5:2:9 | sinkA | -| projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA | -| projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA | -| projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> | -| projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> | -| projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> | -| projectA/views/upward_traversal.ejs:1:5:1:9 | sinkA | -| projectA/views/upward_traversal.ejs:1:5:1:9 | sinkA | -| projectB/src/index.js:6:38:6:53 | req.query.taintB | -| projectB/src/index.js:6:38:6:53 | req.query.taintB | -| projectB/src/index.js:6:38:6:53 | req.query.taintB | -| projectB/src/index.js:13:16:13:30 | req.query.sinkB | -| projectB/src/index.js:13:16:13:30 | req.query.sinkB | -| projectB/src/index.js:13:16:13:30 | req.query.sinkB | -| projectB/src/index.js:18:16:18:30 | req.query.sinkB | -| projectB/src/index.js:18:16:18:30 | req.query.sinkB | -| projectB/src/index.js:18:16:18:30 | req.query.sinkB | -| projectB/src/index.js:23:16:23:30 | req.query.sinkB | -| projectB/src/index.js:23:16:23:30 | req.query.sinkB | -| projectB/src/index.js:23:16:23:30 | req.query.sinkB | -| projectB/src/index.js:38:16:38:30 | req.query.sinkB | -| projectB/src/index.js:38:16:38:30 | req.query.sinkB | -| projectB/src/index.js:38:16:38:30 | req.query.sinkB | -| projectB/src/index.js:43:16:43:30 | req.query.sinkB | -| projectB/src/index.js:43:16:43:30 | req.query.sinkB | -| projectB/src/index.js:43:16:43:30 | req.query.sinkB | -| projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/main.ejs:3:5:3:9 | sinkB | -| projectB/views/main.ejs:3:5:3:9 | sinkB | -| projectB/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | -| projectB/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | -| projectB/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | -| projectB/views/main.ejs:5:5:5:23 | taintedInMiddleware | -| projectB/views/main.ejs:5:5:5:23 | taintedInMiddleware | -| projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/subfolder/index.ejs:3:5:3:9 | sinkB | -| projectB/views/subfolder/index.ejs:3:5:3:9 | sinkB | -| projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB | -| projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB | -| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | -| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | -| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | -| views/angularjs_include.ejs:3:9:3:15 | rawHtml | -| views/angularjs_include.ejs:3:9:3:15 | rawHtml | -| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | -| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | -| views/ejs_include1.ejs:1:1:1:10 | <%- foo %> | -| views/ejs_include1.ejs:1:1:1:10 | <%- foo %> | -| views/ejs_include1.ejs:1:1:1:10 | <%- foo %> | -| views/ejs_include1.ejs:1:5:1:7 | foo | -| views/ejs_include1.ejs:1:5:1:7 | foo | -| views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> | -| views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> | -| views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> | -| views/ejs_include2.ejs:1:5:1:11 | rawHtml | -| views/ejs_include2.ejs:1:5:1:11 | rawHtml | -| views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/ejs_sinks.ejs:4:13:4:19 | rawHtml | -| views/ejs_sinks.ejs:4:13:4:19 | rawHtml | -| views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> | -| views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> | -| views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> | -| views/ejs_sinks.ejs:7:13:7:30 | object.rawHtmlProp | -| views/ejs_sinks.ejs:7:13:7:30 | object.rawHtmlProp | -| views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> | -| views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> | -| views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> | -| views/ejs_sinks.ejs:11:47:11:68 | dataInS ... eralRaw | -| views/ejs_sinks.ejs:11:47:11:68 | dataInS ... eralRaw | -| views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> | -| views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> | -| views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> | -| views/ejs_sinks.ejs:14:46:14:67 | dataInG ... CodeRaw | -| views/ejs_sinks.ejs:14:46:14:67 | dataInG ... CodeRaw | -| views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> | -| views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> | -| views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> | -| views/ejs_sinks.ejs:22:43:22:69 | dataInE ... ringRaw | -| views/ejs_sinks.ejs:22:43:22:69 | dataInE ... ringRaw | -| views/ejs_sinks.ejs:24:44:24:50 | rawHtml | -| views/ejs_sinks.ejs:24:44:24:50 | rawHtml | -| views/hbs_sinks.hbs:9:9:9:23 | {{{ rawHtml }}} | -| views/hbs_sinks.hbs:9:9:9:23 | {{{ rawHtml }}} | -| views/hbs_sinks.hbs:9:9:9:23 | {{{ rawHtml }}} | -| views/hbs_sinks.hbs:9:13:9:19 | rawHtml | -| views/hbs_sinks.hbs:9:13:9:19 | rawHtml | -| views/hbs_sinks.hbs:10:9:10:23 | {{{~rawHtml }}} | -| views/hbs_sinks.hbs:10:9:10:23 | {{{~rawHtml }}} | -| views/hbs_sinks.hbs:10:9:10:23 | {{{~rawHtml }}} | -| views/hbs_sinks.hbs:10:13:10:19 | rawHtml | -| views/hbs_sinks.hbs:10:13:10:19 | rawHtml | -| views/hbs_sinks.hbs:11:9:11:23 | {{{ rawHtml~}}} | -| views/hbs_sinks.hbs:11:9:11:23 | {{{ rawHtml~}}} | -| views/hbs_sinks.hbs:11:9:11:23 | {{{ rawHtml~}}} | -| views/hbs_sinks.hbs:11:13:11:19 | rawHtml | -| views/hbs_sinks.hbs:11:13:11:19 | rawHtml | -| views/hbs_sinks.hbs:12:9:12:23 | {{{~rawHtml~}}} | -| views/hbs_sinks.hbs:12:9:12:23 | {{{~rawHtml~}}} | -| views/hbs_sinks.hbs:12:9:12:23 | {{{~rawHtml~}}} | -| views/hbs_sinks.hbs:12:13:12:19 | rawHtml | -| views/hbs_sinks.hbs:12:13:12:19 | rawHtml | -| views/hbs_sinks.hbs:13:9:13:25 | {{{~ rawHtml ~}}} | -| views/hbs_sinks.hbs:13:9:13:25 | {{{~ rawHtml ~}}} | -| views/hbs_sinks.hbs:13:9:13:25 | {{{~ rawHtml ~}}} | -| views/hbs_sinks.hbs:13:14:13:20 | rawHtml | -| views/hbs_sinks.hbs:13:14:13:20 | rawHtml | -| views/hbs_sinks.hbs:15:9:15:22 | {{& rawHtml }} | -| views/hbs_sinks.hbs:15:9:15:22 | {{& rawHtml }} | -| views/hbs_sinks.hbs:15:9:15:22 | {{& rawHtml }} | -| views/hbs_sinks.hbs:15:13:15:19 | rawHtml | -| views/hbs_sinks.hbs:15:13:15:19 | rawHtml | -| views/hbs_sinks.hbs:19:9:19:34 | {{{ object.rawHtmlProp }}} | -| views/hbs_sinks.hbs:19:9:19:34 | {{{ object.rawHtmlProp }}} | -| views/hbs_sinks.hbs:19:9:19:34 | {{{ object.rawHtmlProp }}} | -| views/hbs_sinks.hbs:19:13:19:30 | object.rawHtmlProp | -| views/hbs_sinks.hbs:19:13:19:30 | object.rawHtmlProp | -| views/hbs_sinks.hbs:23:43:23:72 | {{{ dataInStringLiteralRaw }}} | -| views/hbs_sinks.hbs:23:43:23:72 | {{{ dataInStringLiteralRaw }}} | -| views/hbs_sinks.hbs:23:43:23:72 | {{{ dataInStringLiteralRaw }}} | -| views/hbs_sinks.hbs:23:47:23:68 | dataInS ... eralRaw | -| views/hbs_sinks.hbs:23:47:23:68 | dataInS ... eralRaw | -| views/hbs_sinks.hbs:26:42:26:71 | {{{ dataInGeneratedCodeRaw }}} | -| views/hbs_sinks.hbs:26:42:26:71 | {{{ dataInGeneratedCodeRaw }}} | -| views/hbs_sinks.hbs:26:42:26:71 | {{{ dataInGeneratedCodeRaw }}} | -| views/hbs_sinks.hbs:26:46:26:67 | dataInG ... CodeRaw | -| views/hbs_sinks.hbs:26:46:26:67 | dataInG ... CodeRaw | -| views/hbs_sinks.hbs:34:39:34:73 | {{{ dataInEventHandlerStringRaw }}} | -| views/hbs_sinks.hbs:34:39:34:73 | {{{ dataInEventHandlerStringRaw }}} | -| views/hbs_sinks.hbs:34:39:34:73 | {{{ dataInEventHandlerStringRaw }}} | -| views/hbs_sinks.hbs:34:43:34:69 | dataInE ... ringRaw | -| views/hbs_sinks.hbs:34:43:34:69 | dataInE ... ringRaw | -| views/njk_sinks.njk:4:12:4:18 | rawHtml | -| views/njk_sinks.njk:4:12:4:18 | rawHtml | -| views/njk_sinks.njk:4:12:4:18 | rawHtml | -| views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp | -| views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp | -| views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp | -| views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw | -| views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw | -| views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw | -| views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | -| views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | -| views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | -| views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw | -| views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw | -| views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json | -| views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json | -| views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json | -| views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | -| views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | -| views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | -edges -| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_include2.ejs:1:5:1:11 | rawHtml | -| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_include2.ejs:1:5:1:11 | rawHtml | -| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_include2.ejs:1:5:1:11 | rawHtml | -| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_include2.ejs:1:5:1:11 | rawHtml | -| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_sinks.ejs:4:13:4:19 | rawHtml | -| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_sinks.ejs:4:13:4:19 | rawHtml | -| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_sinks.ejs:4:13:4:19 | rawHtml | -| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_sinks.ejs:4:13:4:19 | rawHtml | -| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_sinks.ejs:24:44:24:50 | rawHtml | -| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_sinks.ejs:24:44:24:50 | rawHtml | -| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_sinks.ejs:24:44:24:50 | rawHtml | -| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_sinks.ejs:24:44:24:50 | rawHtml | -| app.js:11:26:11:46 | req.que ... tmlProp | views/ejs_sinks.ejs:7:13:7:30 | object.rawHtmlProp | -| app.js:11:26:11:46 | req.que ... tmlProp | views/ejs_sinks.ejs:7:13:7:30 | object.rawHtmlProp | -| app.js:11:26:11:46 | req.que ... tmlProp | views/ejs_sinks.ejs:7:13:7:30 | object.rawHtmlProp | -| app.js:11:26:11:46 | req.que ... tmlProp | views/ejs_sinks.ejs:7:13:7:30 | object.rawHtmlProp | -| app.js:14:33:14:64 | req.que ... eralRaw | views/ejs_sinks.ejs:11:47:11:68 | dataInS ... eralRaw | -| app.js:14:33:14:64 | req.que ... eralRaw | views/ejs_sinks.ejs:11:47:11:68 | dataInS ... eralRaw | -| app.js:14:33:14:64 | req.que ... eralRaw | views/ejs_sinks.ejs:11:47:11:68 | dataInS ... eralRaw | -| app.js:14:33:14:64 | req.que ... eralRaw | views/ejs_sinks.ejs:11:47:11:68 | dataInS ... eralRaw | -| app.js:16:33:16:64 | req.que ... CodeRaw | views/ejs_sinks.ejs:14:46:14:67 | dataInG ... CodeRaw | -| app.js:16:33:16:64 | req.que ... CodeRaw | views/ejs_sinks.ejs:14:46:14:67 | dataInG ... CodeRaw | -| app.js:16:33:16:64 | req.que ... CodeRaw | views/ejs_sinks.ejs:14:46:14:67 | dataInG ... CodeRaw | -| app.js:16:33:16:64 | req.que ... CodeRaw | views/ejs_sinks.ejs:14:46:14:67 | dataInG ... CodeRaw | -| app.js:20:38:20:74 | req.que ... ringRaw | views/ejs_sinks.ejs:22:43:22:69 | dataInE ... ringRaw | -| app.js:20:38:20:74 | req.que ... ringRaw | views/ejs_sinks.ejs:22:43:22:69 | dataInE ... ringRaw | -| app.js:20:38:20:74 | req.que ... ringRaw | views/ejs_sinks.ejs:22:43:22:69 | dataInE ... ringRaw | -| app.js:20:38:20:74 | req.que ... ringRaw | views/ejs_sinks.ejs:22:43:22:69 | dataInE ... ringRaw | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:9:13:9:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:9:13:9:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:9:13:9:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:9:13:9:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:10:13:10:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:10:13:10:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:10:13:10:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:10:13:10:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:11:13:11:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:11:13:11:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:11:13:11:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:11:13:11:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:12:13:12:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:12:13:12:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:12:13:12:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:12:13:12:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:13:14:13:20 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:13:14:13:20 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:13:14:13:20 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:13:14:13:20 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:15:13:15:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:15:13:15:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:15:13:15:19 | rawHtml | -| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:15:13:15:19 | rawHtml | -| app.js:30:26:30:46 | req.que ... tmlProp | views/hbs_sinks.hbs:19:13:19:30 | object.rawHtmlProp | -| app.js:30:26:30:46 | req.que ... tmlProp | views/hbs_sinks.hbs:19:13:19:30 | object.rawHtmlProp | -| app.js:30:26:30:46 | req.que ... tmlProp | views/hbs_sinks.hbs:19:13:19:30 | object.rawHtmlProp | -| app.js:30:26:30:46 | req.que ... tmlProp | views/hbs_sinks.hbs:19:13:19:30 | object.rawHtmlProp | -| app.js:33:33:33:64 | req.que ... eralRaw | views/hbs_sinks.hbs:23:47:23:68 | dataInS ... eralRaw | -| app.js:33:33:33:64 | req.que ... eralRaw | views/hbs_sinks.hbs:23:47:23:68 | dataInS ... eralRaw | -| app.js:33:33:33:64 | req.que ... eralRaw | views/hbs_sinks.hbs:23:47:23:68 | dataInS ... eralRaw | -| app.js:33:33:33:64 | req.que ... eralRaw | views/hbs_sinks.hbs:23:47:23:68 | dataInS ... eralRaw | -| app.js:35:33:35:64 | req.que ... CodeRaw | views/hbs_sinks.hbs:26:46:26:67 | dataInG ... CodeRaw | -| app.js:35:33:35:64 | req.que ... CodeRaw | views/hbs_sinks.hbs:26:46:26:67 | dataInG ... CodeRaw | -| app.js:35:33:35:64 | req.que ... CodeRaw | views/hbs_sinks.hbs:26:46:26:67 | dataInG ... CodeRaw | -| app.js:35:33:35:64 | req.que ... CodeRaw | views/hbs_sinks.hbs:26:46:26:67 | dataInG ... CodeRaw | -| app.js:39:38:39:74 | req.que ... ringRaw | views/hbs_sinks.hbs:34:43:34:69 | dataInE ... ringRaw | -| app.js:39:38:39:74 | req.que ... ringRaw | views/hbs_sinks.hbs:34:43:34:69 | dataInE ... ringRaw | -| app.js:39:38:39:74 | req.que ... ringRaw | views/hbs_sinks.hbs:34:43:34:69 | dataInE ... ringRaw | -| app.js:39:38:39:74 | req.que ... ringRaw | views/hbs_sinks.hbs:34:43:34:69 | dataInE ... ringRaw | -| app.js:46:18:46:34 | req.query.rawHtml | views/njk_sinks.njk:4:12:4:18 | rawHtml | -| app.js:46:18:46:34 | req.query.rawHtml | views/njk_sinks.njk:4:12:4:18 | rawHtml | -| app.js:46:18:46:34 | req.query.rawHtml | views/njk_sinks.njk:4:12:4:18 | rawHtml | -| app.js:46:18:46:34 | req.query.rawHtml | views/njk_sinks.njk:4:12:4:18 | rawHtml | -| app.js:46:18:46:34 | req.query.rawHtml | views/njk_sinks.njk:4:12:4:18 | rawHtml | -| app.js:46:18:46:34 | req.query.rawHtml | views/njk_sinks.njk:4:12:4:18 | rawHtml | -| app.js:46:18:46:34 | req.query.rawHtml | views/njk_sinks.njk:4:12:4:18 | rawHtml | -| app.js:49:26:49:46 | req.que ... tmlProp | views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp | -| app.js:49:26:49:46 | req.que ... tmlProp | views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp | -| app.js:49:26:49:46 | req.que ... tmlProp | views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp | -| app.js:49:26:49:46 | req.que ... tmlProp | views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp | -| app.js:49:26:49:46 | req.que ... tmlProp | views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp | -| app.js:49:26:49:46 | req.que ... tmlProp | views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp | -| app.js:49:26:49:46 | req.que ... tmlProp | views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp | -| app.js:52:33:52:64 | req.que ... eralRaw | views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw | -| app.js:52:33:52:64 | req.que ... eralRaw | views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw | -| app.js:52:33:52:64 | req.que ... eralRaw | views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw | -| app.js:52:33:52:64 | req.que ... eralRaw | views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw | -| app.js:52:33:52:64 | req.que ... eralRaw | views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw | -| app.js:52:33:52:64 | req.que ... eralRaw | views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw | -| app.js:52:33:52:64 | req.que ... eralRaw | views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw | -| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | -| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | -| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | -| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | -| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | -| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | -| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | -| app.js:55:37:55:72 | req.que ... JsonRaw | views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw | -| app.js:55:37:55:72 | req.que ... JsonRaw | views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw | -| app.js:55:37:55:72 | req.que ... JsonRaw | views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw | -| app.js:55:37:55:72 | req.que ... JsonRaw | views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw | -| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | -| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | -| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | -| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | -| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | -| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | -| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | -| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:9:3:15 | rawHtml | -| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:9:3:15 | rawHtml | -| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:9:3:15 | rawHtml | -| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:9:3:15 | rawHtml | -| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | -| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | -| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | -| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | -| projectA/src/index.js:6:38:6:53 | req.query.taintA | projectA/views/main.ejs:5:5:5:23 | taintedInMiddleware | -| projectA/src/index.js:6:38:6:53 | req.query.taintA | projectA/views/main.ejs:5:5:5:23 | taintedInMiddleware | -| projectA/src/index.js:6:38:6:53 | req.query.taintA | projectA/views/main.ejs:5:5:5:23 | taintedInMiddleware | -| projectA/src/index.js:6:38:6:53 | req.query.taintA | projectA/views/main.ejs:5:5:5:23 | taintedInMiddleware | -| projectA/src/index.js:12:16:12:30 | req.query.sinkA | projectA/views/main.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:12:16:12:30 | req.query.sinkA | projectA/views/main.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:12:16:12:30 | req.query.sinkA | projectA/views/main.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:12:16:12:30 | req.query.sinkA | projectA/views/main.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:17:16:17:30 | req.query.sinkA | projectA/views/main.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:17:16:17:30 | req.query.sinkA | projectA/views/main.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:17:16:17:30 | req.query.sinkA | projectA/views/main.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:17:16:17:30 | req.query.sinkA | projectA/views/main.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:22:16:22:30 | req.query.sinkA | projectA/views/subfolder/index.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:22:16:22:30 | req.query.sinkA | projectA/views/subfolder/index.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:22:16:22:30 | req.query.sinkA | projectA/views/subfolder/index.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:22:16:22:30 | req.query.sinkA | projectA/views/subfolder/index.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:37:16:37:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:37:16:37:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:37:16:37:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:37:16:37:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:42:16:42:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:42:16:42:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:42:16:42:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:42:16:42:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA | -| projectA/src/index.js:47:16:47:30 | req.query.sinkA | projectA/views/upward_traversal.ejs:1:5:1:9 | sinkA | -| projectA/src/index.js:47:16:47:30 | req.query.sinkA | projectA/views/upward_traversal.ejs:1:5:1:9 | sinkA | -| projectA/src/index.js:47:16:47:30 | req.query.sinkA | projectA/views/upward_traversal.ejs:1:5:1:9 | sinkA | -| projectA/src/index.js:47:16:47:30 | req.query.sinkA | projectA/views/upward_traversal.ejs:1:5:1:9 | sinkA | -| projectA/views/main.ejs:2:5:2:9 | sinkA | projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/main.ejs:2:5:2:9 | sinkA | projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/main.ejs:2:5:2:9 | sinkA | projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/main.ejs:2:5:2:9 | sinkA | projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/main.ejs:5:5:5:23 | taintedInMiddleware | projectA/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | -| projectA/views/main.ejs:5:5:5:23 | taintedInMiddleware | projectA/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | -| projectA/views/main.ejs:5:5:5:23 | taintedInMiddleware | projectA/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | -| projectA/views/main.ejs:5:5:5:23 | taintedInMiddleware | projectA/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | -| projectA/views/subfolder/index.ejs:2:5:2:9 | sinkA | projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/subfolder/index.ejs:2:5:2:9 | sinkA | projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/subfolder/index.ejs:2:5:2:9 | sinkA | projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/subfolder/index.ejs:2:5:2:9 | sinkA | projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA | projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA | projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA | projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA | projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | -| projectA/views/upward_traversal.ejs:1:5:1:9 | sinkA | projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> | -| projectA/views/upward_traversal.ejs:1:5:1:9 | sinkA | projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> | -| projectA/views/upward_traversal.ejs:1:5:1:9 | sinkA | projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> | -| projectA/views/upward_traversal.ejs:1:5:1:9 | sinkA | projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> | -| projectB/src/index.js:6:38:6:53 | req.query.taintB | projectB/views/main.ejs:5:5:5:23 | taintedInMiddleware | -| projectB/src/index.js:6:38:6:53 | req.query.taintB | projectB/views/main.ejs:5:5:5:23 | taintedInMiddleware | -| projectB/src/index.js:6:38:6:53 | req.query.taintB | projectB/views/main.ejs:5:5:5:23 | taintedInMiddleware | -| projectB/src/index.js:6:38:6:53 | req.query.taintB | projectB/views/main.ejs:5:5:5:23 | taintedInMiddleware | -| projectB/src/index.js:13:16:13:30 | req.query.sinkB | projectB/views/main.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:13:16:13:30 | req.query.sinkB | projectB/views/main.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:13:16:13:30 | req.query.sinkB | projectB/views/main.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:13:16:13:30 | req.query.sinkB | projectB/views/main.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:18:16:18:30 | req.query.sinkB | projectB/views/main.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:18:16:18:30 | req.query.sinkB | projectB/views/main.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:18:16:18:30 | req.query.sinkB | projectB/views/main.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:18:16:18:30 | req.query.sinkB | projectB/views/main.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:23:16:23:30 | req.query.sinkB | projectB/views/subfolder/index.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:23:16:23:30 | req.query.sinkB | projectB/views/subfolder/index.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:23:16:23:30 | req.query.sinkB | projectB/views/subfolder/index.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:23:16:23:30 | req.query.sinkB | projectB/views/subfolder/index.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:38:16:38:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:38:16:38:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:38:16:38:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:38:16:38:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:43:16:43:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:43:16:43:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:43:16:43:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB | -| projectB/src/index.js:43:16:43:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB | -| projectB/views/main.ejs:3:5:3:9 | sinkB | projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/main.ejs:3:5:3:9 | sinkB | projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/main.ejs:3:5:3:9 | sinkB | projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/main.ejs:3:5:3:9 | sinkB | projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/main.ejs:5:5:5:23 | taintedInMiddleware | projectB/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | -| projectB/views/main.ejs:5:5:5:23 | taintedInMiddleware | projectB/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | -| projectB/views/main.ejs:5:5:5:23 | taintedInMiddleware | projectB/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | -| projectB/views/main.ejs:5:5:5:23 | taintedInMiddleware | projectB/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | -| projectB/views/subfolder/index.ejs:3:5:3:9 | sinkB | projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/subfolder/index.ejs:3:5:3:9 | sinkB | projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/subfolder/index.ejs:3:5:3:9 | sinkB | projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/subfolder/index.ejs:3:5:3:9 | sinkB | projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB | projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB | projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB | projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | -| projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB | projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | -| views/angularjs_include.ejs:3:9:3:15 | rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | -| views/angularjs_include.ejs:3:9:3:15 | rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | -| views/angularjs_include.ejs:3:9:3:15 | rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | -| views/angularjs_include.ejs:3:9:3:15 | rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | -| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/ejs_include1.ejs:1:5:1:7 | foo | views/ejs_include1.ejs:1:1:1:10 | <%- foo %> | -| views/ejs_include1.ejs:1:5:1:7 | foo | views/ejs_include1.ejs:1:1:1:10 | <%- foo %> | -| views/ejs_include1.ejs:1:5:1:7 | foo | views/ejs_include1.ejs:1:1:1:10 | <%- foo %> | -| views/ejs_include1.ejs:1:5:1:7 | foo | views/ejs_include1.ejs:1:1:1:10 | <%- foo %> | -| views/ejs_include2.ejs:1:5:1:11 | rawHtml | views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> | -| views/ejs_include2.ejs:1:5:1:11 | rawHtml | views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> | -| views/ejs_include2.ejs:1:5:1:11 | rawHtml | views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> | -| views/ejs_include2.ejs:1:5:1:11 | rawHtml | views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> | -| views/ejs_sinks.ejs:4:13:4:19 | rawHtml | views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/ejs_sinks.ejs:4:13:4:19 | rawHtml | views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/ejs_sinks.ejs:4:13:4:19 | rawHtml | views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/ejs_sinks.ejs:4:13:4:19 | rawHtml | views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/ejs_sinks.ejs:7:13:7:30 | object.rawHtmlProp | views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> | -| views/ejs_sinks.ejs:7:13:7:30 | object.rawHtmlProp | views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> | -| views/ejs_sinks.ejs:7:13:7:30 | object.rawHtmlProp | views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> | -| views/ejs_sinks.ejs:7:13:7:30 | object.rawHtmlProp | views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> | -| views/ejs_sinks.ejs:11:47:11:68 | dataInS ... eralRaw | views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> | -| views/ejs_sinks.ejs:11:47:11:68 | dataInS ... eralRaw | views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> | -| views/ejs_sinks.ejs:11:47:11:68 | dataInS ... eralRaw | views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> | -| views/ejs_sinks.ejs:11:47:11:68 | dataInS ... eralRaw | views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> | -| views/ejs_sinks.ejs:14:46:14:67 | dataInG ... CodeRaw | views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> | -| views/ejs_sinks.ejs:14:46:14:67 | dataInG ... CodeRaw | views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> | -| views/ejs_sinks.ejs:14:46:14:67 | dataInG ... CodeRaw | views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> | -| views/ejs_sinks.ejs:14:46:14:67 | dataInG ... CodeRaw | views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> | -| views/ejs_sinks.ejs:22:43:22:69 | dataInE ... ringRaw | views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> | -| views/ejs_sinks.ejs:22:43:22:69 | dataInE ... ringRaw | views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> | -| views/ejs_sinks.ejs:22:43:22:69 | dataInE ... ringRaw | views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> | -| views/ejs_sinks.ejs:22:43:22:69 | dataInE ... ringRaw | views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> | -| views/ejs_sinks.ejs:24:44:24:50 | rawHtml | views/ejs_include1.ejs:1:5:1:7 | foo | -| views/ejs_sinks.ejs:24:44:24:50 | rawHtml | views/ejs_include1.ejs:1:5:1:7 | foo | -| views/hbs_sinks.hbs:9:13:9:19 | rawHtml | views/hbs_sinks.hbs:9:9:9:23 | {{{ rawHtml }}} | -| views/hbs_sinks.hbs:9:13:9:19 | rawHtml | views/hbs_sinks.hbs:9:9:9:23 | {{{ rawHtml }}} | -| views/hbs_sinks.hbs:9:13:9:19 | rawHtml | views/hbs_sinks.hbs:9:9:9:23 | {{{ rawHtml }}} | -| views/hbs_sinks.hbs:9:13:9:19 | rawHtml | views/hbs_sinks.hbs:9:9:9:23 | {{{ rawHtml }}} | -| views/hbs_sinks.hbs:10:13:10:19 | rawHtml | views/hbs_sinks.hbs:10:9:10:23 | {{{~rawHtml }}} | -| views/hbs_sinks.hbs:10:13:10:19 | rawHtml | views/hbs_sinks.hbs:10:9:10:23 | {{{~rawHtml }}} | -| views/hbs_sinks.hbs:10:13:10:19 | rawHtml | views/hbs_sinks.hbs:10:9:10:23 | {{{~rawHtml }}} | -| views/hbs_sinks.hbs:10:13:10:19 | rawHtml | views/hbs_sinks.hbs:10:9:10:23 | {{{~rawHtml }}} | -| views/hbs_sinks.hbs:11:13:11:19 | rawHtml | views/hbs_sinks.hbs:11:9:11:23 | {{{ rawHtml~}}} | -| views/hbs_sinks.hbs:11:13:11:19 | rawHtml | views/hbs_sinks.hbs:11:9:11:23 | {{{ rawHtml~}}} | -| views/hbs_sinks.hbs:11:13:11:19 | rawHtml | views/hbs_sinks.hbs:11:9:11:23 | {{{ rawHtml~}}} | -| views/hbs_sinks.hbs:11:13:11:19 | rawHtml | views/hbs_sinks.hbs:11:9:11:23 | {{{ rawHtml~}}} | -| views/hbs_sinks.hbs:12:13:12:19 | rawHtml | views/hbs_sinks.hbs:12:9:12:23 | {{{~rawHtml~}}} | -| views/hbs_sinks.hbs:12:13:12:19 | rawHtml | views/hbs_sinks.hbs:12:9:12:23 | {{{~rawHtml~}}} | -| views/hbs_sinks.hbs:12:13:12:19 | rawHtml | views/hbs_sinks.hbs:12:9:12:23 | {{{~rawHtml~}}} | -| views/hbs_sinks.hbs:12:13:12:19 | rawHtml | views/hbs_sinks.hbs:12:9:12:23 | {{{~rawHtml~}}} | -| views/hbs_sinks.hbs:13:14:13:20 | rawHtml | views/hbs_sinks.hbs:13:9:13:25 | {{{~ rawHtml ~}}} | -| views/hbs_sinks.hbs:13:14:13:20 | rawHtml | views/hbs_sinks.hbs:13:9:13:25 | {{{~ rawHtml ~}}} | -| views/hbs_sinks.hbs:13:14:13:20 | rawHtml | views/hbs_sinks.hbs:13:9:13:25 | {{{~ rawHtml ~}}} | -| views/hbs_sinks.hbs:13:14:13:20 | rawHtml | views/hbs_sinks.hbs:13:9:13:25 | {{{~ rawHtml ~}}} | -| views/hbs_sinks.hbs:15:13:15:19 | rawHtml | views/hbs_sinks.hbs:15:9:15:22 | {{& rawHtml }} | -| views/hbs_sinks.hbs:15:13:15:19 | rawHtml | views/hbs_sinks.hbs:15:9:15:22 | {{& rawHtml }} | -| views/hbs_sinks.hbs:15:13:15:19 | rawHtml | views/hbs_sinks.hbs:15:9:15:22 | {{& rawHtml }} | -| views/hbs_sinks.hbs:15:13:15:19 | rawHtml | views/hbs_sinks.hbs:15:9:15:22 | {{& rawHtml }} | -| views/hbs_sinks.hbs:19:13:19:30 | object.rawHtmlProp | views/hbs_sinks.hbs:19:9:19:34 | {{{ object.rawHtmlProp }}} | -| views/hbs_sinks.hbs:19:13:19:30 | object.rawHtmlProp | views/hbs_sinks.hbs:19:9:19:34 | {{{ object.rawHtmlProp }}} | -| views/hbs_sinks.hbs:19:13:19:30 | object.rawHtmlProp | views/hbs_sinks.hbs:19:9:19:34 | {{{ object.rawHtmlProp }}} | -| views/hbs_sinks.hbs:19:13:19:30 | object.rawHtmlProp | views/hbs_sinks.hbs:19:9:19:34 | {{{ object.rawHtmlProp }}} | -| views/hbs_sinks.hbs:23:47:23:68 | dataInS ... eralRaw | views/hbs_sinks.hbs:23:43:23:72 | {{{ dataInStringLiteralRaw }}} | -| views/hbs_sinks.hbs:23:47:23:68 | dataInS ... eralRaw | views/hbs_sinks.hbs:23:43:23:72 | {{{ dataInStringLiteralRaw }}} | -| views/hbs_sinks.hbs:23:47:23:68 | dataInS ... eralRaw | views/hbs_sinks.hbs:23:43:23:72 | {{{ dataInStringLiteralRaw }}} | -| views/hbs_sinks.hbs:23:47:23:68 | dataInS ... eralRaw | views/hbs_sinks.hbs:23:43:23:72 | {{{ dataInStringLiteralRaw }}} | -| views/hbs_sinks.hbs:26:46:26:67 | dataInG ... CodeRaw | views/hbs_sinks.hbs:26:42:26:71 | {{{ dataInGeneratedCodeRaw }}} | -| views/hbs_sinks.hbs:26:46:26:67 | dataInG ... CodeRaw | views/hbs_sinks.hbs:26:42:26:71 | {{{ dataInGeneratedCodeRaw }}} | -| views/hbs_sinks.hbs:26:46:26:67 | dataInG ... CodeRaw | views/hbs_sinks.hbs:26:42:26:71 | {{{ dataInGeneratedCodeRaw }}} | -| views/hbs_sinks.hbs:26:46:26:67 | dataInG ... CodeRaw | views/hbs_sinks.hbs:26:42:26:71 | {{{ dataInGeneratedCodeRaw }}} | -| views/hbs_sinks.hbs:34:43:34:69 | dataInE ... ringRaw | views/hbs_sinks.hbs:34:39:34:73 | {{{ dataInEventHandlerStringRaw }}} | -| views/hbs_sinks.hbs:34:43:34:69 | dataInE ... ringRaw | views/hbs_sinks.hbs:34:39:34:73 | {{{ dataInEventHandlerStringRaw }}} | -| views/hbs_sinks.hbs:34:43:34:69 | dataInE ... ringRaw | views/hbs_sinks.hbs:34:39:34:73 | {{{ dataInEventHandlerStringRaw }}} | -| views/hbs_sinks.hbs:34:43:34:69 | dataInE ... ringRaw | views/hbs_sinks.hbs:34:39:34:73 | {{{ dataInEventHandlerStringRaw }}} | -| views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw | views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json | -| views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw | views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json | -| views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw | views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json | -| views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw | views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json | -#select -| projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | projectA/src/index.js:12:16:12:30 | req.query.sinkA | projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | Cross-site scripting vulnerability due to $@. | projectA/src/index.js:12:16:12:30 | req.query.sinkA | user-provided value | -| projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | projectA/src/index.js:17:16:17:30 | req.query.sinkA | projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | Cross-site scripting vulnerability due to $@. | projectA/src/index.js:17:16:17:30 | req.query.sinkA | user-provided value | -| projectA/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | projectA/src/index.js:6:38:6:53 | req.query.taintA | projectA/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | Cross-site scripting vulnerability due to $@. | projectA/src/index.js:6:38:6:53 | req.query.taintA | user-provided value | -| projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> | projectA/src/index.js:22:16:22:30 | req.query.sinkA | projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> | Cross-site scripting vulnerability due to $@. | projectA/src/index.js:22:16:22:30 | req.query.sinkA | user-provided value | -| projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | projectA/src/index.js:37:16:37:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | Cross-site scripting vulnerability due to $@. | projectA/src/index.js:37:16:37:30 | req.query.sinkA | user-provided value | -| projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | projectA/src/index.js:42:16:42:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | Cross-site scripting vulnerability due to $@. | projectA/src/index.js:42:16:42:30 | req.query.sinkA | user-provided value | -| projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> | projectA/src/index.js:47:16:47:30 | req.query.sinkA | projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> | Cross-site scripting vulnerability due to $@. | projectA/src/index.js:47:16:47:30 | req.query.sinkA | user-provided value | -| projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | projectB/src/index.js:13:16:13:30 | req.query.sinkB | projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | Cross-site scripting vulnerability due to $@. | projectB/src/index.js:13:16:13:30 | req.query.sinkB | user-provided value | -| projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | projectB/src/index.js:18:16:18:30 | req.query.sinkB | projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | Cross-site scripting vulnerability due to $@. | projectB/src/index.js:18:16:18:30 | req.query.sinkB | user-provided value | -| projectB/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | projectB/src/index.js:6:38:6:53 | req.query.taintB | projectB/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | Cross-site scripting vulnerability due to $@. | projectB/src/index.js:6:38:6:53 | req.query.taintB | user-provided value | -| projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> | projectB/src/index.js:23:16:23:30 | req.query.sinkB | projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> | Cross-site scripting vulnerability due to $@. | projectB/src/index.js:23:16:23:30 | req.query.sinkB | user-provided value | -| projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | projectB/src/index.js:38:16:38:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | Cross-site scripting vulnerability due to $@. | projectB/src/index.js:38:16:38:30 | req.query.sinkB | user-provided value | -| projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | projectB/src/index.js:43:16:43:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | Cross-site scripting vulnerability due to $@. | projectB/src/index.js:43:16:43:30 | req.query.sinkB | user-provided value | -| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | Cross-site scripting vulnerability due to $@. | app.js:66:18:66:34 | req.query.rawHtml | user-provided value | -| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | Cross-site scripting vulnerability due to $@. | app.js:66:18:66:34 | req.query.rawHtml | user-provided value | -| views/ejs_include1.ejs:1:1:1:10 | <%- foo %> | app.js:8:18:8:34 | req.query.rawHtml | views/ejs_include1.ejs:1:1:1:10 | <%- foo %> | Cross-site scripting vulnerability due to $@. | app.js:8:18:8:34 | req.query.rawHtml | user-provided value | -| views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> | app.js:8:18:8:34 | req.query.rawHtml | views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> | Cross-site scripting vulnerability due to $@. | app.js:8:18:8:34 | req.query.rawHtml | user-provided value | -| views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | app.js:8:18:8:34 | req.query.rawHtml | views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | Cross-site scripting vulnerability due to $@. | app.js:8:18:8:34 | req.query.rawHtml | user-provided value | -| views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> | app.js:11:26:11:46 | req.que ... tmlProp | views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> | Cross-site scripting vulnerability due to $@. | app.js:11:26:11:46 | req.que ... tmlProp | user-provided value | -| views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> | app.js:14:33:14:64 | req.que ... eralRaw | views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> | Cross-site scripting vulnerability due to $@. | app.js:14:33:14:64 | req.que ... eralRaw | user-provided value | -| views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> | app.js:16:33:16:64 | req.que ... CodeRaw | views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> | Cross-site scripting vulnerability due to $@. | app.js:16:33:16:64 | req.que ... CodeRaw | user-provided value | -| views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> | app.js:20:38:20:74 | req.que ... ringRaw | views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> | Cross-site scripting vulnerability due to $@. | app.js:20:38:20:74 | req.que ... ringRaw | user-provided value | -| views/hbs_sinks.hbs:9:9:9:23 | {{{ rawHtml }}} | app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:9:9:9:23 | {{{ rawHtml }}} | Cross-site scripting vulnerability due to $@. | app.js:27:18:27:34 | req.query.rawHtml | user-provided value | -| views/hbs_sinks.hbs:10:9:10:23 | {{{~rawHtml }}} | app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:10:9:10:23 | {{{~rawHtml }}} | Cross-site scripting vulnerability due to $@. | app.js:27:18:27:34 | req.query.rawHtml | user-provided value | -| views/hbs_sinks.hbs:11:9:11:23 | {{{ rawHtml~}}} | app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:11:9:11:23 | {{{ rawHtml~}}} | Cross-site scripting vulnerability due to $@. | app.js:27:18:27:34 | req.query.rawHtml | user-provided value | -| views/hbs_sinks.hbs:12:9:12:23 | {{{~rawHtml~}}} | app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:12:9:12:23 | {{{~rawHtml~}}} | Cross-site scripting vulnerability due to $@. | app.js:27:18:27:34 | req.query.rawHtml | user-provided value | -| views/hbs_sinks.hbs:13:9:13:25 | {{{~ rawHtml ~}}} | app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:13:9:13:25 | {{{~ rawHtml ~}}} | Cross-site scripting vulnerability due to $@. | app.js:27:18:27:34 | req.query.rawHtml | user-provided value | -| views/hbs_sinks.hbs:15:9:15:22 | {{& rawHtml }} | app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:15:9:15:22 | {{& rawHtml }} | Cross-site scripting vulnerability due to $@. | app.js:27:18:27:34 | req.query.rawHtml | user-provided value | -| views/hbs_sinks.hbs:19:9:19:34 | {{{ object.rawHtmlProp }}} | app.js:30:26:30:46 | req.que ... tmlProp | views/hbs_sinks.hbs:19:9:19:34 | {{{ object.rawHtmlProp }}} | Cross-site scripting vulnerability due to $@. | app.js:30:26:30:46 | req.que ... tmlProp | user-provided value | -| views/hbs_sinks.hbs:23:43:23:72 | {{{ dataInStringLiteralRaw }}} | app.js:33:33:33:64 | req.que ... eralRaw | views/hbs_sinks.hbs:23:43:23:72 | {{{ dataInStringLiteralRaw }}} | Cross-site scripting vulnerability due to $@. | app.js:33:33:33:64 | req.que ... eralRaw | user-provided value | -| views/hbs_sinks.hbs:26:42:26:71 | {{{ dataInGeneratedCodeRaw }}} | app.js:35:33:35:64 | req.que ... CodeRaw | views/hbs_sinks.hbs:26:42:26:71 | {{{ dataInGeneratedCodeRaw }}} | Cross-site scripting vulnerability due to $@. | app.js:35:33:35:64 | req.que ... CodeRaw | user-provided value | -| views/hbs_sinks.hbs:34:39:34:73 | {{{ dataInEventHandlerStringRaw }}} | app.js:39:38:39:74 | req.que ... ringRaw | views/hbs_sinks.hbs:34:39:34:73 | {{{ dataInEventHandlerStringRaw }}} | Cross-site scripting vulnerability due to $@. | app.js:39:38:39:74 | req.que ... ringRaw | user-provided value | -| views/njk_sinks.njk:4:12:4:18 | rawHtml | app.js:46:18:46:34 | req.query.rawHtml | views/njk_sinks.njk:4:12:4:18 | rawHtml | Cross-site scripting vulnerability due to $@. | app.js:46:18:46:34 | req.query.rawHtml | user-provided value | -| views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp | app.js:49:26:49:46 | req.que ... tmlProp | views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp | Cross-site scripting vulnerability due to $@. | app.js:49:26:49:46 | req.que ... tmlProp | user-provided value | -| views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw | app.js:52:33:52:64 | req.que ... eralRaw | views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw | Cross-site scripting vulnerability due to $@. | app.js:52:33:52:64 | req.que ... eralRaw | user-provided value | -| views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | Cross-site scripting vulnerability due to $@. | app.js:54:33:54:64 | req.que ... CodeRaw | user-provided value | -| views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json | app.js:55:37:55:72 | req.que ... JsonRaw | views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json | Cross-site scripting vulnerability due to $@. | app.js:55:37:55:72 | req.que ... JsonRaw | user-provided value | -| views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | Cross-site scripting vulnerability due to $@. | app.js:59:38:59:74 | req.que ... ringRaw | user-provided value | diff --git a/javascript/ql/test/library-tests/frameworks/Templating/Xss.qlref b/javascript/ql/test/library-tests/frameworks/Templating/Xss.qlref deleted file mode 100644 index 353427de471..00000000000 --- a/javascript/ql/test/library-tests/frameworks/Templating/Xss.qlref +++ /dev/null @@ -1 +0,0 @@ -Security/CWE-079/Xss.ql diff --git a/javascript/ql/test/library-tests/frameworks/Templating/XssDiff.expected b/javascript/ql/test/library-tests/frameworks/Templating/XssDiff.expected new file mode 100644 index 00000000000..168b17e2a1b --- /dev/null +++ b/javascript/ql/test/library-tests/frameworks/Templating/XssDiff.expected @@ -0,0 +1,40 @@ +legacyDataFlowDifference +flow +| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_include1.ejs:1:1:1:10 | <%- foo %> | +| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> | +| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | +| app.js:11:26:11:46 | req.que ... tmlProp | views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> | +| app.js:14:33:14:64 | req.que ... eralRaw | views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> | +| app.js:16:33:16:64 | req.que ... CodeRaw | views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> | +| app.js:20:38:20:74 | req.que ... ringRaw | views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> | +| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:9:9:9:23 | {{{ rawHtml }}} | +| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:10:9:10:23 | {{{~rawHtml }}} | +| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:11:9:11:23 | {{{ rawHtml~}}} | +| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:12:9:12:23 | {{{~rawHtml~}}} | +| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:13:9:13:25 | {{{~ rawHtml ~}}} | +| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:15:9:15:22 | {{& rawHtml }} | +| app.js:30:26:30:46 | req.que ... tmlProp | views/hbs_sinks.hbs:19:9:19:34 | {{{ object.rawHtmlProp }}} | +| app.js:33:33:33:64 | req.que ... eralRaw | views/hbs_sinks.hbs:23:43:23:72 | {{{ dataInStringLiteralRaw }}} | +| app.js:35:33:35:64 | req.que ... CodeRaw | views/hbs_sinks.hbs:26:42:26:71 | {{{ dataInGeneratedCodeRaw }}} | +| app.js:39:38:39:74 | req.que ... ringRaw | views/hbs_sinks.hbs:34:39:34:73 | {{{ dataInEventHandlerStringRaw }}} | +| app.js:46:18:46:34 | req.query.rawHtml | views/njk_sinks.njk:4:12:4:18 | rawHtml | +| app.js:49:26:49:46 | req.que ... tmlProp | views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp | +| app.js:52:33:52:64 | req.que ... eralRaw | views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw | +| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | +| app.js:55:37:55:72 | req.que ... JsonRaw | views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json | +| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | +| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | +| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | +| projectA/src/index.js:6:38:6:53 | req.query.taintA | projectA/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | +| projectA/src/index.js:12:16:12:30 | req.query.sinkA | projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | +| projectA/src/index.js:17:16:17:30 | req.query.sinkA | projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | +| projectA/src/index.js:22:16:22:30 | req.query.sinkA | projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> | +| projectA/src/index.js:37:16:37:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | +| projectA/src/index.js:42:16:42:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | +| projectA/src/index.js:47:16:47:30 | req.query.sinkA | projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> | +| projectB/src/index.js:6:38:6:53 | req.query.taintB | projectB/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | +| projectB/src/index.js:13:16:13:30 | req.query.sinkB | projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | +| projectB/src/index.js:18:16:18:30 | req.query.sinkB | projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | +| projectB/src/index.js:23:16:23:30 | req.query.sinkB | projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> | +| projectB/src/index.js:38:16:38:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | +| projectB/src/index.js:43:16:43:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | diff --git a/javascript/ql/test/library-tests/frameworks/Templating/XssDiff.ql b/javascript/ql/test/library-tests/frameworks/Templating/XssDiff.ql new file mode 100644 index 00000000000..def7b283440 --- /dev/null +++ b/javascript/ql/test/library-tests/frameworks/Templating/XssDiff.ql @@ -0,0 +1,8 @@ +import javascript +import semmle.javascript.security.dataflow.DomBasedXssQuery +import testUtilities.LegacyDataFlowDiff + +deprecated query predicate legacyDataFlowDifference = + DataFlowDiff::legacyDataFlowDifference/3; + +query predicate flow = DomBasedXssFlow::flow/2; From 995df41532b5df433252460aa7c501362a13b764 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 10:00:56 +0200 Subject: [PATCH 124/514] JS: Update Vuex test --- .../frameworks/Vuex/test.expected | 2 ++ .../library-tests/frameworks/Vuex/test.ql | 28 ++++++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/javascript/ql/test/library-tests/frameworks/Vuex/test.expected b/javascript/ql/test/library-tests/frameworks/Vuex/test.expected index e69de29bb2d..d65d51bc417 100644 --- a/javascript/ql/test/library-tests/frameworks/Vuex/test.expected +++ b/javascript/ql/test/library-tests/frameworks/Vuex/test.expected @@ -0,0 +1,2 @@ +legacyDataFlowDifference +consistencyIssue diff --git a/javascript/ql/test/library-tests/frameworks/Vuex/test.ql b/javascript/ql/test/library-tests/frameworks/Vuex/test.ql index 55464dcf72c..ac58a94374e 100644 --- a/javascript/ql/test/library-tests/frameworks/Vuex/test.ql +++ b/javascript/ql/test/library-tests/frameworks/Vuex/test.ql @@ -1,14 +1,28 @@ import javascript import testUtilities.ConsistencyChecking -class BasicTaint extends TaintTracking::Configuration { - BasicTaint() { this = "BasicTaint" } +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node.(DataFlow::CallNode).getCalleeName() = "source" } - override predicate isSource(DataFlow::Node node) { - node.(DataFlow::CallNode).getCalleeName() = "source" - } - - override predicate isSink(DataFlow::Node node) { + predicate isSink(DataFlow::Node node) { node = any(DataFlow::CallNode call | call.getCalleeName() = "sink").getAnArgument() } } + +module TestFlow = TaintTracking::Global; + +class Consistency extends ConsistencyConfiguration { + Consistency() { this = "Consistency" } + + override DataFlow::Node getAnAlert() { TestFlow::flowTo(result) } +} + +class LegacyConfig extends TaintTracking::Configuration { + LegacyConfig() { this = "LegacyConfig" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } +} + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff From 9372f7993df3db6c4dc28d97e444f8f2f737393d Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 10:02:04 +0200 Subject: [PATCH 125/514] JS: Update Generators test Data flow difference is benign --- .../Generators/DataFlow.expected | 5 ++++ .../test/library-tests/Generators/DataFlow.ql | 26 +++++++++++++++---- .../library-tests/Generators/generators.js | 20 ++++++++++++++ 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/javascript/ql/test/library-tests/Generators/DataFlow.expected b/javascript/ql/test/library-tests/Generators/DataFlow.expected index e69de29bb2d..0b23f47de26 100644 --- a/javascript/ql/test/library-tests/Generators/DataFlow.expected +++ b/javascript/ql/test/library-tests/Generators/DataFlow.expected @@ -0,0 +1,5 @@ +legacyDataFlowDifference +| generators.js:2:16:2:23 | "source" | generators.js:37:10:37:10 | e | only flow with OLD data flow library | +| generators.js:2:16:2:23 | "source" | generators.js:46:10:46:10 | e | only flow with NEW data flow library | +| generators.js:2:16:2:23 | "source" | generators.js:51:10:51:10 | e | only flow with NEW data flow library | +consistencyIssue diff --git a/javascript/ql/test/library-tests/Generators/DataFlow.ql b/javascript/ql/test/library-tests/Generators/DataFlow.ql index 023c60ff853..f613ed62f3b 100644 --- a/javascript/ql/test/library-tests/Generators/DataFlow.ql +++ b/javascript/ql/test/library-tests/Generators/DataFlow.ql @@ -1,12 +1,28 @@ import javascript import testUtilities.ConsistencyChecking -class GeneratorFlowConfig extends DataFlow::Configuration { - GeneratorFlowConfig() { this = "GeneratorFlowConfig" } +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr().getStringValue() = "source" } - override predicate isSource(DataFlow::Node source) { source.asExpr().getStringValue() = "source" } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink = any(DataFlow::CallNode call | call.getCalleeName() = "sink").getAnArgument() } } + +module TestFlow = DataFlow::Global; + +class LegacyConfig extends DataFlow::Configuration { + LegacyConfig() { this = "GeneratorFlowConfig" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } +} + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff + +class Consistency extends ConsistencyConfiguration { + Consistency() { this = "Consistency" } + + override DataFlow::Node getAnAlert() { TestFlow::flowTo(result) } +} diff --git a/javascript/ql/test/library-tests/Generators/generators.js b/javascript/ql/test/library-tests/Generators/generators.js index 89d5be345dc..dc602f15264 100644 --- a/javascript/ql/test/library-tests/Generators/generators.js +++ b/javascript/ql/test/library-tests/Generators/generators.js @@ -31,6 +31,26 @@ sink(e); // NOT OK } + try { + gen4(); + } catch (e) { + sink(e); // OK - exception is only thrown upon iteration + } + + const iterator = gen4(); + try { + for (let v of iterator) { + sink(v); // OK + } + } catch (e) { + sink(e); // NOT OK + } + try { + Array.from(iterator); + } catch (e) { + sink(e); // NOT OK + } + function *delegating() { yield* delegate(); } From 50aace3fa39d9bd0ceabe04a9b1412e6816c6841 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 10:30:12 +0200 Subject: [PATCH 126/514] JS: Add global post-update steps --- .../dataflow/internal/DataFlowPrivate.qll | 2 ++ .../dataflow/internal/FlowSteps.qll | 23 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 0c269a7f152..9de86831748 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -671,6 +671,8 @@ private predicate valuePreservingStep(Node node1, Node node2) { or FlowSteps::globalFlowStep(node1, node2) or + FlowSteps::globalPostUpdateStep(node1, node2) + or node2 = FlowSteps::getThrowTarget(node1) or FlowSummaryImpl::Private::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(), diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll index 2ee04b8dbf5..6294072466d 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll @@ -383,6 +383,14 @@ private module CachedSteps { result = DataFlow::valueNode(gv.getAnAccess()) } + /** + * Gets a post-update of `gv` in `f`. + */ + pragma[noinline] + private DataFlow::ExprPostUpdateNode getAPostUpdateIn(GlobalVariable gv, File f) { + result.getPreUpdateNode() = getAUseIn(gv, f) + } + /** * Holds if there is a flow step from `pred` to `succ` through a global * variable. Both `pred` and `succ` must be in the same file. @@ -395,6 +403,20 @@ private module CachedSteps { ) } + /** + * Holds if `pred` is a post-update node for a use of a global variable, and `succ` + * is a use of the global variable in the same file. + */ + cached + predicate globalPostUpdateStep(DataFlow::Node pred, DataFlow::Node succ) { + exists(GlobalVariable gv, File f | + pred = getAPostUpdateIn(gv, f) and + succ = getAUseIn(gv, f) and + // Remove some unnecessary steps + not succ = any(DataFlow::PropWrite write).getBase() + ) + } + /** * Holds if there is a write to property `prop` of global variable `gv` * in file `f`, where the right-hand side of the write is `rhs`. @@ -438,6 +460,7 @@ private module CachedSteps { predicate basicStoreStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { succ.(DataFlow::SourceNode).hasPropertyWrite(prop, pred) or + // Note that this case is handled by globalPostUpdateStep in dataflow2 exists(GlobalVariable gv, File f | globalPropertyWrite(gv, f, prop, pred) and globalPropertyRead(gv, f, prop, succ) From 0d10aba67d16894fe17c144978e033b516b2ece0 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 21:11:30 +0200 Subject: [PATCH 127/514] Revert "JS: Add global post-update steps" This resulted in huge performance issues from too much global flow --- .../dataflow/internal/DataFlowPrivate.qll | 2 -- .../dataflow/internal/FlowSteps.qll | 23 ------------------- 2 files changed, 25 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 9de86831748..0c269a7f152 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -671,8 +671,6 @@ private predicate valuePreservingStep(Node node1, Node node2) { or FlowSteps::globalFlowStep(node1, node2) or - FlowSteps::globalPostUpdateStep(node1, node2) - or node2 = FlowSteps::getThrowTarget(node1) or FlowSummaryImpl::Private::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(), diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll index 6294072466d..2ee04b8dbf5 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll @@ -383,14 +383,6 @@ private module CachedSteps { result = DataFlow::valueNode(gv.getAnAccess()) } - /** - * Gets a post-update of `gv` in `f`. - */ - pragma[noinline] - private DataFlow::ExprPostUpdateNode getAPostUpdateIn(GlobalVariable gv, File f) { - result.getPreUpdateNode() = getAUseIn(gv, f) - } - /** * Holds if there is a flow step from `pred` to `succ` through a global * variable. Both `pred` and `succ` must be in the same file. @@ -403,20 +395,6 @@ private module CachedSteps { ) } - /** - * Holds if `pred` is a post-update node for a use of a global variable, and `succ` - * is a use of the global variable in the same file. - */ - cached - predicate globalPostUpdateStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(GlobalVariable gv, File f | - pred = getAPostUpdateIn(gv, f) and - succ = getAUseIn(gv, f) and - // Remove some unnecessary steps - not succ = any(DataFlow::PropWrite write).getBase() - ) - } - /** * Holds if there is a write to property `prop` of global variable `gv` * in file `f`, where the right-hand side of the write is `rhs`. @@ -460,7 +438,6 @@ private module CachedSteps { predicate basicStoreStep(DataFlow::Node pred, DataFlow::Node succ, string prop) { succ.(DataFlow::SourceNode).hasPropertyWrite(prop, pred) or - // Note that this case is handled by globalPostUpdateStep in dataflow2 exists(GlobalVariable gv, File f | globalPropertyWrite(gv, f, prop, pred) and globalPropertyRead(gv, f, prop, succ) From 458f0a077cf06accfd2dc349c2f3e9e8ecaff1df Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 10:31:12 +0200 Subject: [PATCH 128/514] JS: Port InterProceduralFlow test All the new results are benign --- .../InterProceduralFlow/DataFlowConfig.qll | 12 ++--- .../InterProceduralFlow/async.js | 12 ++--- .../InterProceduralFlow/properties2.js | 2 +- .../InterProceduralFlow/tests.expected | 11 ++++ .../InterProceduralFlow/tests.ql | 53 +++++++++---------- 5 files changed, 49 insertions(+), 41 deletions(-) diff --git a/javascript/ql/test/library-tests/InterProceduralFlow/DataFlowConfig.qll b/javascript/ql/test/library-tests/InterProceduralFlow/DataFlowConfig.qll index 12edfc8b713..f47fd78c159 100644 --- a/javascript/ql/test/library-tests/InterProceduralFlow/DataFlowConfig.qll +++ b/javascript/ql/test/library-tests/InterProceduralFlow/DataFlowConfig.qll @@ -1,23 +1,21 @@ import javascript -class TestDataFlowConfiguration extends DataFlow::Configuration { - TestDataFlowConfiguration() { this = "TestDataFlowConfiguration" } - - override predicate isSource(DataFlow::Node src) { +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { exists(VariableDeclarator vd | vd.getBindingPattern().(VarDecl).getName().matches("%source%") and src.asExpr() = vd.getInit() ) } - override predicate isSink(DataFlow::Node snk) { + predicate isSink(DataFlow::Node snk) { exists(VariableDeclarator vd | vd.getBindingPattern().(VarDecl).getName().matches("%sink%") and snk.asExpr() = vd.getInit() ) } - override predicate isBarrier(DataFlow::Node node) { + predicate isBarrier(DataFlow::Node node) { exists(Function f | f.getName().matches("%noReturnTracking%") and node = f.getAReturnedExpr().flow() @@ -26,3 +24,5 @@ class TestDataFlowConfiguration extends DataFlow::Configuration { node.asExpr().(PropAccess).getPropertyName() = "notTracked" } } + +module TestFlow = DataFlow::Global; diff --git a/javascript/ql/test/library-tests/InterProceduralFlow/async.js b/javascript/ql/test/library-tests/InterProceduralFlow/async.js index f91cda9cea8..21b9cb4852e 100644 --- a/javascript/ql/test/library-tests/InterProceduralFlow/async.js +++ b/javascript/ql/test/library-tests/InterProceduralFlow/async.js @@ -11,7 +11,7 @@ return source; } let sink3 = sync(); // NOT OK - let sink4 = await sync(); // OK + let sink4 = await sync(); // NOT OK async function throwsAsync() { throw source; @@ -64,7 +64,7 @@ return x.x; } - var sink8 = unpack(pack(source)); // OK + var sink8 = unpack(pack(source)); // OK let sink9 = unpack(await (pack(source))); // NOT OK - but not found } })(); @@ -75,19 +75,19 @@ async function props() { p: x }; } - + let source = "source"; let sink = (await (foo(source))).p; // NOT OK - this requires the immidiatly awaited storeStep. let sink2 = foo("not a source").p; - + async function getP(base) { return base.p; } - + async function getQ(base) { return base.q; } - + let o3 = { p: source }; let sink6 = await (getP(o3)); // NOT OK - this requires the immidiatly awaited loadStep let sink7 = await (getQ(o3)); diff --git a/javascript/ql/test/library-tests/InterProceduralFlow/properties2.js b/javascript/ql/test/library-tests/InterProceduralFlow/properties2.js index 9f1b0c9ba07..83f0b701d10 100644 --- a/javascript/ql/test/library-tests/InterProceduralFlow/properties2.js +++ b/javascript/ql/test/library-tests/InterProceduralFlow/properties2.js @@ -14,7 +14,7 @@ function setP(base, rhs) { var o = {}; setP(o, source); -var sink3 = o.p; // flow from `source` not yet detected +var sink3 = o.p; var sink4 = o.q; var o2 = {}; diff --git a/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected b/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected index 2088e2c1ca2..7278acf7161 100644 --- a/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected +++ b/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected @@ -4,6 +4,7 @@ dataFlow | a.js:2:15:2:28 | "also tainted" | b.js:5:13:5:29 | notTaintedTrustMe | | async.js:2:16:2:23 | "source" | async.js:8:15:8:27 | await async() | | async.js:2:16:2:23 | "source" | async.js:13:15:13:20 | sync() | +| async.js:2:16:2:23 | "source" | async.js:14:15:14:26 | await sync() | | async.js:2:16:2:23 | "source" | async.js:27:17:27:17 | e | | async.js:2:16:2:23 | "source" | async.js:36:17:36:17 | e | | async.js:2:16:2:23 | "source" | async.js:41:17:41:17 | e | @@ -24,6 +25,7 @@ dataFlow | esLib.js:3:21:3:29 | "tainted" | nodeJsClient.js:5:13:5:21 | es.source | | global.js:1:15:1:24 | "tainted1" | global.js:9:13:9:22 | g(source1) | | global.js:1:15:1:24 | "tainted1" | global.js:17:13:17:27 | window.location | +| global.js:1:15:1:24 | "tainted1" | global.js:18:13:18:24 | win.location | | global.js:2:15:2:24 | "tainted2" | global.js:10:13:10:22 | g(source2) | | global.js:5:22:5:35 | "also tainted" | global.js:9:13:9:22 | g(source1) | | global.js:5:22:5:35 | "also tainted" | global.js:10:13:10:22 | g(source2) | @@ -55,7 +57,9 @@ dataFlow | promises.js:12:22:12:31 | "rejected" | promises.js:24:20:24:20 | v | | promises.js:32:24:32:37 | "also tainted" | promises.js:38:32:38:32 | v | | properties2.js:7:14:7:21 | "source" | properties2.js:8:12:8:24 | foo(source).p | +| properties2.js:7:14:7:21 | "source" | properties2.js:17:13:17:15 | o.p | | properties2.js:7:14:7:21 | "source" | properties2.js:33:13:33:20 | getP(o3) | +| properties2.js:7:14:7:21 | "source" | properties2.js:38:13:38:20 | getP(o4) | | properties.js:2:16:2:24 | "tainted" | properties.js:5:14:5:23 | a.someProp | | properties.js:2:16:2:24 | "tainted" | properties.js:12:15:12:24 | x.someProp | | properties.js:2:16:2:24 | "tainted" | properties.js:14:15:14:27 | tmp1.someProp | @@ -106,6 +110,7 @@ taintTracking | esLib.js:3:21:3:29 | "tainted" | nodeJsClient.js:5:13:5:21 | es.source | | global.js:1:15:1:24 | "tainted1" | global.js:9:13:9:22 | g(source1) | | global.js:1:15:1:24 | "tainted1" | global.js:17:13:17:27 | window.location | +| global.js:1:15:1:24 | "tainted1" | global.js:18:13:18:24 | win.location | | global.js:2:15:2:24 | "tainted2" | global.js:10:13:10:22 | g(source2) | | global.js:5:22:5:35 | "also tainted" | global.js:9:13:9:22 | g(source1) | | global.js:5:22:5:35 | "also tainted" | global.js:10:13:10:22 | g(source2) | @@ -140,7 +145,9 @@ taintTracking | promises.js:12:22:12:31 | "rejected" | promises.js:24:20:24:20 | v | | promises.js:32:24:32:37 | "also tainted" | promises.js:38:32:38:32 | v | | properties2.js:7:14:7:21 | "source" | properties2.js:8:12:8:24 | foo(source).p | +| properties2.js:7:14:7:21 | "source" | properties2.js:17:13:17:15 | o.p | | properties2.js:7:14:7:21 | "source" | properties2.js:33:13:33:20 | getP(o3) | +| properties2.js:7:14:7:21 | "source" | properties2.js:38:13:38:20 | getP(o4) | | properties.js:2:16:2:24 | "tainted" | properties.js:5:14:5:23 | a.someProp | | properties.js:2:16:2:24 | "tainted" | properties.js:12:15:12:24 | x.someProp | | properties.js:2:16:2:24 | "tainted" | properties.js:14:15:14:27 | tmp1.someProp | @@ -191,6 +198,7 @@ germanFlow | a.js:2:15:2:28 | "also tainted" | b.js:5:13:5:29 | notTaintedTrustMe | | async.js:2:16:2:23 | "source" | async.js:8:15:8:27 | await async() | | async.js:2:16:2:23 | "source" | async.js:13:15:13:20 | sync() | +| async.js:2:16:2:23 | "source" | async.js:14:15:14:26 | await sync() | | async.js:2:16:2:23 | "source" | async.js:27:17:27:17 | e | | async.js:2:16:2:23 | "source" | async.js:36:17:36:17 | e | | async.js:2:16:2:23 | "source" | async.js:41:17:41:17 | e | @@ -212,6 +220,7 @@ germanFlow | esLib.js:3:21:3:29 | "tainted" | nodeJsClient.js:5:13:5:21 | es.source | | global.js:1:15:1:24 | "tainted1" | global.js:9:13:9:22 | g(source1) | | global.js:1:15:1:24 | "tainted1" | global.js:17:13:17:27 | window.location | +| global.js:1:15:1:24 | "tainted1" | global.js:18:13:18:24 | win.location | | global.js:2:15:2:24 | "tainted2" | global.js:10:13:10:22 | g(source2) | | global.js:5:22:5:35 | "also tainted" | global.js:9:13:9:22 | g(source1) | | global.js:5:22:5:35 | "also tainted" | global.js:10:13:10:22 | g(source2) | @@ -243,7 +252,9 @@ germanFlow | promises.js:12:22:12:31 | "rejected" | promises.js:24:20:24:20 | v | | promises.js:32:24:32:37 | "also tainted" | promises.js:38:32:38:32 | v | | properties2.js:7:14:7:21 | "source" | properties2.js:8:12:8:24 | foo(source).p | +| properties2.js:7:14:7:21 | "source" | properties2.js:17:13:17:15 | o.p | | properties2.js:7:14:7:21 | "source" | properties2.js:33:13:33:20 | getP(o3) | +| properties2.js:7:14:7:21 | "source" | properties2.js:38:13:38:20 | getP(o4) | | properties.js:2:16:2:24 | "tainted" | properties.js:5:14:5:23 | a.someProp | | properties.js:2:16:2:24 | "tainted" | properties.js:12:15:12:24 | x.someProp | | properties.js:2:16:2:24 | "tainted" | properties.js:14:15:14:27 | tmp1.someProp | diff --git a/javascript/ql/test/library-tests/InterProceduralFlow/tests.ql b/javascript/ql/test/library-tests/InterProceduralFlow/tests.ql index a490c4c9146..e20ec8ff6d4 100644 --- a/javascript/ql/test/library-tests/InterProceduralFlow/tests.ql +++ b/javascript/ql/test/library-tests/InterProceduralFlow/tests.ql @@ -1,8 +1,7 @@ +import javascript import DataFlowConfig -query predicate dataFlow(DataFlow::Node src, DataFlow::Node snk) { - exists(TestDataFlowConfiguration tttc | tttc.hasFlow(src, snk)) -} +query predicate dataFlow(DataFlow::Node src, DataFlow::Node snk) { TestFlow::flow(src, snk) } class Parity extends DataFlow::FlowLabel { Parity() { this = "even" or this = "odd" } @@ -10,21 +9,21 @@ class Parity extends DataFlow::FlowLabel { Parity flip() { result != this } } -class FLowLabelConfig extends DataFlow::Configuration { - FLowLabelConfig() { this = "FLowLabelConfig" } +module FlowLabelConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; - override predicate isSource(DataFlow::Node nd, DataFlow::FlowLabel lbl) { + predicate isSource(DataFlow::Node nd, DataFlow::FlowLabel lbl) { nd.(DataFlow::CallNode).getCalleeName() = "source" and lbl = "even" } - override predicate isSink(DataFlow::Node nd, DataFlow::FlowLabel lbl) { + predicate isSink(DataFlow::Node nd, DataFlow::FlowLabel lbl) { nd = any(DataFlow::CallNode c | c.getCalleeName() = "sink").getAnArgument() and lbl = "even" } - override predicate isAdditionalFlowStep( - DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel predLabel, + predicate isAdditionalFlowStep( + DataFlow::Node pred, DataFlow::FlowLabel predLabel, DataFlow::Node succ, DataFlow::FlowLabel succLabel ) { exists(DataFlow::CallNode c | c = succ | @@ -35,28 +34,28 @@ class FLowLabelConfig extends DataFlow::Configuration { } } -query predicate flowLabels(DataFlow::PathNode source, DataFlow::PathNode sink) { - exists(FLowLabelConfig cfg | cfg.hasFlowPath(source, sink)) +module FlowLabelFlow = DataFlow::GlobalWithState; + +query predicate flowLabels(FlowLabelFlow::PathNode source, FlowLabelFlow::PathNode sink) { + FlowLabelFlow::flowPath(source, sink) } -class TestTaintTrackingConfiguration extends TaintTracking::Configuration { - TestTaintTrackingConfiguration() { this = "TestTaintTrackingConfiguration" } - - override predicate isSource(DataFlow::Node src) { +module TaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { exists(VariableDeclarator vd | vd.getBindingPattern().(VarDecl).getName().matches("%source%") and src.asExpr() = vd.getInit() ) } - override predicate isSink(DataFlow::Node snk) { + predicate isSink(DataFlow::Node snk) { exists(VariableDeclarator vd | vd.getBindingPattern().(VarDecl).getName().matches("%sink%") and snk.asExpr() = vd.getInit() ) } - override predicate isSanitizer(DataFlow::Node node) { + predicate isBarrier(DataFlow::Node node) { exists(Function f | f.getName().matches("%noReturnTracking%") and node = f.getAReturnedExpr().flow() @@ -66,14 +65,12 @@ class TestTaintTrackingConfiguration extends TaintTracking::Configuration { } } -query predicate taintTracking(DataFlow::Node src, DataFlow::Node snk) { - exists(TestTaintTrackingConfiguration tttc | tttc.hasFlow(src, snk)) -} +module TaintFlow = TaintTracking::Global; -class GermanFlowConfig extends DataFlow::Configuration { - GermanFlowConfig() { this = "GermanFlowConfig" } +query predicate taintTracking(DataFlow::Node src, DataFlow::Node snk) { TaintFlow::flow(src, snk) } - override predicate isSource(DataFlow::Node src) { +module GermanConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { exists(VariableDeclarator vd | vd.getBindingPattern().(VarDecl).getName().matches("%source%") and src.asExpr() = vd.getInit() @@ -82,7 +79,7 @@ class GermanFlowConfig extends DataFlow::Configuration { src.asExpr() = any(Variable v | v.getName() = "quelle").getAnAssignedExpr() } - override predicate isSink(DataFlow::Node snk) { + predicate isSink(DataFlow::Node snk) { exists(VariableDeclarator vd | vd.getBindingPattern().(VarDecl).getName().matches("%sink%") and snk.asExpr() = vd.getInit() @@ -91,7 +88,7 @@ class GermanFlowConfig extends DataFlow::Configuration { snk.asExpr() = any(Variable v | v.getName() = "abfluss").getAnAssignedExpr() } - override predicate isBarrier(DataFlow::Node node) { + predicate isBarrier(DataFlow::Node node) { exists(Function f | f.getName().matches("%noReturnTracking%") and node = f.getAReturnedExpr().flow() @@ -101,6 +98,6 @@ class GermanFlowConfig extends DataFlow::Configuration { } } -query predicate germanFlow(DataFlow::Node src, DataFlow::Node snk) { - exists(GermanFlowConfig tttc | tttc.hasFlow(src, snk)) -} +module GermanFlow = DataFlow::Global; + +query predicate germanFlow(DataFlow::Node src, DataFlow::Node snk) { GermanFlow::flow(src, snk) } From dd8a24c6c0e1be3516c2e8f4e4de5cb9b5e5ac17 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 10:33:27 +0200 Subject: [PATCH 129/514] JS: Port LabelledBarrierGuards test --- .../LabelledBarrierGuards.expected | 2 + .../LabelledBarrierGuards.ql | 46 ++++++++++++++++--- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/javascript/ql/test/library-tests/LabelledBarrierGuards/LabelledBarrierGuards.expected b/javascript/ql/test/library-tests/LabelledBarrierGuards/LabelledBarrierGuards.expected index c4ce68baa8b..4597c58babe 100644 --- a/javascript/ql/test/library-tests/LabelledBarrierGuards/LabelledBarrierGuards.expected +++ b/javascript/ql/test/library-tests/LabelledBarrierGuards/LabelledBarrierGuards.expected @@ -1,3 +1,5 @@ +legacyDataFlowDifference +#select | tst.js:2:11:2:18 | source() | tst.js:8:12:8:12 | x | | tst.js:2:11:2:18 | source() | tst.js:12:12:12:12 | x | | tst.js:2:11:2:18 | source() | tst.js:14:12:14:12 | x | diff --git a/javascript/ql/test/library-tests/LabelledBarrierGuards/LabelledBarrierGuards.ql b/javascript/ql/test/library-tests/LabelledBarrierGuards/LabelledBarrierGuards.ql index 002fafb8c2b..781db8026f3 100644 --- a/javascript/ql/test/library-tests/LabelledBarrierGuards/LabelledBarrierGuards.ql +++ b/javascript/ql/test/library-tests/LabelledBarrierGuards/LabelledBarrierGuards.ql @@ -4,15 +4,15 @@ class CustomFlowLabel extends DataFlow::FlowLabel { CustomFlowLabel() { this = "A" or this = "B" } } -class Config extends TaintTracking::Configuration { - Config() { this = "Config" } +module TestConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; - override predicate isSource(DataFlow::Node node, DataFlow::FlowLabel lbl) { + predicate isSource(DataFlow::Node node, DataFlow::FlowLabel lbl) { node.(DataFlow::CallNode).getCalleeName() = "source" and lbl instanceof CustomFlowLabel } - override predicate isSink(DataFlow::Node node, DataFlow::FlowLabel lbl) { + predicate isSink(DataFlow::Node node, DataFlow::FlowLabel lbl) { exists(DataFlow::CallNode call | call.getCalleeName() = "sink" and node = call.getAnArgument() and @@ -20,10 +20,32 @@ class Config extends TaintTracking::Configuration { ) } - override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode node) { + additional predicate isBarrierGuard(DataFlow::BarrierGuardNode node) { node instanceof IsTypeAGuard or node instanceof IsSanitizedGuard } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel lbl) { + node = DataFlow::MakeLegacyBarrierGuardLabeled::getABarrierNode(lbl) + } +} + +module TestFlow = TaintTracking::GlobalWithState; + +class LegacyConfig extends TaintTracking::Configuration { + LegacyConfig() { this = "LegacyConfig" } + + override predicate isSource(DataFlow::Node node, DataFlow::FlowLabel lbl) { + TestConfig::isSource(node, lbl) + } + + override predicate isSink(DataFlow::Node node, DataFlow::FlowLabel lbl) { + TestConfig::isSink(node, lbl) + } + + override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode node) { + TestConfig::isBarrierGuard(node) + } } /** @@ -34,6 +56,10 @@ class IsTypeAGuard extends TaintTracking::LabeledSanitizerGuardNode, DataFlow::C IsTypeAGuard() { this.getCalleeName() = "isTypeA" } override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { + this.blocksExpr(outcome, e, lbl) + } + + predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { e = this.getArgument(0).asExpr() and ( outcome = true and lbl = "B" @@ -47,6 +73,10 @@ class IsSanitizedGuard extends TaintTracking::LabeledSanitizerGuardNode, DataFlo IsSanitizedGuard() { this.getCalleeName() = "sanitizeA" or this.getCalleeName() = "sanitizeB" } override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { + this.blocksExpr(outcome, e, lbl) + } + + predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { e = this.getArgument(0).asExpr() and outcome = true and ( @@ -57,6 +87,8 @@ class IsSanitizedGuard extends TaintTracking::LabeledSanitizerGuardNode, DataFlo } } -from Config cfg, DataFlow::Node source, DataFlow::Node sink -where cfg.hasFlow(source, sink) +import testUtilities.LegacyDataFlowDiff::DataFlowDiff + +from DataFlow::Node source, DataFlow::Node sink +where TestFlow::flow(source, sink) select source, sink From 81bd292a161602b6709ada5ba0b43a82e582de2d Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 10:39:19 +0200 Subject: [PATCH 130/514] JS: Port Promises test Result changes are benign --- .../ql/test/library-tests/Promises/flow.js | 2 +- .../ql/test/library-tests/Promises/flow.qll | 49 +++++++++++++------ .../ql/test/library-tests/Promises/flow2.js | 8 +-- .../library-tests/Promises/tests.expected | 6 ++- 4 files changed, 45 insertions(+), 20 deletions(-) diff --git a/javascript/ql/test/library-tests/Promises/flow.js b/javascript/ql/test/library-tests/Promises/flow.js index 81af660561a..189e870fcee 100644 --- a/javascript/ql/test/library-tests/Promises/flow.js +++ b/javascript/ql/test/library-tests/Promises/flow.js @@ -65,7 +65,7 @@ await new Promise((resolve, reject) => reject(source)); } try { - throws(); + await throws(); } catch(e) { sink(e); // NOT OK! } diff --git a/javascript/ql/test/library-tests/Promises/flow.qll b/javascript/ql/test/library-tests/Promises/flow.qll index 94c2af70674..90069773b45 100644 --- a/javascript/ql/test/library-tests/Promises/flow.qll +++ b/javascript/ql/test/library-tests/Promises/flow.qll @@ -1,39 +1,60 @@ import javascript private import semmle.javascript.dataflow.internal.StepSummary +import testUtilities.LegacyDataFlowDiff -class Configuration extends DataFlow::Configuration { - Configuration() { this = "PromiseDataFlowFlowTestingConfig" } - - override predicate isSource(DataFlow::Node source) { +module ValueFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.getEnclosingExpr().getStringValue() = "source" } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { any(DataFlow::InvokeNode call | call.getCalleeName() = "sink").getAnArgument() = sink } } -class TaintConfig extends TaintTracking::Configuration { - TaintConfig() { this = "PromiseTaintFlowTestingConfig" } +module ValueFlow = DataFlow::Global; - override predicate isSource(DataFlow::Node source) { +module TaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.getEnclosingExpr().getStringValue() = "source" } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { any(DataFlow::InvokeNode call | call.getCalleeName() = "sink").getAnArgument() = sink } } -query predicate flow(DataFlow::Node source, DataFlow::Node sink) { - any(Configuration c).hasFlow(source, sink) -} +module TaintFlow = TaintTracking::Global; + +query predicate flow(DataFlow::Node source, DataFlow::Node sink) { ValueFlow::flow(source, sink) } query predicate exclusiveTaintFlow(DataFlow::Node source, DataFlow::Node sink) { - not any(Configuration c).hasFlow(source, sink) and - any(TaintConfig c).hasFlow(source, sink) + not ValueFlow::flow(source, sink) and + TaintFlow::flow(source, sink) } query predicate typetrack(DataFlow::SourceNode succ, DataFlow::SourceNode pred, StepSummary summary) { succ = PromiseTypeTracking::promiseStep(pred, summary) } + +class LegacyValueConfig extends DataFlow::Configuration { + LegacyValueConfig() { this = "LegacyValueConfig" } + + override predicate isSource(DataFlow::Node source) { ValueFlowConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { ValueFlowConfig::isSink(sink) } +} + +query predicate valueFlowDifference = + DataFlowDiff::legacyDataFlowDifference/3; + +class LegacyTaintConfig extends TaintTracking::Configuration { + LegacyTaintConfig() { this = "LegacyTaintConfig" } + + override predicate isSource(DataFlow::Node source) { TaintConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TaintConfig::isSink(sink) } +} + +query predicate taintFlowDifference = + DataFlowDiff::legacyDataFlowDifference/3; diff --git a/javascript/ql/test/library-tests/Promises/flow2.js b/javascript/ql/test/library-tests/Promises/flow2.js index ccafb83fd3f..87994bd8245 100644 --- a/javascript/ql/test/library-tests/Promises/flow2.js +++ b/javascript/ql/test/library-tests/Promises/flow2.js @@ -17,11 +17,11 @@ var [clean3, tainted3] = await Promise.all(["clean", Promise.resolve(source)]); sink(clean3); // OK - sink(tainted3); // NOT OK - but only flagged by taint-tracking + sink(tainted3); // NOT OK var tainted4 = await Promise.race(["clean", Promise.resolve(source)]); - sink(tainted4); // NOT OK - but only flagged by taint-tracking + sink(tainted4); // NOT OK var tainted5 = await Promise.any(["clean", Promise.resolve(source)]); - sink(tainted5); // NOT OK - but only flagged by taint-tracking -}); \ No newline at end of file + sink(tainted5); // NOT OK +}); diff --git a/javascript/ql/test/library-tests/Promises/tests.expected b/javascript/ql/test/library-tests/Promises/tests.expected index c600ce91be4..b20e828c472 100644 --- a/javascript/ql/test/library-tests/Promises/tests.expected +++ b/javascript/ql/test/library-tests/Promises/tests.expected @@ -237,6 +237,7 @@ flow | flow2.js:2:15:2:22 | "source" | flow2.js:6:8:6:13 | arr[0] | | flow2.js:2:15:2:22 | "source" | flow2.js:12:7:12:13 | tainted | | flow2.js:2:15:2:22 | "source" | flow2.js:16:7:16:14 | tainted2 | +| flow2.js:2:15:2:22 | "source" | flow2.js:20:7:20:14 | tainted3 | | flow2.js:2:15:2:22 | "source" | flow2.js:23:7:23:14 | tainted4 | | flow2.js:2:15:2:22 | "source" | flow2.js:26:7:26:14 | tainted5 | | flow.js:2:15:2:22 | "source" | flow.js:5:7:5:14 | await p1 | @@ -273,7 +274,6 @@ flow | flow.js:136:15:136:22 | "source" | flow.js:142:7:142:19 | await async() | | flow.js:136:15:136:22 | "source" | flow.js:155:9:155:9 | e | exclusiveTaintFlow -| flow2.js:2:15:2:22 | "source" | flow2.js:20:7:20:14 | tainted3 | | flow.js:136:15:136:22 | "source" | flow.js:141:7:141:13 | async() | | flow.js:160:15:160:22 | "source" | flow.js:164:39:164:39 | x | | flow.js:160:15:160:22 | "source" | flow.js:167:7:167:9 | foo | @@ -367,6 +367,7 @@ typetrack | flow.js:62:2:62:24 | p12.cat ... ink(x)) | flow.js:62:17:62:23 | sink(x) | copy $PromiseResolveField$ | | flow.js:62:2:62:24 | p12.cat ... ink(x)) | flow.js:62:17:62:23 | sink(x) | store $PromiseResolveField$ | | flow.js:65:3:65:56 | await n ... ource)) | flow.js:65:9:65:56 | new Pro ... ource)) | load $PromiseResolveField$ | +| flow.js:68:3:68:16 | await throws() | flow.js:68:9:68:16 | throws() | load $PromiseResolveField$ | | flow.js:76:2:76:52 | chained ... ink(e)) | flow.js:76:2:76:32 | chained ... => {}) | copy $PromiseResolveField$ | | flow.js:76:2:76:52 | chained ... ink(e)) | flow.js:76:45:76:51 | sink(e) | copy $PromiseResolveField$ | | flow.js:76:2:76:52 | chained ... ink(e)) | flow.js:76:45:76:51 | sink(e) | store $PromiseResolveField$ | @@ -462,3 +463,6 @@ typetrack | promises.js:143:17:143:50 | Synchro ... source) | promises.js:143:44:143:49 | source | store $PromiseResolveField$ | | promises.js:153:17:153:39 | Promise ... source) | promises.js:153:33:153:38 | source | copy $PromiseResolveField$ | | promises.js:153:17:153:39 | Promise ... source) | promises.js:153:33:153:38 | source | store $PromiseResolveField$ | +valueFlowDifference +| flow2.js:2:15:2:22 | "source" | flow2.js:20:7:20:14 | tainted3 | only flow with NEW data flow library | +taintFlowDifference From 98d1bb382619b65972f312ba8bafd98d1c1ca78d Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 10:39:59 +0200 Subject: [PATCH 131/514] JS: Reorder result sets in a test (trivial change) --- .../library-tests/Promises/tests.expected | 122 +++++++++--------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/javascript/ql/test/library-tests/Promises/tests.expected b/javascript/ql/test/library-tests/Promises/tests.expected index b20e828c472..1b0d5466281 100644 --- a/javascript/ql/test/library-tests/Promises/tests.expected +++ b/javascript/ql/test/library-tests/Promises/tests.expected @@ -1,3 +1,40 @@ +test_PromiseDefinition +| flow.js:7:11:7:59 | new Pro ... ource)) | +| flow.js:10:11:10:58 | new Pro ... ource)) | +| flow.js:13:11:13:58 | new Pro ... ource)) | +| flow.js:24:2:24:49 | new Pro ... ource)) | +| flow.js:26:2:26:49 | new Pro ... ource)) | +| flow.js:32:2:32:49 | new Pro ... ource)) | +| flow.js:40:2:40:49 | new Pro ... ource)) | +| flow.js:42:2:42:49 | new Pro ... ource)) | +| flow.js:48:2:48:36 | new Pro ... urce }) | +| flow.js:55:11:55:58 | new Pro ... ource)) | +| flow.js:60:12:60:59 | new Pro ... ource)) | +| flow.js:65:9:65:56 | new Pro ... ource)) | +| flow.js:74:10:74:57 | new Pro ... ource)) | +| flow.js:86:23:86:70 | new Pro ... ource)) | +| flow.js:91:21:91:68 | new Pro ... ource)) | +| flow.js:100:34:100:81 | new Pro ... ource)) | +| flow.js:103:2:103:48 | new Pro ... "BLA")) | +| flow.js:105:2:105:48 | new Pro ... "BLA")) | +| flow.js:107:17:107:64 | new Pro ... ource)) | +| flow.js:109:2:109:48 | new Pro ... "BLA")) | +| flow.js:111:2:111:48 | new Pro ... "BLA")) | +| flow.js:113:2:113:48 | new Pro ... "BLA")) | +| flow.js:117:2:117:48 | new Pro ... "BLA")) | +| flow.js:119:2:119:48 | new Pro ... "BLA")) | +| flow.js:129:2:129:52 | new Pro ... olved)) | +| interflow.js:11:12:15:6 | new Pro ... \\n }) | +| promises.js:3:17:5:4 | new Pro ... );\\n }) | +| promises.js:10:18:17:4 | new Pro ... );\\n }) | +| promises.js:33:19:35:6 | new Pro ... \\n }) | +| promises.js:43:19:45:6 | Q.Promi ... \\n }) | +| promises.js:88:17:90:4 | Q.Promi ... );\\n }) | +| promises.js:112:17:112:62 | new RSV ... ct) {}) | +| promises.js:124:19:124:30 | when(source) | +| promises.js:130:14:130:69 | new Pro ... s'); }) | +| promises.js:135:3:137:4 | new Pro ... );\\n }) | +| promises.js:148:10:148:49 | new Pro ... ect){}) | test_ResolvedPromiseDefinition | flow2.js:4:2:4:31 | Promise ... lean"]) | flow2.js:4:15:4:20 | source | | flow2.js:4:2:4:31 | Promise ... lean"]) | flow2.js:4:23:4:29 | "clean" | @@ -45,21 +82,6 @@ test_ResolvedPromiseDefinition | promises.js:125:20:125:39 | when.resolve(source) | promises.js:125:33:125:38 | source | | promises.js:143:17:143:50 | Synchro ... source) | promises.js:143:44:143:49 | source | | promises.js:153:17:153:39 | Promise ... source) | promises.js:153:33:153:38 | source | -test_PromiseDefinition_getARejectHandler -| flow.js:26:2:26:49 | new Pro ... ource)) | flow.js:26:69:26:80 | y => sink(y) | -| flow.js:32:2:32:49 | new Pro ... ource)) | flow.js:32:57:32:68 | x => sink(x) | -| flow.js:42:2:42:49 | new Pro ... ource)) | flow.js:42:67:42:75 | () => { } | -| flow.js:48:2:48:36 | new Pro ... urce }) | flow.js:48:44:48:55 | x => sink(x) | -| flow.js:103:2:103:48 | new Pro ... "BLA")) | flow.js:103:56:103:75 | x => {return source} | -| flow.js:105:2:105:48 | new Pro ... "BLA")) | flow.js:105:58:105:76 | x => {throw source} | -| flow.js:109:2:109:48 | new Pro ... "BLA")) | flow.js:109:58:109:70 | x => rejected | -| flow.js:111:2:111:48 | new Pro ... "BLA")) | flow.js:111:56:111:68 | x => rejected | -| flow.js:113:2:113:48 | new Pro ... "BLA")) | flow.js:113:56:113:68 | x => rejected | -| flow.js:117:2:117:48 | new Pro ... "BLA")) | flow.js:117:56:117:68 | x => resolved | -| flow.js:119:2:119:48 | new Pro ... "BLA")) | flow.js:119:56:119:68 | x => resolved | -| promises.js:10:18:17:4 | new Pro ... );\\n }) | promises.js:20:6:22:3 | (v) => ... v;\\n } | -| promises.js:10:18:17:4 | new Pro ... );\\n }) | promises.js:23:18:25:3 | (v) => ... v;\\n } | -| promises.js:10:18:17:4 | new Pro ... );\\n }) | promises.js:26:20:28:3 | (v) => ... v;\\n } | test_PromiseDefinition_getExecutor | flow.js:7:11:7:59 | new Pro ... ource)) | flow.js:7:23:7:58 | (resolv ... source) | | flow.js:10:11:10:58 | new Pro ... ource)) | flow.js:10:23:10:57 | (resolv ... source) | @@ -96,47 +118,34 @@ test_PromiseDefinition_getExecutor | promises.js:130:14:130:69 | new Pro ... s'); }) | promises.js:130:26:130:68 | functio ... ns'); } | | promises.js:135:3:137:4 | new Pro ... );\\n }) | promises.js:135:15:137:3 | functio ... a);\\n } | | promises.js:148:10:148:49 | new Pro ... ect){}) | promises.js:148:22:148:48 | functio ... ject){} | +test_PromiseDefinition_getACatchHandler +| flow.js:32:2:32:49 | new Pro ... ource)) | flow.js:32:57:32:68 | x => sink(x) | +| flow.js:48:2:48:36 | new Pro ... urce }) | flow.js:48:44:48:55 | x => sink(x) | +| flow.js:103:2:103:48 | new Pro ... "BLA")) | flow.js:103:56:103:75 | x => {return source} | +| flow.js:111:2:111:48 | new Pro ... "BLA")) | flow.js:111:56:111:68 | x => rejected | +| flow.js:113:2:113:48 | new Pro ... "BLA")) | flow.js:113:56:113:68 | x => rejected | +| flow.js:117:2:117:48 | new Pro ... "BLA")) | flow.js:117:56:117:68 | x => resolved | +| flow.js:119:2:119:48 | new Pro ... "BLA")) | flow.js:119:56:119:68 | x => resolved | +| promises.js:10:18:17:4 | new Pro ... );\\n }) | promises.js:23:18:25:3 | (v) => ... v;\\n } | +test_PromiseDefinition_getARejectHandler +| flow.js:26:2:26:49 | new Pro ... ource)) | flow.js:26:69:26:80 | y => sink(y) | +| flow.js:32:2:32:49 | new Pro ... ource)) | flow.js:32:57:32:68 | x => sink(x) | +| flow.js:42:2:42:49 | new Pro ... ource)) | flow.js:42:67:42:75 | () => { } | +| flow.js:48:2:48:36 | new Pro ... urce }) | flow.js:48:44:48:55 | x => sink(x) | +| flow.js:103:2:103:48 | new Pro ... "BLA")) | flow.js:103:56:103:75 | x => {return source} | +| flow.js:105:2:105:48 | new Pro ... "BLA")) | flow.js:105:58:105:76 | x => {throw source} | +| flow.js:109:2:109:48 | new Pro ... "BLA")) | flow.js:109:58:109:70 | x => rejected | +| flow.js:111:2:111:48 | new Pro ... "BLA")) | flow.js:111:56:111:68 | x => rejected | +| flow.js:113:2:113:48 | new Pro ... "BLA")) | flow.js:113:56:113:68 | x => rejected | +| flow.js:117:2:117:48 | new Pro ... "BLA")) | flow.js:117:56:117:68 | x => resolved | +| flow.js:119:2:119:48 | new Pro ... "BLA")) | flow.js:119:56:119:68 | x => resolved | +| promises.js:10:18:17:4 | new Pro ... );\\n }) | promises.js:20:6:22:3 | (v) => ... v;\\n } | +| promises.js:10:18:17:4 | new Pro ... );\\n }) | promises.js:23:18:25:3 | (v) => ... v;\\n } | +| promises.js:10:18:17:4 | new Pro ... );\\n }) | promises.js:26:20:28:3 | (v) => ... v;\\n } | test_PromiseDefinition_getAFinallyHandler | flow.js:105:2:105:48 | new Pro ... "BLA")) | flow.js:105:58:105:76 | x => {throw source} | | flow.js:109:2:109:48 | new Pro ... "BLA")) | flow.js:109:58:109:70 | x => rejected | | promises.js:10:18:17:4 | new Pro ... );\\n }) | promises.js:26:20:28:3 | (v) => ... v;\\n } | -test_PromiseDefinition -| flow.js:7:11:7:59 | new Pro ... ource)) | -| flow.js:10:11:10:58 | new Pro ... ource)) | -| flow.js:13:11:13:58 | new Pro ... ource)) | -| flow.js:24:2:24:49 | new Pro ... ource)) | -| flow.js:26:2:26:49 | new Pro ... ource)) | -| flow.js:32:2:32:49 | new Pro ... ource)) | -| flow.js:40:2:40:49 | new Pro ... ource)) | -| flow.js:42:2:42:49 | new Pro ... ource)) | -| flow.js:48:2:48:36 | new Pro ... urce }) | -| flow.js:55:11:55:58 | new Pro ... ource)) | -| flow.js:60:12:60:59 | new Pro ... ource)) | -| flow.js:65:9:65:56 | new Pro ... ource)) | -| flow.js:74:10:74:57 | new Pro ... ource)) | -| flow.js:86:23:86:70 | new Pro ... ource)) | -| flow.js:91:21:91:68 | new Pro ... ource)) | -| flow.js:100:34:100:81 | new Pro ... ource)) | -| flow.js:103:2:103:48 | new Pro ... "BLA")) | -| flow.js:105:2:105:48 | new Pro ... "BLA")) | -| flow.js:107:17:107:64 | new Pro ... ource)) | -| flow.js:109:2:109:48 | new Pro ... "BLA")) | -| flow.js:111:2:111:48 | new Pro ... "BLA")) | -| flow.js:113:2:113:48 | new Pro ... "BLA")) | -| flow.js:117:2:117:48 | new Pro ... "BLA")) | -| flow.js:119:2:119:48 | new Pro ... "BLA")) | -| flow.js:129:2:129:52 | new Pro ... olved)) | -| interflow.js:11:12:15:6 | new Pro ... \\n }) | -| promises.js:3:17:5:4 | new Pro ... );\\n }) | -| promises.js:10:18:17:4 | new Pro ... );\\n }) | -| promises.js:33:19:35:6 | new Pro ... \\n }) | -| promises.js:43:19:45:6 | Q.Promi ... \\n }) | -| promises.js:88:17:90:4 | Q.Promi ... );\\n }) | -| promises.js:112:17:112:62 | new RSV ... ct) {}) | -| promises.js:124:19:124:30 | when(source) | -| promises.js:130:14:130:69 | new Pro ... s'); }) | -| promises.js:135:3:137:4 | new Pro ... );\\n }) | -| promises.js:148:10:148:49 | new Pro ... ect){}) | test_PromiseDefinition_getAResolveHandler | flow.js:24:2:24:49 | new Pro ... ource)) | flow.js:24:56:24:67 | x => sink(x) | | flow.js:26:2:26:49 | new Pro ... ource)) | flow.js:26:56:26:66 | x => foo(x) | @@ -224,15 +233,6 @@ test_PromiseDefinition_getResolveParameter | promises.js:130:14:130:69 | new Pro ... s'); }) | promises.js:130:36:130:42 | resolve | | promises.js:135:3:137:4 | new Pro ... );\\n }) | promises.js:135:25:135:31 | resolve | | promises.js:148:10:148:49 | new Pro ... ect){}) | promises.js:148:31:148:37 | resolve | -test_PromiseDefinition_getACatchHandler -| flow.js:32:2:32:49 | new Pro ... ource)) | flow.js:32:57:32:68 | x => sink(x) | -| flow.js:48:2:48:36 | new Pro ... urce }) | flow.js:48:44:48:55 | x => sink(x) | -| flow.js:103:2:103:48 | new Pro ... "BLA")) | flow.js:103:56:103:75 | x => {return source} | -| flow.js:111:2:111:48 | new Pro ... "BLA")) | flow.js:111:56:111:68 | x => rejected | -| flow.js:113:2:113:48 | new Pro ... "BLA")) | flow.js:113:56:113:68 | x => rejected | -| flow.js:117:2:117:48 | new Pro ... "BLA")) | flow.js:117:56:117:68 | x => resolved | -| flow.js:119:2:119:48 | new Pro ... "BLA")) | flow.js:119:56:119:68 | x => resolved | -| promises.js:10:18:17:4 | new Pro ... );\\n }) | promises.js:23:18:25:3 | (v) => ... v;\\n } | flow | flow2.js:2:15:2:22 | "source" | flow2.js:6:8:6:13 | arr[0] | | flow2.js:2:15:2:22 | "source" | flow2.js:12:7:12:13 | tainted | From 2364bd84e06b242fa549a8c59adf3829fa4cb605 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 10:40:11 +0200 Subject: [PATCH 132/514] JS: Fix whitespace in a test (trivial change) --- .../ql/test/library-tests/Promises/flow.js | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/javascript/ql/test/library-tests/Promises/flow.js b/javascript/ql/test/library-tests/Promises/flow.js index 189e870fcee..52c8f512a1f 100644 --- a/javascript/ql/test/library-tests/Promises/flow.js +++ b/javascript/ql/test/library-tests/Promises/flow.js @@ -51,7 +51,7 @@ return Promise.resolve(src); } createPromise(source).then(v => sink(v)); // NOT OK! - + var p8 = new Promise((resolve, reject) => reject(source)); var p9 = p8.then(() => {}); var p10 = p9.finally(() => {}); @@ -69,27 +69,27 @@ } catch(e) { sink(e); // NOT OK! } - + function chainedPromise() { return new Promise((resolve, reject) => reject(source)).then(() => {}); } chainedPromise().then(() => {}).catch(e => sink(e)); // NOT OK! - + function leaksResolvedPromise(p) { p.then(x => sink(x)); // NOT OK! } leaksResolvedPromise(Promise.resolve(source)); - + function leaksRejectedPromise(p) { p.catch(e => sink(e)); // NOT OK! } leaksRejectedPromise(new Promise((resolve, reject) => reject(source))); - + function leaksRejectedAgain(p) { ("foo", p).then(() => {}).catch(e => sink(e)); // NOT OK! } leaksRejectedAgain(new Promise((resolve, reject) => reject(source)).then(() => {})); - + async function returnsRejected(p) { try { await p; @@ -99,48 +99,48 @@ } var foo = await returnsRejected(new Promise((resolve, reject) => reject(source))); sink(foo); // NOT OK! - + new Promise((resolve, reject) => reject("BLA")).catch(x => {return source}).then(x => sink(x)); // NOT OK - + new Promise((resolve, reject) => reject("BLA")).finally(x => {throw source}).catch(x => sink(x)); // NOT OK - + var rejected = new Promise((resolve, reject) => reject(source)); - + new Promise((resolve, reject) => reject("BLA")).finally(x => rejected).catch(x => sink(x)); // NOT OK - + new Promise((resolve, reject) => reject("BLA")).catch(x => rejected).then(x => sink(x)) // OK - + new Promise((resolve, reject) => reject("BLA")).catch(x => rejected).catch(x => sink(x)) // NOT OK - + var resolved = Promise.resolve(source); - + new Promise((resolve, reject) => reject("BLA")).catch(x => resolved).catch(x => sink(x)) // OK - + new Promise((resolve, reject) => reject("BLA")).catch(x => resolved).then(x => sink(x)) // NOT OK - + Promise.resolve(123).then(x => resolved).catch(x => sink(x)) // OK - + Promise.resolve(123).then(x => resolved).then(x => sink(x)) // NOT OK - + Promise.resolve(123).then(x => rejected).catch(x => sink(x)) // NOT OK - + Promise.resolve(123).then(x => rejected).then(x => sink(x)) // OK - + new Promise((resolve, reject) => resolve(resolved)).then(x => sink(x)); // NOT OK - + Promise.resolve(resolved).then(x => sink(x)); // NOT OK })(); (async function () { var source = "source"; - + async function async() { return source; } sink(async()); // OK - wrapped in a promise. (NOT OK for taint-tracking configs) sink(await async()); // NOT OK - + async function throwsAsync() { throw source; } @@ -165,4 +165,4 @@ const foo = bluebird.mapSeries(source, x => x); sink(foo); // NOT OK (for taint-tracking configs) -}) \ No newline at end of file +}) From 771519bbc5e7320fb7ea5520cfff9d3e02d1285e Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 10:41:29 +0200 Subject: [PATCH 133/514] JS: Port Routing test --- .../test/library-tests/Routing/test.expected | 2 ++ .../ql/test/library-tests/Routing/test.ql | 26 +++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/javascript/ql/test/library-tests/Routing/test.expected b/javascript/ql/test/library-tests/Routing/test.expected index e69de29bb2d..d65d51bc417 100644 --- a/javascript/ql/test/library-tests/Routing/test.expected +++ b/javascript/ql/test/library-tests/Routing/test.expected @@ -0,0 +1,2 @@ +legacyDataFlowDifference +consistencyIssue diff --git a/javascript/ql/test/library-tests/Routing/test.ql b/javascript/ql/test/library-tests/Routing/test.ql index b427f710894..6a97d040bb9 100644 --- a/javascript/ql/test/library-tests/Routing/test.ql +++ b/javascript/ql/test/library-tests/Routing/test.ql @@ -3,18 +3,34 @@ import testUtilities.ConsistencyChecking API::Node testInstance() { result = API::moduleImport("@example/test").getInstance() } -class Taint extends TaintTracking::Configuration { - Taint() { this = "Taint" } - - override predicate isSource(DataFlow::Node node) { +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node.(DataFlow::CallNode).getCalleeName() = "source" or node = testInstance().getMember("getSource").getReturn().asSource() } - override predicate isSink(DataFlow::Node node) { + predicate isSink(DataFlow::Node node) { node = any(DataFlow::CallNode call | call.getCalleeName() = "sink").getAnArgument() or node = testInstance().getMember("getSink").getAParameter().asSink() } } + +module TestFlow = TaintTracking::Global; + +class Consistency extends ConsistencyConfiguration { + Consistency() { this = "Consistency" } + + override DataFlow::Node getAnAlert() { TestFlow::flowTo(result) } +} + +class LegacyConfig extends TaintTracking::Configuration { + LegacyConfig() { this = "LegacyConfig" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } +} + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff From e5946bf43bc33df242d55b0c3339c557c9fd2aeb Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 10:43:07 +0200 Subject: [PATCH 134/514] JS: Port HeuristicSource test --- .../heuristics/HeuristicSource.expected | 2 ++ .../Security/heuristics/HeuristicSource.ql | 26 +++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.expected b/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.expected index e69de29bb2d..d65d51bc417 100644 --- a/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.expected +++ b/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.expected @@ -0,0 +1,2 @@ +legacyDataFlowDifference +consistencyIssue diff --git a/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.ql b/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.ql index 72d94707e6b..44258ecb6ff 100644 --- a/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.ql +++ b/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.ql @@ -2,12 +2,28 @@ import javascript private import semmle.javascript.heuristics.AdditionalSources import testUtilities.ConsistencyChecking -class Taint extends TaintTracking::Configuration { - Taint() { this = "Taint" } +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node instanceof HeuristicSource } - override predicate isSource(DataFlow::Node node) { node instanceof HeuristicSource } - - override predicate isSink(DataFlow::Node node) { + predicate isSink(DataFlow::Node node) { node = any(DataFlow::CallNode call | call.getCalleeName() = "sink").getAnArgument() } } + +module TestFlow = TaintTracking::Global; + +class Consistency extends ConsistencyConfiguration { + Consistency() { this = "Consistency" } + + override DataFlow::Node getAnAlert() { TestFlow::flowTo(result) } +} + +class LegacyConfig extends TaintTracking::Configuration { + LegacyConfig() { this = "LegacyConfig" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } +} + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff From 6c9f4a10acb7dfaedf76f34203513cd15923d88c Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 10:45:57 +0200 Subject: [PATCH 135/514] JS: Port TaintBarriers test --- .../TaintBarriers/ExampleConfiguration.qll | 37 ++++++++++++++----- .../TaintBarriers/tests.expected | 1 + .../test/library-tests/TaintBarriers/tests.ql | 4 +- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/javascript/ql/test/library-tests/TaintBarriers/ExampleConfiguration.qll b/javascript/ql/test/library-tests/TaintBarriers/ExampleConfiguration.qll index 50ac0fbfd24..56217573da8 100644 --- a/javascript/ql/test/library-tests/TaintBarriers/ExampleConfiguration.qll +++ b/javascript/ql/test/library-tests/TaintBarriers/ExampleConfiguration.qll @@ -6,16 +6,14 @@ StringOps::ConcatenationRoot sinkConcatenation() { result.getConstantStringParts().matches("%") } -class ExampleConfiguration extends TaintTracking::Configuration { - ExampleConfiguration() { this = "ExampleConfiguration" } - - override predicate isSource(DataFlow::Node source) { +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr().(CallExpr).getCalleeName() = "SOURCE" or source = sourceVariable() } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(CallExpr callExpr | callExpr.getCalleeName() = "SINK" and DataFlow::valueNode(callExpr.getArgument(0)) = sink @@ -24,19 +22,40 @@ class ExampleConfiguration extends TaintTracking::Configuration { sink = sinkConcatenation() } - override predicate isSanitizerIn(DataFlow::Node node) { node = sourceVariable() } + predicate isBarrierIn(DataFlow::Node node) { node = sourceVariable() } - override predicate isSanitizerOut(DataFlow::Node node) { node = sinkConcatenation() } + predicate isBarrierOut(DataFlow::Node node) { node = sinkConcatenation() } - override predicate isSanitizer(DataFlow::Node node) { + additional predicate isBarrier1(DataFlow::Node node) { exists(CallExpr callExpr | callExpr.getCalleeName() = "SANITIZE" and DataFlow::valueNode(callExpr.getArgument(0)) = node ) } + predicate isBarrier(DataFlow::Node node) { + isBarrier1(node) + or + node = TaintTracking::AdHocWhitelistCheckSanitizer::getABarrierNode() + } +} + +module TestFlow = TaintTracking::Global; + +class ExampleConfiguration extends TaintTracking::Configuration { + ExampleConfiguration() { this = "ExampleConfiguration" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } + + override predicate isSanitizerIn(DataFlow::Node node) { TestConfig::isBarrierIn(node) } + + override predicate isSanitizerOut(DataFlow::Node node) { TestConfig::isBarrierOut(node) } + + override predicate isSanitizer(DataFlow::Node node) { TestConfig::isBarrier1(node) } + override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) { - // add additional generic sanitizers guard instanceof TaintTracking::AdHocWhitelistCheckSanitizer } } diff --git a/javascript/ql/test/library-tests/TaintBarriers/tests.expected b/javascript/ql/test/library-tests/TaintBarriers/tests.expected index 4417a918423..32731bbcb7a 100644 --- a/javascript/ql/test/library-tests/TaintBarriers/tests.expected +++ b/javascript/ql/test/library-tests/TaintBarriers/tests.expected @@ -1,3 +1,4 @@ +legacyDataFlowDifference isBarrier isLabeledBarrier | ExampleConfiguration | tst.js:6:14:6:14 | v | taint | diff --git a/javascript/ql/test/library-tests/TaintBarriers/tests.ql b/javascript/ql/test/library-tests/TaintBarriers/tests.ql index d63d67cf6b1..0feeae23a64 100644 --- a/javascript/ql/test/library-tests/TaintBarriers/tests.ql +++ b/javascript/ql/test/library-tests/TaintBarriers/tests.ql @@ -16,5 +16,7 @@ query predicate sanitizingGuard(TaintTracking::SanitizerGuardNode g, Expr e, boo } query predicate taintedSink(DataFlow::Node source, DataFlow::Node sink) { - exists(ExampleConfiguration cfg | cfg.hasFlow(source, sink)) + TestFlow::flow(source, sink) } + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff From b8a0afbb9fc9867b0efdd44d8c14fb0962c05016 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 11:00:19 +0200 Subject: [PATCH 136/514] JS: Make overriding ConsistencyChecking.getATestFile() optional --- javascript/ql/test/testUtilities/ConsistencyChecking.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/test/testUtilities/ConsistencyChecking.qll b/javascript/ql/test/testUtilities/ConsistencyChecking.qll index 3c30f8accb2..94979bcaab0 100644 --- a/javascript/ql/test/testUtilities/ConsistencyChecking.qll +++ b/javascript/ql/test/testUtilities/ConsistencyChecking.qll @@ -129,7 +129,7 @@ private predicate falseNegative(File file, int line, AssertionComment comment, C private File getATestFile(string conf) { not exists(any(ConsistencyConfiguration res).getAFile()) and result = any(LineComment comment).getFile() and - conf = "" + (conf = "" or conf instanceof ConsistencyConfiguration) or result = conf.(ConsistencyConfiguration).getAFile() } From 32eddd3c07eccaefd261ba0ae751a354349a54b3 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 13:52:12 +0200 Subject: [PATCH 137/514] JS: Update ReactJS test output --- .../test/library-tests/frameworks/ReactJS/tests.expected | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/javascript/ql/test/library-tests/frameworks/ReactJS/tests.expected b/javascript/ql/test/library-tests/frameworks/ReactJS/tests.expected index e05a8445cfa..0cbe3b58ac2 100644 --- a/javascript/ql/test/library-tests/frameworks/ReactJS/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/ReactJS/tests.expected @@ -89,6 +89,7 @@ test_ReactComponent_ref | es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | | es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | es5.js:19:11:19:10 | this | | es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | es5.js:20:24:20:27 | this | +| es6.js:1:1:8:1 | class H ... ;\\n }\\n} | es6.js:1:37:1:36 | implicit 'this' argument of super(...args) | | es6.js:1:1:8:1 | class H ... ;\\n }\\n} | es6.js:1:37:1:36 | this | | es6.js:1:1:8:1 | class H ... ;\\n }\\n} | es6.js:2:9:2:8 | this | | es6.js:1:1:8:1 | class H ... ;\\n }\\n} | es6.js:3:24:3:27 | this | @@ -99,24 +100,31 @@ test_ReactComponent_ref | es6.js:14:1:20:1 | class H ... }\\n} | es6.js:18:9:18:12 | this | | exportedComponent.jsx:1:8:3:1 | functio ... r}}/>\\n} | exportedComponent.jsx:1:8:1:7 | this | | importedComponent.jsx:3:8:5:1 | functio ... or}/>\\n} | importedComponent.jsx:3:8:3:7 | this | +| namedImport.js:3:1:3:28 | class C ... nent {} | namedImport.js:3:27:3:26 | implicit 'this' argument of super(...args) | | namedImport.js:3:1:3:28 | class C ... nent {} | namedImport.js:3:27:3:26 | this | +| namedImport.js:5:1:5:20 | class D extends C {} | namedImport.js:5:19:5:18 | implicit 'this' argument of super(...args) | | namedImport.js:5:1:5:20 | class D extends C {} | namedImport.js:5:19:5:18 | this | | plainfn.js:1:1:3:1 | functio ... div>;\\n} | plainfn.js:1:1:1:0 | this | | plainfn.js:5:1:7:1 | functio ... iv");\\n} | plainfn.js:5:1:5:0 | this | | plainfn.js:9:1:12:1 | functio ... rn x;\\n} | plainfn.js:9:1:9:0 | this | | plainfn.js:20:1:24:1 | functio ... n 42;\\n} | plainfn.js:20:1:20:0 | this | +| preact.js:1:1:7:1 | class H ... }\\n} | preact.js:1:38:1:37 | implicit 'this' argument of super(...args) | | preact.js:1:1:7:1 | class H ... }\\n} | preact.js:1:38:1:37 | this | | preact.js:1:1:7:1 | class H ... }\\n} | preact.js:2:11:2:10 | this | +| preact.js:9:1:11:1 | class H ... nt {\\n\\n} | preact.js:9:38:9:37 | implicit 'this' argument of super(...args) | | preact.js:9:1:11:1 | class H ... nt {\\n\\n} | preact.js:9:38:9:37 | this | +| probably-a-component.js:1:1:6:1 | class H ... }\\n} | probably-a-component.js:1:31:1:30 | implicit 'this' argument of super(...args) | | probably-a-component.js:1:1:6:1 | class H ... }\\n} | probably-a-component.js:1:31:1:30 | this | | probably-a-component.js:1:1:6:1 | class H ... }\\n} | probably-a-component.js:2:11:2:10 | this | | probably-a-component.js:1:1:6:1 | class H ... }\\n} | probably-a-component.js:3:9:3:12 | this | +| props.js:2:5:3:5 | class C ... {\\n } | props.js:2:37:2:36 | implicit 'this' argument of super(...args) | | props.js:2:5:3:5 | class C ... {\\n } | props.js:2:37:2:36 | this | | props.js:2:5:3:5 | class C ... {\\n } | props.js:9:5:9:55 | new C({ ... ctor"}) | | props.js:13:31:17:5 | {\\n ... }\\n } | props.js:13:31:17:5 | {\\n ... }\\n } | | props.js:13:31:17:5 | {\\n ... }\\n } | props.js:14:24:14:23 | this | | props.js:26:5:28:5 | functio ... ;\\n } | props.js:26:5:26:4 | this | | props.js:26:5:28:5 | functio ... ;\\n } | props.js:34:5:34:55 | new C({ ... ctor"}) | +| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:1:33:1:32 | implicit 'this' argument of super(...args) | | rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:1:33:1:32 | this | | rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:2:36:2:35 | this | | rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:5:26:5:25 | this | From b304fb4337f433d7c1365139920e1087011f4131 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 13:52:30 +0200 Subject: [PATCH 138/514] JS: Reorder result sets in ReactJS test output --- .../frameworks/ReactJS/tests.expected | 250 +++++++++--------- 1 file changed, 125 insertions(+), 125 deletions(-) diff --git a/javascript/ql/test/library-tests/frameworks/ReactJS/tests.expected b/javascript/ql/test/library-tests/frameworks/ReactJS/tests.expected index 0cbe3b58ac2..e3b226f74f9 100644 --- a/javascript/ql/test/library-tests/frameworks/ReactJS/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/ReactJS/tests.expected @@ -1,43 +1,3 @@ -test_getADirectStateAccess -| es6.js:14:1:20:1 | class H ... }\\n} | es6.js:16:9:16:18 | this.state | -| es6.js:14:1:20:1 | class H ... }\\n} | es6.js:17:9:17:18 | this.state | -| es6.js:14:1:20:1 | class H ... }\\n} | es6.js:18:9:18:18 | this.state | -| preact.js:1:1:7:1 | class H ... }\\n} | preact.js:2:19:2:23 | state | -| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | statePropertyReads.js:3:9:3:18 | this.state | -| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | statePropertyReads.js:5:9:5:18 | this.state | -| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:4:9:4:17 | cmp.state | -| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:6:9:6:17 | cmp.state | -| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:10:9:10:17 | cmp.state | -| thisAccesses.js:47:1:52:1 | class C ... }\\n} | thisAccesses.js:49:9:49:18 | this.state | -| thisAccesses.js:47:1:52:1 | class C ... }\\n} | thisAccesses.js:50:9:50:18 | this.state | -test_ReactComponent_getInstanceMethod -| es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | getDefaultProps | es5.js:6:20:10:3 | functio ... };\\n } | -| es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | render | es5.js:3:11:5:3 | functio ... v>;\\n } | -| es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | render | es5.js:19:11:21:3 | functio ... 1>;\\n } | -| es6.js:1:1:8:1 | class H ... ;\\n }\\n} | render | es6.js:2:9:4:3 | () {\\n ... v>;\\n } | -| exportedComponent.jsx:1:8:3:1 | functio ... r}}/>\\n} | render | exportedComponent.jsx:1:8:3:1 | functio ... r}}/>\\n} | -| importedComponent.jsx:3:8:5:1 | functio ... or}/>\\n} | render | importedComponent.jsx:3:8:5:1 | functio ... or}/>\\n} | -| plainfn.js:1:1:3:1 | functio ... div>;\\n} | render | plainfn.js:1:1:3:1 | functio ... div>;\\n} | -| plainfn.js:5:1:7:1 | functio ... iv");\\n} | render | plainfn.js:5:1:7:1 | functio ... iv");\\n} | -| plainfn.js:9:1:12:1 | functio ... rn x;\\n} | render | plainfn.js:9:1:12:1 | functio ... rn x;\\n} | -| plainfn.js:20:1:24:1 | functio ... n 42;\\n} | render | plainfn.js:20:1:24:1 | functio ... n 42;\\n} | -| preact.js:1:1:7:1 | class H ... }\\n} | render | preact.js:2:11:6:5 | (props, ... ;\\n } | -| probably-a-component.js:1:1:6:1 | class H ... }\\n} | render | probably-a-component.js:2:11:5:5 | () {\\n ... ;\\n } | -| props.js:13:31:17:5 | {\\n ... }\\n } | getDefaultProps | props.js:14:24:16:9 | () {\\n ... } | -| props.js:26:5:28:5 | functio ... ;\\n } | render | props.js:26:5:28:5 | functio ... ;\\n } | -| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | getSnapshotBeforeUpdate | rare-lifecycle-methods.js:8:28:10:5 | (prevPr ... ;\\n } | -| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | shouldComponentUpdate | rare-lifecycle-methods.js:5:26:7:5 | (nextPr ... ;\\n } | -| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | componentDidUpdate | statePropertyReads.js:10:23:12:5 | (prevPr ... ;\\n } | -| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | getInitialState | statePropertyWrites.js:25:20:29:5 | () { // ... ;\\n } | -| statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | getInitialState | statePropertyWrites.js:40:20:44:3 | functio ... };\\n } | -| statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | render | statePropertyWrites.js:37:11:39:3 | functio ... v>;\\n } | -| thisAccesses.js:1:1:16:1 | class C ... }\\n} | someInstanceMethod | thisAccesses.js:13:23:15:5 | () {\\n ... ;\\n } | -| thisAccesses.js:18:19:29:1 | {\\n r ... }\\n} | render | thisAccesses.js:19:13:24:5 | functio ... ;\\n } | -| thisAccesses.js:18:19:29:1 | {\\n r ... }\\n} | someInstanceMethod | thisAccesses.js:26:25:28:5 | functio ... ;\\n } | -| thisAccesses.js:31:2:36:1 | functio ... iv/>;\\n} | render | thisAccesses.js:31:2:36:1 | functio ... iv/>;\\n} | -| thisAccesses.js:38:19:45:1 | {\\n r ... },\\n} | render | thisAccesses.js:39:13:44:5 | functio ... ;\\n } | -| thisAccesses.js:54:1:63:1 | class C ... }\\n} | render | thisAccesses.js:59:11:62:5 | () {\\n ... ;\\n } | -| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | render | thisAccesses_importedMappers.js:5:13:14:5 | functio ... ;\\n } | test_react | es5.js:1:13:1:17 | React | | es6.js:1:21:1:25 | React | @@ -76,11 +36,62 @@ test_react | thisAccesses_importedMappers.js:1:8:1:12 | React | | thisAccesses_importedMappers.js:4:1:4:5 | React | | thisAccesses_importedMappers.js:6:9:6:13 | React | -test_ReactComponent_getAPreviousStateSource -| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:2:44:2:48 | state | -| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:8:40:8:48 | prevState | -| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | statePropertyReads.js:7:24:7:32 | prevState | -| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | statePropertyReads.js:10:35:10:43 | prevState | +test_JSXname +| es5.js:4:12:4:45 |
He ... }
| es5.js:4:13:4:15 | div | div | Identifier | +| es5.js:20:12:20:44 |

Hel ... e}

| es5.js:20:13:20:14 | h1 | h1 | Identifier | +| es6.js:3:12:3:45 |
He ... }
| es6.js:3:13:3:15 | div | div | Identifier | +| exportedComponent.jsx:2:12:2:46 |
| exportedComponent.jsx:2:13:2:15 | div | div | Identifier | +| importedComponent.jsx:4:12:4:39 | | importedComponent.jsx:4:13:4:23 | MyComponent | MyComponent | Identifier | +| plainfn.js:2:10:2:38 |
He ... }
| plainfn.js:2:11:2:13 | div | div | Identifier | +| preact.js:5:16:5:21 |
| preact.js:5:17:5:19 | div | div | Identifier | +| probably-a-component.js:4:16:4:21 |
| probably-a-component.js:4:17:4:19 | div | div | Identifier | +| props.js:7:6:7:37 | | props.js:7:7:7:7 | C | C | Identifier | +| props.js:19:6:19:37 | | props.js:19:7:19:7 | C | C | Identifier | +| props.js:27:16:27:21 |
| props.js:27:17:27:19 | div | div | Identifier | +| props.js:32:6:32:37 | | props.js:32:7:32:7 | C | C | Identifier | +| statePropertyWrites.js:38:12:38:45 |
He ... }
| statePropertyWrites.js:38:13:38:15 | div | div | Identifier | +| thisAccesses.js:23:16:23:21 |
| thisAccesses.js:23:17:23:19 | div | div | Identifier | +| thisAccesses.js:35:12:35:17 |
| thisAccesses.js:35:13:35:15 | div | div | Identifier | +| thisAccesses.js:43:16:43:21 |
| thisAccesses.js:43:17:43:19 | div | div | Identifier | +| thisAccesses.js:60:19:60:41 | | thisAccesses.js:60:20:60:28 | this.name | this.name | dot | +| thisAccesses.js:61:19:61:41 | | thisAccesses.js:61:20:61:28 | this.this | this.this | dot | +| thisAccesses_importedMappers.js:13:16:13:21 |
| thisAccesses_importedMappers.js:13:17:13:19 | div | div | Identifier | +| use-react-router.jsx:5:17:5:87 | | use-react-router.jsx:5:18:5:23 | Router | Router | Identifier | +| use-react-router.jsx:5:25:5:78 | ... /Route> | use-react-router.jsx:5:26:5:30 | Route | Route | Identifier | +| use-react-router.jsx:5:32:5:70 | | use-react-router.jsx:5:33:5:49 | ImportedComponent | ImportedComponent | Identifier | +| useHigherOrderComponent.jsx:5:12:5:39 | | useHigherOrderComponent.jsx:5:13:5:25 | SomeComponent | SomeComponent | Identifier | +| useHigherOrderComponent.jsx:11:12:11:46 | | useHigherOrderComponent.jsx:11:13:11:31 | LazyLoadedComponent | LazyLoadedComponent | Identifier | +| useHigherOrderComponent.jsx:17:12:17:48 | | useHigherOrderComponent.jsx:17:13:17:32 | LazyLoadedComponent2 | LazyLoadedComponent2 | Identifier | +test_ReactComponent +| es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | +| es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | +| es6.js:1:1:8:1 | class H ... ;\\n }\\n} | +| es6.js:14:1:20:1 | class H ... }\\n} | +| exportedComponent.jsx:1:8:3:1 | functio ... r}}/>\\n} | +| importedComponent.jsx:3:8:5:1 | functio ... or}/>\\n} | +| namedImport.js:3:1:3:28 | class C ... nent {} | +| namedImport.js:5:1:5:20 | class D extends C {} | +| plainfn.js:1:1:3:1 | functio ... div>;\\n} | +| plainfn.js:5:1:7:1 | functio ... iv");\\n} | +| plainfn.js:9:1:12:1 | functio ... rn x;\\n} | +| plainfn.js:20:1:24:1 | functio ... n 42;\\n} | +| preact.js:1:1:7:1 | class H ... }\\n} | +| preact.js:9:1:11:1 | class H ... nt {\\n\\n} | +| probably-a-component.js:1:1:6:1 | class H ... }\\n} | +| props.js:2:5:3:5 | class C ... {\\n } | +| props.js:13:31:17:5 | {\\n ... }\\n } | +| props.js:26:5:28:5 | functio ... ;\\n } | +| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | +| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | +| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | +| statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | +| thisAccesses.js:1:1:16:1 | class C ... }\\n} | +| thisAccesses.js:18:19:29:1 | {\\n r ... }\\n} | +| thisAccesses.js:31:2:36:1 | functio ... iv/>;\\n} | +| thisAccesses.js:38:19:45:1 | {\\n r ... },\\n} | +| thisAccesses.js:47:1:52:1 | class C ... }\\n} | +| thisAccesses.js:54:1:63:1 | class C ... }\\n} | +| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | test_ReactComponent_ref | es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | | es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | es5.js:3:11:3:10 | this | @@ -189,19 +200,57 @@ test_ReactComponent_ref | thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | thisAccesses_importedMappers.js:9:25:9:24 | this | | thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | thisAccesses_importedMappers.js:10:13:10:16 | this | | thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | thisAccesses_importedMappers.js:11:12:11:15 | this | -test_ReactComponent_getACandidateStateSource -| es6.js:14:1:20:1 | class H ... }\\n} | es6.js:18:22:18:31 | { baz: 42} | -| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:3:16:3:17 | {} | -| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:5:38:5:46 | nextState | -| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | statePropertyReads.js:7:45:7:56 | prevState.p3 | -| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:8:18:8:19 | {} | -| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:12:18:12:19 | {} | -| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:16:18:16:19 | {} | -| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:20:18:20:19 | {} | -| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:31:13:33:5 | {\\n ... 2\\n } | -| statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | statePropertyWrites.js:41:12:43:5 | {\\n p8: 42\\n } | -| thisAccesses.js:47:1:52:1 | class C ... }\\n} | thisAccesses.js:48:18:48:18 | y | -| thisAccesses.js:47:1:52:1 | class C ... }\\n} | thisAccesses.js:49:22:49:22 | x | +test_getADirectStateAccess +| es6.js:14:1:20:1 | class H ... }\\n} | es6.js:16:9:16:18 | this.state | +| es6.js:14:1:20:1 | class H ... }\\n} | es6.js:17:9:17:18 | this.state | +| es6.js:14:1:20:1 | class H ... }\\n} | es6.js:18:9:18:18 | this.state | +| preact.js:1:1:7:1 | class H ... }\\n} | preact.js:2:19:2:23 | state | +| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | statePropertyReads.js:3:9:3:18 | this.state | +| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | statePropertyReads.js:5:9:5:18 | this.state | +| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:4:9:4:17 | cmp.state | +| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:6:9:6:17 | cmp.state | +| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:10:9:10:17 | cmp.state | +| thisAccesses.js:47:1:52:1 | class C ... }\\n} | thisAccesses.js:49:9:49:18 | this.state | +| thisAccesses.js:47:1:52:1 | class C ... }\\n} | thisAccesses.js:50:9:50:18 | this.state | +test_ReactComponent_getAPropRead +| es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | name | es5.js:4:24:4:38 | this.props.name | +| es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | name | es5.js:20:24:20:38 | this.props.name | +| es6.js:1:1:8:1 | class H ... ;\\n }\\n} | name | es6.js:3:24:3:38 | this.props.name | +| exportedComponent.jsx:1:8:3:1 | functio ... r}}/>\\n} | color | exportedComponent.jsx:2:32:2:42 | props.color | +| importedComponent.jsx:3:8:5:1 | functio ... or}/>\\n} | color | importedComponent.jsx:3:25:3:29 | color | +| importedComponent.jsx:3:8:5:1 | functio ... or}/>\\n} | location | importedComponent.jsx:3:32:3:39 | location | +| plainfn.js:1:1:3:1 | functio ... div>;\\n} | name | plainfn.js:2:22:2:31 | props.name | +| preact.js:1:1:7:1 | class H ... }\\n} | name | preact.js:3:9:3:18 | props.name | +| probably-a-component.js:1:1:6:1 | class H ... }\\n} | name | probably-a-component.js:3:9:3:23 | this.props.name | +| statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | name | statePropertyWrites.js:38:24:38:38 | this.props.name | +test_ReactComponent_getInstanceMethod +| es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | getDefaultProps | es5.js:6:20:10:3 | functio ... };\\n } | +| es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | render | es5.js:3:11:5:3 | functio ... v>;\\n } | +| es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | render | es5.js:19:11:21:3 | functio ... 1>;\\n } | +| es6.js:1:1:8:1 | class H ... ;\\n }\\n} | render | es6.js:2:9:4:3 | () {\\n ... v>;\\n } | +| exportedComponent.jsx:1:8:3:1 | functio ... r}}/>\\n} | render | exportedComponent.jsx:1:8:3:1 | functio ... r}}/>\\n} | +| importedComponent.jsx:3:8:5:1 | functio ... or}/>\\n} | render | importedComponent.jsx:3:8:5:1 | functio ... or}/>\\n} | +| plainfn.js:1:1:3:1 | functio ... div>;\\n} | render | plainfn.js:1:1:3:1 | functio ... div>;\\n} | +| plainfn.js:5:1:7:1 | functio ... iv");\\n} | render | plainfn.js:5:1:7:1 | functio ... iv");\\n} | +| plainfn.js:9:1:12:1 | functio ... rn x;\\n} | render | plainfn.js:9:1:12:1 | functio ... rn x;\\n} | +| plainfn.js:20:1:24:1 | functio ... n 42;\\n} | render | plainfn.js:20:1:24:1 | functio ... n 42;\\n} | +| preact.js:1:1:7:1 | class H ... }\\n} | render | preact.js:2:11:6:5 | (props, ... ;\\n } | +| probably-a-component.js:1:1:6:1 | class H ... }\\n} | render | probably-a-component.js:2:11:5:5 | () {\\n ... ;\\n } | +| props.js:13:31:17:5 | {\\n ... }\\n } | getDefaultProps | props.js:14:24:16:9 | () {\\n ... } | +| props.js:26:5:28:5 | functio ... ;\\n } | render | props.js:26:5:28:5 | functio ... ;\\n } | +| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | getSnapshotBeforeUpdate | rare-lifecycle-methods.js:8:28:10:5 | (prevPr ... ;\\n } | +| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | shouldComponentUpdate | rare-lifecycle-methods.js:5:26:7:5 | (nextPr ... ;\\n } | +| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | componentDidUpdate | statePropertyReads.js:10:23:12:5 | (prevPr ... ;\\n } | +| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | getInitialState | statePropertyWrites.js:25:20:29:5 | () { // ... ;\\n } | +| statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | getInitialState | statePropertyWrites.js:40:20:44:3 | functio ... };\\n } | +| statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | render | statePropertyWrites.js:37:11:39:3 | functio ... v>;\\n } | +| thisAccesses.js:1:1:16:1 | class C ... }\\n} | someInstanceMethod | thisAccesses.js:13:23:15:5 | () {\\n ... ;\\n } | +| thisAccesses.js:18:19:29:1 | {\\n r ... }\\n} | render | thisAccesses.js:19:13:24:5 | functio ... ;\\n } | +| thisAccesses.js:18:19:29:1 | {\\n r ... }\\n} | someInstanceMethod | thisAccesses.js:26:25:28:5 | functio ... ;\\n } | +| thisAccesses.js:31:2:36:1 | functio ... iv/>;\\n} | render | thisAccesses.js:31:2:36:1 | functio ... iv/>;\\n} | +| thisAccesses.js:38:19:45:1 | {\\n r ... },\\n} | render | thisAccesses.js:39:13:44:5 | functio ... ;\\n } | +| thisAccesses.js:54:1:63:1 | class C ... }\\n} | render | thisAccesses.js:59:11:62:5 | () {\\n ... ;\\n } | +| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | render | thisAccesses_importedMappers.js:5:13:14:5 | functio ... ;\\n } | test_ReactComponent_getADirectPropsSource | es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | es5.js:4:24:4:33 | this.props | | es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | es5.js:20:24:20:33 | this.props | @@ -241,73 +290,24 @@ test_ReactComponent_getACandidatePropsValue | useHigherOrderComponent.jsx:5:33:5:37 | "red" | | useHigherOrderComponent.jsx:11:39:11:44 | "lazy" | | useHigherOrderComponent.jsx:17:40:17:46 | "lazy2" | -test_ReactComponent -| es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | -| es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | -| es6.js:1:1:8:1 | class H ... ;\\n }\\n} | -| es6.js:14:1:20:1 | class H ... }\\n} | -| exportedComponent.jsx:1:8:3:1 | functio ... r}}/>\\n} | -| importedComponent.jsx:3:8:5:1 | functio ... or}/>\\n} | -| namedImport.js:3:1:3:28 | class C ... nent {} | -| namedImport.js:5:1:5:20 | class D extends C {} | -| plainfn.js:1:1:3:1 | functio ... div>;\\n} | -| plainfn.js:5:1:7:1 | functio ... iv");\\n} | -| plainfn.js:9:1:12:1 | functio ... rn x;\\n} | -| plainfn.js:20:1:24:1 | functio ... n 42;\\n} | -| preact.js:1:1:7:1 | class H ... }\\n} | -| preact.js:9:1:11:1 | class H ... nt {\\n\\n} | -| probably-a-component.js:1:1:6:1 | class H ... }\\n} | -| props.js:2:5:3:5 | class C ... {\\n } | -| props.js:13:31:17:5 | {\\n ... }\\n } | -| props.js:26:5:28:5 | functio ... ;\\n } | -| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | -| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | -| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | -| statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | -| thisAccesses.js:1:1:16:1 | class C ... }\\n} | -| thisAccesses.js:18:19:29:1 | {\\n r ... }\\n} | -| thisAccesses.js:31:2:36:1 | functio ... iv/>;\\n} | -| thisAccesses.js:38:19:45:1 | {\\n r ... },\\n} | -| thisAccesses.js:47:1:52:1 | class C ... }\\n} | -| thisAccesses.js:54:1:63:1 | class C ... }\\n} | -| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | -test_ReactComponent_getAPropRead -| es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | name | es5.js:4:24:4:38 | this.props.name | -| es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | name | es5.js:20:24:20:38 | this.props.name | -| es6.js:1:1:8:1 | class H ... ;\\n }\\n} | name | es6.js:3:24:3:38 | this.props.name | -| exportedComponent.jsx:1:8:3:1 | functio ... r}}/>\\n} | color | exportedComponent.jsx:2:32:2:42 | props.color | -| importedComponent.jsx:3:8:5:1 | functio ... or}/>\\n} | color | importedComponent.jsx:3:25:3:29 | color | -| importedComponent.jsx:3:8:5:1 | functio ... or}/>\\n} | location | importedComponent.jsx:3:32:3:39 | location | -| plainfn.js:1:1:3:1 | functio ... div>;\\n} | name | plainfn.js:2:22:2:31 | props.name | -| preact.js:1:1:7:1 | class H ... }\\n} | name | preact.js:3:9:3:18 | props.name | -| probably-a-component.js:1:1:6:1 | class H ... }\\n} | name | probably-a-component.js:3:9:3:23 | this.props.name | -| statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | name | statePropertyWrites.js:38:24:38:38 | this.props.name | -test_JSXname -| es5.js:4:12:4:45 |
He ... }
| es5.js:4:13:4:15 | div | div | Identifier | -| es5.js:20:12:20:44 |

Hel ... e}

| es5.js:20:13:20:14 | h1 | h1 | Identifier | -| es6.js:3:12:3:45 |
He ... }
| es6.js:3:13:3:15 | div | div | Identifier | -| exportedComponent.jsx:2:12:2:46 |
| exportedComponent.jsx:2:13:2:15 | div | div | Identifier | -| importedComponent.jsx:4:12:4:39 | | importedComponent.jsx:4:13:4:23 | MyComponent | MyComponent | Identifier | -| plainfn.js:2:10:2:38 |
He ... }
| plainfn.js:2:11:2:13 | div | div | Identifier | -| preact.js:5:16:5:21 |
| preact.js:5:17:5:19 | div | div | Identifier | -| probably-a-component.js:4:16:4:21 |
| probably-a-component.js:4:17:4:19 | div | div | Identifier | -| props.js:7:6:7:37 | | props.js:7:7:7:7 | C | C | Identifier | -| props.js:19:6:19:37 | | props.js:19:7:19:7 | C | C | Identifier | -| props.js:27:16:27:21 |
| props.js:27:17:27:19 | div | div | Identifier | -| props.js:32:6:32:37 | | props.js:32:7:32:7 | C | C | Identifier | -| statePropertyWrites.js:38:12:38:45 |
He ... }
| statePropertyWrites.js:38:13:38:15 | div | div | Identifier | -| thisAccesses.js:23:16:23:21 |
| thisAccesses.js:23:17:23:19 | div | div | Identifier | -| thisAccesses.js:35:12:35:17 |
| thisAccesses.js:35:13:35:15 | div | div | Identifier | -| thisAccesses.js:43:16:43:21 |
| thisAccesses.js:43:17:43:19 | div | div | Identifier | -| thisAccesses.js:60:19:60:41 | | thisAccesses.js:60:20:60:28 | this.name | this.name | dot | -| thisAccesses.js:61:19:61:41 | | thisAccesses.js:61:20:61:28 | this.this | this.this | dot | -| thisAccesses_importedMappers.js:13:16:13:21 |
| thisAccesses_importedMappers.js:13:17:13:19 | div | div | Identifier | -| use-react-router.jsx:5:17:5:87 | | use-react-router.jsx:5:18:5:23 | Router | Router | Identifier | -| use-react-router.jsx:5:25:5:78 | ... /Route> | use-react-router.jsx:5:26:5:30 | Route | Route | Identifier | -| use-react-router.jsx:5:32:5:70 | | use-react-router.jsx:5:33:5:49 | ImportedComponent | ImportedComponent | Identifier | -| useHigherOrderComponent.jsx:5:12:5:39 | | useHigherOrderComponent.jsx:5:13:5:25 | SomeComponent | SomeComponent | Identifier | -| useHigherOrderComponent.jsx:11:12:11:46 | | useHigherOrderComponent.jsx:11:13:11:31 | LazyLoadedComponent | LazyLoadedComponent | Identifier | -| useHigherOrderComponent.jsx:17:12:17:48 | | useHigherOrderComponent.jsx:17:13:17:32 | LazyLoadedComponent2 | LazyLoadedComponent2 | Identifier | +test_ReactComponent_getAPreviousStateSource +| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:2:44:2:48 | state | +| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:8:40:8:48 | prevState | +| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | statePropertyReads.js:7:24:7:32 | prevState | +| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | statePropertyReads.js:10:35:10:43 | prevState | +test_ReactComponent_getACandidateStateSource +| es6.js:14:1:20:1 | class H ... }\\n} | es6.js:18:22:18:31 | { baz: 42} | +| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:3:16:3:17 | {} | +| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:5:38:5:46 | nextState | +| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | statePropertyReads.js:7:45:7:56 | prevState.p3 | +| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:8:18:8:19 | {} | +| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:12:18:12:19 | {} | +| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:16:18:16:19 | {} | +| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:20:18:20:19 | {} | +| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:31:13:33:5 | {\\n ... 2\\n } | +| statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | statePropertyWrites.js:41:12:43:5 | {\\n p8: 42\\n } | +| thisAccesses.js:47:1:52:1 | class C ... }\\n} | thisAccesses.js:48:18:48:18 | y | +| thisAccesses.js:47:1:52:1 | class C ... }\\n} | thisAccesses.js:49:22:49:22 | x | test_JsxName_this | es5.js:4:12:4:45 |
He ... }
| es5.js:4:24:4:27 | this | | es5.js:20:12:20:44 |

Hel ... e}

| es5.js:20:24:20:27 | this | From c2f66c0f9317effedd429115e66029dd6c5150ab Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 13:55:24 +0200 Subject: [PATCH 139/514] JS: Update Restify2 test --- .../library-tests/frameworks/Restify2/tests.ql | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/javascript/ql/test/library-tests/frameworks/Restify2/tests.ql b/javascript/ql/test/library-tests/frameworks/Restify2/tests.ql index e385b558458..720f35ba21d 100644 --- a/javascript/ql/test/library-tests/frameworks/Restify2/tests.ql +++ b/javascript/ql/test/library-tests/frameworks/Restify2/tests.ql @@ -57,9 +57,7 @@ query predicate passingPositiveTests(string res, string expectation, InlineTest exists(ReflectedXss::Sink n | t.inNode(n)) or expectation = "xss" and - exists(XssConfig::Configuration cfg, DataFlow::Node sink | - cfg.hasFlow(_, sink) and t.inNode(sink) - ) + exists(DataFlow::Node sink | XssConfig::ReflectedXssFlow::flowTo(sink) and t.inNode(sink)) or expectation = "cleartextStorageSink" and exists(CleartextStorage::Sink n | t.inNode(n)) @@ -107,9 +105,7 @@ query predicate failingPositiveTests(string res, string expectation, InlineTest not exists(ReflectedXss::Sink n | t.inNode(n)) or expectation = "xss" and - not exists(XssConfig::Configuration cfg, DataFlow::Node sink | - cfg.hasFlow(_, sink) and t.inNode(sink) - ) + not exists(DataFlow::Node sink | XssConfig::ReflectedXssFlow::flowTo(sink) and t.inNode(sink)) or expectation = "cleartextStorageSink" and not exists(CleartextStorage::Sink n | t.inNode(n)) @@ -157,9 +153,7 @@ query predicate passingNegativeTests(string res, string expectation, InlineTest not exists(ReflectedXss::Sink n | t.inNode(n)) or expectation = "!xss" and - not exists(XssConfig::Configuration cfg, DataFlow::Node sink | - cfg.hasFlow(_, sink) and t.inNode(sink) - ) + not exists(DataFlow::Node sink | XssConfig::ReflectedXssFlow::flowTo(sink) and t.inNode(sink)) or expectation = "!cleartextStorageSink" and not exists(CleartextStorage::Sink n | t.inNode(n)) @@ -207,9 +201,7 @@ query predicate failingNegativeTests(string res, string expectation, InlineTest exists(ReflectedXss::Sink n | t.inNode(n)) or expectation = "!xss" and - exists(XssConfig::Configuration cfg, DataFlow::Node sink | - cfg.hasFlow(_, sink) and t.inNode(sink) - ) + exists(DataFlow::Node sink | XssConfig::ReflectedXssFlow::flowTo(sink) and t.inNode(sink)) or expectation = "!cleartextStorageSink" and exists(CleartextStorage::Sink n | t.inNode(n)) From 75c915b2a3cfca5b833b91942404c1b4a216fe5b Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 14:41:07 +0200 Subject: [PATCH 140/514] JS: Update Spife test --- .../test/library-tests/frameworks/Spife/tests.ql | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/javascript/ql/test/library-tests/frameworks/Spife/tests.ql b/javascript/ql/test/library-tests/frameworks/Spife/tests.ql index ef785a2860b..2ea6fc4bd4c 100644 --- a/javascript/ql/test/library-tests/frameworks/Spife/tests.ql +++ b/javascript/ql/test/library-tests/frameworks/Spife/tests.ql @@ -63,9 +63,7 @@ query predicate passingPositiveTests(string res, string expectation, InlineTest exists(ReflectedXss::Sink n | t.inNode(n)) or expectation = "xss" and - exists(XssConfig::Configuration cfg, DataFlow::Node sink | - cfg.hasFlow(_, sink) and t.inNode(sink) - ) + exists(DataFlow::Node sink | XssConfig::ReflectedXssFlow::flowTo(sink) and t.inNode(sink)) or expectation = "cleartextStorageSink" and exists(CleartextStorage::Sink n | t.inNode(n)) @@ -119,9 +117,7 @@ query predicate failingPositiveTests(string res, string expectation, InlineTest not exists(ReflectedXss::Sink n | t.inNode(n)) or expectation = "xss" and - not exists(XssConfig::Configuration cfg, DataFlow::Node sink | - cfg.hasFlow(_, sink) and t.inNode(sink) - ) + not exists(DataFlow::Node sink | XssConfig::ReflectedXssFlow::flowTo(sink) and t.inNode(sink)) or expectation = "cleartextStorageSink" and not exists(CleartextStorage::Sink n | t.inNode(n)) @@ -175,9 +171,7 @@ query predicate passingNegativeTests(string res, string expectation, InlineTest not exists(ReflectedXss::Sink n | t.inNode(n)) or expectation = "!xss" and - not exists(XssConfig::Configuration cfg, DataFlow::Node sink | - cfg.hasFlow(_, sink) and t.inNode(sink) - ) + not exists(DataFlow::Node sink | XssConfig::ReflectedXssFlow::flowTo(sink) and t.inNode(sink)) or expectation = "!cleartextStorageSink" and not exists(CleartextStorage::Sink n | t.inNode(n)) @@ -231,9 +225,7 @@ query predicate failingNegativeTests(string res, string expectation, InlineTest exists(ReflectedXss::Sink n | t.inNode(n)) or expectation = "!xss" and - exists(XssConfig::Configuration cfg, DataFlow::Node sink | - cfg.hasFlow(_, sink) and t.inNode(sink) - ) + exists(DataFlow::Node sink | XssConfig::ReflectedXssFlow::flowTo(sink) and t.inNode(sink)) or expectation = "!cleartextStorageSink" and exists(CleartextStorage::Sink n | t.inNode(n)) From b5ad36686ef5fba19d4772807ef9013c10ad61ea Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 15:00:08 +0200 Subject: [PATCH 141/514] JS: Block flow into window.location --- .../javascript/dataflow/internal/DataFlowPrivate.qll | 8 ++++++++ .../test/library-tests/InterProceduralFlow/global.js | 10 +++++----- .../test/library-tests/InterProceduralFlow/global2.js | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 0c269a7f152..223a0ff1550 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -846,6 +846,14 @@ predicate clearsContent(Node n, ContentSet c) { // We implement this rule by clearing any captured-content before storing into another captured-content. VariableCaptureOutput::storeStep(getClosureNode(n), _, _) and c = MkAnyCapturedContent() + or + // Block flow into the "window.location" property, as any assignment/mutation to this causes a page load and stops execution. + // The use of clearsContent here ensures we also block assignments like `window.location.href = ...` + exists(DataFlow::PropRef ref | + ref = DataFlow::globalObjectRef().getAPropertyReference("location") and + n = ref.getBase().getPostUpdateNode() and + c = ContentSet::property("location") + ) } /** diff --git a/javascript/ql/test/library-tests/InterProceduralFlow/global.js b/javascript/ql/test/library-tests/InterProceduralFlow/global.js index a7132f1dcb5..99badab76b8 100644 --- a/javascript/ql/test/library-tests/InterProceduralFlow/global.js +++ b/javascript/ql/test/library-tests/InterProceduralFlow/global.js @@ -9,11 +9,11 @@ function g(x) { let sink1 = g(source1); let sink2 = g(source2); -document.location = source1; // should not flow to `global2.js` in spite of assignment +document.someProp = source1; // should not flow to `global2.js` in spite of assignment // `document = {}` in `fake-document.js` -window.location = source1; +window.someProp = source1; let win = window; -let sink3 = window.location; -let sink4 = win.location; -let sink5 = location; +let sink3 = window.someProp; +let sink4 = win.someProp; +let sink5 = someProp; diff --git a/javascript/ql/test/library-tests/InterProceduralFlow/global2.js b/javascript/ql/test/library-tests/InterProceduralFlow/global2.js index 258b79a7df9..004a4ce50bb 100644 --- a/javascript/ql/test/library-tests/InterProceduralFlow/global2.js +++ b/javascript/ql/test/library-tests/InterProceduralFlow/global2.js @@ -1,2 +1,2 @@ let remote_sink = source1; -let other_remote_sink = document.location; +let other_remote_sink = document.someProp; From 2eff07f4760c99c0d5e16801228ea21306547d1d Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 15:12:18 +0200 Subject: [PATCH 142/514] JS: Update TaintTracking test --- .../TaintTracking/BasicTaintTracking.expected | 119 ++++++--- .../TaintTracking/BasicTaintTracking.ql | 55 ++--- .../TaintTracking/DataFlowTracking.expected | 96 ++++++-- .../TaintTracking/DataFlowTracking.ql | 38 ++- .../TaintTracking/arrays-init.js | 18 +- .../library-tests/TaintTracking/booleanOps.js | 14 +- .../TaintTracking/bound-function.js | 25 +- .../library-tests/TaintTracking/call-apply.js | 22 +- .../library-tests/TaintTracking/callbacks.js | 4 +- .../TaintTracking/capture-flow.js | 228 ++++++++++++++++++ .../TaintTracking/constructor-calls.js | 20 +- .../library-tests/TaintTracking/exceptions.js | 16 +- .../TaintTracking/getters-and-setters.js | 4 +- .../TaintTracking/implied-receiver.js | 11 + .../TaintTracking/nested-props.js | 2 +- .../TaintTracking/object-bypass-sanitizer.js | 4 +- .../TaintTracking/partialCalls.js | 2 +- .../library-tests/TaintTracking/promise.js | 30 ++- .../TaintTracking/sanitizer-guards.js | 16 +- .../stringification-read-steps.js | 31 +++ 20 files changed, 598 insertions(+), 157 deletions(-) create mode 100644 javascript/ql/test/library-tests/TaintTracking/implied-receiver.js create mode 100644 javascript/ql/test/library-tests/TaintTracking/stringification-read-steps.js diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 74095771abb..594ea1acdbe 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -1,17 +1,29 @@ -typeInferenceMismatch -| call-apply.js:27:14:27:21 | source() | call-apply.js:3:1:5:1 | 'arguments' object of function foo1 | -| call-apply.js:27:14:27:21 | source() | call-apply.js:7:1:9:1 | 'arguments' object of function foo2 | -| call-apply.js:27:14:27:21 | source() | call-apply.js:12:10:12:30 | reflective call | -| call-apply.js:27:14:27:21 | source() | call-apply.js:16:10:16:40 | reflective call | -| call-apply.js:27:14:27:21 | source() | call-apply.js:23:1:25:1 | 'arguments' object of function foo1_sink | -| call-apply.js:27:14:27:21 | source() | call-apply.js:29:6:29:32 | reflective call | -| call-apply.js:27:14:27:21 | source() | call-apply.js:32:6:32:35 | reflective call | -| call-apply.js:27:14:27:21 | source() | call-apply.js:33:6:33:35 | reflective call | -| call-apply.js:27:14:27:21 | source() | call-apply.js:64:3:66:3 | 'arguments' object of function sinkArguments1 | -| call-apply.js:27:14:27:21 | source() | call-apply.js:67:3:69:3 | 'arguments' object of function sinkArguments0 | -| call-apply.js:27:14:27:21 | source() | call-apply.js:71:3:74:3 | 'arguments' object of function fowardArguments | -| destruct.js:20:7:20:14 | source() | destruct.js:13:14:13:19 | [a, b] | -#select +legacyDataFlowDifference +| bound-function.js:27:8:27:15 | source() | bound-function.js:30:10:30:10 | y | only flow with OLD data flow library | +| call-apply.js:45:8:45:15 | source() | call-apply.js:55:6:55:13 | foo(obj) | only flow with NEW data flow library | +| callbacks.js:37:17:37:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | +| callbacks.js:37:17:37:24 | source() | callbacks.js:41:10:41:10 | x | only flow with NEW data flow library | +| callbacks.js:44:17:44:24 | source() | callbacks.js:37:37:37:37 | x | only flow with NEW data flow library | +| callbacks.js:44:17:44:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | +| capture-flow.js:89:13:89:20 | source() | capture-flow.js:89:6:89:21 | test3c(source()) | only flow with NEW data flow library | +| capture-flow.js:101:12:101:19 | source() | capture-flow.js:102:6:102:20 | test5("safe")() | only flow with OLD data flow library | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:40:8:40:14 | e.taint | only flow with NEW data flow library | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:44:8:44:19 | f_safe.taint | only flow with NEW data flow library | +| constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:39:8:39:14 | e.param | only flow with NEW data flow library | +| exceptions.js:53:14:53:21 | source() | exceptions.js:54:10:54:10 | e | only flow with NEW data flow library | +| getters-and-setters.js:53:21:53:28 | source() | getters-and-setters.js:53:10:53:30 | getX(ne ... rce())) | only flow with NEW data flow library | +| nested-props.js:14:15:14:22 | source() | nested-props.js:15:10:15:16 | obj.x.y | only flow with NEW data flow library | +| nested-props.js:19:17:19:24 | source() | nested-props.js:20:10:20:18 | obj.x.y.z | only flow with NEW data flow library | +| nested-props.js:27:18:27:25 | source() | nested-props.js:28:10:28:14 | obj.x | only flow with NEW data flow library | +| nested-props.js:51:22:51:29 | source() | nested-props.js:52:10:52:16 | obj.x.y | only flow with NEW data flow library | +| object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:23:14:23:20 | obj.foo | only flow with OLD data flow library | +| object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:28:10:28:30 | sanitiz ... bj).foo | only flow with OLD data flow library | +| promise.js:12:20:12:27 | source() | promise.js:13:8:13:23 | resolver.promise | only flow with OLD data flow library | +| sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | only flow with NEW data flow library | +| stringification-read-steps.js:7:22:7:29 | source() | stringification-read-steps.js:17:10:17:31 | JSON.st ... object) | only flow with NEW data flow library | +| stringification-read-steps.js:7:22:7:29 | source() | stringification-read-steps.js:25:10:25:31 | JSON.st ... object) | only flow with NEW data flow library | +consistencyIssue +flow | access-path-sanitizer.js:2:18:2:25 | source() | access-path-sanitizer.js:4:8:4:12 | obj.x | | addexpr.js:4:10:4:17 | source() | addexpr.js:7:8:7:8 | x | | addexpr.js:11:15:11:22 | source() | addexpr.js:21:8:21:12 | value | @@ -46,22 +58,22 @@ typeInferenceMismatch | booleanOps.js:2:11:2:18 | source() | booleanOps.js:13:10:13:10 | x | | booleanOps.js:2:11:2:18 | source() | booleanOps.js:19:10:19:10 | x | | booleanOps.js:2:11:2:18 | source() | booleanOps.js:22:10:22:10 | x | -| bound-function.js:12:12:12:19 | source() | bound-function.js:4:10:4:10 | y | -| bound-function.js:14:6:14:13 | source() | bound-function.js:4:10:4:10 | y | -| bound-function.js:22:8:22:15 | source() | bound-function.js:25:10:25:10 | y | -| bound-function.js:45:10:45:17 | source() | bound-function.js:45:6:45:18 | id3(source()) | -| bound-function.js:49:12:49:19 | source() | bound-function.js:54:6:54:14 | source0() | -| bound-function.js:49:12:49:19 | source() | bound-function.js:55:6:55:14 | source1() | +| bound-function.js:17:21:17:28 | source() | bound-function.js:5:10:5:16 | y.test2 | +| bound-function.js:19:15:19:22 | source() | bound-function.js:6:10:6:16 | y.test3 | +| bound-function.js:50:10:50:17 | source() | bound-function.js:50:6:50:18 | id3(source()) | +| bound-function.js:54:12:54:19 | source() | bound-function.js:59:6:59:14 | source0() | +| bound-function.js:54:12:54:19 | source() | bound-function.js:60:6:60:14 | source1() | | call-apply.js:27:14:27:21 | source() | call-apply.js:24:8:24:11 | arg1 | | call-apply.js:27:14:27:21 | source() | call-apply.js:29:6:29:32 | foo1.ca ... ce, "") | | call-apply.js:27:14:27:21 | source() | call-apply.js:32:6:32:35 | foo1.ap ... e, ""]) | | call-apply.js:27:14:27:21 | source() | call-apply.js:33:6:33:35 | foo2.ap ... e, ""]) | -| call-apply.js:27:14:27:21 | source() | call-apply.js:40:6:40:29 | foo1_ap ... e, ""]) | -| call-apply.js:27:14:27:21 | source() | call-apply.js:46:6:46:28 | foo1_ca ... e, ""]) | -| call-apply.js:27:14:27:21 | source() | call-apply.js:47:6:47:28 | foo1_ca ... ource]) | -| call-apply.js:27:14:27:21 | source() | call-apply.js:65:10:65:21 | arguments[1] | -| call-apply.js:27:14:27:21 | source() | call-apply.js:68:10:68:21 | arguments[0] | -| call-apply.js:87:17:87:24 | source() | call-apply.js:84:8:84:11 | this | +| call-apply.js:27:14:27:21 | source() | call-apply.js:34:6:34:29 | foo1_ap ... e, ""]) | +| call-apply.js:27:14:27:21 | source() | call-apply.js:40:6:40:28 | foo1_ca ... e, ""]) | +| call-apply.js:27:14:27:21 | source() | call-apply.js:41:6:41:28 | foo1_ca ... ource]) | +| call-apply.js:27:14:27:21 | source() | call-apply.js:59:10:59:21 | arguments[1] | +| call-apply.js:27:14:27:21 | source() | call-apply.js:62:10:62:21 | arguments[0] | +| call-apply.js:45:8:45:15 | source() | call-apply.js:55:6:55:13 | foo(obj) | +| call-apply.js:81:17:81:24 | source() | call-apply.js:78:8:78:11 | this | | callbacks.js:4:6:4:13 | source() | callbacks.js:34:27:34:27 | x | | callbacks.js:4:6:4:13 | source() | callbacks.js:35:27:35:27 | x | | callbacks.js:5:6:5:13 | source() | callbacks.js:34:27:34:27 | x | @@ -69,6 +81,10 @@ typeInferenceMismatch | callbacks.js:25:16:25:23 | source() | callbacks.js:47:26:47:26 | x | | callbacks.js:25:16:25:23 | source() | callbacks.js:48:26:48:26 | x | | callbacks.js:37:17:37:24 | source() | callbacks.js:37:37:37:37 | x | +| callbacks.js:37:17:37:24 | source() | callbacks.js:38:35:38:35 | x | +| callbacks.js:37:17:37:24 | source() | callbacks.js:41:10:41:10 | x | +| callbacks.js:44:17:44:24 | source() | callbacks.js:37:37:37:37 | x | +| callbacks.js:44:17:44:24 | source() | callbacks.js:38:35:38:35 | x | | callbacks.js:44:17:44:24 | source() | callbacks.js:41:10:41:10 | x | | callbacks.js:50:18:50:25 | source() | callbacks.js:30:29:30:29 | y | | callbacks.js:51:18:51:25 | source() | callbacks.js:30:29:30:29 | y | @@ -76,6 +92,27 @@ typeInferenceMismatch | capture-flow.js:9:11:9:18 | source() | capture-flow.js:14:10:14:16 | outer() | | capture-flow.js:9:11:9:18 | source() | capture-flow.js:19:6:19:16 | outerMost() | | capture-flow.js:31:14:31:21 | source() | capture-flow.js:31:6:31:22 | confuse(source()) | +| capture-flow.js:45:12:45:19 | source() | capture-flow.js:45:6:45:20 | test3(source()) | +| capture-flow.js:60:13:60:20 | source() | capture-flow.js:60:6:60:21 | test3a(source()) | +| capture-flow.js:76:13:76:20 | source() | capture-flow.js:76:6:76:21 | test3b(source()) | +| capture-flow.js:89:13:89:20 | source() | capture-flow.js:89:6:89:21 | test3c(source()) | +| capture-flow.js:93:13:93:20 | source() | capture-flow.js:96:6:96:14 | test4()() | +| capture-flow.js:101:12:101:19 | source() | capture-flow.js:101:6:101:22 | test5(source())() | +| capture-flow.js:110:12:110:19 | source() | capture-flow.js:106:14:106:14 | x | +| capture-flow.js:118:37:118:44 | source() | capture-flow.js:114:14:114:14 | x | +| capture-flow.js:126:25:126:32 | source() | capture-flow.js:123:14:123:26 | orderingTaint | +| capture-flow.js:126:25:126:32 | source() | capture-flow.js:129:14:129:26 | orderingTaint | +| capture-flow.js:177:26:177:33 | source() | capture-flow.js:173:14:173:14 | x | +| capture-flow.js:187:34:187:41 | source() | capture-flow.js:183:14:183:14 | x | +| capture-flow.js:195:24:195:31 | source() | capture-flow.js:191:14:191:14 | x | +| capture-flow.js:205:24:205:31 | source() | capture-flow.js:200:18:200:18 | x | +| capture-flow.js:225:13:225:20 | source() | capture-flow.js:220:51:220:59 | fileOrDir | +| capture-flow.js:230:9:230:16 | source() | capture-flow.js:233:14:233:14 | x | +| capture-flow.js:259:23:259:30 | source() | capture-flow.js:243:18:243:40 | objectW ... s.field | +| capture-flow.js:259:23:259:30 | source() | capture-flow.js:247:18:247:40 | objectW ... s.field | +| capture-flow.js:259:23:259:30 | source() | capture-flow.js:248:18:248:27 | this.field | +| capture-flow.js:259:23:259:30 | source() | capture-flow.js:252:14:252:36 | objectW ... s.field | +| capture-flow.js:259:23:259:30 | source() | capture-flow.js:253:14:253:23 | this.field | | captured-sanitizer.js:25:3:25:10 | source() | captured-sanitizer.js:15:10:15:10 | x | | case.js:2:16:2:23 | source() | case.js:5:8:5:35 | changeC ... source) | | case.js:2:16:2:23 | source() | case.js:8:8:8:24 | camelCase(source) | @@ -88,12 +125,15 @@ typeInferenceMismatch | closure.js:6:15:6:22 | source() | closure.js:8:8:8:31 | string. ... (taint) | | closure.js:6:15:6:22 | source() | closure.js:9:8:9:25 | string.trim(taint) | | closure.js:6:15:6:22 | source() | closure.js:10:8:10:33 | string. ... nt, 50) | -| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:18:8:18:14 | c.taint | -| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:22:8:22:19 | c_safe.taint | -| constructor-calls.js:10:16:10:23 | source() | constructor-calls.js:26:8:26:14 | d.taint | -| constructor-calls.js:10:16:10:23 | source() | constructor-calls.js:30:8:30:19 | d_safe.taint | -| constructor-calls.js:14:15:14:22 | source() | constructor-calls.js:17:8:17:14 | c.param | -| constructor-calls.js:14:15:14:22 | source() | constructor-calls.js:25:8:25:14 | d.param | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:24:8:24:14 | c.taint | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:28:8:28:19 | c_safe.taint | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:40:8:40:14 | e.taint | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:44:8:44:19 | f_safe.taint | +| constructor-calls.js:10:16:10:23 | source() | constructor-calls.js:32:8:32:14 | d.taint | +| constructor-calls.js:10:16:10:23 | source() | constructor-calls.js:36:8:36:19 | d_safe.taint | +| constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:23:8:23:14 | c.param | +| constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:31:8:31:14 | d.param | +| constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:39:8:39:14 | e.param | | destruct.js:20:7:20:14 | source() | destruct.js:5:10:5:10 | z | | destruct.js:20:7:20:14 | source() | destruct.js:8:10:8:10 | w | | destruct.js:20:7:20:14 | source() | destruct.js:11:10:11:10 | q | @@ -104,6 +144,7 @@ typeInferenceMismatch | exceptions.js:21:17:21:24 | source() | exceptions.js:24:10:24:21 | e.toString() | | exceptions.js:21:17:21:24 | source() | exceptions.js:25:10:25:18 | e.message | | exceptions.js:21:17:21:24 | source() | exceptions.js:26:10:26:19 | e.fileName | +| exceptions.js:53:14:53:21 | source() | exceptions.js:54:10:54:10 | e | | exceptions.js:59:24:59:31 | source() | exceptions.js:61:12:61:12 | e | | exceptions.js:88:6:88:13 | source() | exceptions.js:11:10:11:10 | e | | exceptions.js:88:6:88:13 | source() | exceptions.js:32:10:32:10 | e | @@ -125,12 +166,14 @@ typeInferenceMismatch | getters-and-setters.js:6:20:6:27 | source() | getters-and-setters.js:13:18:13:20 | c.x | | getters-and-setters.js:27:15:27:22 | source() | getters-and-setters.js:23:18:23:18 | v | | getters-and-setters.js:47:23:47:30 | source() | getters-and-setters.js:45:14:45:16 | c.x | +| getters-and-setters.js:53:21:53:28 | source() | getters-and-setters.js:53:10:53:30 | getX(ne ... rce())) | | getters-and-setters.js:60:20:60:27 | source() | getters-and-setters.js:66:10:66:14 | obj.x | | getters-and-setters.js:67:13:67:20 | source() | getters-and-setters.js:63:18:63:22 | value | | getters-and-setters.js:79:20:79:27 | source() | getters-and-setters.js:88:10:88:18 | new C().x | | getters-and-setters.js:79:20:79:27 | source() | getters-and-setters.js:92:14:92:16 | c.x | | getters-and-setters.js:79:20:79:27 | source() | getters-and-setters.js:100:10:100:22 | getX(new C()) | | getters-and-setters.js:89:17:89:24 | source() | getters-and-setters.js:82:18:82:22 | value | +| implied-receiver.js:4:16:4:23 | source() | implied-receiver.js:7:18:7:25 | this.foo | | importedReactComponent.jsx:4:40:4:47 | source() | exportedReactComponent.jsx:2:10:2:19 | props.text | | indexOf.js:4:11:4:18 | source() | indexOf.js:9:10:9:10 | x | | json-stringify.js:2:16:2:23 | source() | json-stringify.js:5:8:5:29 | JSON.st ... source) | @@ -156,12 +199,14 @@ typeInferenceMismatch | json-stringify.js:3:15:3:22 | source() | json-stringify.js:8:8:8:31 | jsonStr ... (taint) | | nested-props.js:4:13:4:20 | source() | nested-props.js:5:10:5:14 | obj.x | | nested-props.js:9:18:9:25 | source() | nested-props.js:10:10:10:16 | obj.x.y | +| nested-props.js:14:15:14:22 | source() | nested-props.js:15:10:15:16 | obj.x.y | +| nested-props.js:19:17:19:24 | source() | nested-props.js:20:10:20:18 | obj.x.y.z | +| nested-props.js:27:18:27:25 | source() | nested-props.js:28:10:28:14 | obj.x | | nested-props.js:35:13:35:20 | source() | nested-props.js:36:10:36:20 | doLoad(obj) | | nested-props.js:43:13:43:20 | source() | nested-props.js:44:10:44:18 | id(obj).x | +| nested-props.js:51:22:51:29 | source() | nested-props.js:52:10:52:16 | obj.x.y | | nested-props.js:67:31:67:38 | source() | nested-props.js:68:10:68:10 | x | | nested-props.js:77:36:77:43 | source() | nested-props.js:78:10:78:10 | x | -| object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:23:14:23:20 | obj.foo | -| object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:28:10:28:30 | sanitiz ... bj).foo | | partialCalls.js:4:17:4:24 | source() | partialCalls.js:17:14:17:14 | x | | partialCalls.js:4:17:4:24 | source() | partialCalls.js:20:14:20:14 | y | | partialCalls.js:4:17:4:24 | source() | partialCalls.js:30:14:30:20 | x.value | @@ -170,7 +215,8 @@ typeInferenceMismatch | promise.js:4:24:4:31 | source() | promise.js:4:8:4:32 | Promise ... urce()) | | promise.js:5:25:5:32 | source() | promise.js:5:8:5:33 | bluebir ... urce()) | | promise.js:10:24:10:31 | source() | promise.js:10:8:10:32 | Promise ... urce()) | -| promise.js:12:20:12:27 | source() | promise.js:13:8:13:23 | resolver.promise | +| promise.js:18:22:18:29 | source() | promise.js:24:10:24:10 | e | +| promise.js:33:21:33:28 | source() | promise.js:38:10:38:10 | e | | rxjs.js:3:1:3:8 | source() | rxjs.js:10:14:10:17 | data | | rxjs.js:13:1:13:8 | source() | rxjs.js:17:23:17:23 | x | | rxjs.js:13:1:13:8 | source() | rxjs.js:18:23:18:23 | x | @@ -185,6 +231,7 @@ typeInferenceMismatch | sanitizer-guards.js:13:14:13:21 | source() | sanitizer-guards.js:26:9:26:14 | this.x | | sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:45:8:45:8 | x | | sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:48:10:48:10 | x | +| sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | | sanitizer-guards.js:68:11:68:18 | source() | sanitizer-guards.js:75:8:75:8 | x | | sanitizer-guards.js:79:11:79:18 | source() | sanitizer-guards.js:81:8:81:8 | x | | sanitizer-guards.js:79:11:79:18 | source() | sanitizer-guards.js:84:10:84:10 | x | @@ -208,6 +255,8 @@ typeInferenceMismatch | string-replace.js:3:13:3:20 | source() | string-replace.js:21:6:21:41 | safe(). ... taint) | | string-replace.js:3:13:3:20 | source() | string-replace.js:22:6:22:48 | safe(). ... taint) | | string-replace.js:3:13:3:20 | source() | string-replace.js:24:6:24:45 | taint.r ... + '!') | +| stringification-read-steps.js:7:22:7:29 | source() | stringification-read-steps.js:17:10:17:31 | JSON.st ... object) | +| stringification-read-steps.js:7:22:7:29 | source() | stringification-read-steps.js:25:10:25:31 | JSON.st ... object) | | summarize-store-load-in-call.js:9:15:9:22 | source() | summarize-store-load-in-call.js:9:10:9:23 | blah(source()) | | thisAssignments.js:4:17:4:24 | source() | thisAssignments.js:5:10:5:18 | obj.field | | thisAssignments.js:7:19:7:26 | source() | thisAssignments.js:8:10:8:20 | this.field2 | diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql index cfbd3a530db..d76cd7b8fb9 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql @@ -1,5 +1,6 @@ import javascript import semmle.javascript.dataflow.InferredTypes +import testUtilities.ConsistencyChecking DataFlow::CallNode getACall(string name) { result.getCalleeName() = name @@ -7,53 +8,53 @@ DataFlow::CallNode getACall(string name) { result.getCalleeNode().getALocalSource() = DataFlow::globalVarRef(name) } -class Sink extends DataFlow::Node { - Sink() { this = getACall("sink").getAnArgument() } -} +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node = getACall("source") } -/** - * A node that shouldn't be taintable according to the type inference, - * as it claims to be neither an object nor a string. - */ -class UntaintableNode extends DataFlow::Node { - UntaintableNode() { - not this.analyze().getAType() = TTObject() and - not this.analyze().getAType() = TTString() + predicate isSink(DataFlow::Node node) { node = getACall("sink").getAnArgument() } + + predicate isBarrier(DataFlow::Node node) { + node.(DataFlow::InvokeNode).getCalleeName().matches("sanitizer_%") or + node = DataFlow::MakeBarrierGuard::getABarrierNode() or + node = TaintTracking::AdHocWhitelistCheckSanitizer::getABarrierNode() } } -class BasicConfig extends TaintTracking::Configuration { - BasicConfig() { this = "BasicConfig" } +module TestFlow = TaintTracking::Global; - override predicate isSource(DataFlow::Node node) { node = getACall("source") } +class LegacyConfig extends TaintTracking::Configuration { + LegacyConfig() { this = "LegacyConfig" } - override predicate isSink(DataFlow::Node node) { - node instanceof Sink - or - node instanceof UntaintableNode - } + override predicate isSource(DataFlow::Node node) { TestConfig::isSource(node) } + + override predicate isSink(DataFlow::Node node) { TestConfig::isSink(node) } override predicate isSanitizer(DataFlow::Node node) { node.(DataFlow::InvokeNode).getCalleeName().matches("sanitizer_%") } override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode node) { - node instanceof BasicSanitizerGuard + node instanceof BasicSanitizerGuard or + node instanceof TaintTracking::AdHocWhitelistCheckSanitizer } } +import testUtilities.LegacyDataFlowDiff::DataFlowDiff + class BasicSanitizerGuard extends TaintTracking::SanitizerGuardNode, DataFlow::CallNode { BasicSanitizerGuard() { this = getACall("isSafe") } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = this.getArgument(0).asExpr() } } -query predicate typeInferenceMismatch(DataFlow::Node source, UntaintableNode sink) { - any(BasicConfig cfg).hasFlow(source, sink) -} +query predicate flow = TestFlow::flow/2; -from BasicConfig cfg, DataFlow::Node src, Sink sink -where cfg.hasFlow(src, sink) -select src, sink +class Consistency extends ConsistencyConfiguration { + Consistency() { this = "Consistency" } + + override DataFlow::Node getAnAlert() { TestFlow::flowTo(result) } +} diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected index 3808a3e618f..9f5ed2f6573 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected @@ -1,9 +1,34 @@ +legacyDataFlowDifference +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:38:8:38:13 | arr[5] | only flow with NEW data flow library | +| bound-function.js:27:8:27:15 | source() | bound-function.js:30:10:30:10 | y | only flow with OLD data flow library | +| call-apply.js:27:14:27:21 | source() | call-apply.js:34:6:34:29 | foo1_ap ... e, ""]) | only flow with NEW data flow library | +| call-apply.js:45:8:45:15 | source() | call-apply.js:55:6:55:13 | foo(obj) | only flow with NEW data flow library | +| callbacks.js:37:17:37:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | +| callbacks.js:37:17:37:24 | source() | callbacks.js:41:10:41:10 | x | only flow with NEW data flow library | +| callbacks.js:44:17:44:24 | source() | callbacks.js:37:37:37:37 | x | only flow with NEW data flow library | +| callbacks.js:44:17:44:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | +| capture-flow.js:89:13:89:20 | source() | capture-flow.js:89:6:89:21 | test3c(source()) | only flow with NEW data flow library | +| capture-flow.js:101:12:101:19 | source() | capture-flow.js:102:6:102:20 | test5("safe")() | only flow with OLD data flow library | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:40:8:40:14 | e.taint | only flow with NEW data flow library | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:44:8:44:19 | f_safe.taint | only flow with NEW data flow library | +| constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:39:8:39:14 | e.param | only flow with NEW data flow library | +| exceptions.js:53:14:53:21 | source() | exceptions.js:54:10:54:10 | e | only flow with NEW data flow library | +| getters-and-setters.js:53:21:53:28 | source() | getters-and-setters.js:53:10:53:30 | getX(ne ... rce())) | only flow with NEW data flow library | +| nested-props.js:14:15:14:22 | source() | nested-props.js:15:10:15:16 | obj.x.y | only flow with NEW data flow library | +| nested-props.js:19:17:19:24 | source() | nested-props.js:20:10:20:18 | obj.x.y.z | only flow with NEW data flow library | +| nested-props.js:27:18:27:25 | source() | nested-props.js:28:10:28:14 | obj.x | only flow with NEW data flow library | +| nested-props.js:51:22:51:29 | source() | nested-props.js:52:10:52:16 | obj.x.y | only flow with NEW data flow library | +| sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | only flow with NEW data flow library | +| tst.js:2:13:2:20 | source() | tst.js:35:14:35:16 | ary | only flow with NEW data flow library | +| tst.js:2:13:2:20 | source() | tst.js:41:14:41:16 | ary | only flow with NEW data flow library | +flow | access-path-sanitizer.js:2:18:2:25 | source() | access-path-sanitizer.js:4:8:4:12 | obj.x | | advanced-callgraph.js:2:13:2:20 | source() | advanced-callgraph.js:6:22:6:22 | v | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:17:8:17:13 | arr[1] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:22:8:22:13 | arr[6] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:28:8:28:13 | arr[1] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:34:8:34:13 | arr[1] | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:38:8:38:13 | arr[5] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:43:10:43:15 | arr[i] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:55:10:55:15 | arr[i] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:61:10:61:13 | item | @@ -13,18 +38,19 @@ | booleanOps.js:2:11:2:18 | source() | booleanOps.js:13:10:13:10 | x | | booleanOps.js:2:11:2:18 | source() | booleanOps.js:19:10:19:10 | x | | booleanOps.js:2:11:2:18 | source() | booleanOps.js:22:10:22:10 | x | -| bound-function.js:12:12:12:19 | source() | bound-function.js:4:10:4:10 | y | -| bound-function.js:14:6:14:13 | source() | bound-function.js:4:10:4:10 | y | -| bound-function.js:22:8:22:15 | source() | bound-function.js:25:10:25:10 | y | -| bound-function.js:45:10:45:17 | source() | bound-function.js:45:6:45:18 | id3(source()) | -| bound-function.js:49:12:49:19 | source() | bound-function.js:54:6:54:14 | source0() | -| bound-function.js:49:12:49:19 | source() | bound-function.js:55:6:55:14 | source1() | +| bound-function.js:17:21:17:28 | source() | bound-function.js:5:10:5:16 | y.test2 | +| bound-function.js:19:15:19:22 | source() | bound-function.js:6:10:6:16 | y.test3 | +| bound-function.js:50:10:50:17 | source() | bound-function.js:50:6:50:18 | id3(source()) | +| bound-function.js:54:12:54:19 | source() | bound-function.js:59:6:59:14 | source0() | +| bound-function.js:54:12:54:19 | source() | bound-function.js:60:6:60:14 | source1() | | call-apply.js:27:14:27:21 | source() | call-apply.js:24:8:24:11 | arg1 | | call-apply.js:27:14:27:21 | source() | call-apply.js:29:6:29:32 | foo1.ca ... ce, "") | | call-apply.js:27:14:27:21 | source() | call-apply.js:32:6:32:35 | foo1.ap ... e, ""]) | -| call-apply.js:27:14:27:21 | source() | call-apply.js:46:6:46:28 | foo1_ca ... e, ""]) | -| call-apply.js:27:14:27:21 | source() | call-apply.js:68:10:68:21 | arguments[0] | -| call-apply.js:87:17:87:24 | source() | call-apply.js:84:8:84:11 | this | +| call-apply.js:27:14:27:21 | source() | call-apply.js:34:6:34:29 | foo1_ap ... e, ""]) | +| call-apply.js:27:14:27:21 | source() | call-apply.js:40:6:40:28 | foo1_ca ... e, ""]) | +| call-apply.js:27:14:27:21 | source() | call-apply.js:62:10:62:21 | arguments[0] | +| call-apply.js:45:8:45:15 | source() | call-apply.js:55:6:55:13 | foo(obj) | +| call-apply.js:81:17:81:24 | source() | call-apply.js:78:8:78:11 | this | | callbacks.js:4:6:4:13 | source() | callbacks.js:34:27:34:27 | x | | callbacks.js:4:6:4:13 | source() | callbacks.js:35:27:35:27 | x | | callbacks.js:5:6:5:13 | source() | callbacks.js:34:27:34:27 | x | @@ -32,6 +58,10 @@ | callbacks.js:25:16:25:23 | source() | callbacks.js:47:26:47:26 | x | | callbacks.js:25:16:25:23 | source() | callbacks.js:48:26:48:26 | x | | callbacks.js:37:17:37:24 | source() | callbacks.js:37:37:37:37 | x | +| callbacks.js:37:17:37:24 | source() | callbacks.js:38:35:38:35 | x | +| callbacks.js:37:17:37:24 | source() | callbacks.js:41:10:41:10 | x | +| callbacks.js:44:17:44:24 | source() | callbacks.js:37:37:37:37 | x | +| callbacks.js:44:17:44:24 | source() | callbacks.js:38:35:38:35 | x | | callbacks.js:44:17:44:24 | source() | callbacks.js:41:10:41:10 | x | | callbacks.js:50:18:50:25 | source() | callbacks.js:30:29:30:29 | y | | callbacks.js:51:18:51:25 | source() | callbacks.js:30:29:30:29 | y | @@ -39,14 +69,39 @@ | capture-flow.js:9:11:9:18 | source() | capture-flow.js:14:10:14:16 | outer() | | capture-flow.js:9:11:9:18 | source() | capture-flow.js:19:6:19:16 | outerMost() | | capture-flow.js:31:14:31:21 | source() | capture-flow.js:31:6:31:22 | confuse(source()) | +| capture-flow.js:45:12:45:19 | source() | capture-flow.js:45:6:45:20 | test3(source()) | +| capture-flow.js:60:13:60:20 | source() | capture-flow.js:60:6:60:21 | test3a(source()) | +| capture-flow.js:76:13:76:20 | source() | capture-flow.js:76:6:76:21 | test3b(source()) | +| capture-flow.js:89:13:89:20 | source() | capture-flow.js:89:6:89:21 | test3c(source()) | +| capture-flow.js:93:13:93:20 | source() | capture-flow.js:96:6:96:14 | test4()() | +| capture-flow.js:101:12:101:19 | source() | capture-flow.js:101:6:101:22 | test5(source())() | +| capture-flow.js:110:12:110:19 | source() | capture-flow.js:106:14:106:14 | x | +| capture-flow.js:118:37:118:44 | source() | capture-flow.js:114:14:114:14 | x | +| capture-flow.js:126:25:126:32 | source() | capture-flow.js:123:14:123:26 | orderingTaint | +| capture-flow.js:126:25:126:32 | source() | capture-flow.js:129:14:129:26 | orderingTaint | +| capture-flow.js:177:26:177:33 | source() | capture-flow.js:173:14:173:14 | x | +| capture-flow.js:187:34:187:41 | source() | capture-flow.js:183:14:183:14 | x | +| capture-flow.js:195:24:195:31 | source() | capture-flow.js:191:14:191:14 | x | +| capture-flow.js:205:24:205:31 | source() | capture-flow.js:200:18:200:18 | x | +| capture-flow.js:225:13:225:20 | source() | capture-flow.js:220:51:220:59 | fileOrDir | +| capture-flow.js:230:9:230:16 | source() | capture-flow.js:233:14:233:14 | x | +| capture-flow.js:259:23:259:30 | source() | capture-flow.js:243:18:243:40 | objectW ... s.field | +| capture-flow.js:259:23:259:30 | source() | capture-flow.js:247:18:247:40 | objectW ... s.field | +| capture-flow.js:259:23:259:30 | source() | capture-flow.js:248:18:248:27 | this.field | +| capture-flow.js:259:23:259:30 | source() | capture-flow.js:252:14:252:36 | objectW ... s.field | +| capture-flow.js:259:23:259:30 | source() | capture-flow.js:253:14:253:23 | this.field | | captured-sanitizer.js:25:3:25:10 | source() | captured-sanitizer.js:15:10:15:10 | x | -| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:18:8:18:14 | c.taint | -| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:22:8:22:19 | c_safe.taint | -| constructor-calls.js:10:16:10:23 | source() | constructor-calls.js:26:8:26:14 | d.taint | -| constructor-calls.js:10:16:10:23 | source() | constructor-calls.js:30:8:30:19 | d_safe.taint | -| constructor-calls.js:14:15:14:22 | source() | constructor-calls.js:17:8:17:14 | c.param | -| constructor-calls.js:14:15:14:22 | source() | constructor-calls.js:25:8:25:14 | d.param | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:24:8:24:14 | c.taint | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:28:8:28:19 | c_safe.taint | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:40:8:40:14 | e.taint | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:44:8:44:19 | f_safe.taint | +| constructor-calls.js:10:16:10:23 | source() | constructor-calls.js:32:8:32:14 | d.taint | +| constructor-calls.js:10:16:10:23 | source() | constructor-calls.js:36:8:36:19 | d_safe.taint | +| constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:23:8:23:14 | c.param | +| constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:31:8:31:14 | d.param | +| constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:39:8:39:14 | e.param | | exceptions.js:3:15:3:22 | source() | exceptions.js:5:10:5:10 | e | +| exceptions.js:53:14:53:21 | source() | exceptions.js:54:10:54:10 | e | | exceptions.js:59:24:59:31 | source() | exceptions.js:61:12:61:12 | e | | exceptions.js:88:6:88:13 | source() | exceptions.js:11:10:11:10 | e | | exceptions.js:93:11:93:18 | source() | exceptions.js:95:10:95:10 | e | @@ -64,18 +119,24 @@ | getters-and-setters.js:6:20:6:27 | source() | getters-and-setters.js:13:18:13:20 | c.x | | getters-and-setters.js:27:15:27:22 | source() | getters-and-setters.js:23:18:23:18 | v | | getters-and-setters.js:47:23:47:30 | source() | getters-and-setters.js:45:14:45:16 | c.x | +| getters-and-setters.js:53:21:53:28 | source() | getters-and-setters.js:53:10:53:30 | getX(ne ... rce())) | | getters-and-setters.js:60:20:60:27 | source() | getters-and-setters.js:66:10:66:14 | obj.x | | getters-and-setters.js:67:13:67:20 | source() | getters-and-setters.js:63:18:63:22 | value | | getters-and-setters.js:79:20:79:27 | source() | getters-and-setters.js:88:10:88:18 | new C().x | | getters-and-setters.js:79:20:79:27 | source() | getters-and-setters.js:92:14:92:16 | c.x | | getters-and-setters.js:79:20:79:27 | source() | getters-and-setters.js:100:10:100:22 | getX(new C()) | | getters-and-setters.js:89:17:89:24 | source() | getters-and-setters.js:82:18:82:22 | value | +| implied-receiver.js:4:16:4:23 | source() | implied-receiver.js:7:18:7:25 | this.foo | | indexOf.js:4:11:4:18 | source() | indexOf.js:9:10:9:10 | x | | indexOf.js:4:11:4:18 | source() | indexOf.js:13:10:13:10 | x | | nested-props.js:4:13:4:20 | source() | nested-props.js:5:10:5:14 | obj.x | | nested-props.js:9:18:9:25 | source() | nested-props.js:10:10:10:16 | obj.x.y | +| nested-props.js:14:15:14:22 | source() | nested-props.js:15:10:15:16 | obj.x.y | +| nested-props.js:19:17:19:24 | source() | nested-props.js:20:10:20:18 | obj.x.y.z | +| nested-props.js:27:18:27:25 | source() | nested-props.js:28:10:28:14 | obj.x | | nested-props.js:35:13:35:20 | source() | nested-props.js:36:10:36:20 | doLoad(obj) | | nested-props.js:43:13:43:20 | source() | nested-props.js:44:10:44:18 | id(obj).x | +| nested-props.js:51:22:51:29 | source() | nested-props.js:52:10:52:16 | obj.x.y | | nested-props.js:67:31:67:38 | source() | nested-props.js:68:10:68:10 | x | | object-bypass-sanitizer.js:32:21:32:28 | source() | object-bypass-sanitizer.js:15:10:15:24 | sanitizer_id(x) | | object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:27:10:27:30 | sanitiz ... bj.foo) | @@ -97,10 +158,11 @@ | sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:45:8:45:8 | x | | sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:48:10:48:10 | x | | sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:52:10:52:10 | x | +| sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | | sanitizer-guards.js:68:11:68:18 | source() | sanitizer-guards.js:75:8:75:8 | x | | sanitizer-guards.js:79:11:79:18 | source() | sanitizer-guards.js:81:8:81:8 | x | | sanitizer-guards.js:79:11:79:18 | source() | sanitizer-guards.js:84:10:84:10 | x | -| sanitizer-guards.js:79:11:79:18 | source() | sanitizer-guards.js:86:7:86:7 | x | +| sanitizer-guards.js:79:11:79:18 | source() | sanitizer-guards.js:86:9:86:9 | x | | sanitizer-guards.js:91:11:91:18 | source() | sanitizer-guards.js:93:8:93:8 | x | | sanitizer-guards.js:91:11:91:18 | source() | sanitizer-guards.js:96:10:96:10 | x | | sanitizer-guards.js:91:11:91:18 | source() | sanitizer-guards.js:98:7:98:7 | x | @@ -109,4 +171,6 @@ | thisAssignments.js:4:17:4:24 | source() | thisAssignments.js:5:10:5:18 | obj.field | | thisAssignments.js:7:19:7:26 | source() | thisAssignments.js:8:10:8:20 | this.field2 | | tst.js:2:13:2:20 | source() | tst.js:4:10:4:10 | x | +| tst.js:2:13:2:20 | source() | tst.js:35:14:35:16 | ary | +| tst.js:2:13:2:20 | source() | tst.js:41:14:41:16 | ary | | tst.js:2:13:2:20 | source() | tst.js:54:14:54:19 | unsafe | diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.ql b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.ql index 6799b0ffd78..62abcda81a5 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.ql +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.ql @@ -2,26 +2,44 @@ import javascript DataFlow::CallNode getACall(string name) { result.getCalleeName() = name } -class BasicConfig extends DataFlow::Configuration { - BasicConfig() { this = "BasicConfig" } +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node = getACall("source") } - override predicate isSource(DataFlow::Node node) { node = getACall("source") } + predicate isSink(DataFlow::Node node) { node = getACall("sink").getAnArgument() } - override predicate isSink(DataFlow::Node node) { node = getACall("sink").getAnArgument() } - - override predicate isBarrierGuard(DataFlow::BarrierGuardNode node) { + additional predicate isBarrierGuard(DataFlow::BarrierGuardNode node) { node instanceof BasicBarrierGuard } + + predicate isBarrier(DataFlow::Node node) { + node = DataFlow::MakeLegacyBarrierGuard::getABarrierNode() + } } +module TestFlow = DataFlow::Global; + class BasicBarrierGuard extends DataFlow::BarrierGuardNode, DataFlow::CallNode { BasicBarrierGuard() { this = getACall("isSafe") } - override predicate blocks(boolean outcome, Expr e) { + override predicate blocks(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = this.getArgument(0).asExpr() } } -from BasicConfig cfg, DataFlow::Node src, DataFlow::Node sink -where cfg.hasFlow(src, sink) -select src, sink +class LegacyConfig extends DataFlow::Configuration { + LegacyConfig() { this = "LegacyConfig" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } + + override predicate isBarrierGuard(DataFlow::BarrierGuardNode node) { + TestConfig::isBarrierGuard(node) + } +} + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff + +query predicate flow = TestFlow::flow/2; diff --git a/javascript/ql/test/library-tests/TaintTracking/arrays-init.js b/javascript/ql/test/library-tests/TaintTracking/arrays-init.js index 74faa593478..a0f3839d275 100644 --- a/javascript/ql/test/library-tests/TaintTracking/arrays-init.js +++ b/javascript/ql/test/library-tests/TaintTracking/arrays-init.js @@ -1,7 +1,7 @@ (function () { let source = source(); - var str = "FALSE"; + var str = "FALSE"; console.log("=== access by index (init by ctor) ==="); var arr = new Array(2); @@ -24,18 +24,18 @@ console.log("=== access by index (init by [...]) ==="); var arr = [str, source]; - sink(arr[0]); // OK + sink(arr[0]); // OK [INCONSISTENCY] sink(arr[1]); // NOT OK sink(str); // OK console.log("=== access by index (init by [...], array.lenght > 5) ==="); var arr = [str, source, 'b', 'c', 'd', source]; - sink(arr[0]); // OK + sink(arr[0]); // OK [INCONSISTENCY] sink(arr[1]); // NOT OK - sink(arr[2]); // OK - sink(arr[3]); // OK - sink(arr[4]); // OK - sink(arr[5]); // NOT OK - but not flagged [INCONSISTENCY] + sink(arr[2]); // OK [INCONSISTENCY] + sink(arr[3]); // OK [INCONSISTENCY] + sink(arr[4]); // OK [INCONSISTENCY] + sink(arr[5]); // NOT OK console.log("=== access in for (init by [...]) ==="); var arr = [str, source]; @@ -58,6 +58,6 @@ console.log("=== access in forof (init by [...]) ==="); var arr = [str, source]; for (const item of arr) { - sink(item); // NOT OK + sink(item); // NOT OK } -}()); \ No newline at end of file +}()); diff --git a/javascript/ql/test/library-tests/TaintTracking/booleanOps.js b/javascript/ql/test/library-tests/TaintTracking/booleanOps.js index 876d43bbc39..6cb0d6cea33 100644 --- a/javascript/ql/test/library-tests/TaintTracking/booleanOps.js +++ b/javascript/ql/test/library-tests/TaintTracking/booleanOps.js @@ -1,23 +1,23 @@ function test() { let x = source(); - + sink(x); // NOT OK - + if (x === 'a') sink(x); // OK - + if (x === 'a' || x === 'b') sink(x); // OK - + if (x === 'a' || 1 === 1) sink(x); // NOT OK if (isSafe(x)) sink(x); // OK - + if (isSafe(x, y) || isSafe(x, z)) - sink(x); // OK - + sink(x); // OK [INCONSISTENCY] + if (isSafe(x) || 1 === 1) sink(x); // NOT OK } diff --git a/javascript/ql/test/library-tests/TaintTracking/bound-function.js b/javascript/ql/test/library-tests/TaintTracking/bound-function.js index b38dee1c922..bc74312ea61 100644 --- a/javascript/ql/test/library-tests/TaintTracking/bound-function.js +++ b/javascript/ql/test/library-tests/TaintTracking/bound-function.js @@ -1,28 +1,33 @@ import * as dummy from 'dummy'; function foo(x, y) { - sink(y); + sink(y.test1); // OK + sink(y.test2); // NOT OK + sink(y.test3); // NOT OK + sink(y.test4); // OK + sink(y.test5); // OK + sink(y.test6); // OK } let foo0 = foo.bind(null); let foo1 = foo.bind(null, null); let foo2 = foo.bind(null, null, null); -foo0(source(), null); // OK -foo0(null, source()); // NOT OK +foo0({ test1: source() }, null); +foo0(null, { test2: source() }); -foo1(source()); // NOT OK -foo1(null, source()); // OK +foo1({ test3: source() }); +foo1(null, { test4: source() }); -foo2(source()); // OK -foo2(null, source()); // OK +foo2({ test5: source() }); +foo2(null, { test6: source() }); function takesCallback(cb) { - cb(source()); // NOT OK + cb(source()); } function callback(x, y) { - sink(y); + sink(y); // NOT OK [INCONSISTENCY] - lambda flow in dataflow2 does not handle partial invocations yet } takesCallback(callback.bind(null, null)); @@ -33,7 +38,7 @@ function id(x) { let sourceGetter = id.bind(null, source()); let constGetter = id.bind(null, 'safe'); -sink(sourceGetter()); // NOT OK - but not flagged +sink(sourceGetter()); // NOT OK [INCONSISTENCY] sink(constGetter()); // OK function id2(x, y) { diff --git a/javascript/ql/test/library-tests/TaintTracking/call-apply.js b/javascript/ql/test/library-tests/TaintTracking/call-apply.js index e26e3aa3835..0782ad71bab 100644 --- a/javascript/ql/test/library-tests/TaintTracking/call-apply.js +++ b/javascript/ql/test/library-tests/TaintTracking/call-apply.js @@ -30,21 +30,15 @@ sink(foo1.call(null, source, "")); // NOT OK sink(foo2.call(null, source, "")); // OK sink(foo1.apply(null, [source, ""])); // NOT OK -sink(foo2.apply(null, [source, ""])); // OK - -// doesn't work due to fundamental limitations of our dataflow analysis. -// exactly (and I mean exactly) the same thing happens in the below `obj.foo` example. -// in general we don't track flow that first goes through a call, and then a return, unless we can summarize it. -// in the other examples we can summarize the flow, because it's quite simple, but here we can't. -// (try to read the QLDoc in the top of `Configuration.qll`, that might help). -sink(foo1_apply([source, ""])); // NOT OK - but not flagged [INCONSISTENCY] +sink(foo2.apply(null, [source, ""])); // OK [INCONSISTENCY] +sink(foo1_apply([source, ""])); // NOT OK foo1_apply_sink([source, ""]); // This works, because we don't need a return after a call (the sink is inside the called function). sink(foo1_apply.apply(["", source])); // OK sink(foo1_call([source, ""])); // NOT OK -sink(foo1_call(["", source])); // OK +sink(foo1_call(["", source])); // OK [INCONSISTENCY] var obj = { @@ -58,21 +52,21 @@ function foo(x) { function bar(x) { return x.foo; } -sink(foo(obj)); // NOT OK - but not flagged [INCONSISTENCY] +sink(foo(obj)); // NOT OK function argumentsObject() { function sinkArguments1() { - sink(arguments[1]); // OK + sink(arguments[1]); // OK [INCONSISTENCY] } function sinkArguments0() { sink(arguments[0]); // NOT OK } - + function fowardArguments() { sinkArguments1.apply(this, arguments); sinkArguments0.apply(this, arguments); } - + fowardArguments.apply(this, [source, ""]); } @@ -84,4 +78,4 @@ function sinksThis2() { sink(this); // NOT OK } -sinksThis.apply(source(), []); \ No newline at end of file +sinksThis.apply(source(), []); diff --git a/javascript/ql/test/library-tests/TaintTracking/callbacks.js b/javascript/ql/test/library-tests/TaintTracking/callbacks.js index e317514f88f..62299defcd9 100644 --- a/javascript/ql/test/library-tests/TaintTracking/callbacks.js +++ b/javascript/ql/test/library-tests/TaintTracking/callbacks.js @@ -35,8 +35,8 @@ function test() { provideTaint2(x => sink(x)); // NOT OK forwardTaint2(source(), x => sink(x)); // NOT OK - forwardTaint2("safe", x => sink(x)); // OK - + forwardTaint2("safe", x => sink(x)); // OK [INCONSISTENCY] + function helper1(x) { sink(x); // NOT OK return x; diff --git a/javascript/ql/test/library-tests/TaintTracking/capture-flow.js b/javascript/ql/test/library-tests/TaintTracking/capture-flow.js index af50e7523a9..bb9dc523bb8 100644 --- a/javascript/ql/test/library-tests/TaintTracking/capture-flow.js +++ b/javascript/ql/test/library-tests/TaintTracking/capture-flow.js @@ -29,3 +29,231 @@ function confuse(x) { sink(confuse('safe')); // OK sink(confuse(source())); // NOT OK + +function test3(param) { + var x; + function one() { + x = param; + } + function two() { + one(); + return x; + } + return two(); +} + +sink(test3(source())); // NOT OK +sink(test3("safe")); // OK + +function test3a(param) { + var x; + function one() { + x = param; + } + one(); + function two() { + return x; + } + return two(); +} + +sink(test3a(source())); // NOT OK +sink(test3a("safe")); // OK + +function test3b(param) { + var x; + function one() { + x = param; + } + one(); + function two() { + one(); + return x; + } + return two(); +} + +sink(test3b(source())); // NOT OK +sink(test3b("safe")); // OK + +function test3c(param) { + function one() { + return param; + } + function two() { + return one(); + } + return two(); +} + +sink(test3c(source())); // NOT OK +sink(test3c("safe")); // OK + +function test4() { + var x = source(); + return () => x; +} +sink(test4()()); // NOT OK + +function test5(x) { + return () => x; +} +sink(test5(source())()); // NOT OK +sink(test5("safe")()); // OK + +function testEscape(x) { + function escapingFunction() { + sink(x); // NOT OK + } + global.doEscape(escapingFunction); +} +testEscape(source()); + +function testEscapeViaReturn(x) { + function escapingFunction() { + sink(x); // NOT OK + } + return escapingFunction; +} +global.doEscape(testEscapeViaReturn(source())); + +function ordering() { + var orderingTaint; + global.addEventListener('click', () => { + sink(orderingTaint); // NOT OK + }); + global.addEventListener('load', () => { + orderingTaint = source(); + }); + global.addEventListener('click', () => { + sink(orderingTaint); // NOT OK + }); +} +ordering(); + +function makeSafe(x) { + console.log(x); + return "safe"; +} +function flowSensitiveParamUpdate(x) { + x = makeSafe(x); + function captureX() { + console.log(x); + } + captureX(); + sink(x); // OK +} +flowSensitiveParamUpdate(source()); + +function flowSensitiveLocalUpdate() { + let x = source(); + x = makeSafe(x); + function captureX() { + console.log(x); + } + captureX(); + sink(x); // OK +} +flowSensitiveLocalUpdate(); + +function flowSensitiveLocalIncrement() { + let x = source(); + ++x; + function captureX() { + console.log(x); + } + captureX(); + sink(x); // OK +} +flowSensitiveLocalIncrement(); + +function destructuredVarDecl(param) { + let { x } = param; + function inner() { + sink(x); // NOT OK + } + inner(); +} +destructuredVarDecl({ x: source() }); + +function destructuredLocalAssignment(param) { + let x; + ({ x } = param); + function inner() { + sink(x); // NOT OK + } + inner(); +} +destructuredLocalAssignment({ x: source() }); + +function destructuredParam({ x }) { + function inner() { + sink(x); // NOT OK + } + inner(); +} +destructuredParam({ x: source() }); + +function destructuredLoop(data) { + for (let { x } of data) { + function inner() { + sink(x); // NOT OK + } + inner(); + } +} +destructuredLoop([{ x: source() }]); + + +function testPromise(arg) { + function transform(x) { + return { prop: x }; + } + class Foo { + updatePrVisibility(y) { + const { prop: variable } = transform(y); + this.exists(variable).then(() => { + transform(variable); + }); + } + exists(fileOrDir) { + return new Promise(resolve => fs.sink(fileOrDir, err => resolve(!err))); // NOT OK + } + } + new Foo().updatePrVisibility(arg); +} +testPromise(source()); + +function sinkInner() { + var x = "safe"; + console.log(x); + x = source(); + console.log(x); + function inner() { + sink(x); // NOT OK + } + inner(); +} +sinkInner(); + +function testObjectWithMethods(taint) { + const objectWithMethods = { + field: taint, + arrowFunction: () => { + sink(objectWithMethods.field); // NOT OK + sink(this.field); // OK - refers to outer 'this' + }, + regularFunction() { + sink(objectWithMethods.field); // NOT OK + sink(this.field); // NOT OK + }, + }; + objectWithMethods.functionAddedLater = function() { + sink(objectWithMethods.field); // NOT OK + sink(this.field); // NOT OK + }; + objectWithMethods.arrowFunction(); + objectWithMethods.regularFunction(); + objectWithMethods.functionAddedLater(); +} +testObjectWithMethods(source()); diff --git a/javascript/ql/test/library-tests/TaintTracking/constructor-calls.js b/javascript/ql/test/library-tests/TaintTracking/constructor-calls.js index c5991552787..049bf486e5c 100644 --- a/javascript/ql/test/library-tests/TaintTracking/constructor-calls.js +++ b/javascript/ql/test/library-tests/TaintTracking/constructor-calls.js @@ -10,22 +10,36 @@ function JsClass(param) { this.taint = source(); } +class SubClass extends EcmaClass { + constructor(param) { + super(param); + } +} + function test() { let taint = source(); let c = new EcmaClass(taint); sink(c.param); // NOT OK sink(c.taint); // NOT OK - + let c_safe = new EcmaClass("safe"); sink(c_safe.param); // OK sink(c_safe.taint); // NOT OK - + let d = new JsClass(taint); sink(d.param); // NOT OK sink(d.taint); // NOT OK - + let d_safe = new JsClass("safe"); sink(d_safe.param); // OK sink(d_safe.taint); // NOT OK + + let e = new SubClass(taint); + sink(e.param); // NOT OK + sink(e.taint); // NOT OK + + let f_safe = new SubClass("safe"); + sink(f_safe.param); // OK + sink(f_safe.taint); // NOT OK } diff --git a/javascript/ql/test/library-tests/TaintTracking/exceptions.js b/javascript/ql/test/library-tests/TaintTracking/exceptions.js index 72d822be9ad..6ada4f4fb50 100644 --- a/javascript/ql/test/library-tests/TaintTracking/exceptions.js +++ b/javascript/ql/test/library-tests/TaintTracking/exceptions.js @@ -23,7 +23,7 @@ function test(unsafe, safe) { sink(e); // NOT OK sink(e.toString()); // NOT OK sink(e.message); // NOT OK - sink(e.fileName); // OK - but flagged anyway + sink(e.fileName); // OK - but flagged anyway [INCONSISTENCY] } try { @@ -32,16 +32,16 @@ function test(unsafe, safe) { sink(e); // NOT OK sink(e.toString()); // NOT OK sink(e.message); // NOT OK - sink(e.fileName); // OK - but flagged anyway + sink(e.fileName); // OK - but flagged anyway [INCONSISTENCY] } try { throwError2(safe); } catch (e) { - sink(e); // NOT OK - sink(e.toString()); // NOT OK - sink(e.message); // NOT OK - sink(e.fileName); // OK - but flagged anyway + sink(e); // OK + sink(e.toString()); // OK + sink(e.message); // OK + sink(e.fileName); // OK } try { @@ -51,14 +51,14 @@ function test(unsafe, safe) { } throwAsync(source()).catch(e => { - sink(e); // NOT OK - but not flagged + sink(e); // NOT OK }); async function asyncTester() { try { await throwAsync(source()); } catch (e) { - sink(e); // NOT OK - but not flagged + sink(e); // NOT OK } } } diff --git a/javascript/ql/test/library-tests/TaintTracking/getters-and-setters.js b/javascript/ql/test/library-tests/TaintTracking/getters-and-setters.js index 4fae44d083c..677110e003a 100644 --- a/javascript/ql/test/library-tests/TaintTracking/getters-and-setters.js +++ b/javascript/ql/test/library-tests/TaintTracking/getters-and-setters.js @@ -50,7 +50,7 @@ function testFlowThroughGetter() { function getX(c) { return c.x; } - sink(getX(new C(source()))); // NOT OK - but not flagged + sink(getX(new C(source()))); // NOT OK getX(null); } @@ -67,7 +67,7 @@ function testFlowThroughObjectLiteralAccessors() { obj.y = source(); function indirection(c) { - sink(c.x); // NOT OK - but not currently flagged + sink(c.x); // NOT OK - but not currently flagged [INCONSISTENCY] } indirection(obj); indirection(null); diff --git a/javascript/ql/test/library-tests/TaintTracking/implied-receiver.js b/javascript/ql/test/library-tests/TaintTracking/implied-receiver.js new file mode 100644 index 00000000000..5fb230ee7b6 --- /dev/null +++ b/javascript/ql/test/library-tests/TaintTracking/implied-receiver.js @@ -0,0 +1,11 @@ +import 'dummy'; + +function Foo() { + this.foo = source(); + var obj = { + bar: function() { + sink(this.foo); // NOT OK + } + }; + Object.assign(this, obj); +} diff --git a/javascript/ql/test/library-tests/TaintTracking/nested-props.js b/javascript/ql/test/library-tests/TaintTracking/nested-props.js index a5ea3cc248b..e3878b1a185 100644 --- a/javascript/ql/test/library-tests/TaintTracking/nested-props.js +++ b/javascript/ql/test/library-tests/TaintTracking/nested-props.js @@ -57,7 +57,7 @@ function doLoadLoad(obj) { } function storeBackloadCallLoadLoadReturn(obj) { obj.x.y = source(); - sink(doLoadStore(obj)); // NOT OK - but not found + sink(doLoadStore(obj)); // NOT OK - but not found [INCONSISTENCY] } function doStoreReturn(val) { diff --git a/javascript/ql/test/library-tests/TaintTracking/object-bypass-sanitizer.js b/javascript/ql/test/library-tests/TaintTracking/object-bypass-sanitizer.js index 129b3ed7b32..bc12c0162b6 100644 --- a/javascript/ql/test/library-tests/TaintTracking/object-bypass-sanitizer.js +++ b/javascript/ql/test/library-tests/TaintTracking/object-bypass-sanitizer.js @@ -20,12 +20,12 @@ function useTaintedValue(x) { function useTaintedObject(obj) { if (isSafe(obj)) { sink(obj); // OK - sink(obj.foo); // NOT OK + sink(obj.foo); // NOT OK [INCONSISTENCY] - FN caused by barriers blocking content flow } sink(sanitizer_id(obj)); // OK sink(sanitizer_id(obj.foo)); // OK - sink(sanitizer_id(obj).foo); // NOT OK + sink(sanitizer_id(obj).foo); // NOT OK [INCONSISTENCY] - FN caused by barriers blocking content flow } function test() { diff --git a/javascript/ql/test/library-tests/TaintTracking/partialCalls.js b/javascript/ql/test/library-tests/TaintTracking/partialCalls.js index e673538005c..1fc61e96ffd 100644 --- a/javascript/ql/test/library-tests/TaintTracking/partialCalls.js +++ b/javascript/ql/test/library-tests/TaintTracking/partialCalls.js @@ -42,7 +42,7 @@ function test() { let taintGetter = id.bind(null, taint); sink(taintGetter); // OK - this is a function object - sink(taintGetter()); // NOT OK - but not currently detected + sink(taintGetter()); // NOT OK - but not currently detected [INCONSISTENCY] function safearray(x) { sink(x); // OK diff --git a/javascript/ql/test/library-tests/TaintTracking/promise.js b/javascript/ql/test/library-tests/TaintTracking/promise.js index 9714d258df5..84c972f4d68 100644 --- a/javascript/ql/test/library-tests/TaintTracking/promise.js +++ b/javascript/ql/test/library-tests/TaintTracking/promise.js @@ -10,5 +10,31 @@ function closure() { sink(Promise.resolve(source())); // NOT OK let resolver = Promise.withResolver(); resolver.resolve(source()); - sink(resolver.promise); // NOT OK -} \ No newline at end of file + sink(resolver.promise); // NOT OK [INCONSISTENCY] - flow summary for withResolver() currently not working +} + +function exceptionThroughThen() { + return new Promise((resolve, reject) => { + reject(new Error(source())); + }) + .then(x => "safe") + .then(x => "safe") + .then(x => "safe") + .catch(e => { + sink(e); // NOT OK + }) +} + +function exceptionThroughThen2() { + return new Promise((resolve, reject) => { + resolve("safe") + }) + .then(x => { + throw new Error(source()) + }) + .then(x => "safe") + .then(x => "safe") + .catch(e => { + sink(e); // NOT OK + }) +} diff --git a/javascript/ql/test/library-tests/TaintTracking/sanitizer-guards.js b/javascript/ql/test/library-tests/TaintTracking/sanitizer-guards.js index 8aaa9fd24e2..14f4139ca08 100644 --- a/javascript/ql/test/library-tests/TaintTracking/sanitizer-guards.js +++ b/javascript/ql/test/library-tests/TaintTracking/sanitizer-guards.js @@ -1,8 +1,8 @@ function test() { let x = source(); - + sink(x); // NOT OK - + if (isSafe(x)) { sink(x); // OK } @@ -18,7 +18,7 @@ class C { sink(this.x); // OK addEventListener('hey', () => { - sink(this.x); // OK - but still flagged + sink(this.x); // OK - but still flagged [INCONSISTENCY] }); } @@ -61,7 +61,7 @@ function phi() { } else { x = null; } - sink(x); // OK + sink(x); // OK [INCONSISTENCY] - dataflow2 cannot block the phi edge } function phi2() { @@ -77,13 +77,13 @@ function phi2() { function falsy() { let x = source(); - + sink(x); // NOT OK - + if (x) { - sink(x); // OK (for taint-tracking) + sink(x); // NOT OK (for taint-tracking) } else { - sink(x); // NOT OK + sink(x); // OK } } diff --git a/javascript/ql/test/library-tests/TaintTracking/stringification-read-steps.js b/javascript/ql/test/library-tests/TaintTracking/stringification-read-steps.js new file mode 100644 index 00000000000..a17bd43aa69 --- /dev/null +++ b/javascript/ql/test/library-tests/TaintTracking/stringification-read-steps.js @@ -0,0 +1,31 @@ +import 'dummy'; + +function makeObject() { + return { + foo: { + bar: { + baz: source() + } + } + }; +} + +function test() { + const object = makeObject(); + + sink(object); // OK + sink(JSON.stringify(object)); // NOT OK + sink(object); // OK +} + +function testCapture() { + const object = makeObject(); + + sink(object); // OK + sink(JSON.stringify(object)); // NOT OK + sink(object); // OK - use-use flow should not see the effects of the implicit read in JSON.stringify + + function capture() { + object; + } +} From 85e8998067984c21406e6912bef0e24f607e2c44 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 15:16:48 +0200 Subject: [PATCH 143/514] JS: Update ImportEquals test --- .../TypeScript/ImportEquals/tests.expected | 3 ++- .../TypeScript/ImportEquals/tests.ql | 22 +++++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/javascript/ql/test/library-tests/TypeScript/ImportEquals/tests.expected b/javascript/ql/test/library-tests/TypeScript/ImportEquals/tests.expected index 4299e997ca8..d891fe49179 100644 --- a/javascript/ql/test/library-tests/TypeScript/ImportEquals/tests.expected +++ b/javascript/ql/test/library-tests/TypeScript/ImportEquals/tests.expected @@ -1,3 +1,4 @@ +legacyDataFlowDifference dataFlowModuleImports | ./esDefaultExport | tst.ts:1:26:1:53 | require ... xport') | | ./esNamedExports | tst.ts:2:18:2:44 | require ... ports') | @@ -29,4 +30,4 @@ resolution | tst.ts:10:1:10:20 | new NodeFullExport() | nodeFullExport.ts:3:18:3:40 | class N ... port {} | tst.ts | NodeFullExport | nodeFullExport.ts | | tst.ts:11:1:11:31 | new nod ... xport() | nodeNamedExport.ts:3:27:3:50 | class N ... port {} | tst.ts | NodeNamedExport | nodeNamedExport.ts | taint -| test taint config | taintSource.ts:3:27:3:47 | externa ... ource() | tst.ts:18:19:18:42 | taintSo ... edValue | +| taintSource.ts:3:27:3:47 | externa ... ource() | tst.ts:18:19:18:42 | taintSo ... edValue | diff --git a/javascript/ql/test/library-tests/TypeScript/ImportEquals/tests.ql b/javascript/ql/test/library-tests/TypeScript/ImportEquals/tests.ql index c7bc1929209..caa919ffe8d 100644 --- a/javascript/ql/test/library-tests/TypeScript/ImportEquals/tests.ql +++ b/javascript/ql/test/library-tests/TypeScript/ImportEquals/tests.ql @@ -38,18 +38,26 @@ query predicate resolution( klassFile = klass.getFile().getBaseName() } -class TaintConfig extends TaintTracking::Configuration { - TaintConfig() { this = "test taint config" } - - override predicate isSource(DataFlow::Node node) { +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node = DataFlow::moduleImport("externalTaintSource").getACall() } - override predicate isSink(DataFlow::Node node) { + predicate isSink(DataFlow::Node node) { node = DataFlow::moduleImport("externalTaintSink").getACall().getArgument(0) } } -query predicate taint(TaintConfig cfg, DataFlow::Node source, DataFlow::Node sink) { - cfg.hasFlow(source, sink) +module TestFlow = TaintTracking::Global; + +query predicate taint = TestFlow::flow/2; + +class LegacyConfig extends TaintTracking::Configuration { + LegacyConfig() { this = "LegacyConfig" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } + +import testUtilities.LegacyDataFlowDiff::DataFlowDiff From bab639f23caa8da4949693dfe362f783f638cdcf Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 15:25:07 +0200 Subject: [PATCH 144/514] JS: Update ReflectedXssWithCustomSanitizer test --- .../ReflectedXss/ReflectedXssWithCustomSanitizer.ql | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.ql b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.ql index 3fcf8c0377b..b9c4107a6ad 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.ql @@ -3,18 +3,17 @@ // import javascript import semmle.javascript.security.dataflow.ReflectedXssQuery +private import semmle.javascript.security.dataflow.Xss::Shared as SharedXss -class IsVarNameSanitizer extends TaintTracking::AdditionalSanitizerGuardNode, DataFlow::CallNode { +class IsVarNameSanitizer extends SharedXss::BarrierGuard, DataFlow::CallNode { IsVarNameSanitizer() { this.getCalleeName() = "isVarName" } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = this.getArgument(0).asExpr() } - - override predicate appliesTo(TaintTracking::Configuration cfg) { cfg instanceof Configuration } } -from Configuration xss, Source source, Sink sink -where xss.hasFlow(source, sink) +from Source source, Sink sink +where ReflectedXssFlow::flow(source, sink) select sink, "Cross-site scripting vulnerability due to $@.", source, "user-provided value" From 9b46c4596c9c1343d2131a6d7df0ee3636c7ce76 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 15:25:47 +0200 Subject: [PATCH 145/514] JS: Update HeuristicSoruceCodeInjection test --- .../HeuristicSourceCodeInjection.expected | 393 +++++------------- .../HeuristicSourceCodeInjection.ql | 6 +- 2 files changed, 96 insertions(+), 303 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected index 7e4bd305955..cdeea504be4 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected @@ -1,342 +1,135 @@ -nodes -| NoSQLCodeInjection.js:18:24:18:31 | req.body | -| NoSQLCodeInjection.js:18:24:18:31 | req.body | -| NoSQLCodeInjection.js:18:24:18:37 | req.body.query | -| NoSQLCodeInjection.js:18:24:18:37 | req.body.query | -| NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | -| NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | -| NoSQLCodeInjection.js:19:36:19:43 | req.body | -| NoSQLCodeInjection.js:19:36:19:43 | req.body | -| NoSQLCodeInjection.js:19:36:19:48 | req.body.name | -| NoSQLCodeInjection.js:22:24:22:48 | "name = ... dy.name | -| NoSQLCodeInjection.js:22:24:22:48 | "name = ... dy.name | -| NoSQLCodeInjection.js:22:36:22:43 | req.body | -| NoSQLCodeInjection.js:22:36:22:43 | req.body | -| NoSQLCodeInjection.js:22:36:22:48 | req.body.name | -| actions.js:4:10:4:50 | github. ... message | -| actions.js:4:10:4:50 | github. ... message | -| actions.js:4:10:4:50 | github. ... message | -| angularjs.js:10:22:10:36 | location.search | -| angularjs.js:10:22:10:36 | location.search | -| angularjs.js:10:22:10:36 | location.search | -| angularjs.js:13:23:13:37 | location.search | -| angularjs.js:13:23:13:37 | location.search | -| angularjs.js:13:23:13:37 | location.search | -| angularjs.js:16:28:16:42 | location.search | -| angularjs.js:16:28:16:42 | location.search | -| angularjs.js:16:28:16:42 | location.search | -| angularjs.js:19:22:19:36 | location.search | -| angularjs.js:19:22:19:36 | location.search | -| angularjs.js:19:22:19:36 | location.search | -| angularjs.js:22:27:22:41 | location.search | -| angularjs.js:22:27:22:41 | location.search | -| angularjs.js:22:27:22:41 | location.search | -| angularjs.js:25:23:25:37 | location.search | -| angularjs.js:25:23:25:37 | location.search | -| angularjs.js:25:23:25:37 | location.search | -| angularjs.js:28:33:28:47 | location.search | -| angularjs.js:28:33:28:47 | location.search | -| angularjs.js:28:33:28:47 | location.search | -| angularjs.js:31:28:31:42 | location.search | -| angularjs.js:31:28:31:42 | location.search | -| angularjs.js:31:28:31:42 | location.search | -| angularjs.js:34:18:34:32 | location.search | -| angularjs.js:34:18:34:32 | location.search | -| angularjs.js:34:18:34:32 | location.search | -| angularjs.js:40:18:40:32 | location.search | -| angularjs.js:40:18:40:32 | location.search | -| angularjs.js:40:18:40:32 | location.search | -| angularjs.js:44:17:44:31 | location.search | -| angularjs.js:44:17:44:31 | location.search | -| angularjs.js:44:17:44:31 | location.search | -| angularjs.js:47:16:47:30 | location.search | -| angularjs.js:47:16:47:30 | location.search | -| angularjs.js:47:16:47:30 | location.search | -| angularjs.js:50:22:50:36 | location.search | -| angularjs.js:50:22:50:36 | location.search | -| angularjs.js:50:22:50:36 | location.search | -| angularjs.js:53:32:53:46 | location.search | -| angularjs.js:53:32:53:46 | location.search | -| angularjs.js:53:32:53:46 | location.search | -| eslint-escope-build.js:20:22:20:22 | c | -| eslint-escope-build.js:20:22:20:22 | c | -| eslint-escope-build.js:21:16:21:16 | c | -| eslint-escope-build.js:21:16:21:16 | c | -| express.js:7:24:7:69 | "return ... + "];" | -| express.js:7:24:7:69 | "return ... + "];" | -| express.js:7:44:7:62 | req.param("wobble") | -| express.js:7:44:7:62 | req.param("wobble") | -| express.js:9:34:9:79 | "return ... + "];" | -| express.js:9:34:9:79 | "return ... + "];" | -| express.js:9:54:9:72 | req.param("wobble") | -| express.js:9:54:9:72 | req.param("wobble") | -| express.js:12:8:12:53 | "return ... + "];" | -| express.js:12:8:12:53 | "return ... + "];" | -| express.js:12:28:12:46 | req.param("wobble") | -| express.js:12:28:12:46 | req.param("wobble") | -| express.js:15:22:15:54 | req.par ... ction") | -| express.js:15:22:15:54 | req.par ... ction") | -| express.js:15:22:15:54 | req.par ... ction") | -| express.js:17:30:17:53 | req.par ... cript") | -| express.js:17:30:17:53 | req.par ... cript") | -| express.js:17:30:17:53 | req.par ... cript") | -| express.js:19:37:19:70 | req.par ... odule") | -| express.js:19:37:19:70 | req.par ... odule") | -| express.js:19:37:19:70 | req.par ... odule") | -| express.js:21:19:21:48 | req.par ... ntext") | -| express.js:21:19:21:48 | req.par ... ntext") | -| express.js:21:19:21:48 | req.par ... ntext") | -| express.js:26:9:26:35 | taint | -| express.js:26:17:26:35 | req.param("wobble") | -| express.js:26:17:26:35 | req.param("wobble") | -| express.js:27:34:27:38 | taint | -| express.js:27:34:27:38 | taint | -| express.js:34:9:34:35 | taint | -| express.js:34:17:34:35 | req.param("wobble") | -| express.js:34:17:34:35 | req.param("wobble") | -| express.js:43:15:43:19 | taint | -| express.js:43:15:43:19 | taint | -| express.js:49:30:49:32 | msg | -| express.js:49:30:49:32 | msg | -| express.js:50:10:50:12 | msg | -| express.js:50:10:50:12 | msg | -| module.js:9:16:9:29 | req.query.code | -| module.js:9:16:9:29 | req.query.code | -| module.js:9:16:9:29 | req.query.code | -| module.js:11:17:11:30 | req.query.code | -| module.js:11:17:11:30 | req.query.code | -| module.js:11:17:11:30 | req.query.code | -| react-native.js:7:7:7:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:8:32:8:38 | tainted | -| react-native.js:8:32:8:38 | tainted | -| react-native.js:10:23:10:29 | tainted | -| react-native.js:10:23:10:29 | tainted | -| react.js:10:56:10:77 | documen ... on.hash | -| react.js:10:56:10:77 | documen ... on.hash | -| react.js:10:56:10:77 | documen ... on.hash | -| template-sinks.js:18:9:18:31 | tainted | -| template-sinks.js:18:19:18:31 | req.query.foo | -| template-sinks.js:18:19:18:31 | req.query.foo | -| template-sinks.js:20:17:20:23 | tainted | -| template-sinks.js:20:17:20:23 | tainted | -| template-sinks.js:21:16:21:22 | tainted | -| template-sinks.js:21:16:21:22 | tainted | -| template-sinks.js:22:18:22:24 | tainted | -| template-sinks.js:22:18:22:24 | tainted | -| template-sinks.js:23:17:23:23 | tainted | -| template-sinks.js:23:17:23:23 | tainted | -| template-sinks.js:24:18:24:24 | tainted | -| template-sinks.js:24:18:24:24 | tainted | -| template-sinks.js:25:16:25:22 | tainted | -| template-sinks.js:25:16:25:22 | tainted | -| template-sinks.js:26:27:26:33 | tainted | -| template-sinks.js:26:27:26:33 | tainted | -| template-sinks.js:27:21:27:27 | tainted | -| template-sinks.js:27:21:27:27 | tainted | -| template-sinks.js:28:17:28:23 | tainted | -| template-sinks.js:28:17:28:23 | tainted | -| template-sinks.js:29:24:29:30 | tainted | -| template-sinks.js:29:24:29:30 | tainted | -| template-sinks.js:30:21:30:27 | tainted | -| template-sinks.js:30:21:30:27 | tainted | -| template-sinks.js:31:19:31:25 | tainted | -| template-sinks.js:31:19:31:25 | tainted | -| template-sinks.js:32:16:32:22 | tainted | -| template-sinks.js:32:16:32:22 | tainted | -| template-sinks.js:33:17:33:23 | tainted | -| template-sinks.js:33:17:33:23 | tainted | -| tst.js:2:6:2:27 | documen ... on.href | -| tst.js:2:6:2:27 | documen ... on.href | -| tst.js:2:6:2:83 | documen ... t=")+8) | -| tst.js:2:6:2:83 | documen ... t=")+8) | -| tst.js:5:12:5:33 | documen ... on.hash | -| tst.js:5:12:5:33 | documen ... on.hash | -| tst.js:5:12:5:33 | documen ... on.hash | -| tst.js:14:10:14:33 | documen ... .search | -| tst.js:14:10:14:33 | documen ... .search | -| tst.js:14:10:14:74 | documen ... , "$1") | -| tst.js:14:10:14:74 | documen ... , "$1") | -| tst.js:17:21:17:42 | documen ... on.hash | -| tst.js:17:21:17:42 | documen ... on.hash | -| tst.js:17:21:17:42 | documen ... on.hash | -| tst.js:20:30:20:51 | documen ... on.hash | -| tst.js:20:30:20:51 | documen ... on.hash | -| tst.js:20:30:20:51 | documen ... on.hash | -| tst.js:23:6:23:46 | atob(do ... ing(1)) | -| tst.js:23:6:23:46 | atob(do ... ing(1)) | -| tst.js:23:11:23:32 | documen ... on.hash | -| tst.js:23:11:23:32 | documen ... on.hash | -| tst.js:23:11:23:45 | documen ... ring(1) | -| tst.js:26:26:26:40 | location.search | -| tst.js:26:26:26:40 | location.search | -| tst.js:26:26:26:53 | locatio ... ring(1) | -| tst.js:26:26:26:53 | locatio ... ring(1) | -| tst.js:29:9:29:82 | source | -| tst.js:29:18:29:41 | documen ... .search | -| tst.js:29:18:29:41 | documen ... .search | -| tst.js:29:18:29:82 | documen ... , "$1") | -| tst.js:31:18:31:23 | source | -| tst.js:31:18:31:23 | source | -| tst.js:33:14:33:19 | source | -| tst.js:33:14:33:19 | source | -| tst.js:35:28:35:33 | source | -| tst.js:35:28:35:33 | source | -| tst.js:37:33:37:38 | source | -| tst.js:37:33:37:38 | source | -| webix/webix.html:3:16:3:37 | documen ... on.hash | -| webix/webix.html:3:16:3:37 | documen ... on.hash | -| webix/webix.html:3:16:3:37 | documen ... on.hash | -| webix/webix.html:4:26:4:47 | documen ... on.hash | -| webix/webix.html:4:26:4:47 | documen ... on.hash | -| webix/webix.html:4:26:4:47 | documen ... on.hash | -| webix/webix.html:5:47:5:68 | documen ... on.hash | -| webix/webix.html:5:47:5:68 | documen ... on.hash | -| webix/webix.html:5:47:5:68 | documen ... on.hash | -| webix/webix.js:3:12:3:33 | documen ... on.hash | -| webix/webix.js:3:12:3:33 | documen ... on.hash | -| webix/webix.js:3:12:3:33 | documen ... on.hash | -| webix/webix.js:4:22:4:43 | documen ... on.hash | -| webix/webix.js:4:22:4:43 | documen ... on.hash | -| webix/webix.js:4:22:4:43 | documen ... on.hash | -| webix/webix.js:5:43:5:64 | documen ... on.hash | -| webix/webix.js:5:43:5:64 | documen ... on.hash | -| webix/webix.js:5:43:5:64 | documen ... on.hash | edges | NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | -| NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | -| NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | -| NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | -| NoSQLCodeInjection.js:19:36:19:43 | req.body | NoSQLCodeInjection.js:19:36:19:48 | req.body.name | -| NoSQLCodeInjection.js:19:36:19:43 | req.body | NoSQLCodeInjection.js:19:36:19:48 | req.body.name | -| NoSQLCodeInjection.js:19:36:19:48 | req.body.name | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | -| NoSQLCodeInjection.js:19:36:19:48 | req.body.name | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | -| NoSQLCodeInjection.js:22:36:22:43 | req.body | NoSQLCodeInjection.js:22:36:22:48 | req.body.name | -| NoSQLCodeInjection.js:22:36:22:43 | req.body | NoSQLCodeInjection.js:22:36:22:48 | req.body.name | -| NoSQLCodeInjection.js:22:36:22:48 | req.body.name | NoSQLCodeInjection.js:22:24:22:48 | "name = ... dy.name | -| NoSQLCodeInjection.js:22:36:22:48 | req.body.name | NoSQLCodeInjection.js:22:24:22:48 | "name = ... dy.name | -| actions.js:4:10:4:50 | github. ... message | actions.js:4:10:4:50 | github. ... message | -| angularjs.js:10:22:10:36 | location.search | angularjs.js:10:22:10:36 | location.search | -| angularjs.js:13:23:13:37 | location.search | angularjs.js:13:23:13:37 | location.search | -| angularjs.js:16:28:16:42 | location.search | angularjs.js:16:28:16:42 | location.search | -| angularjs.js:19:22:19:36 | location.search | angularjs.js:19:22:19:36 | location.search | -| angularjs.js:22:27:22:41 | location.search | angularjs.js:22:27:22:41 | location.search | -| angularjs.js:25:23:25:37 | location.search | angularjs.js:25:23:25:37 | location.search | -| angularjs.js:28:33:28:47 | location.search | angularjs.js:28:33:28:47 | location.search | -| angularjs.js:31:28:31:42 | location.search | angularjs.js:31:28:31:42 | location.search | -| angularjs.js:34:18:34:32 | location.search | angularjs.js:34:18:34:32 | location.search | -| angularjs.js:40:18:40:32 | location.search | angularjs.js:40:18:40:32 | location.search | -| angularjs.js:44:17:44:31 | location.search | angularjs.js:44:17:44:31 | location.search | -| angularjs.js:47:16:47:30 | location.search | angularjs.js:47:16:47:30 | location.search | -| angularjs.js:50:22:50:36 | location.search | angularjs.js:50:22:50:36 | location.search | -| angularjs.js:53:32:53:46 | location.search | angularjs.js:53:32:53:46 | location.search | -| eslint-escope-build.js:20:22:20:22 | c | eslint-escope-build.js:21:16:21:16 | c | -| eslint-escope-build.js:20:22:20:22 | c | eslint-escope-build.js:21:16:21:16 | c | -| eslint-escope-build.js:20:22:20:22 | c | eslint-escope-build.js:21:16:21:16 | c | +| NoSQLCodeInjection.js:19:36:19:43 | req.body | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | +| NoSQLCodeInjection.js:22:36:22:43 | req.body | NoSQLCodeInjection.js:22:24:22:48 | "name = ... dy.name | | eslint-escope-build.js:20:22:20:22 | c | eslint-escope-build.js:21:16:21:16 | c | | express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | -| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | -| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | -| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | -| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | -| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | -| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | | express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | | express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | -| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | -| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | -| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | -| express.js:15:22:15:54 | req.par ... ction") | express.js:15:22:15:54 | req.par ... ction") | -| express.js:17:30:17:53 | req.par ... cript") | express.js:17:30:17:53 | req.par ... cript") | -| express.js:19:37:19:70 | req.par ... odule") | express.js:19:37:19:70 | req.par ... odule") | -| express.js:21:19:21:48 | req.par ... ntext") | express.js:21:19:21:48 | req.par ... ntext") | -| express.js:26:9:26:35 | taint | express.js:27:34:27:38 | taint | | express.js:26:9:26:35 | taint | express.js:27:34:27:38 | taint | | express.js:26:17:26:35 | req.param("wobble") | express.js:26:9:26:35 | taint | -| express.js:26:17:26:35 | req.param("wobble") | express.js:26:9:26:35 | taint | -| express.js:34:9:34:35 | taint | express.js:43:15:43:19 | taint | | express.js:34:9:34:35 | taint | express.js:43:15:43:19 | taint | | express.js:34:17:34:35 | req.param("wobble") | express.js:34:9:34:35 | taint | -| express.js:34:17:34:35 | req.param("wobble") | express.js:34:9:34:35 | taint | | express.js:49:30:49:32 | msg | express.js:50:10:50:12 | msg | -| express.js:49:30:49:32 | msg | express.js:50:10:50:12 | msg | -| express.js:49:30:49:32 | msg | express.js:50:10:50:12 | msg | -| express.js:49:30:49:32 | msg | express.js:50:10:50:12 | msg | -| module.js:9:16:9:29 | req.query.code | module.js:9:16:9:29 | req.query.code | -| module.js:11:17:11:30 | req.query.code | module.js:11:17:11:30 | req.query.code | -| react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted | | react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted | | react-native.js:7:7:7:33 | tainted | react-native.js:10:23:10:29 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:10:23:10:29 | tainted | | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | -| react.js:10:56:10:77 | documen ... on.hash | react.js:10:56:10:77 | documen ... on.hash | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:20:17:20:23 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:20:17:20:23 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:21:16:21:22 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:21:16:21:22 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:22:18:22:24 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:22:18:22:24 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:23:17:23:23 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:23:17:23:23 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:24:18:24:24 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:24:18:24:24 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:25:16:25:22 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:25:16:25:22 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:26:27:26:33 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:26:27:26:33 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:27:21:27:27 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:27:21:27:27 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:28:17:28:23 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:28:17:28:23 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:29:24:29:30 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:29:24:29:30 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:30:21:30:27 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:30:21:30:27 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:31:19:31:25 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:31:19:31:25 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:32:16:32:22 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:32:16:32:22 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:33:17:33:23 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:33:17:33:23 | tainted | -| template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:18:9:18:31 | tainted | | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:18:9:18:31 | tainted | | tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | -| tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | -| tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | -| tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | -| tst.js:5:12:5:33 | documen ... on.hash | tst.js:5:12:5:33 | documen ... on.hash | | tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | -| tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | -| tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | -| tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | -| tst.js:17:21:17:42 | documen ... on.hash | tst.js:17:21:17:42 | documen ... on.hash | -| tst.js:20:30:20:51 | documen ... on.hash | tst.js:20:30:20:51 | documen ... on.hash | -| tst.js:23:11:23:32 | documen ... on.hash | tst.js:23:11:23:45 | documen ... ring(1) | | tst.js:23:11:23:32 | documen ... on.hash | tst.js:23:11:23:45 | documen ... ring(1) | | tst.js:23:11:23:45 | documen ... ring(1) | tst.js:23:6:23:46 | atob(do ... ing(1)) | -| tst.js:23:11:23:45 | documen ... ring(1) | tst.js:23:6:23:46 | atob(do ... ing(1)) | -| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | -| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | -| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | | tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | | tst.js:29:9:29:82 | source | tst.js:31:18:31:23 | source | -| tst.js:29:9:29:82 | source | tst.js:31:18:31:23 | source | -| tst.js:29:9:29:82 | source | tst.js:33:14:33:19 | source | | tst.js:29:9:29:82 | source | tst.js:33:14:33:19 | source | | tst.js:29:9:29:82 | source | tst.js:35:28:35:33 | source | -| tst.js:29:9:29:82 | source | tst.js:35:28:35:33 | source | | tst.js:29:9:29:82 | source | tst.js:37:33:37:38 | source | -| tst.js:29:9:29:82 | source | tst.js:37:33:37:38 | source | -| tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") | | tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") | | tst.js:29:18:29:82 | documen ... , "$1") | tst.js:29:9:29:82 | source | -| webix/webix.html:3:16:3:37 | documen ... on.hash | webix/webix.html:3:16:3:37 | documen ... on.hash | -| webix/webix.html:4:26:4:47 | documen ... on.hash | webix/webix.html:4:26:4:47 | documen ... on.hash | -| webix/webix.html:5:47:5:68 | documen ... on.hash | webix/webix.html:5:47:5:68 | documen ... on.hash | -| webix/webix.js:3:12:3:33 | documen ... on.hash | webix/webix.js:3:12:3:33 | documen ... on.hash | -| webix/webix.js:4:22:4:43 | documen ... on.hash | webix/webix.js:4:22:4:43 | documen ... on.hash | -| webix/webix.js:5:43:5:64 | documen ... on.hash | webix/webix.js:5:43:5:64 | documen ... on.hash | +nodes +| NoSQLCodeInjection.js:18:24:18:31 | req.body | semmle.label | req.body | +| NoSQLCodeInjection.js:18:24:18:37 | req.body.query | semmle.label | req.body.query | +| NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | semmle.label | "name = ... dy.name | +| NoSQLCodeInjection.js:19:36:19:43 | req.body | semmle.label | req.body | +| NoSQLCodeInjection.js:22:24:22:48 | "name = ... dy.name | semmle.label | "name = ... dy.name | +| NoSQLCodeInjection.js:22:36:22:43 | req.body | semmle.label | req.body | +| actions.js:4:10:4:50 | github. ... message | semmle.label | github. ... message | +| angularjs.js:10:22:10:36 | location.search | semmle.label | location.search | +| angularjs.js:13:23:13:37 | location.search | semmle.label | location.search | +| angularjs.js:16:28:16:42 | location.search | semmle.label | location.search | +| angularjs.js:19:22:19:36 | location.search | semmle.label | location.search | +| angularjs.js:22:27:22:41 | location.search | semmle.label | location.search | +| angularjs.js:25:23:25:37 | location.search | semmle.label | location.search | +| angularjs.js:28:33:28:47 | location.search | semmle.label | location.search | +| angularjs.js:31:28:31:42 | location.search | semmle.label | location.search | +| angularjs.js:34:18:34:32 | location.search | semmle.label | location.search | +| angularjs.js:40:18:40:32 | location.search | semmle.label | location.search | +| angularjs.js:44:17:44:31 | location.search | semmle.label | location.search | +| angularjs.js:47:16:47:30 | location.search | semmle.label | location.search | +| angularjs.js:50:22:50:36 | location.search | semmle.label | location.search | +| angularjs.js:53:32:53:46 | location.search | semmle.label | location.search | +| eslint-escope-build.js:20:22:20:22 | c | semmle.label | c | +| eslint-escope-build.js:21:16:21:16 | c | semmle.label | c | +| express.js:7:24:7:69 | "return ... + "];" | semmle.label | "return ... + "];" | +| express.js:7:44:7:62 | req.param("wobble") | semmle.label | req.param("wobble") | +| express.js:9:34:9:79 | "return ... + "];" | semmle.label | "return ... + "];" | +| express.js:9:54:9:72 | req.param("wobble") | semmle.label | req.param("wobble") | +| express.js:12:8:12:53 | "return ... + "];" | semmle.label | "return ... + "];" | +| express.js:12:28:12:46 | req.param("wobble") | semmle.label | req.param("wobble") | +| express.js:15:22:15:54 | req.par ... ction") | semmle.label | req.par ... ction") | +| express.js:17:30:17:53 | req.par ... cript") | semmle.label | req.par ... cript") | +| express.js:19:37:19:70 | req.par ... odule") | semmle.label | req.par ... odule") | +| express.js:21:19:21:48 | req.par ... ntext") | semmle.label | req.par ... ntext") | +| express.js:26:9:26:35 | taint | semmle.label | taint | +| express.js:26:17:26:35 | req.param("wobble") | semmle.label | req.param("wobble") | +| express.js:27:34:27:38 | taint | semmle.label | taint | +| express.js:34:9:34:35 | taint | semmle.label | taint | +| express.js:34:17:34:35 | req.param("wobble") | semmle.label | req.param("wobble") | +| express.js:43:15:43:19 | taint | semmle.label | taint | +| express.js:49:30:49:32 | msg | semmle.label | msg | +| express.js:50:10:50:12 | msg | semmle.label | msg | +| module.js:9:16:9:29 | req.query.code | semmle.label | req.query.code | +| module.js:11:17:11:30 | req.query.code | semmle.label | req.query.code | +| react-native.js:7:7:7:33 | tainted | semmle.label | tainted | +| react-native.js:7:17:7:33 | req.param("code") | semmle.label | req.param("code") | +| react-native.js:8:32:8:38 | tainted | semmle.label | tainted | +| react-native.js:10:23:10:29 | tainted | semmle.label | tainted | +| react.js:10:56:10:77 | documen ... on.hash | semmle.label | documen ... on.hash | +| template-sinks.js:18:9:18:31 | tainted | semmle.label | tainted | +| template-sinks.js:18:19:18:31 | req.query.foo | semmle.label | req.query.foo | +| template-sinks.js:20:17:20:23 | tainted | semmle.label | tainted | +| template-sinks.js:21:16:21:22 | tainted | semmle.label | tainted | +| template-sinks.js:22:18:22:24 | tainted | semmle.label | tainted | +| template-sinks.js:23:17:23:23 | tainted | semmle.label | tainted | +| template-sinks.js:24:18:24:24 | tainted | semmle.label | tainted | +| template-sinks.js:25:16:25:22 | tainted | semmle.label | tainted | +| template-sinks.js:26:27:26:33 | tainted | semmle.label | tainted | +| template-sinks.js:27:21:27:27 | tainted | semmle.label | tainted | +| template-sinks.js:28:17:28:23 | tainted | semmle.label | tainted | +| template-sinks.js:29:24:29:30 | tainted | semmle.label | tainted | +| template-sinks.js:30:21:30:27 | tainted | semmle.label | tainted | +| template-sinks.js:31:19:31:25 | tainted | semmle.label | tainted | +| template-sinks.js:32:16:32:22 | tainted | semmle.label | tainted | +| template-sinks.js:33:17:33:23 | tainted | semmle.label | tainted | +| tst.js:2:6:2:27 | documen ... on.href | semmle.label | documen ... on.href | +| tst.js:2:6:2:83 | documen ... t=")+8) | semmle.label | documen ... t=")+8) | +| tst.js:5:12:5:33 | documen ... on.hash | semmle.label | documen ... on.hash | +| tst.js:14:10:14:33 | documen ... .search | semmle.label | documen ... .search | +| tst.js:14:10:14:74 | documen ... , "$1") | semmle.label | documen ... , "$1") | +| tst.js:17:21:17:42 | documen ... on.hash | semmle.label | documen ... on.hash | +| tst.js:20:30:20:51 | documen ... on.hash | semmle.label | documen ... on.hash | +| tst.js:23:6:23:46 | atob(do ... ing(1)) | semmle.label | atob(do ... ing(1)) | +| tst.js:23:11:23:32 | documen ... on.hash | semmle.label | documen ... on.hash | +| tst.js:23:11:23:45 | documen ... ring(1) | semmle.label | documen ... ring(1) | +| tst.js:26:26:26:40 | location.search | semmle.label | location.search | +| tst.js:26:26:26:53 | locatio ... ring(1) | semmle.label | locatio ... ring(1) | +| tst.js:29:9:29:82 | source | semmle.label | source | +| tst.js:29:18:29:41 | documen ... .search | semmle.label | documen ... .search | +| tst.js:29:18:29:82 | documen ... , "$1") | semmle.label | documen ... , "$1") | +| tst.js:31:18:31:23 | source | semmle.label | source | +| tst.js:33:14:33:19 | source | semmle.label | source | +| tst.js:35:28:35:33 | source | semmle.label | source | +| tst.js:37:33:37:38 | source | semmle.label | source | +| webix/webix.html:3:16:3:37 | documen ... on.hash | semmle.label | documen ... on.hash | +| webix/webix.html:4:26:4:47 | documen ... on.hash | semmle.label | documen ... on.hash | +| webix/webix.html:5:47:5:68 | documen ... on.hash | semmle.label | documen ... on.hash | +| webix/webix.js:3:12:3:33 | documen ... on.hash | semmle.label | documen ... on.hash | +| webix/webix.js:4:22:4:43 | documen ... on.hash | semmle.label | documen ... on.hash | +| webix/webix.js:5:43:5:64 | documen ... on.hash | semmle.label | documen ... on.hash | +subpaths #select | eslint-escope-build.js:21:16:21:16 | c | eslint-escope-build.js:20:22:20:22 | c | eslint-escope-build.js:21:16:21:16 | c | $@ flows to here and is interpreted as code. | eslint-escope-build.js:20:22:20:22 | c | User-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.ql b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.ql index 2e5a95533f1..da6b4f631a9 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.ql +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.ql @@ -1,9 +1,9 @@ import javascript import semmle.javascript.heuristics.AdditionalSources import semmle.javascript.security.dataflow.CodeInjectionQuery -import DataFlow::PathGraph +import CodeInjectionFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource +from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink +where CodeInjectionFlow::flowPath(source, sink) and source.getNode() instanceof HeuristicSource select sink.getNode(), source, sink, "$@ flows to here and is interpreted as code.", source.getNode(), "User-provided value" From 98c79e7674af63be1ec60be5fb138ace92a4529a Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 9 Oct 2023 10:46:36 +0200 Subject: [PATCH 146/514] JS: Update test output showing lack of global flow (geniune FN) --- .../library-tests/InterProceduralFlow/tests.expected | 9 --------- 1 file changed, 9 deletions(-) diff --git a/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected b/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected index 7278acf7161..aab7951f480 100644 --- a/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected +++ b/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected @@ -24,8 +24,6 @@ dataFlow | esLib.js:3:21:3:29 | "tainted" | esClient.js:11:13:11:17 | esFoo | | esLib.js:3:21:3:29 | "tainted" | nodeJsClient.js:5:13:5:21 | es.source | | global.js:1:15:1:24 | "tainted1" | global.js:9:13:9:22 | g(source1) | -| global.js:1:15:1:24 | "tainted1" | global.js:17:13:17:27 | window.location | -| global.js:1:15:1:24 | "tainted1" | global.js:18:13:18:24 | win.location | | global.js:2:15:2:24 | "tainted2" | global.js:10:13:10:22 | g(source2) | | global.js:5:22:5:35 | "also tainted" | global.js:9:13:9:22 | g(source1) | | global.js:5:22:5:35 | "also tainted" | global.js:10:13:10:22 | g(source2) | @@ -63,7 +61,6 @@ dataFlow | properties.js:2:16:2:24 | "tainted" | properties.js:5:14:5:23 | a.someProp | | properties.js:2:16:2:24 | "tainted" | properties.js:12:15:12:24 | x.someProp | | properties.js:2:16:2:24 | "tainted" | properties.js:14:15:14:27 | tmp1.someProp | -| properties.js:18:26:18:42 | "tainted as well" | properties.js:20:24:20:33 | window.foo | | tst2.js:2:17:2:26 | "tainted1" | tst2.js:10:15:10:24 | g(source1) | | tst2.js:3:17:3:26 | "tainted2" | tst2.js:11:15:11:24 | g(source2) | | tst2.js:6:24:6:37 | "also tainted" | tst2.js:10:15:10:24 | g(source1) | @@ -109,8 +106,6 @@ taintTracking | esLib.js:3:21:3:29 | "tainted" | esClient.js:11:13:11:17 | esFoo | | esLib.js:3:21:3:29 | "tainted" | nodeJsClient.js:5:13:5:21 | es.source | | global.js:1:15:1:24 | "tainted1" | global.js:9:13:9:22 | g(source1) | -| global.js:1:15:1:24 | "tainted1" | global.js:17:13:17:27 | window.location | -| global.js:1:15:1:24 | "tainted1" | global.js:18:13:18:24 | win.location | | global.js:2:15:2:24 | "tainted2" | global.js:10:13:10:22 | g(source2) | | global.js:5:22:5:35 | "also tainted" | global.js:9:13:9:22 | g(source1) | | global.js:5:22:5:35 | "also tainted" | global.js:10:13:10:22 | g(source2) | @@ -151,7 +146,6 @@ taintTracking | properties.js:2:16:2:24 | "tainted" | properties.js:5:14:5:23 | a.someProp | | properties.js:2:16:2:24 | "tainted" | properties.js:12:15:12:24 | x.someProp | | properties.js:2:16:2:24 | "tainted" | properties.js:14:15:14:27 | tmp1.someProp | -| properties.js:18:26:18:42 | "tainted as well" | properties.js:20:24:20:33 | window.foo | | tst2.js:2:17:2:26 | "tainted1" | tst2.js:10:15:10:24 | g(source1) | | tst2.js:3:17:3:26 | "tainted2" | tst2.js:11:15:11:24 | g(source2) | | tst2.js:6:24:6:37 | "also tainted" | tst2.js:10:15:10:24 | g(source1) | @@ -219,8 +213,6 @@ germanFlow | esLib.js:3:21:3:29 | "tainted" | esClient.js:11:13:11:17 | esFoo | | esLib.js:3:21:3:29 | "tainted" | nodeJsClient.js:5:13:5:21 | es.source | | global.js:1:15:1:24 | "tainted1" | global.js:9:13:9:22 | g(source1) | -| global.js:1:15:1:24 | "tainted1" | global.js:17:13:17:27 | window.location | -| global.js:1:15:1:24 | "tainted1" | global.js:18:13:18:24 | win.location | | global.js:2:15:2:24 | "tainted2" | global.js:10:13:10:22 | g(source2) | | global.js:5:22:5:35 | "also tainted" | global.js:9:13:9:22 | g(source1) | | global.js:5:22:5:35 | "also tainted" | global.js:10:13:10:22 | g(source2) | @@ -258,7 +250,6 @@ germanFlow | properties.js:2:16:2:24 | "tainted" | properties.js:5:14:5:23 | a.someProp | | properties.js:2:16:2:24 | "tainted" | properties.js:12:15:12:24 | x.someProp | | properties.js:2:16:2:24 | "tainted" | properties.js:14:15:14:27 | tmp1.someProp | -| properties.js:18:26:18:42 | "tainted as well" | properties.js:20:24:20:33 | window.foo | | tst2.js:2:17:2:26 | "tainted1" | tst2.js:10:15:10:24 | g(source1) | | tst2.js:3:17:3:26 | "tainted2" | tst2.js:11:15:11:24 | g(source2) | | tst2.js:6:24:6:37 | "also tainted" | tst2.js:10:15:10:24 | g(source1) | From 7c5eb89491a35845b9f45e43af1a2048c5fd33ac Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 9 Oct 2023 10:00:46 +0200 Subject: [PATCH 147/514] JS: Add tests for captured 'this' (genuine FN) --- .../TaintTracking/BasicTaintTracking.expected | 6 +++++ .../TaintTracking/DataFlowTracking.expected | 4 +++ .../TaintTracking/capture-flow.js | 25 +++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 594ea1acdbe..2a1bcc1c998 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -7,6 +7,9 @@ legacyDataFlowDifference | callbacks.js:44:17:44:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | | capture-flow.js:89:13:89:20 | source() | capture-flow.js:89:6:89:21 | test3c(source()) | only flow with NEW data flow library | | capture-flow.js:101:12:101:19 | source() | capture-flow.js:102:6:102:20 | test5("safe")() | only flow with OLD data flow library | +| capture-flow.js:274:33:274:40 | source() | capture-flow.js:272:10:272:17 | this.foo | only flow with OLD data flow library | +| capture-flow.js:274:33:274:40 | source() | capture-flow.js:274:6:274:45 | new Cap ... ()).foo | only flow with OLD data flow library | +| capture-flow.js:283:34:283:41 | source() | capture-flow.js:284:6:284:44 | new Cap ... e').foo | only flow with NEW data flow library | | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:40:8:40:14 | e.taint | only flow with NEW data flow library | | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:44:8:44:19 | f_safe.taint | only flow with NEW data flow library | | constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:39:8:39:14 | e.param | only flow with NEW data flow library | @@ -113,6 +116,9 @@ flow | capture-flow.js:259:23:259:30 | source() | capture-flow.js:248:18:248:27 | this.field | | capture-flow.js:259:23:259:30 | source() | capture-flow.js:252:14:252:36 | objectW ... s.field | | capture-flow.js:259:23:259:30 | source() | capture-flow.js:253:14:253:23 | this.field | +| capture-flow.js:262:16:262:23 | source() | capture-flow.js:264:14:264:21 | this.foo | +| capture-flow.js:283:34:283:41 | source() | capture-flow.js:283:6:283:46 | new Cap ... ()).foo | +| capture-flow.js:283:34:283:41 | source() | capture-flow.js:284:6:284:44 | new Cap ... e').foo | | captured-sanitizer.js:25:3:25:10 | source() | captured-sanitizer.js:15:10:15:10 | x | | case.js:2:16:2:23 | source() | case.js:5:8:5:35 | changeC ... source) | | case.js:2:16:2:23 | source() | case.js:8:8:8:24 | camelCase(source) | diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected index 9f5ed2f6573..5bcd9a8f9c3 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected @@ -9,6 +9,8 @@ legacyDataFlowDifference | callbacks.js:44:17:44:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | | capture-flow.js:89:13:89:20 | source() | capture-flow.js:89:6:89:21 | test3c(source()) | only flow with NEW data flow library | | capture-flow.js:101:12:101:19 | source() | capture-flow.js:102:6:102:20 | test5("safe")() | only flow with OLD data flow library | +| capture-flow.js:274:33:274:40 | source() | capture-flow.js:272:10:272:17 | this.foo | only flow with OLD data flow library | +| capture-flow.js:274:33:274:40 | source() | capture-flow.js:274:6:274:45 | new Cap ... ()).foo | only flow with OLD data flow library | | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:40:8:40:14 | e.taint | only flow with NEW data flow library | | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:44:8:44:19 | f_safe.taint | only flow with NEW data flow library | | constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:39:8:39:14 | e.param | only flow with NEW data flow library | @@ -90,6 +92,8 @@ flow | capture-flow.js:259:23:259:30 | source() | capture-flow.js:248:18:248:27 | this.field | | capture-flow.js:259:23:259:30 | source() | capture-flow.js:252:14:252:36 | objectW ... s.field | | capture-flow.js:259:23:259:30 | source() | capture-flow.js:253:14:253:23 | this.field | +| capture-flow.js:262:16:262:23 | source() | capture-flow.js:264:14:264:21 | this.foo | +| capture-flow.js:283:34:283:41 | source() | capture-flow.js:283:6:283:46 | new Cap ... ()).foo | | captured-sanitizer.js:25:3:25:10 | source() | captured-sanitizer.js:15:10:15:10 | x | | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:24:8:24:14 | c.taint | | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:28:8:28:19 | c_safe.taint | diff --git a/javascript/ql/test/library-tests/TaintTracking/capture-flow.js b/javascript/ql/test/library-tests/TaintTracking/capture-flow.js index bb9dc523bb8..baa6c6c95d2 100644 --- a/javascript/ql/test/library-tests/TaintTracking/capture-flow.js +++ b/javascript/ql/test/library-tests/TaintTracking/capture-flow.js @@ -257,3 +257,28 @@ function testObjectWithMethods(taint) { objectWithMethods.functionAddedLater(); } testObjectWithMethods(source()); + +function captureThis() { + this.foo = source(); + window.addEventListener('click', () => { + sink(this.foo); // NOT OK + }); +} + +function CaptureThisWithoutJump(x) { + [1].forEach(() => { + this.foo = x; + }); + sink(this.foo); // NOT OK [INCONSISTENCY] +} +sink(new CaptureThisWithoutJump(source()).foo); // NOT OK [INCONSISTENCY] +sink(new CaptureThisWithoutJump('safe').foo); // OK + +function CaptureThisWithoutJump2(x) { + this.foo = x; + let y; + [1].forEach(() => y = this.foo); + return y; +} +sink(new CaptureThisWithoutJump2(source()).foo); // NOT OK +sink(new CaptureThisWithoutJump2('safe').foo); // OK [INCONSISTENCY] From 24bab27ffed04256f024d99dd3418d5a1d6cfefb Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Oct 2023 15:30:20 +0200 Subject: [PATCH 148/514] JS: Add TODO for dynamic import step --- javascript/ql/lib/semmle/javascript/Promises.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/javascript/ql/lib/semmle/javascript/Promises.qll b/javascript/ql/lib/semmle/javascript/Promises.qll index c254128f87b..f25fa2bc820 100644 --- a/javascript/ql/lib/semmle/javascript/Promises.qll +++ b/javascript/ql/lib/semmle/javascript/Promises.qll @@ -705,6 +705,7 @@ private module DynamicImportSteps { */ class DynamicImportStep extends LegacyPreCallGraphStep { override predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { + // TODO: this step needs to be ported to dataflow2 exists(DynamicImportExpr imprt | pred = imprt.getImportedModule().getAnExportedValue("default") and succ = imprt.flow() and From 51dec79401713bd11cc7473fea2862343971095b Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 15:48:25 +0200 Subject: [PATCH 149/514] JS: Lower access path limit to 2 --- .../javascript/dataflow/internal/DataFlowPrivate.qll | 2 +- .../TaintTracking/BasicTaintTracking.expected | 9 +++------ .../TaintTracking/DataFlowTracking.expected | 2 -- .../ql/test/library-tests/frameworks/Redux/test.expected | 2 +- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 223a0ff1550..c8f7e749030 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -879,7 +879,7 @@ predicate isUnreachableInCall(Node n, DataFlowCall call) { none() // TODO: could be useful, but not currently implemented for JS } -int accessPathLimit() { result = 5 } +int accessPathLimit() { result = 2 } /** * Holds if flow is allowed to pass from parameter `p` and back to itself as a diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 2a1bcc1c998..c71c187c98a 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -16,16 +16,16 @@ legacyDataFlowDifference | exceptions.js:53:14:53:21 | source() | exceptions.js:54:10:54:10 | e | only flow with NEW data flow library | | getters-and-setters.js:53:21:53:28 | source() | getters-and-setters.js:53:10:53:30 | getX(ne ... rce())) | only flow with NEW data flow library | | nested-props.js:14:15:14:22 | source() | nested-props.js:15:10:15:16 | obj.x.y | only flow with NEW data flow library | -| nested-props.js:19:17:19:24 | source() | nested-props.js:20:10:20:18 | obj.x.y.z | only flow with NEW data flow library | | nested-props.js:27:18:27:25 | source() | nested-props.js:28:10:28:14 | obj.x | only flow with NEW data flow library | | nested-props.js:51:22:51:29 | source() | nested-props.js:52:10:52:16 | obj.x.y | only flow with NEW data flow library | | object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:23:14:23:20 | obj.foo | only flow with OLD data flow library | | object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:28:10:28:30 | sanitiz ... bj).foo | only flow with OLD data flow library | | promise.js:12:20:12:27 | source() | promise.js:13:8:13:23 | resolver.promise | only flow with OLD data flow library | | sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | only flow with NEW data flow library | -| stringification-read-steps.js:7:22:7:29 | source() | stringification-read-steps.js:17:10:17:31 | JSON.st ... object) | only flow with NEW data flow library | -| stringification-read-steps.js:7:22:7:29 | source() | stringification-read-steps.js:25:10:25:31 | JSON.st ... object) | only flow with NEW data flow library | consistencyIssue +| library-tests/TaintTracking/nested-props.js:20 | expected an alert, but found none | NOT OK - but not found | Consistency | +| library-tests/TaintTracking/stringification-read-steps.js:17 | expected an alert, but found none | NOT OK | Consistency | +| library-tests/TaintTracking/stringification-read-steps.js:25 | expected an alert, but found none | NOT OK | Consistency | flow | access-path-sanitizer.js:2:18:2:25 | source() | access-path-sanitizer.js:4:8:4:12 | obj.x | | addexpr.js:4:10:4:17 | source() | addexpr.js:7:8:7:8 | x | @@ -206,7 +206,6 @@ flow | nested-props.js:4:13:4:20 | source() | nested-props.js:5:10:5:14 | obj.x | | nested-props.js:9:18:9:25 | source() | nested-props.js:10:10:10:16 | obj.x.y | | nested-props.js:14:15:14:22 | source() | nested-props.js:15:10:15:16 | obj.x.y | -| nested-props.js:19:17:19:24 | source() | nested-props.js:20:10:20:18 | obj.x.y.z | | nested-props.js:27:18:27:25 | source() | nested-props.js:28:10:28:14 | obj.x | | nested-props.js:35:13:35:20 | source() | nested-props.js:36:10:36:20 | doLoad(obj) | | nested-props.js:43:13:43:20 | source() | nested-props.js:44:10:44:18 | id(obj).x | @@ -261,8 +260,6 @@ flow | string-replace.js:3:13:3:20 | source() | string-replace.js:21:6:21:41 | safe(). ... taint) | | string-replace.js:3:13:3:20 | source() | string-replace.js:22:6:22:48 | safe(). ... taint) | | string-replace.js:3:13:3:20 | source() | string-replace.js:24:6:24:45 | taint.r ... + '!') | -| stringification-read-steps.js:7:22:7:29 | source() | stringification-read-steps.js:17:10:17:31 | JSON.st ... object) | -| stringification-read-steps.js:7:22:7:29 | source() | stringification-read-steps.js:25:10:25:31 | JSON.st ... object) | | summarize-store-load-in-call.js:9:15:9:22 | source() | summarize-store-load-in-call.js:9:10:9:23 | blah(source()) | | thisAssignments.js:4:17:4:24 | source() | thisAssignments.js:5:10:5:18 | obj.field | | thisAssignments.js:7:19:7:26 | source() | thisAssignments.js:8:10:8:20 | this.field2 | diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected index 5bcd9a8f9c3..6ca5cb174b8 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected @@ -17,7 +17,6 @@ legacyDataFlowDifference | exceptions.js:53:14:53:21 | source() | exceptions.js:54:10:54:10 | e | only flow with NEW data flow library | | getters-and-setters.js:53:21:53:28 | source() | getters-and-setters.js:53:10:53:30 | getX(ne ... rce())) | only flow with NEW data flow library | | nested-props.js:14:15:14:22 | source() | nested-props.js:15:10:15:16 | obj.x.y | only flow with NEW data flow library | -| nested-props.js:19:17:19:24 | source() | nested-props.js:20:10:20:18 | obj.x.y.z | only flow with NEW data flow library | | nested-props.js:27:18:27:25 | source() | nested-props.js:28:10:28:14 | obj.x | only flow with NEW data flow library | | nested-props.js:51:22:51:29 | source() | nested-props.js:52:10:52:16 | obj.x.y | only flow with NEW data flow library | | sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | only flow with NEW data flow library | @@ -136,7 +135,6 @@ flow | nested-props.js:4:13:4:20 | source() | nested-props.js:5:10:5:14 | obj.x | | nested-props.js:9:18:9:25 | source() | nested-props.js:10:10:10:16 | obj.x.y | | nested-props.js:14:15:14:22 | source() | nested-props.js:15:10:15:16 | obj.x.y | -| nested-props.js:19:17:19:24 | source() | nested-props.js:20:10:20:18 | obj.x.y.z | | nested-props.js:27:18:27:25 | source() | nested-props.js:28:10:28:14 | obj.x | | nested-props.js:35:13:35:20 | source() | nested-props.js:36:10:36:20 | doLoad(obj) | | nested-props.js:43:13:43:20 | source() | nested-props.js:44:10:44:18 | id(obj).x | diff --git a/javascript/ql/test/library-tests/frameworks/Redux/test.expected b/javascript/ql/test/library-tests/frameworks/Redux/test.expected index 92c12137ad7..62997826b36 100644 --- a/javascript/ql/test/library-tests/frameworks/Redux/test.expected +++ b/javascript/ql/test/library-tests/frameworks/Redux/test.expected @@ -1,4 +1,5 @@ legacyDataFlowDifference +| react-redux.jsx:70:30:70:37 | source() | react-redux.jsx:77:10:77:28 | props.propFromAsync | only flow with OLD data flow library | reducerArg | exportedReducer.js:12:12:12:35 | (state, ... > state | | react-redux.jsx:12:33:17:9 | (state, ... } | @@ -112,7 +113,6 @@ taintFlow | react-redux.jsx:69:31:69:38 | source() | react-redux.jsx:74:10:74:35 | props.p ... lAction | | react-redux.jsx:69:31:69:38 | source() | react-redux.jsx:75:10:75:36 | props.p ... Action2 | | react-redux.jsx:69:31:69:38 | source() | react-redux.jsx:76:10:76:36 | props.p ... Action3 | -| react-redux.jsx:70:30:70:37 | source() | react-redux.jsx:77:10:77:28 | props.propFromAsync | reactComponentRef | accessPaths.js:7:1:15:1 | functio ... pan>;\\n} | accessPaths.js:7:1:15:1 | functio ... pan>;\\n} | | react-redux.jsx:64:1:80:1 | functio ... r}}/>\\n} | react-redux.jsx:64:1:80:1 | functio ... r}}/>\\n} | From d3f5169e6622611d82c9bd1dbdf675cbe7c4b20a Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Oct 2023 15:58:08 +0200 Subject: [PATCH 150/514] JS: Lower field-flow branch limit on Polynomial ReDoS --- .../semmle/javascript/security/regexp/PolynomialReDoSQuery.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSQuery.qll b/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSQuery.qll index dbe45503f2c..3046febcc2a 100644 --- a/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSQuery.qll @@ -27,6 +27,8 @@ module PolynomialReDoSConfig implements DataFlow::ConfigSig { // TODO: localFieldStep is too expensive with dataflow2 // DataFlow::localFieldStep(pred, succ) } + + int fieldFlowBranchLimit() { result = 1 } // library inputs are too expensive on some projects } /** Taint-tracking for reasoning about polynomial regular expression denial-of-service attacks. */ From e738b5d1255bfcc94feb2b59663f6c4a500fa56f Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Oct 2023 14:35:26 +0200 Subject: [PATCH 151/514] JS: Expand callback test case Type-based pruning is confused by the different tests being interleaved, so we additionally want to have a test that is independent from the other parts of this test. --- .../TaintTracking/BasicTaintTracking.expected | 3 +++ .../TaintTracking/DataFlowTracking.expected | 3 +++ .../test/library-tests/TaintTracking/callbacks.js | 15 +++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index c71c187c98a..b37f63afae0 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -5,6 +5,7 @@ legacyDataFlowDifference | callbacks.js:37:17:37:24 | source() | callbacks.js:41:10:41:10 | x | only flow with NEW data flow library | | callbacks.js:44:17:44:24 | source() | callbacks.js:37:37:37:37 | x | only flow with NEW data flow library | | callbacks.js:44:17:44:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | +| callbacks.js:73:17:73:24 | source() | callbacks.js:74:35:74:35 | x | only flow with NEW data flow library | | capture-flow.js:89:13:89:20 | source() | capture-flow.js:89:6:89:21 | test3c(source()) | only flow with NEW data flow library | | capture-flow.js:101:12:101:19 | source() | capture-flow.js:102:6:102:20 | test5("safe")() | only flow with OLD data flow library | | capture-flow.js:274:33:274:40 | source() | capture-flow.js:272:10:272:17 | this.foo | only flow with OLD data flow library | @@ -92,6 +93,8 @@ flow | callbacks.js:50:18:50:25 | source() | callbacks.js:30:29:30:29 | y | | callbacks.js:51:18:51:25 | source() | callbacks.js:30:29:30:29 | y | | callbacks.js:53:23:53:30 | source() | callbacks.js:58:10:58:10 | x | +| callbacks.js:73:17:73:24 | source() | callbacks.js:73:37:73:37 | x | +| callbacks.js:73:17:73:24 | source() | callbacks.js:74:35:74:35 | x | | capture-flow.js:9:11:9:18 | source() | capture-flow.js:14:10:14:16 | outer() | | capture-flow.js:9:11:9:18 | source() | capture-flow.js:19:6:19:16 | outerMost() | | capture-flow.js:31:14:31:21 | source() | capture-flow.js:31:6:31:22 | confuse(source()) | diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected index 6ca5cb174b8..4ebebe573f1 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected @@ -7,6 +7,7 @@ legacyDataFlowDifference | callbacks.js:37:17:37:24 | source() | callbacks.js:41:10:41:10 | x | only flow with NEW data flow library | | callbacks.js:44:17:44:24 | source() | callbacks.js:37:37:37:37 | x | only flow with NEW data flow library | | callbacks.js:44:17:44:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | +| callbacks.js:73:17:73:24 | source() | callbacks.js:74:35:74:35 | x | only flow with NEW data flow library | | capture-flow.js:89:13:89:20 | source() | capture-flow.js:89:6:89:21 | test3c(source()) | only flow with NEW data flow library | | capture-flow.js:101:12:101:19 | source() | capture-flow.js:102:6:102:20 | test5("safe")() | only flow with OLD data flow library | | capture-flow.js:274:33:274:40 | source() | capture-flow.js:272:10:272:17 | this.foo | only flow with OLD data flow library | @@ -67,6 +68,8 @@ flow | callbacks.js:50:18:50:25 | source() | callbacks.js:30:29:30:29 | y | | callbacks.js:51:18:51:25 | source() | callbacks.js:30:29:30:29 | y | | callbacks.js:53:23:53:30 | source() | callbacks.js:58:10:58:10 | x | +| callbacks.js:73:17:73:24 | source() | callbacks.js:73:37:73:37 | x | +| callbacks.js:73:17:73:24 | source() | callbacks.js:74:35:74:35 | x | | capture-flow.js:9:11:9:18 | source() | capture-flow.js:14:10:14:16 | outer() | | capture-flow.js:9:11:9:18 | source() | capture-flow.js:19:6:19:16 | outerMost() | | capture-flow.js:31:14:31:21 | source() | capture-flow.js:31:6:31:22 | confuse(source()) | diff --git a/javascript/ql/test/library-tests/TaintTracking/callbacks.js b/javascript/ql/test/library-tests/TaintTracking/callbacks.js index 62299defcd9..2724571e956 100644 --- a/javascript/ql/test/library-tests/TaintTracking/callbacks.js +++ b/javascript/ql/test/library-tests/TaintTracking/callbacks.js @@ -58,3 +58,18 @@ function test() { sink(x); // NOT OK }); } + +function forwardTaint3(x, cb) { + cb(x); // Same as 'forwardTaint' but copied to avoid interference between tests + cb(x); +} + +function forwardTaint4(x, cb) { + forwardTaint3(x, cb); // Same as 'forwardTaint2' but copied to avoid interference between tests + forwardTaint3(x, cb); +} + +function test2() { + forwardTaint4(source(), x => sink(x)); // NOT OK + forwardTaint4("safe", x => sink(x)); // OK [INCONSISTENCY] +} From 9faf300dd0bdabe09d942e5bd0ebbd9e0dc03cf3 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Oct 2023 14:39:53 +0200 Subject: [PATCH 152/514] JS: Use type-pruning to restrict callback flow --- .../dataflow/internal/DataFlowPrivate.qll | 48 ++++++++++++++++--- .../TaintTracking/BasicTaintTracking.expected | 2 - .../TaintTracking/DataFlowTracking.expected | 2 - .../library-tests/TaintTracking/callbacks.js | 2 +- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index c8f7e749030..2c6227f522b 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -297,16 +297,46 @@ DataFlowCallable nodeGetEnclosingCallable(Node node) { } private newtype TDataFlowType = - TTodoDataFlowType() or - TTodoDataFlowType2() // Add a dummy value to prevent bad functionality-induced joins arising from a type of size 1. + TFunctionType(Function f) or + TAnyType() class DataFlowType extends TDataFlowType { - string toString() { result = "" } + string toString() { + this instanceof TFunctionType and + result = + "TFunctionType(" + this.asFunction().toString() + ") at line " + + this.asFunction().getLocation().getStartLine() + or + this instanceof TAnyType and result = "TAnyType" + } + + Function asFunction() { this = TFunctionType(result) } } -predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() } +/** + * Holds if `t1` is strictly stronger than `t2`. + */ +predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { + t1 instanceof TFunctionType and t2 = TAnyType() +} -DataFlowType getNodeType(Node node) { result = TTodoDataFlowType() and exists(node) } +private DataFlowType getPreciseType(Node node) { + exists(Function f | + (node = TValueNode(f) or node = TFunctionSelfReferenceNode(f)) and + result = TFunctionType(f) + ) + or + result = getPreciseType(node.getImmediatePredecessor()) + or + result = getPreciseType(node.(PostUpdateNode).getPreUpdateNode()) +} + +DataFlowType getNodeType(Node node) { + result = getPreciseType(node) + or + not exists(getPreciseType(node)) and + result = TAnyType() +} predicate nodeIsHidden(Node node) { DataFlow::PathNode::shouldNodeBeHidden(node) @@ -344,7 +374,13 @@ predicate neverSkipInPathGraph(Node node) { string ppReprType(DataFlowType t) { none() } pragma[inline] -predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { any() } +predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { + t1 = t2 + or + t1 instanceof TAnyType and exists(t2) + or + t2 instanceof TAnyType and exists(t1) +} predicate forceHighPrecision(Content c) { none() } diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index b37f63afae0..50cc7e73946 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -5,7 +5,6 @@ legacyDataFlowDifference | callbacks.js:37:17:37:24 | source() | callbacks.js:41:10:41:10 | x | only flow with NEW data flow library | | callbacks.js:44:17:44:24 | source() | callbacks.js:37:37:37:37 | x | only flow with NEW data flow library | | callbacks.js:44:17:44:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | -| callbacks.js:73:17:73:24 | source() | callbacks.js:74:35:74:35 | x | only flow with NEW data flow library | | capture-flow.js:89:13:89:20 | source() | capture-flow.js:89:6:89:21 | test3c(source()) | only flow with NEW data flow library | | capture-flow.js:101:12:101:19 | source() | capture-flow.js:102:6:102:20 | test5("safe")() | only flow with OLD data flow library | | capture-flow.js:274:33:274:40 | source() | capture-flow.js:272:10:272:17 | this.foo | only flow with OLD data flow library | @@ -94,7 +93,6 @@ flow | callbacks.js:51:18:51:25 | source() | callbacks.js:30:29:30:29 | y | | callbacks.js:53:23:53:30 | source() | callbacks.js:58:10:58:10 | x | | callbacks.js:73:17:73:24 | source() | callbacks.js:73:37:73:37 | x | -| callbacks.js:73:17:73:24 | source() | callbacks.js:74:35:74:35 | x | | capture-flow.js:9:11:9:18 | source() | capture-flow.js:14:10:14:16 | outer() | | capture-flow.js:9:11:9:18 | source() | capture-flow.js:19:6:19:16 | outerMost() | | capture-flow.js:31:14:31:21 | source() | capture-flow.js:31:6:31:22 | confuse(source()) | diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected index 4ebebe573f1..7fedc241a2c 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected @@ -7,7 +7,6 @@ legacyDataFlowDifference | callbacks.js:37:17:37:24 | source() | callbacks.js:41:10:41:10 | x | only flow with NEW data flow library | | callbacks.js:44:17:44:24 | source() | callbacks.js:37:37:37:37 | x | only flow with NEW data flow library | | callbacks.js:44:17:44:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | -| callbacks.js:73:17:73:24 | source() | callbacks.js:74:35:74:35 | x | only flow with NEW data flow library | | capture-flow.js:89:13:89:20 | source() | capture-flow.js:89:6:89:21 | test3c(source()) | only flow with NEW data flow library | | capture-flow.js:101:12:101:19 | source() | capture-flow.js:102:6:102:20 | test5("safe")() | only flow with OLD data flow library | | capture-flow.js:274:33:274:40 | source() | capture-flow.js:272:10:272:17 | this.foo | only flow with OLD data flow library | @@ -69,7 +68,6 @@ flow | callbacks.js:51:18:51:25 | source() | callbacks.js:30:29:30:29 | y | | callbacks.js:53:23:53:30 | source() | callbacks.js:58:10:58:10 | x | | callbacks.js:73:17:73:24 | source() | callbacks.js:73:37:73:37 | x | -| callbacks.js:73:17:73:24 | source() | callbacks.js:74:35:74:35 | x | | capture-flow.js:9:11:9:18 | source() | capture-flow.js:14:10:14:16 | outer() | | capture-flow.js:9:11:9:18 | source() | capture-flow.js:19:6:19:16 | outerMost() | | capture-flow.js:31:14:31:21 | source() | capture-flow.js:31:6:31:22 | confuse(source()) | diff --git a/javascript/ql/test/library-tests/TaintTracking/callbacks.js b/javascript/ql/test/library-tests/TaintTracking/callbacks.js index 2724571e956..2c0bb776a6a 100644 --- a/javascript/ql/test/library-tests/TaintTracking/callbacks.js +++ b/javascript/ql/test/library-tests/TaintTracking/callbacks.js @@ -71,5 +71,5 @@ function forwardTaint4(x, cb) { function test2() { forwardTaint4(source(), x => sink(x)); // NOT OK - forwardTaint4("safe", x => sink(x)); // OK [INCONSISTENCY] + forwardTaint4("safe", x => sink(x)); // OK } From 5775fe6d6e921ff30eda70c631aaad4405fab91d Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 13 Oct 2023 11:06:57 +0200 Subject: [PATCH 153/514] JS: Use TAnyType in FlowSummaryPrivate --- .../dataflow/internal/DataFlowPrivate.qll | 2 +- .../dataflow/internal/FlowSummaryPrivate.qll | 23 ++++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 2c6227f522b..10cbd9ad659 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -296,7 +296,7 @@ DataFlowCallable nodeGetEnclosingCallable(Node node) { node = TGenericSynthesizedNode(_, _, result) } -private newtype TDataFlowType = +newtype TDataFlowType = TFunctionType(Function f) or TAnyType() diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index a872dc10135..e838281f0bd 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -38,31 +38,42 @@ ArgumentPosition callbackSelfParameterPosition() { result.isFunctionSelfReferenc SummaryCall summaryDataFlowCall(Private::SummaryNode receiver) { receiver = result.getReceiver() } /** Gets the type of content `c`. */ -DataFlowType getContentType(ContentSet c) { any() } +DataFlowType getContentType(ContentSet c) { result = TAnyType() and exists(c) } /** Gets the type of the parameter at the given position. */ bindingset[c, pos] -DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) { any() } +DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) { + // TODO: we could assign a more precise type to the function self-reference parameter + result = TAnyType() and exists(c) and exists(pos) +} /** Gets the return type of kind `rk` for callable `c`. */ bindingset[c, rk] -DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { any() } +DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { + result = TAnyType() and exists(c) and exists(rk) +} /** * Gets the type of the `i`th parameter in a synthesized call that targets a * callback of type `t`. */ bindingset[t, pos] -DataFlowType getCallbackParameterType(DataFlowType t, ArgumentPosition pos) { any() } +DataFlowType getCallbackParameterType(DataFlowType t, ArgumentPosition pos) { + result = TAnyType() and exists(t) and exists(pos) +} /** * Gets the return type of kind `rk` in a synthesized call that targets a * callback of type `t`. */ -DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { any() } +DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { + result = TAnyType() and exists(t) and exists(rk) +} /** Gets the type of synthetic global `sg`. */ -DataFlowType getSyntheticGlobalType(SummaryComponent::SyntheticGlobal sg) { any() } +DataFlowType getSyntheticGlobalType(SummaryComponent::SyntheticGlobal sg) { + result = TAnyType() and exists(sg) +} /** * Holds if an external flow summary exists for `c` with input specification From 3c7c5377ecef6a5fcb1f4560bd005fbf882c34dd Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Oct 2023 14:51:54 +0200 Subject: [PATCH 154/514] JS: Add content approximation This seems to fix a performance issue for RegExpInjection in angular --- .../dataflow/internal/DataFlowPrivate.qll | 57 ++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 10cbd9ad659..3f3bc38e3d4 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -384,10 +384,63 @@ predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { predicate forceHighPrecision(Content c) { none() } -class ContentApprox = Unit; +newtype TContentApprox = + TApproxPropertyContent() or + TApproxMapKey() or + TApproxMapValue() or + TApproxSetElement() or + TApproxIteratorElement() or + TApproxIteratorError() or + TApproxPromiseValue() or + TApproxPromiseError() or + TApproxCapturedContent() + +class ContentApprox extends TContentApprox { + string toString() { + this = TApproxPropertyContent() and result = "TApproxPropertyContent" + or + this = TApproxMapKey() and result = "TApproxMapKey" + or + this = TApproxMapValue() and result = "TApproxMapValue" + or + this = TApproxSetElement() and result = "TApproxSetElement" + or + this = TApproxIteratorElement() and result = "TApproxIteratorElement" + or + this = TApproxIteratorError() and result = "TApproxIteratorError" + or + this = TApproxPromiseValue() and result = "TApproxPromiseValue" + or + this = TApproxPromiseError() and result = "TApproxPromiseError" + or + this = TApproxCapturedContent() and result = "TApproxCapturedContent" + } +} pragma[inline] -ContentApprox getContentApprox(Content c) { exists(result) and exists(c) } +ContentApprox getContentApprox(Content c) { + c instanceof MkPropertyContent and result = TApproxPropertyContent() + or + c instanceof MkArrayElementUnknown and result = TApproxPropertyContent() + or + c instanceof MkMapKey and result = TApproxMapKey() + or + c instanceof MkMapValueWithKnownKey and result = TApproxMapValue() + or + c instanceof MkMapValueWithUnknownKey and result = TApproxMapValue() + or + c instanceof MkSetElement and result = TApproxSetElement() + or + c instanceof MkIteratorElement and result = TApproxIteratorElement() + or + c instanceof MkIteratorError and result = TApproxIteratorError() + or + c instanceof MkPromiseValue and result = TApproxPromiseValue() + or + c instanceof MkPromiseError and result = TApproxPromiseError() + or + c instanceof MkCapturedContent and result = TApproxCapturedContent() +} cached private newtype TDataFlowCall = From a02ab2ad886c9073b12e2479432b4c6c45fad958 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 11 Oct 2023 12:50:04 +0200 Subject: [PATCH 155/514] JS: Port heuristic versions of standard queries --- .../CWE-020/UntrustedDataToExternalAPI.ql | 10 ++++--- .../src/Security/CWE-078/CommandInjection.ql | 12 ++++----- .../heuristics/ql/src/Security/CWE-079/Xss.ql | 6 ++--- .../ql/src/Security/CWE-089/SqlInjection.ql | 26 ++++++++++++------- .../ql/src/Security/CWE-117/LogInjection.ql | 6 ++--- .../Security/CWE-770/ResourceExhaustion.ql | 6 ++--- .../src/Security/CWE-807/ConditionalBypass.ql | 10 ++++--- .../CWE-915/PrototypePollutingAssignment.ql | 3 ++- 8 files changed, 46 insertions(+), 33 deletions(-) diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-020/UntrustedDataToExternalAPI.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-020/UntrustedDataToExternalAPI.ql index dff26536319..4bf06b54447 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-020/UntrustedDataToExternalAPI.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-020/UntrustedDataToExternalAPI.ql @@ -12,11 +12,15 @@ import javascript import semmle.javascript.security.dataflow.ExternalAPIUsedWithUntrustedDataQuery -import DataFlow::PathGraph import semmle.javascript.heuristics.AdditionalSources +import ExternalAPIUsedWithUntrustedDataFlow::PathGraph -from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource +from + ExternalAPIUsedWithUntrustedDataFlow::PathNode source, + ExternalAPIUsedWithUntrustedDataFlow::PathNode sink +where + ExternalAPIUsedWithUntrustedDataFlow::flowPath(source, sink) and + source.getNode() instanceof HeuristicSource select sink, source, sink, "Call to " + sink.getNode().(Sink).getApiName() + " with untrusted data from $@.", source, source.toString() diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-078/CommandInjection.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-078/CommandInjection.ql index b21c86fc50a..f59de018f8b 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-078/CommandInjection.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-078/CommandInjection.ql @@ -16,17 +16,17 @@ import javascript import semmle.javascript.security.dataflow.CommandInjectionQuery -import DataFlow::PathGraph import semmle.javascript.heuristics.AdditionalSources +import CommandInjectionFlow::PathGraph from - Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node highlight, - Source sourceNode + CommandInjectionFlow::PathNode source, CommandInjectionFlow::PathNode sink, + DataFlow::Node highlight, Source sourceNode where - cfg.hasFlowPath(source, sink) and + CommandInjectionFlow::flowPath(source, sink) and ( - if cfg.isSinkWithHighlight(sink.getNode(), _) - then cfg.isSinkWithHighlight(sink.getNode(), highlight) + if isSinkWithHighlight(sink.getNode(), _) + then isSinkWithHighlight(sink.getNode(), highlight) else highlight = sink.getNode() ) and sourceNode = source.getNode() and diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-079/Xss.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-079/Xss.ql index e93cd7e6ca5..2db4b18e570 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-079/Xss.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-079/Xss.ql @@ -15,11 +15,11 @@ import javascript import semmle.javascript.security.dataflow.DomBasedXssQuery -import DataFlow::PathGraph import semmle.javascript.heuristics.AdditionalSources +import DomBasedXssFlow::PathGraph -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource +from DomBasedXssFlow::PathNode source, DomBasedXssFlow::PathNode sink +where DomBasedXssFlow::flowPath(source, sink) and source.getNode() instanceof HeuristicSource select sink.getNode(), source, sink, sink.getNode().(Sink).getVulnerabilityKind() + " vulnerability due to $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-089/SqlInjection.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-089/SqlInjection.ql index e82b9d40d5b..b8928021085 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-089/SqlInjection.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-089/SqlInjection.ql @@ -15,18 +15,24 @@ */ import javascript -import semmle.javascript.security.dataflow.SqlInjectionQuery as SqlInjection -import semmle.javascript.security.dataflow.NosqlInjectionQuery as NosqlInjection -import DataFlow::PathGraph +import semmle.javascript.security.dataflow.SqlInjectionQuery as Sql +import semmle.javascript.security.dataflow.NosqlInjectionQuery as Nosql import semmle.javascript.heuristics.AdditionalSources -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, string type +module Merged = + DataFlow::MergePathGraph; + +import DataFlow::DeduplicatePathGraph + +from PathNode source, PathNode sink, string type where - ( - cfg instanceof SqlInjection::Configuration and type = "string" - or - cfg instanceof NosqlInjection::Configuration and type = "object" - ) and - cfg.hasFlowPath(source, sink) + Sql::SqlInjectionFlow::flowPath(source.getAnOriginalPathNode().asPathNode1(), + sink.getAnOriginalPathNode().asPathNode1()) and + type = "string" + or + Nosql::NosqlInjectionFlow::flowPath(source.getAnOriginalPathNode().asPathNode2(), + sink.getAnOriginalPathNode().asPathNode2()) and + type = "object" select sink.getNode(), source, sink, "This query " + type + " depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-117/LogInjection.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-117/LogInjection.ql index 534de916772..8d9eca39be5 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-117/LogInjection.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-117/LogInjection.ql @@ -13,11 +13,11 @@ */ import javascript -import DataFlow::PathGraph import semmle.javascript.security.dataflow.LogInjectionQuery import semmle.javascript.heuristics.AdditionalSources +import LogInjectionFlow::PathGraph -from LogInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource +from LogInjectionFlow::PathNode source, LogInjectionFlow::PathNode sink +where LogInjectionFlow::flowPath(source, sink) and source.getNode() instanceof HeuristicSource select sink.getNode(), source, sink, "Log entry depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-770/ResourceExhaustion.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-770/ResourceExhaustion.ql index 37e702b55e0..9b37ce896d1 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-770/ResourceExhaustion.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-770/ResourceExhaustion.ql @@ -14,11 +14,11 @@ */ import javascript -import DataFlow::PathGraph import semmle.javascript.security.dataflow.ResourceExhaustionQuery import semmle.javascript.heuristics.AdditionalSources +import ResourceExhaustionFlow::PathGraph -from Configuration dataflow, DataFlow::PathNode source, DataFlow::PathNode sink -where dataflow.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource +from ResourceExhaustionFlow::PathNode source, ResourceExhaustionFlow::PathNode sink +where ResourceExhaustionFlow::flowPath(source, sink) and source.getNode() instanceof HeuristicSource select sink, source, sink, sink.getNode().(Sink).getProblemDescription() + " from a $@.", source, "user-provided value" diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-807/ConditionalBypass.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-807/ConditionalBypass.ql index 6fe3ff742f3..2980b78e1d1 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-807/ConditionalBypass.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-807/ConditionalBypass.ql @@ -14,13 +14,15 @@ import javascript import semmle.javascript.security.dataflow.ConditionalBypassQuery -import DataFlow::PathGraph import semmle.javascript.heuristics.AdditionalSources +import ConditionalBypassFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, SensitiveAction action +from + ConditionalBypassFlow::PathNode source, ConditionalBypassFlow::PathNode sink, + SensitiveAction action where - isTaintedGuardForSensitiveAction(sink, source, action) and - not isEarlyAbortGuard(sink, action) and + isTaintedGuardNodeForSensitiveAction(sink, source, action) and + not isEarlyAbortGuardNode(sink, action) and source.getNode() instanceof HeuristicSource select sink.getNode(), source, sink, "This condition guards a sensitive $@, but a $@ controls it.", action, "action", source.getNode(), "user-provided value" diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-915/PrototypePollutingAssignment.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-915/PrototypePollutingAssignment.ql index a939794e375..2b619f0614e 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-915/PrototypePollutingAssignment.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-915/PrototypePollutingAssignment.ql @@ -20,13 +20,14 @@ import javascript import semmle.javascript.security.dataflow.PrototypePollutingAssignmentQuery -import PrototypePollutingAssignmentFlow::PathGraph import semmle.javascript.heuristics.AdditionalSources +import PrototypePollutingAssignmentFlow::PathGraph from PrototypePollutingAssignmentFlow::PathNode source, PrototypePollutingAssignmentFlow::PathNode sink where PrototypePollutingAssignmentFlow::flowPath(source, sink) and + not isIgnoredLibraryFlow(source.getNode(), sink.getNode()) and source.getNode() instanceof HeuristicSource select sink, source, sink, "This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@.", From f94aa2ceec53d4533cf9f3fb30ff8e2c455cd58d Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 Mar 2024 14:41:11 +0100 Subject: [PATCH 156/514] Update javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll --- .../ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index 8323bc23314..60a139f6f1e 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -50,7 +50,7 @@ private module Cached { // We have read steps out of the await operand, so it technically needs a post-update e = any(AwaitExpr a).getOperand() or e = any(Function f) or // functions are passed as their own self-reference argument - // RHS of a setter call is an argument, so it needs a post-update node + // The RHS of an assignment can be an argument to a setter-call, so it needs a post-update node e = any(Assignment asn | asn.getTarget() instanceof PropAccess).getRhs() } or TConstructorThisArgumentNode(InvokeExpr e) { e instanceof NewExpr or e instanceof SuperCall } or From 28fc8ba0c19ad945ae31b4f26e5e96a9539f3e5e Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 Mar 2024 14:59:04 +0100 Subject: [PATCH 157/514] JS: Remove EmptyType --- .../javascript/dataflow/internal/DataFlowPrivate.qll | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 3f3bc38e3d4..1970163794d 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -140,11 +140,6 @@ class OutNode extends DataFlow::Node { OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) { result = getAnOutNodeImpl(call, kind) } -/** - * Base class for classes that should be empty. - */ -abstract private class EmptyType extends DataFlow::Node { } - cached predicate postUpdatePair(Node pre, Node post) { exists(AST::ValueNode expr | @@ -173,7 +168,9 @@ predicate postUpdatePair(Node pre, Node post) { VariableCaptureOutput::capturePostUpdateNode(getClosureNode(post), getClosureNode(pre)) } -class CastNode extends DataFlow::Node instanceof EmptyType { } +class CastNode extends DataFlow::Node { + CastNode() { none() } +} cached newtype TDataFlowCallable = From 76e0445af03cf2c6663f58931b47e21dfcada987 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 Mar 2024 15:08:59 +0100 Subject: [PATCH 158/514] JS: Be consistent about caching in PreCallGraphStep --- .../semmle/javascript/dataflow/internal/PreCallGraphStep.qll | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/PreCallGraphStep.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/PreCallGraphStep.qll index 0416dc99a02..01b109ba276 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/PreCallGraphStep.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/PreCallGraphStep.qll @@ -46,6 +46,7 @@ class PreCallGraphStep extends Unit { } } +cached module PreCallGraphStep { /** * Holds if there is a step from `pred` to `succ`. @@ -83,6 +84,7 @@ module PreCallGraphStep { /** * Holds if there is a step from the `loadProp` property of `pred` to the `storeProp` property in `succ`. */ + cached predicate loadStoreStep( DataFlow::Node pred, DataFlow::SourceNode succ, string loadProp, string storeProp ) { @@ -129,6 +131,7 @@ class LegacyPreCallGraphStep extends Unit { } } +cached module LegacyPreCallGraphStep { /** * Holds if there is a step from `pred` to `succ`. @@ -166,6 +169,7 @@ module LegacyPreCallGraphStep { /** * Holds if there is a step from the `loadProp` property of `pred` to the `storeProp` property in `succ`. */ + cached predicate loadStoreStep( DataFlow::Node pred, DataFlow::SourceNode succ, string loadProp, string storeProp ) { From 5aafd33cec30c439898aae08a75858978ae27f47 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 Mar 2024 15:11:25 +0100 Subject: [PATCH 159/514] JS: Rename Arrays2 -> Arrays --- .../javascript/internal/flow_summaries/AllFlowSummaries.qll | 2 +- .../internal/flow_summaries/{Arrays2.qll => Arrays.qll} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename javascript/ql/lib/semmle/javascript/internal/flow_summaries/{Arrays2.qll => Arrays.qll} (100%) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll index 9ca967f7354..13cf48cb5a9 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll @@ -1,5 +1,5 @@ private import AmbiguousCoreMethods -private import Arrays2 +private import Arrays private import AsyncAwait private import ForOfLoops private import Generators diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays2.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll similarity index 100% rename from javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays2.qll rename to javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll From b3fad7a8dc029b5e9551daef3c832191d660a13a Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 Mar 2024 15:12:07 +0100 Subject: [PATCH 160/514] JS: Rename Iterators2 -> Iterators --- .../javascript/internal/flow_summaries/AllFlowSummaries.qll | 2 +- .../internal/flow_summaries/{Iterators2.qll => Iterators.qll} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename javascript/ql/lib/semmle/javascript/internal/flow_summaries/{Iterators2.qll => Iterators.qll} (100%) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll index 13cf48cb5a9..9fe734c90d8 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll @@ -3,7 +3,7 @@ private import Arrays private import AsyncAwait private import ForOfLoops private import Generators -private import Iterators2 +private import Iterators private import JsonStringify private import Maps2 private import Promises2 diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Iterators2.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Iterators.qll similarity index 100% rename from javascript/ql/lib/semmle/javascript/internal/flow_summaries/Iterators2.qll rename to javascript/ql/lib/semmle/javascript/internal/flow_summaries/Iterators.qll From e2f35652272973264a258cb1dfff0ce23b1d82fc Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 Mar 2024 21:14:29 +0100 Subject: [PATCH 161/514] JS: Rename Maps2 -> Maps --- .../javascript/internal/flow_summaries/AllFlowSummaries.qll | 2 +- .../javascript/internal/flow_summaries/{Maps2.qll => Maps.qll} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename javascript/ql/lib/semmle/javascript/internal/flow_summaries/{Maps2.qll => Maps.qll} (100%) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll index 9fe734c90d8..47c35d643d3 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll @@ -5,7 +5,7 @@ private import ForOfLoops private import Generators private import Iterators private import JsonStringify -private import Maps2 +private import Maps private import Promises2 private import Sets2 private import Strings2 diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Maps2.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Maps.qll similarity index 100% rename from javascript/ql/lib/semmle/javascript/internal/flow_summaries/Maps2.qll rename to javascript/ql/lib/semmle/javascript/internal/flow_summaries/Maps.qll From 433489478d3311ca0c3a58f98e35e9c2701c4610 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 Mar 2024 21:16:43 +0100 Subject: [PATCH 162/514] JS: Rename Promise2 -> Promise --- .../javascript/internal/flow_summaries/AllFlowSummaries.qll | 2 +- .../internal/flow_summaries/{Promises2.qll => Promises.qll} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename javascript/ql/lib/semmle/javascript/internal/flow_summaries/{Promises2.qll => Promises.qll} (100%) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll index 47c35d643d3..2d1c70f8c1d 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll @@ -6,6 +6,6 @@ private import Generators private import Iterators private import JsonStringify private import Maps -private import Promises2 +private import Promises private import Sets2 private import Strings2 diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises2.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises.qll similarity index 100% rename from javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises2.qll rename to javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises.qll From 478dd25f3e06f6a16a126f6ebf919fc9990078e3 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 Mar 2024 21:17:29 +0100 Subject: [PATCH 163/514] JS: Rename Sets2 -> Sets --- .../javascript/internal/flow_summaries/AllFlowSummaries.qll | 2 +- .../javascript/internal/flow_summaries/{Sets2.qll => Sets.qll} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename javascript/ql/lib/semmle/javascript/internal/flow_summaries/{Sets2.qll => Sets.qll} (100%) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll index 2d1c70f8c1d..03858c57731 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll @@ -7,5 +7,5 @@ private import Iterators private import JsonStringify private import Maps private import Promises -private import Sets2 +private import Sets private import Strings2 diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Sets2.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Sets.qll similarity index 100% rename from javascript/ql/lib/semmle/javascript/internal/flow_summaries/Sets2.qll rename to javascript/ql/lib/semmle/javascript/internal/flow_summaries/Sets.qll From 2c1aa08f793fbc5c971939bbbc6c821fa2ab297f Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 Mar 2024 21:18:14 +0100 Subject: [PATCH 164/514] JS: Rename Strings2 -> Strings --- .../javascript/internal/flow_summaries/AllFlowSummaries.qll | 2 +- .../internal/flow_summaries/{Strings2.qll => Strings.qll} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename javascript/ql/lib/semmle/javascript/internal/flow_summaries/{Strings2.qll => Strings.qll} (100%) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll index 03858c57731..d7eba4852db 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll @@ -8,4 +8,4 @@ private import JsonStringify private import Maps private import Promises private import Sets -private import Strings2 +private import Strings diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings2.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll similarity index 100% rename from javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings2.qll rename to javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll From 13a8e0fbf0581cb97d21e71fdd34284705888b9e Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 08:54:06 +0100 Subject: [PATCH 165/514] JS: Add failing test for Promise.all() --- .../library-tests/TaintTracking/BasicTaintTracking.expected | 2 ++ javascript/ql/test/library-tests/TaintTracking/promise.js | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 50cc7e73946..70ea63077bc 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -21,9 +21,11 @@ legacyDataFlowDifference | object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:23:14:23:20 | obj.foo | only flow with OLD data flow library | | object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:28:10:28:30 | sanitiz ... bj).foo | only flow with OLD data flow library | | promise.js:12:20:12:27 | source() | promise.js:13:8:13:23 | resolver.promise | only flow with OLD data flow library | +| promise.js:43:20:43:27 | source() | promise.js:43:8:43:28 | Promise ... urce()) | only flow with OLD data flow library | | sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | only flow with NEW data flow library | consistencyIssue | library-tests/TaintTracking/nested-props.js:20 | expected an alert, but found none | NOT OK - but not found | Consistency | +| library-tests/TaintTracking/promise.js:43 | expected an alert, but found none | NOT OK | Consistency | | library-tests/TaintTracking/stringification-read-steps.js:17 | expected an alert, but found none | NOT OK | Consistency | | library-tests/TaintTracking/stringification-read-steps.js:25 | expected an alert, but found none | NOT OK | Consistency | flow diff --git a/javascript/ql/test/library-tests/TaintTracking/promise.js b/javascript/ql/test/library-tests/TaintTracking/promise.js index 84c972f4d68..6401cd971a2 100644 --- a/javascript/ql/test/library-tests/TaintTracking/promise.js +++ b/javascript/ql/test/library-tests/TaintTracking/promise.js @@ -38,3 +38,7 @@ function exceptionThroughThen2() { sink(e); // NOT OK }) } + +function promiseAllTaint() { + sink(Promise.all(source())); // NOT OK +} From 858c79e3959e3c758f3ae7f5762b9be5baaf10b7 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 08:57:42 +0100 Subject: [PATCH 166/514] JS: Add plain taint step through Promise.all() --- .../semmle/javascript/internal/flow_summaries/Promises.qll | 4 ++++ .../library-tests/TaintTracking/BasicTaintTracking.expected | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises.qll index 9a2a79e8a0a..fb2f05f17b7 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises.qll @@ -228,6 +228,10 @@ private class PromiseAll extends SummarizedCallable { preservesValue = true and input = "Argument[0].ArrayElement.WithAwaited[error]" and output = "ReturnValue" + or + preservesValue = false and + input = "Argument[0]" and + output = "ReturnValue" } } diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 70ea63077bc..41c60235be2 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -21,11 +21,9 @@ legacyDataFlowDifference | object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:23:14:23:20 | obj.foo | only flow with OLD data flow library | | object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:28:10:28:30 | sanitiz ... bj).foo | only flow with OLD data flow library | | promise.js:12:20:12:27 | source() | promise.js:13:8:13:23 | resolver.promise | only flow with OLD data flow library | -| promise.js:43:20:43:27 | source() | promise.js:43:8:43:28 | Promise ... urce()) | only flow with OLD data flow library | | sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | only flow with NEW data flow library | consistencyIssue | library-tests/TaintTracking/nested-props.js:20 | expected an alert, but found none | NOT OK - but not found | Consistency | -| library-tests/TaintTracking/promise.js:43 | expected an alert, but found none | NOT OK | Consistency | | library-tests/TaintTracking/stringification-read-steps.js:17 | expected an alert, but found none | NOT OK | Consistency | | library-tests/TaintTracking/stringification-read-steps.js:25 | expected an alert, but found none | NOT OK | Consistency | flow @@ -225,6 +223,7 @@ flow | promise.js:10:24:10:31 | source() | promise.js:10:8:10:32 | Promise ... urce()) | | promise.js:18:22:18:29 | source() | promise.js:24:10:24:10 | e | | promise.js:33:21:33:28 | source() | promise.js:38:10:38:10 | e | +| promise.js:43:20:43:27 | source() | promise.js:43:8:43:28 | Promise ... urce()) | | rxjs.js:3:1:3:8 | source() | rxjs.js:10:14:10:17 | data | | rxjs.js:13:1:13:8 | source() | rxjs.js:17:23:17:23 | x | | rxjs.js:13:1:13:8 | source() | rxjs.js:18:23:18:23 | x | From 4043bc13ab7c61e21efb94eb949cb44032fe8bc5 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 09:19:03 +0100 Subject: [PATCH 167/514] JS: Explicit mark comment as a TODO --- .../ql/lib/semmle/javascript/internal/flow_summaries/Maps.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Maps.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Maps.qll index 57d4fb69340..c80bee19aaa 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Maps.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Maps.qll @@ -82,7 +82,7 @@ class MapGet extends SummarizedCallable { MapGet() { this = "Map#get" } override DataFlow::MethodCallNode getACallSimple() { - none() and // Disabled for now - need MaD syntax for known map values + none() and // TODO: Disabled for now - need MaD syntax for known map values result.getMethodName() = "get" and result.getNumArgument() = 1 } @@ -108,7 +108,7 @@ class MapSet extends SummarizedCallable { output = "ReturnValue" or preservesValue = true and - none() and // Disabled for now - need MaD syntax for known map values + none() and // TODO: Disabled for now - need MaD syntax for known map values ( input = "Argument[0]" and output = "Argument[this].MapKey" From e66f27cfe3c302a58d7b3c9c1a9bb146ba56277c Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 09:19:26 +0100 Subject: [PATCH 168/514] JS: Move hasWildcardReplaceRegExp to a shared place --- .../ql/lib/semmle/javascript/StandardLibrary.qll | 9 +++++++++ .../lib/semmle/javascript/dataflow/TaintTracking.qll | 8 +------- .../javascript/internal/flow_summaries/Strings.qll | 10 ++-------- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/StandardLibrary.qll b/javascript/ql/lib/semmle/javascript/StandardLibrary.qll index b40f10d9369..dc856fbab4b 100644 --- a/javascript/ql/lib/semmle/javascript/StandardLibrary.qll +++ b/javascript/ql/lib/semmle/javascript/StandardLibrary.qll @@ -154,6 +154,15 @@ class StringReplaceCall extends DataFlow::MethodCallNode { new = ret.getStringValue() ) } + + /** + * Holds if this call takes a regexp containing a wildcard-like term such as `.`. + * + * Also see `RegExp::isWildcardLike`. + */ + final predicate hasRegExpContainingWildcard() { + RegExp::isWildcardLike(this.getRegExp().getRoot().getAChild*()) + } } /** diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 8e1964ac0e3..2574660fbeb 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -424,7 +424,7 @@ module TaintTracking { // In and out of .replace callbacks exists(StringReplaceCall call | // Into the callback if the regexp does not sanitize matches - hasWildcardReplaceRegExp(call) and + call.hasRegExpContainingWildcard() and pred = call.getReceiver() and succ = call.getReplacementCallback().getParameter(0) or @@ -435,12 +435,6 @@ module TaintTracking { } } - /** Holds if the given call takes a regexp containing a wildcard. */ - pragma[noinline] - private predicate hasWildcardReplaceRegExp(StringReplaceCall call) { - RegExp::isWildcardLike(call.getRegExp().getRoot().getAChild*()) - } - /** * A taint propagating data flow edge arising from string formatting. */ diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll index cfa8688105e..941b9a825c3 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll @@ -5,12 +5,6 @@ private import javascript private import semmle.javascript.dataflow.FlowSummary -/** Holds if the given call takes a regexp containing a wildcard. */ -pragma[noinline] -private predicate hasWildcardReplaceRegExp(StringReplaceCall call) { - RegExp::isWildcardLike(call.getRegExp().getRoot().getAChild*()) -} - /** * Summary for calls to `.replace` or `.replaceAll` (without a regexp pattern containing a wildcard). */ @@ -19,7 +13,7 @@ private class StringReplaceNoWildcard extends SummarizedCallable { this = "String#replace / String#replaceAll (without wildcard pattern)" } - override StringReplaceCall getACall() { not hasWildcardReplaceRegExp(result) } + override StringReplaceCall getACall() { not result.hasRegExpContainingWildcard() } override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { preservesValue = false and @@ -43,7 +37,7 @@ private class StringReplaceWithWildcard extends SummarizedCallable { this = "String#replace / String#replaceAll (with wildcard pattern)" } - override StringReplaceCall getACall() { hasWildcardReplaceRegExp(result) } + override StringReplaceCall getACall() { result.hasRegExpContainingWildcard() } override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { preservesValue = false and From 14e75be5103a394a5a409886e3d88076805c84fa Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 09:27:00 +0100 Subject: [PATCH 169/514] JS: Expand comments and synthetic node name in ForOfLoops --- .../internal/flow_summaries/ForOfLoops.qll | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ForOfLoops.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ForOfLoops.qll index 0efe77bcab8..1407ce7c79e 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ForOfLoops.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ForOfLoops.qll @@ -10,8 +10,14 @@ private import semmle.javascript.dataflow.internal.DataFlowPrivate class ForOfLoopStep extends AdditionalFlowInternal { override predicate needsSynthesizedNode(AstNode node, string tag, DataFlowCallable container) { // Intermediate nodes to convert (MapKey, MapValue) to a `[key, value]` array. + // + // For the loop `for (let lvalue of domain)` we generate the following steps: + // + // domain --- READ[MapKey] ---> synthetic node 1 --- STORE[0] ---> lvalue + // domain --- READ[MapValue] ---> synthetic node 2 --- STORE[1] ---> lvalue + // node instanceof ForOfStmt and - tag = ["map-key", "map-value"] and + tag = ["for-of-map-key", "for-of-map-value"] and container.asSourceCallable() = node.getContainer() } @@ -27,10 +33,10 @@ class ForOfLoopStep extends AdditionalFlowInternal { succ = DataFlow::lvalueNode(stmt.getLValue()) or contents = DataFlow::ContentSet::mapKey() and - succ = getSynthesizedNode(stmt, "map-key") + succ = getSynthesizedNode(stmt, "for-of-map-key") or contents = DataFlow::ContentSet::mapValueAll() and - succ = getSynthesizedNode(stmt, "map-value") + succ = getSynthesizedNode(stmt, "for-of-map-value") or contents = DataFlow::ContentSet::iteratorError() and succ = stmt.getIterationDomain().getExceptionTarget() @@ -41,10 +47,10 @@ class ForOfLoopStep extends AdditionalFlowInternal { DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ ) { exists(ForOfStmt stmt | - pred = getSynthesizedNode(stmt, "map-key") and + pred = getSynthesizedNode(stmt, "for-of-map-key") and contents.asArrayIndex() = 0 or - pred = getSynthesizedNode(stmt, "map-value") and + pred = getSynthesizedNode(stmt, "for-of-map-value") and contents.asArrayIndex() = 1 | succ = DataFlow::lvalueNode(stmt.getLValue()) From e6401540480508e715aa7bb272884a9c5672ef51 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 10:54:02 +0100 Subject: [PATCH 170/514] JS: Be backwards compatible with AdditionalBarrierGuardNode I've confirmed that the 'legacyBarrier' predicate does not occur in the DIL --- .../dataflow/internal/DataFlowPrivate.qll | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 1970163794d..2bcad7d9f1a 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -8,6 +8,7 @@ private import semmle.javascript.dataflow.internal.VariableCapture private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon private import semmle.javascript.internal.flow_summaries.AllFlowSummaries private import sharedlib.FlowSummaryImpl as FlowSummaryImpl +private import semmle.javascript.dataflow.internal.BarrierGuards private class Node = DataFlow::Node; @@ -730,18 +731,36 @@ private predicate sameContainerAsEnclosingContainer(Node node, Function fun) { node.getContainer() = fun.getEnclosingContainer() } +private class BarrierGuardAdapter extends DataFlow::Node instanceof DataFlow::AdditionalBarrierGuardNode +{ + // Note: avoid depending on DataFlow::FlowLabel here as it will cause these barriers to be re-evaluated + predicate blocksExpr(boolean outcome, Expr e) { super.blocks(outcome, e) } +} + /** - * Holds if `node` should be removed from the local data flow graph, but the node - * still exists for use by the legacy data flow library. + * Holds if `node` should be a barrier in all data flow configurations due to custom subclasses + * of `AdditionalBarrierGuardNode`. + * + * The standard library contains no subclasses of that class; this is for backwards compatibility only. */ pragma[nomagic] -private predicate isBlockedLegacyNode(TCapturedVariableNode node) { +private predicate legacyBarrier(DataFlow::Node node) { + node = MakeBarrierGuard::getABarrierNode() +} + +/** + * Holds if `node` should be removed from the local data flow graph, for compatibility with legacy code. + */ +pragma[nomagic] +private predicate isBlockedLegacyNode(Node node) { // Ignore captured variable nodes for those variables that are handled by the captured-variable library. // Note that some variables, such as top-level variables, are still modelled with these nodes (which will result in jump steps). exists(LocalVariable variable | node = TCapturedVariableNode(variable) and variable instanceof VariableCaptureConfig::CapturedVariable ) + or + legacyBarrier(node) } /** From fce2be0af30a473c146fe5903a9294d541c1a63f Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 11:02:09 +0100 Subject: [PATCH 171/514] JS: Use BarrierGuardLegacy in TaintedPath --- .../dataflow/TaintedPathCustomizations.qll | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll index 77227841c42..d4deb186b09 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll @@ -44,10 +44,10 @@ module TaintedPath { } /** 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) } + abstract class BarrierGuardLegacy extends BarrierGuard, DataFlow::BarrierGuardNode { + override predicate blocks(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } - override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { + override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel label) { this.blocksExpr(outcome, e, label) } } @@ -366,7 +366,7 @@ module TaintedPath { * * This is relevant for paths that are known to be normalized. */ - class StartsWithDotDotSanitizer extends BarrierGuard instanceof StringOps::StartsWith { + class StartsWithDotDotSanitizer extends BarrierGuardLegacy instanceof StringOps::StartsWith { StartsWithDotDotSanitizer() { isDotDotSlashPrefix(super.getSubstring()) } override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { @@ -386,7 +386,7 @@ module TaintedPath { /** * A check of the form `whitelist.includes(x)` or equivalent, which sanitizes `x` in its "then" branch. */ - class MembershipTestBarrierGuard extends BarrierGuard { + class MembershipTestBarrierGuard extends BarrierGuardLegacy { MembershipCandidate candidate; MembershipTestBarrierGuard() { this = candidate.getTest() } @@ -401,7 +401,7 @@ module TaintedPath { * A check of form `x.startsWith(dir)` that sanitizes normalized absolute paths, since it is then * known to be in a subdirectory of `dir`. */ - class StartsWithDirSanitizer extends BarrierGuard { + class StartsWithDirSanitizer extends BarrierGuardLegacy { StringOps::StartsWith startsWith; StartsWithDirSanitizer() { @@ -425,7 +425,7 @@ module TaintedPath { * A call to `path.isAbsolute` as a sanitizer for relative paths in true branch, * and a sanitizer for absolute paths in the false branch. */ - class IsAbsoluteSanitizer extends BarrierGuard { + class IsAbsoluteSanitizer extends BarrierGuardLegacy { DataFlow::Node operand; boolean polarity; boolean negatable; @@ -461,7 +461,7 @@ module TaintedPath { /** * An expression of form `x.includes("..")` or similar. */ - class ContainsDotDotSanitizer extends BarrierGuard instanceof StringOps::Includes { + class ContainsDotDotSanitizer extends BarrierGuardLegacy instanceof StringOps::Includes { ContainsDotDotSanitizer() { isDotDotSlashPrefix(super.getSubstring()) } override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { @@ -474,7 +474,7 @@ module TaintedPath { /** * An expression of form `x.matches(/\.\./)` or similar. */ - class ContainsDotDotRegExpSanitizer extends BarrierGuard instanceof StringOps::RegExpTest { + class ContainsDotDotRegExpSanitizer extends BarrierGuardLegacy instanceof StringOps::RegExpTest { ContainsDotDotRegExpSanitizer() { super.getRegExp().getAMatchedString() = [".", "..", "../"] } override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { @@ -505,7 +505,7 @@ module TaintedPath { * } * ``` */ - class RelativePathStartsWithSanitizer extends BarrierGuard { + class RelativePathStartsWithSanitizer extends BarrierGuardLegacy { StringOps::StartsWith startsWith; DataFlow::CallNode pathCall; string member; @@ -563,7 +563,7 @@ module TaintedPath { * An expression of form `isInside(x, y)` or similar, where `isInside` is * a library check for the relation between `x` and `y`. */ - class IsInsideCheckSanitizer extends BarrierGuard { + class IsInsideCheckSanitizer extends BarrierGuardLegacy { DataFlow::Node checked; boolean onlyNormalizedAbsolutePaths; From e0aae53ac7dcb5342cc9bb8dbff9b294a3b167ae Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 11:05:23 +0100 Subject: [PATCH 172/514] JS: Remove unnecessary BarrierGuardLegacy class --- .../javascript/security/dataflow/StoredXssCustomizations.qll | 5 ----- 1 file changed, 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssCustomizations.qll index b0de349a53d..412332b5411 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssCustomizations.qll @@ -31,11 +31,6 @@ module StoredXss { predicate blocksExpr(boolean outcome, Expr e) { 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) } - } - /** An arbitrary XSS sink, considered as a flow sink for stored XSS. */ private class AnySink extends Sink { AnySink() { this instanceof Shared::Sink } From b31f20a64e61177fc07304ed1740be29b53b925f Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 11:08:25 +0100 Subject: [PATCH 173/514] JS: Explain why ObjetWrapperFlowLabel is deprecated --- .../dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll index b05190e4b7a..2af00bdac2a 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll @@ -39,7 +39,12 @@ module ExternalAPIUsedWithUntrustedDataConfig implements DataFlow::ConfigSig { module ExternalAPIUsedWithUntrustedDataFlow = TaintTracking::Global; -/** Flow label for objects from which a tainted value is reachable. */ +/** + * Flow label for objects from which a tainted value is reachable. + * + * Only used by the legacy data-flow configuration, as the new data flow configuration + * uses `allowImplicitRead` to achieve this instead. + */ deprecated private class ObjectWrapperFlowLabel extends DataFlow::FlowLabel { ObjectWrapperFlowLabel() { this = "object-wrapper" } } From 11983faccfa3ba06083216748cde92dee7a4915d Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 11:26:56 +0100 Subject: [PATCH 174/514] JS: Remove out-commented code --- .../javascript/security/dataflow/FileAccessToHttpQuery.qll | 2 -- 1 file changed, 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/FileAccessToHttpQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/FileAccessToHttpQuery.qll index 7f3d2c5f341..6b713af340a 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/FileAccessToHttpQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/FileAccessToHttpQuery.qll @@ -22,8 +22,6 @@ module FileAccessToHttpConfig implements DataFlow::ConfigSig { predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet contents) { isSink(node) and - // or - // node = any(DataFlow::MethodCallNode call | call.getMethodName() = "stringify").getAnArgument() contents = DataFlow::ContentSet::anyProperty() } } From 0a2050bc42c68caf058d402a5300613fb6280731 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 11:27:18 +0100 Subject: [PATCH 175/514] JS: Deduplicate predicate in HostHeaderPoisoningQuery --- .../HostHeaderPoisoningInEmailGenerationQuery.qll | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGenerationQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGenerationQuery.qll index 88950066802..acc2eacec07 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGenerationQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGenerationQuery.qll @@ -30,14 +30,7 @@ module HostHeaderPoisoningFlow = TaintTracking::Global Date: Wed, 13 Mar 2024 11:30:52 +0100 Subject: [PATCH 176/514] JS: Add comment about allowImplicitRead in PostMessageStar --- .../semmle/javascript/security/dataflow/PostMessageStarQuery.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/PostMessageStarQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/PostMessageStarQuery.qll index c267c9df8e0..5fde270041e 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/PostMessageStarQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/PostMessageStarQuery.qll @@ -34,6 +34,7 @@ module PostMessageStarConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet contents) { + // If an object leaks, all of its properties have leaked isSink(node) and contents = DataFlow::ContentSet::anyProperty() } } From ea4bc9cdbbddd4ab1016c34e3b824a86f13e1502 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 12:26:56 +0100 Subject: [PATCH 177/514] JS: Comment about manually applying taint steps --- .../security/dataflow/SecondOrderCommandInjectionQuery.qll | 2 ++ .../security/dataflow/TemplateObjectInjectionQuery.qll | 2 ++ 2 files changed, 4 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionQuery.qll index 86045d167f1..1fab45843a9 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionQuery.qll @@ -43,6 +43,8 @@ module SecondOrderCommandInjectionConfig implements DataFlow::StateConfigSig { ) { TaintedObject::step(src, trg, inlbl, outlbl) or + // We're not using a taint-tracking config because taint steps would then apply to all flow states. + // So we use a plain data flow config and manually add the default taint steps. inlbl.isTaint() and TaintTracking::defaultTaintStep(src, trg) and inlbl = outlbl diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TemplateObjectInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TemplateObjectInjectionQuery.qll index 0d3c7657810..1a4f02be601 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TemplateObjectInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TemplateObjectInjectionQuery.qll @@ -39,6 +39,8 @@ module TemplateObjectInjectionConfig implements DataFlow::StateConfigSig { ) { TaintedObject::step(src, trg, inlbl, outlbl) or + // We're not using a taint-tracking config because taint steps would then apply to all flow states. + // So we use a plain data flow config and manually add the default taint steps. inlbl.isTaint() and TaintTracking::defaultTaintStep(src, trg) and inlbl = outlbl From fa8933eb415e02c8f3a8a37f25569bb74510a0f4 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 12:29:56 +0100 Subject: [PATCH 178/514] JS: Reduce duplication in UnsafeDynamicMethodAccessQuery --- .../UnsafeDynamicMethodAccessQuery.qll | 38 +++++++------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccessQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccessQuery.qll index 556204375df..1d1098f87e1 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccessQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccessQuery.qll @@ -43,7 +43,7 @@ module UnsafeDynamicMethodAccessConfig implements DataFlow::StateConfigSig { label.isTaint() } - predicate isAdditionalFlowStep( + additional predicate additionalFlowStep( DataFlow::Node src, DataFlow::FlowLabel srclabel, DataFlow::Node dst, DataFlow::FlowLabel dstlabel ) { @@ -64,7 +64,16 @@ module UnsafeDynamicMethodAccessConfig implements DataFlow::StateConfigSig { srclabel.isTaint() and dstlabel = unsafeFunction() ) + } + + predicate isAdditionalFlowStep( + DataFlow::Node src, DataFlow::FlowLabel srclabel, DataFlow::Node dst, + DataFlow::FlowLabel dstlabel + ) { + additionalFlowStep(src, srclabel, dst, dstlabel) or + // We're not using a taint-tracking config because taint steps would then apply to all flow states. + // So we use a plain data flow config and manually add the default taint steps. srclabel.isTaint() and TaintTracking::defaultTaintStep(src, dst) and srclabel = dstlabel @@ -83,20 +92,17 @@ deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "UnsafeDynamicMethodAccess" } override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { - source.(Source).getFlowLabel() = label + UnsafeDynamicMethodAccessConfig::isSource(source, label) } override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { - sink.(Sink).getFlowLabel() = label + UnsafeDynamicMethodAccessConfig::isSink(sink, label) } override predicate isSanitizer(DataFlow::Node node) { super.isSanitizer(node) or - node instanceof Sanitizer - or - exists(StringConcatenation::getOperand(node, _)) and - not StringConcatenation::isCoercion(node) + UnsafeDynamicMethodAccessConfig::isBarrier(node) } /** @@ -110,22 +116,6 @@ deprecated class Configuration extends TaintTracking::Configuration { DataFlow::Node src, DataFlow::Node dst, DataFlow::FlowLabel srclabel, DataFlow::FlowLabel dstlabel ) { - // Reading a property of the global object or of a function - exists(DataFlow::PropRead read | - this.hasUnsafeMethods(read.getBase().getALocalSource()) and - src = read.getPropertyNameExpr().flow() and - dst = read and - srclabel.isTaint() and - dstlabel = unsafeFunction() - ) - or - // Reading a chain of properties from any object with a prototype can lead to Function - exists(PropertyProjection proj | - not PropertyInjection::isPrototypeLessObject(proj.getObject().getALocalSource()) and - src = proj.getASelector() and - dst = proj and - srclabel.isTaint() and - dstlabel = unsafeFunction() - ) + UnsafeDynamicMethodAccessConfig::additionalFlowStep(src, srclabel, dst, dstlabel) } } From 97567f412e5d33ac1d0915b6d3e893a400337178 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 14:53:00 +0100 Subject: [PATCH 179/514] JS: Update VariableCapture.qll after changes to API --- .../semmle/javascript/dataflow/internal/VariableCapture.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll index 1b1f50b9ecd..5e5ebacbf6b 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll @@ -3,7 +3,7 @@ private import semmle.javascript.dataflow.internal.DataFlowNode private import codeql.dataflow.VariableCapture private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon -module VariableCaptureConfig implements InputSig { +module VariableCaptureConfig implements InputSig { private js::Function getLambdaFromVariable(js::LocalVariable variable) { result.getVariable() = variable or @@ -261,7 +261,7 @@ module VariableCaptureConfig implements InputSig { predicate exitBlock(BasicBlock bb) { bb.getLastNode() instanceof js::ControlFlowExitNode } } -module VariableCaptureOutput = Flow; +module VariableCaptureOutput = Flow; js::DataFlow::Node getNodeFromClosureNode(VariableCaptureOutput::ClosureNode node) { result = TValueNode(node.(VariableCaptureOutput::ExprNode).getExpr()) From bb1f729a3f463de7ef603907f61cb9fded6810f8 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 15:16:37 +0100 Subject: [PATCH 180/514] Update VariableCapture.qll --- .../lib/semmle/javascript/dataflow/internal/VariableCapture.qll | 2 -- 1 file changed, 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll index 5e5ebacbf6b..8cb83930f4f 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll @@ -130,8 +130,6 @@ module VariableCaptureConfig implements InputSig { Callable getEnclosingCallable() { result = this.getContainer().getFunctionBoundary() } } - class Location = js::Location; - class Callable extends js::StmtContainer { predicate isConstructor() { // TODO: clarify exactly what the library wants to know here as the meaning of "constructor" varies between languages. From e5bc8db2f07e4e2f03999599c7c790a7b7b8f1b3 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 15:17:08 +0100 Subject: [PATCH 181/514] JS: Fix conflicting default for visbleImplInCallContext --- .../javascript/dataflow/internal/sharedlib/DataFlowArg.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll index 6422dca52dd..fda3d94c4c9 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll @@ -12,6 +12,8 @@ module JSDataFlow implements SharedDataFlow::InputSig { predicate neverSkipInPathGraph = Private::neverSkipInPathGraph/1; predicate accessPathLimit = Private::accessPathLimit/0; + + predicate viableImplInCallContext = Private::viableImplInCallContext/2; } module JSTaintFlow implements SharedTaintTracking::InputSig { From 82abd867a029e9e059216424c1ef17a883ac74c5 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 15:17:58 +0100 Subject: [PATCH 182/514] JS: Update uses of AccessPathSyntax This doesn't yet migrate to the FlowSummaryImpl.qll in a qlpack, just trying to make things compile first --- .../javascript/dataflow/internal/Contents.qll | 6 ++--- .../dataflow/internal/FlowSummaryPrivate.qll | 8 +++--- .../internal/sharedlib/FlowSummaryImpl.qll | 26 +++++++++---------- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll index 5c87d3c0a51..6c6272e6e32 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll @@ -1,5 +1,5 @@ private import javascript -private import semmle.javascript.frameworks.data.internal.AccessPathSyntax as AccessPathSyntax +private import semmle.javascript.frameworks.data.internal.ApiGraphModels as ApiGraphModels module Private { import Public @@ -25,7 +25,7 @@ module Private { call.getArgument(0).getStringValue() = key ) or - exists(AccessPathSyntax::AccessPathToken token | + exists(ApiGraphModels::AccessPathToken token | token.getName() = "MapValue" and token.getAnArgument() = key ) @@ -47,7 +47,7 @@ module Private { or this = getAPreciseArrayIndex().toString() or - exists(AccessPathSyntax::AccessPathToken tok | + exists(ApiGraphModels::AccessPathToken tok | tok.getName() = "Member" and this = tok.getAnArgument() ) } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index e838281f0bd..58ab67ec8a7 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -9,7 +9,7 @@ private import semmle.javascript.dataflow.FlowSummary as FlowSummary private import sharedlib.DataFlowImplCommon private import sharedlib.FlowSummaryImpl::Private as Private private import sharedlib.FlowSummaryImpl::Public -import semmle.javascript.frameworks.data.internal.AccessPathSyntax as AccessPathSyntax +private import codeql.dataflow.internal.AccessPathSyntax as AccessPathSyntax private class Node = DataFlow::Node; @@ -147,7 +147,7 @@ private predicate desugaredPositionName(ParameterPosition pos, string operand) { operand = "any" and pos.asPositionalLowerBound() = 0 or - pos.asPositional() = AccessPathSyntax::AccessPath::parseInt(operand) // parse closed intervals + pos.asPositional() = AccessPathSyntax::parseInt(operand) // parse closed intervals } bindingset[operand] @@ -186,7 +186,7 @@ SummaryComponent interpretComponentSpecific(Private::AccessPathToken c) { result = makePropertyContentComponents(c, "ArrayElement", n.toString()) or // ArrayElement[n..] refers to index n or greater - n = AccessPathSyntax::AccessPath::parseLowerBound(c.getAnArgument()) and + n = AccessPathSyntax::parseLowerBound(c.getAnArgument()) and result = makeContentComponents(c, "ArrayElement", ContentSet::arrayElementLowerBoundFromInt(n)) ) or @@ -355,7 +355,7 @@ ArgumentPosition parseParamBody(string s) { or s = "function" and result.isFunctionSelfReference() or - result.asPositional() = AccessPathSyntax::AccessPath::parseInt(s) + result.asPositional() = AccessPathSyntax::parseInt(s) } /** Gets the parameter position obtained by parsing `X` in `Argument[X]`. */ diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll index 0aa17c521b4..7bbb1abe2f9 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll @@ -340,7 +340,7 @@ module Public { */ module Private { private import Public - import AccessPathSyntax + private import codeql.dataflow.internal.AccessPathSyntax newtype TSummaryComponent = TContentSummaryComponent(ContentSet c) or @@ -1037,23 +1037,21 @@ module Private { } } + /** Holds if `spec` is a relevant external specification. */ + private predicate relevantSpec(string spec) { + summaryElement(_, spec, _, _, _) or + summaryElement(_, _, spec, _, _) or + sourceElement(_, spec, _, _) or + sinkElement(_, spec, _, _) + } + + import AccessPath + /** * Provides a means of translating externally (e.g., MaD) defined flow * summaries into a `SummarizedCallable`s. */ module External { - /** Holds if `spec` is a relevant external specification. */ - private predicate relevantSpec(string spec) { - summaryElement(_, spec, _, _, _) or - summaryElement(_, _, spec, _, _) or - sourceElement(_, spec, _, _) or - sinkElement(_, spec, _, _) - } - - private class AccessPathRange extends AccessPath::Range { - AccessPathRange() { relevantSpec(this) } - } - /** Holds if specification component `token` parses as parameter `pos`. */ predicate parseParam(AccessPathToken token, ArgumentPosition pos) { token.getName() = "Parameter" and @@ -1184,7 +1182,7 @@ module Private { predicate invalidIndexComponent(AccessPath spec, AccessPathToken part) { part = spec.getToken(_) and part.getName() = ["Parameter", "Argument"] and - AccessPath::parseInt(part.getArgumentList()) < 0 + parseInt(part.getArgumentList()) < 0 } private predicate inputNeedsReference(AccessPathToken c) { From 8ecdb5cefe9cd08d22275f4eba62f920403b695c Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 15:24:20 +0100 Subject: [PATCH 183/514] Update VariableCapture.qll --- .../semmle/javascript/dataflow/internal/VariableCapture.qll | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll index 8cb83930f4f..4e8aa233eb2 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll @@ -185,7 +185,7 @@ module VariableCaptureConfig implements InputSig { string toString() { none() } // Overridden in subclass - Location getLocation() { none() } // Overridden in subclass + js::Location getLocation() { none() } // Overridden in subclass predicate hasCfgNode(BasicBlock bb, int i) { none() } // Overridden in subclass @@ -203,7 +203,7 @@ module VariableCaptureConfig implements InputSig { override string toString() { result = pattern.toString() } /** Gets the location of this write. */ - override Location getLocation() { result = pattern.getLocation() } + override js::Location getLocation() { result = pattern.getLocation() } override js::DataFlow::Node getSource() { // Note: there is not always an expression corresponding to the RHS of the assignment. @@ -239,7 +239,7 @@ module VariableCaptureConfig implements InputSig { override string toString() { result = "[implicit init] " + variable } - override Location getLocation() { result = variable.getLocation() } + override js::Location getLocation() { result = variable.getLocation() } override CapturedVariable getVariable() { result = variable } From ddf6eb3a045875316b81b4f3d475ab4057e2390c Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 15:24:53 +0100 Subject: [PATCH 184/514] JS: Quick fix to make DeduplicatePathGraph compile There's an open PR for this where a real fix should be written --- shared/dataflow/codeql/dataflow/DataFlow.qll | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/DataFlow.qll b/shared/dataflow/codeql/dataflow/DataFlow.qll index 5ef4ffbb36a..97d6ef7a1b0 100644 --- a/shared/dataflow/codeql/dataflow/DataFlow.qll +++ b/shared/dataflow/codeql/dataflow/DataFlow.qll @@ -935,11 +935,15 @@ module DataFlowMake { exists(getAPathNode(node, toString)) } + private predicate edgesProj(InputPathNode node1, InputPathNode node2) { + Graph::edges(node2, node1, _, _) + } + private module Pass1 = - MakeDiscriminatorPass; + MakeDiscriminatorPass; private predicate edgesRev(InputPathNode node1, InputPathNode node2) { - Graph::edges(node2, node1) + Graph::edges(node2, node1, _, _) } private predicate subpathsRev( @@ -1009,8 +1013,9 @@ module DataFlowMake { Graph::nodes(node.getAnOriginalPathNode(), key, val) } - query predicate edges(PathNode node1, PathNode node2) { - Graph::edges(node1.getAnOriginalPathNode(), node2.getAnOriginalPathNode()) + query predicate edges(PathNode node1, PathNode node2, string key, string val) { + // TODO: ensure deduplication preserves key/val sequence? + Graph::edges(node1.getAnOriginalPathNode(), node2.getAnOriginalPathNode(), key, val) } query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) { From eff5f3b7d6d6a354370e2d404ce5fd38b1477c49 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 Mar 2024 20:43:44 +0100 Subject: [PATCH 185/514] JS: Remove duplicate dependency from qlpack.yml --- javascript/ql/lib/qlpack.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index da79517156f..ef3ca7521ac 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -12,7 +12,6 @@ dependencies: codeql/tutorial: ${workspace} codeql/util: ${workspace} codeql/yaml: ${workspace} - codeql/dataflow: ${workspace} dataExtensions: - semmle/javascript/frameworks/**/model.yml warnOnImplicitThis: true From 711a08b0d4b6c7cf17e65dd6f9d2de42e080e144 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 15 Mar 2024 09:26:19 +0100 Subject: [PATCH 186/514] JS: Add TODO about switching to the shared library --- .../javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll index 7bbb1abe2f9..6671fc229bc 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll @@ -12,6 +12,7 @@ private import DataFlowImplSpecific::Public private import DataFlowImplCommon private import codeql.util.Unit +// TODO: switch to the shared implementation of FlowSummaryImpl.qll /** Provides classes and predicates for defining flow summaries. */ module Public { private import Private From 2de9af2236c1acaa02c1aa91db7f024ae42c0706 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 6 May 2024 10:09:20 +0200 Subject: [PATCH 187/514] JS: Update to getLocation() in DeduplicatePathGraph --- shared/dataflow/codeql/dataflow/DataFlow.qll | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/DataFlow.qll b/shared/dataflow/codeql/dataflow/DataFlow.qll index 33fd249cb64..ce7814c1c74 100644 --- a/shared/dataflow/codeql/dataflow/DataFlow.qll +++ b/shared/dataflow/codeql/dataflow/DataFlow.qll @@ -1004,19 +1004,8 @@ module DataFlowMake Lang> { result = this.asPreservedNode().toString() or this = TCollapsedPathNode(_, result) } - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - this.getAnOriginalPathNode() - .hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } + /** Gets the location of this node. */ + Location getLocation() { result = this.getAnOriginalPathNode().getLocation() } /** Gets the corresponding data-flow node. */ Node getNode() { From 19f14622f3450041b64d7736d190a56baa04fe16 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 6 May 2024 10:11:49 +0200 Subject: [PATCH 188/514] JS: Update use of Locations --- .../semmle/javascript/dataflow/DataFlow.qll | 26 +++---------------- .../dataflow/internal/DataFlowPrivate.qll | 12 +-------- .../dataflow/internal/VariableCapture.qll | 10 +++---- .../dataflow/internal/sharedlib/DataFlow.qll | 3 ++- .../internal/sharedlib/DataFlowArg.qll | 5 ++-- .../internal/sharedlib/DataFlowImpl.qll | 3 ++- .../internal/sharedlib/DataFlowImplCommon.qll | 3 ++- .../internal/sharedlib/TaintTracking.qll | 3 ++- 8 files changed, 21 insertions(+), 44 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index 5726c0b30a2..a80b2e79ff9 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -1056,11 +1056,7 @@ module DataFlow { override StmtContainer getContainer() { result = expr.getContainer() } - override predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - expr.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } + override Location getLocation() { result = expr.getLocation() } } /** @@ -1075,13 +1071,7 @@ module DataFlow { override StmtContainer getContainer() { result = constructor } - override predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - constructor - .getLocation() - .hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } + override Location getLocation() { result = constructor.getLocation() } } /** @@ -1403,11 +1393,7 @@ module DataFlow { override string toString() { result = "[function self-reference] " + function.toString() } - override predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - function.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } + override Location getLocation() { result = function.getLocation() } } /** @@ -1423,11 +1409,7 @@ module DataFlow { override StmtContainer getContainer() { result = expr.getContainer() } - override predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - expr.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } + override Location getLocation() { result = expr.getLocation() } override string toString() { result = "[post update] " + expr.toString() } } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 2bcad7d9f1a..d19e265a2b4 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -59,12 +59,6 @@ class CaptureNode extends DataFlow::Node, TSynthCaptureNode { cached private Location getLocation() { result = this.getNode().getLocation() } - - override predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } } class GenericSynthesizedNode extends DataFlow::Node, TGenericSynthesizedNode { @@ -78,11 +72,7 @@ class GenericSynthesizedNode extends DataFlow::Node, TGenericSynthesizedNode { override string toString() { result = "[synthetic node] " + tag } - override predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - node.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } + override Location getLocation() { result = node.getLocation() } string getTag() { result = tag } } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll index 4e8aa233eb2..f170b99e892 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll @@ -3,7 +3,7 @@ private import semmle.javascript.dataflow.internal.DataFlowNode private import codeql.dataflow.VariableCapture private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon -module VariableCaptureConfig implements InputSig { +module VariableCaptureConfig implements InputSig { private js::Function getLambdaFromVariable(js::LocalVariable variable) { result.getVariable() = variable or @@ -185,7 +185,7 @@ module VariableCaptureConfig implements InputSig { string toString() { none() } // Overridden in subclass - js::Location getLocation() { none() } // Overridden in subclass + js::DbLocation getLocation() { none() } // Overridden in subclass predicate hasCfgNode(BasicBlock bb, int i) { none() } // Overridden in subclass @@ -203,7 +203,7 @@ module VariableCaptureConfig implements InputSig { override string toString() { result = pattern.toString() } /** Gets the location of this write. */ - override js::Location getLocation() { result = pattern.getLocation() } + override js::DbLocation getLocation() { result = pattern.getLocation() } override js::DataFlow::Node getSource() { // Note: there is not always an expression corresponding to the RHS of the assignment. @@ -239,7 +239,7 @@ module VariableCaptureConfig implements InputSig { override string toString() { result = "[implicit init] " + variable } - override js::Location getLocation() { result = variable.getLocation() } + override js::DbLocation getLocation() { result = variable.getLocation() } override CapturedVariable getVariable() { result = variable } @@ -259,7 +259,7 @@ module VariableCaptureConfig implements InputSig { predicate exitBlock(BasicBlock bb) { bb.getLastNode() instanceof js::ControlFlowExitNode } } -module VariableCaptureOutput = Flow; +module VariableCaptureOutput = Flow; js::DataFlow::Node getNodeFromClosureNode(VariableCaptureOutput::ClosureNode node) { result = TValueNode(node.(VariableCaptureOutput::ExprNode).getExpr()) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlow.qll index fda541f1d31..a9148af94ac 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlow.qll @@ -1,4 +1,5 @@ +private import semmle.javascript.Locations private import codeql.dataflow.DataFlow private import DataFlowArg -import DataFlowMake +import DataFlowMake import DataFlowImplSpecific::Public diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll index fda3d94c4c9..4b102e76ec4 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll @@ -1,8 +1,9 @@ +private import semmle.javascript.Locations private import DataFlowImplSpecific private import codeql.dataflow.DataFlow as SharedDataFlow private import codeql.dataflow.TaintTracking as SharedTaintTracking -module JSDataFlow implements SharedDataFlow::InputSig { +module JSDataFlow implements SharedDataFlow::InputSig { import Private import Public @@ -16,6 +17,6 @@ module JSDataFlow implements SharedDataFlow::InputSig { predicate viableImplInCallContext = Private::viableImplInCallContext/2; } -module JSTaintFlow implements SharedTaintTracking::InputSig { +module JSTaintFlow implements SharedTaintTracking::InputSig { import semmle.javascript.dataflow.internal.TaintTrackingPrivate } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImpl.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImpl.qll index 1b888d53859..3ddcb693f54 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImpl.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImpl.qll @@ -1,3 +1,4 @@ +private import semmle.javascript.Locations private import codeql.dataflow.internal.DataFlowImpl private import DataFlowArg -import MakeImpl +import MakeImpl diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImplCommon.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImplCommon.qll index 8db21ff168f..62188d47b80 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImplCommon.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowImplCommon.qll @@ -1,3 +1,4 @@ +private import semmle.javascript.Locations private import DataFlowArg private import codeql.dataflow.internal.DataFlowImplCommon -import MakeImplCommon +import MakeImplCommon diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/TaintTracking.qll index d5f3604202a..bfa4c4de8c9 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/TaintTracking.qll @@ -1,3 +1,4 @@ +private import semmle.javascript.Locations private import codeql.dataflow.TaintTracking private import DataFlowArg -import TaintFlowMake +import TaintFlowMake From 5a2260b4813c7e442b0d5ecbcd0f494ac3c0cdb5 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 6 May 2024 10:12:15 +0200 Subject: [PATCH 189/514] JS: Update to match changes to API --- .../javascript/dataflow/internal/DataFlowPrivate.qll | 12 +++++++++++- .../dataflow/internal/TaintTrackingPrivate.qll | 4 ++++ .../dataflow/internal/sharedlib/DataFlowArg.qll | 2 ++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index d19e265a2b4..22d8a98861e 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -10,6 +10,8 @@ private import semmle.javascript.internal.flow_summaries.AllFlowSummaries private import sharedlib.FlowSummaryImpl as FlowSummaryImpl private import semmle.javascript.dataflow.internal.BarrierGuards +class DataFlowSecondLevelScope = Unit; + private class Node = DataFlow::Node; class PostUpdateNode = DataFlow::PostUpdateNode; @@ -701,7 +703,7 @@ DataFlowCallable viableCallable(DataFlowCall node) { * Holds if the set of viable implementations that can be called by `call` * might be improved by knowing the call context. */ -predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c) { none() } +predicate mayBenefitFromCallContext(DataFlowCall call) { none() } /** * Gets a viable dispatch target of `call` in the context `ctx`. This is @@ -780,6 +782,14 @@ private predicate valuePreservingStep(Node node1, Node node2) { ) } +predicate knownSourceModel(Node sink, string model) { none() } + +predicate knownSinkModel(Node sink, string model) { none() } + +predicate simpleLocalFlowStep(Node node1, Node node2, string model) { + simpleLocalFlowStep(node1, node2) and model = "" +} + predicate simpleLocalFlowStep(Node node1, Node node2) { valuePreservingStep(node1, node2) and nodeGetEnclosingCallable(pragma[only_bind_out](node1)) = diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index 03d82ad42ea..f60c4e0f5db 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -19,6 +19,10 @@ predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) ContentSet::arrayElement(), node2.(FlowSummaryNode).getSummaryNode()) } +predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2, string model) { + defaultAdditionalTaintStep(node1, node2) and model = "" // TODO: set model +} + private class SanitizerGuardAdapter extends DataFlow::Node instanceof TaintTracking::AdditionalSanitizerGuardNode { // Note: avoid depending on DataFlow::FlowLabel here as it will cause these barriers to be re-evaluated diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll index 4b102e76ec4..e3a85506307 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll @@ -15,6 +15,8 @@ module JSDataFlow implements SharedDataFlow::InputSig { predicate accessPathLimit = Private::accessPathLimit/0; predicate viableImplInCallContext = Private::viableImplInCallContext/2; + + predicate mayBenefitFromCallContext = Private::mayBenefitFromCallContext/1; } module JSTaintFlow implements SharedTaintTracking::InputSig { From 23d28fc098caa20a0eaa7d9ce3b676f5b3a8ef58 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 6 May 2024 13:50:40 +0200 Subject: [PATCH 190/514] Shared: add location for 'this' nodes --- shared/dataflow/codeql/dataflow/VariableCapture.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shared/dataflow/codeql/dataflow/VariableCapture.qll b/shared/dataflow/codeql/dataflow/VariableCapture.qll index 9fd385d4458..c48b46e8a7b 100644 --- a/shared/dataflow/codeql/dataflow/VariableCapture.qll +++ b/shared/dataflow/codeql/dataflow/VariableCapture.qll @@ -645,6 +645,8 @@ module Flow Input> implements OutputSig Location getLocation() { exists(CapturedVariable v | this = TVariable(v) and result = v.getLocation()) + or + exists(Callable c | this = TThis(c) and result = c.getLocation()) } } From 536c115c1c130b3f1077efb7a2957f3f38f58cb5 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 6 May 2024 13:51:25 +0200 Subject: [PATCH 191/514] JS: Fix location override in CaptureNode --- .../lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 22d8a98861e..54a6148993b 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -60,7 +60,7 @@ class CaptureNode extends DataFlow::Node, TSynthCaptureNode { override string toString() { result = this.toStringInternal() } // cached in parent class cached - private Location getLocation() { result = this.getNode().getLocation() } + override Location getLocation() { result = this.getNode().getLocation() } } class GenericSynthesizedNode extends DataFlow::Node, TGenericSynthesizedNode { From f43a189f06623ccdf411162a45b53c7e0d93e9f2 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 6 May 2024 13:51:35 +0200 Subject: [PATCH 192/514] JS: Make CaptureNode.toString() more explicit --- .../lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 54a6148993b..330b0a59038 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -55,7 +55,7 @@ class CaptureNode extends DataFlow::Node, TSynthCaptureNode { override StmtContainer getContainer() { result = this.getNode().getEnclosingCallable() } cached - private string toStringInternal() { result = this.getNode().toString() } + private string toStringInternal() { result = this.getNode().toString() + " [capture node]" } override string toString() { result = this.toStringInternal() } // cached in parent class From 20df5adbaa7bd868a958b75ca2d31cd9b10278e1 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 25 Jun 2024 10:28:29 +0200 Subject: [PATCH 193/514] JS: Bugfix in DeduplicatePathGraph This was introduced after a quick fix to handle the addition of provenance. --- shared/dataflow/codeql/dataflow/DataFlow.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/dataflow/codeql/dataflow/DataFlow.qll b/shared/dataflow/codeql/dataflow/DataFlow.qll index ce7814c1c74..e110d65468a 100644 --- a/shared/dataflow/codeql/dataflow/DataFlow.qll +++ b/shared/dataflow/codeql/dataflow/DataFlow.qll @@ -957,7 +957,7 @@ module DataFlowMake Lang> { } private predicate edgesProj(InputPathNode node1, InputPathNode node2) { - Graph::edges(node2, node1, _, _) + Graph::edges(node1, node2, _, _) } private module Pass1 = From bd3fccd1a8ed3b16af2d5e070d567b76d764af1b Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 25 Jun 2024 10:03:35 +0200 Subject: [PATCH 194/514] JS: Update test output with provenance column --- .../IndirectCommandInjection.expected | 222 +-- ...llCommandInjectionFromEnvironment.expected | 12 +- .../UnsafeShellCommandConstruction.expected | 280 ++-- .../UnsafeDynamicMethodAccess.expected | 52 +- .../Security/CWE-201/PostMessageStar.expected | 12 +- .../CWE-327/BrokenCryptoAlgorithm.expected | 6 +- .../CWE-338/InsecureRandomness.expected | 64 +- .../CWE-798/HardcodedCredentials.expected | 76 +- .../CWE-829/InsecureDownload.expected | 32 +- .../PrototypePollutingFunction.expected | 1388 ++++++++--------- 10 files changed, 1072 insertions(+), 1072 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected index 51c52e86449..1dd1715cdcc 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected @@ -1,115 +1,115 @@ edges -| actions.js:4:6:4:16 | process.env | actions.js:4:6:4:29 | process ... _DATA'] | -| actions.js:7:15:7:15 | e | actions.js:8:10:8:10 | e | -| actions.js:8:10:8:10 | e | actions.js:8:10:8:23 | e['TEST_DATA'] | -| actions.js:12:6:12:16 | process.env | actions.js:7:15:7:15 | e | -| command-line-parameter-command-injection.js:8:22:8:33 | process.argv | command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | -| command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:11:14:11:17 | args | -| command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:12:26:12:29 | args | -| command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:14:18:14:21 | args | -| command-line-parameter-command-injection.js:10:6:10:33 | args [ArrayElement] | command-line-parameter-command-injection.js:14:18:14:21 | args [ArrayElement] | -| command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | -| command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) [ArrayElement] | -| command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | command-line-parameter-command-injection.js:10:6:10:33 | args | -| command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) [ArrayElement] | command-line-parameter-command-injection.js:10:6:10:33 | args [ArrayElement] | -| command-line-parameter-command-injection.js:11:14:11:17 | args | command-line-parameter-command-injection.js:11:14:11:20 | args[0] | -| command-line-parameter-command-injection.js:12:26:12:29 | args | command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | -| command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | -| command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | -| command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | -| command-line-parameter-command-injection.js:14:18:14:21 | args | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | -| command-line-parameter-command-injection.js:14:18:14:21 | args [ArrayElement] | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | -| command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | -| command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | -| command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | -| command-line-parameter-command-injection.js:18:6:18:24 | arg0 | command-line-parameter-command-injection.js:19:14:19:17 | arg0 | -| command-line-parameter-command-injection.js:18:6:18:24 | arg0 | command-line-parameter-command-injection.js:20:26:20:29 | arg0 | -| command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | -| command-line-parameter-command-injection.js:20:26:20:29 | arg0 | command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | -| command-line-parameter-command-injection.js:24:8:24:35 | args | command-line-parameter-command-injection.js:26:32:26:35 | args | -| command-line-parameter-command-injection.js:24:8:24:35 | args | command-line-parameter-command-injection.js:27:32:27:35 | args | -| command-line-parameter-command-injection.js:24:15:24:26 | process.argv | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | -| command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | command-line-parameter-command-injection.js:24:8:24:35 | args | -| command-line-parameter-command-injection.js:26:32:26:35 | args | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | -| command-line-parameter-command-injection.js:27:32:27:35 | args | command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | -| command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | -| command-line-parameter-command-injection.js:30:21:30:46 | require ... rgs")() | command-line-parameter-command-injection.js:30:9:30:50 | "cmd.sh ... )().foo | -| command-line-parameter-command-injection.js:32:21:32:41 | require ... ").argv | command-line-parameter-command-injection.js:32:9:32:45 | "cmd.sh ... rgv.foo | -| command-line-parameter-command-injection.js:33:21:33:44 | require ... ").argv | command-line-parameter-command-injection.js:33:9:33:48 | "cmd.sh ... rgv.foo | -| command-line-parameter-command-injection.js:36:6:39:7 | args | command-line-parameter-command-injection.js:41:22:41:25 | args | -| command-line-parameter-command-injection.js:36:13:39:7 | require ... \\t\\t.argv | command-line-parameter-command-injection.js:36:6:39:7 | args | -| command-line-parameter-command-injection.js:41:22:41:25 | args | command-line-parameter-command-injection.js:41:10:41:25 | "cmd.sh " + args | -| command-line-parameter-command-injection.js:43:22:43:58 | require ... parse() | command-line-parameter-command-injection.js:43:10:43:62 | "cmd.sh ... e().foo | -| command-line-parameter-command-injection.js:47:8:53:12 | args | command-line-parameter-command-injection.js:55:22:55:25 | args | -| command-line-parameter-command-injection.js:48:3:50:3 | argv: { ... rgs\\n\\t\\t} | command-line-parameter-command-injection.js:48:9:50:3 | {\\n\\t\\t\\t...args\\n\\t\\t} | -| command-line-parameter-command-injection.js:48:9:50:3 | {\\n\\t\\t\\t...args\\n\\t\\t} | command-line-parameter-command-injection.js:47:8:53:12 | args | -| command-line-parameter-command-injection.js:55:22:55:25 | args | command-line-parameter-command-injection.js:55:10:55:25 | "cmd.sh " + args | -| command-line-parameter-command-injection.js:57:6:57:37 | tainted1 | command-line-parameter-command-injection.js:61:11:61:18 | tainted1 | -| command-line-parameter-command-injection.js:57:17:57:37 | require ... ').argv | command-line-parameter-command-injection.js:57:6:57:37 | tainted1 | -| command-line-parameter-command-injection.js:58:6:58:40 | tainted2 | command-line-parameter-command-injection.js:62:11:62:18 | tainted2 | -| command-line-parameter-command-injection.js:58:17:58:40 | require ... parse() | command-line-parameter-command-injection.js:58:6:58:40 | tainted2 | -| command-line-parameter-command-injection.js:60:8:60:56 | {taint1 ... 2rest}} [taint1] | command-line-parameter-command-injection.js:60:9:60:31 | taint1: ... t1rest} | -| command-line-parameter-command-injection.js:60:8:60:56 | {taint1 ... 2rest}} [taint2] | command-line-parameter-command-injection.js:60:33:60:55 | taint2: ... t2rest} | -| command-line-parameter-command-injection.js:60:8:63:2 | taint1rest | command-line-parameter-command-injection.js:65:22:65:31 | taint1rest | -| command-line-parameter-command-injection.js:60:8:63:2 | taint2rest | command-line-parameter-command-injection.js:66:22:66:31 | taint2rest | -| command-line-parameter-command-injection.js:60:9:60:31 | taint1: ... t1rest} | command-line-parameter-command-injection.js:60:17:60:31 | {...taint1rest} | -| command-line-parameter-command-injection.js:60:17:60:31 | {...taint1rest} | command-line-parameter-command-injection.js:60:8:63:2 | taint1rest | -| command-line-parameter-command-injection.js:60:33:60:55 | taint2: ... t2rest} | command-line-parameter-command-injection.js:60:41:60:55 | {...taint2rest} | -| command-line-parameter-command-injection.js:60:41:60:55 | {...taint2rest} | command-line-parameter-command-injection.js:60:8:63:2 | taint2rest | -| command-line-parameter-command-injection.js:60:60:63:2 | {\\n\\t\\ttai ... ted2\\n\\t} [taint1] | command-line-parameter-command-injection.js:60:8:60:56 | {taint1 ... 2rest}} [taint1] | -| command-line-parameter-command-injection.js:60:60:63:2 | {\\n\\t\\ttai ... ted2\\n\\t} [taint2] | command-line-parameter-command-injection.js:60:8:60:56 | {taint1 ... 2rest}} [taint2] | -| command-line-parameter-command-injection.js:61:11:61:18 | tainted1 | command-line-parameter-command-injection.js:60:60:63:2 | {\\n\\t\\ttai ... ted2\\n\\t} [taint1] | -| command-line-parameter-command-injection.js:62:11:62:18 | tainted2 | command-line-parameter-command-injection.js:60:60:63:2 | {\\n\\t\\ttai ... ted2\\n\\t} [taint2] | -| command-line-parameter-command-injection.js:65:22:65:31 | taint1rest | command-line-parameter-command-injection.js:65:10:65:31 | "cmd.sh ... nt1rest | -| command-line-parameter-command-injection.js:66:22:66:31 | taint2rest | command-line-parameter-command-injection.js:66:10:66:31 | "cmd.sh ... nt2rest | -| command-line-parameter-command-injection.js:68:6:68:16 | {...taint3} | command-line-parameter-command-injection.js:68:6:68:40 | taint3 | -| command-line-parameter-command-injection.js:68:6:68:40 | taint3 | command-line-parameter-command-injection.js:69:22:69:27 | taint3 | -| command-line-parameter-command-injection.js:68:20:68:40 | require ... ').argv | command-line-parameter-command-injection.js:68:6:68:16 | {...taint3} | -| command-line-parameter-command-injection.js:69:22:69:27 | taint3 | command-line-parameter-command-injection.js:69:10:69:27 | "cmd.sh " + taint3 | -| command-line-parameter-command-injection.js:71:6:71:16 | [...taint4] | command-line-parameter-command-injection.js:71:6:71:40 | taint4 | -| command-line-parameter-command-injection.js:71:6:71:40 | taint4 | command-line-parameter-command-injection.js:72:22:72:27 | taint4 | -| command-line-parameter-command-injection.js:71:20:71:40 | require ... ').argv | command-line-parameter-command-injection.js:71:6:71:16 | [...taint4] | -| command-line-parameter-command-injection.js:72:22:72:27 | taint4 | command-line-parameter-command-injection.js:72:10:72:27 | "cmd.sh " + taint4 | -| command-line-parameter-command-injection.js:76:8:76:35 | argv | command-line-parameter-command-injection.js:79:31:79:34 | argv | -| command-line-parameter-command-injection.js:76:15:76:26 | process.argv | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | -| command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | command-line-parameter-command-injection.js:76:8:76:35 | argv | -| command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | command-line-parameter-command-injection.js:79:10:79:39 | "cmd.sh ... gv).foo | -| command-line-parameter-command-injection.js:79:31:79:34 | argv | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | -| command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | command-line-parameter-command-injection.js:82:10:82:54 | "cmd.sh ... 2)).foo | -| command-line-parameter-command-injection.js:82:29:82:40 | process.argv | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | -| command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | -| command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | command-line-parameter-command-injection.js:85:10:85:59 | "cmd.sh ... 2)).foo | -| command-line-parameter-command-injection.js:85:34:85:45 | process.argv | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | -| command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | -| command-line-parameter-command-injection.js:88:6:88:37 | flags | command-line-parameter-command-injection.js:89:22:89:26 | flags | -| command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | command-line-parameter-command-injection.js:88:6:88:37 | flags | -| command-line-parameter-command-injection.js:88:25:88:36 | process.argv | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | -| command-line-parameter-command-injection.js:89:22:89:26 | flags | command-line-parameter-command-injection.js:89:10:89:30 | "cmd.sh ... ags.foo | -| command-line-parameter-command-injection.js:91:6:91:38 | flags | command-line-parameter-command-injection.js:92:22:92:26 | flags | -| command-line-parameter-command-injection.js:91:14:91:38 | require ... .spec}) | command-line-parameter-command-injection.js:91:6:91:38 | flags | -| command-line-parameter-command-injection.js:92:22:92:26 | flags | command-line-parameter-command-injection.js:92:10:92:30 | "cmd.sh ... ags.foo | -| command-line-parameter-command-injection.js:102:22:102:40 | parser.parse_args() | command-line-parameter-command-injection.js:102:10:102:44 | "cmd.sh ... s().foo | -| command-line-parameter-command-injection.js:107:8:107:51 | options | command-line-parameter-command-injection.js:108:22:108:28 | options | -| command-line-parameter-command-injection.js:107:18:107:51 | command ... itions) | command-line-parameter-command-injection.js:107:8:107:51 | options | -| command-line-parameter-command-injection.js:108:22:108:28 | options | command-line-parameter-command-injection.js:108:10:108:32 | "cmd.sh ... ons.foo | -| command-line-parameter-command-injection.js:114:8:114:52 | cli | command-line-parameter-command-injection.js:116:22:116:24 | cli | -| command-line-parameter-command-injection.js:114:14:114:52 | meow(`h ... lags}}) | command-line-parameter-command-injection.js:114:8:114:52 | cli | -| command-line-parameter-command-injection.js:116:22:116:24 | cli | command-line-parameter-command-injection.js:116:10:116:33 | "cmd.sh ... nput[0] | -| command-line-parameter-command-injection.js:122:6:122:46 | opts | command-line-parameter-command-injection.js:124:22:124:25 | opts | -| command-line-parameter-command-injection.js:122:13:122:46 | dashdas ... tions}) | command-line-parameter-command-injection.js:122:6:122:46 | opts | -| command-line-parameter-command-injection.js:124:22:124:25 | opts | command-line-parameter-command-injection.js:124:10:124:29 | "cmd.sh " + opts.foo | -| command-line-parameter-command-injection.js:127:6:127:26 | opts | command-line-parameter-command-injection.js:129:22:129:25 | opts | -| command-line-parameter-command-injection.js:127:13:127:26 | parser.parse() | command-line-parameter-command-injection.js:127:6:127:26 | opts | -| command-line-parameter-command-injection.js:129:22:129:25 | opts | command-line-parameter-command-injection.js:129:10:129:29 | "cmd.sh " + opts.foo | -| command-line-parameter-command-injection.js:133:8:133:41 | program | command-line-parameter-command-injection.js:137:22:137:28 | program | -| command-line-parameter-command-injection.js:133:10:133:16 | program | command-line-parameter-command-injection.js:133:8:133:41 | program | -| command-line-parameter-command-injection.js:136:22:136:35 | program.opts() | command-line-parameter-command-injection.js:136:10:136:45 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:136:22:136:45 | program ... zzaType | command-line-parameter-command-injection.js:136:10:136:45 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:137:22:137:28 | program | command-line-parameter-command-injection.js:137:10:137:38 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:137:22:137:38 | program.pizzaType | command-line-parameter-command-injection.js:137:10:137:38 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:145:22:145:35 | program.opts() | command-line-parameter-command-injection.js:145:10:145:45 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:145:22:145:45 | program ... zzaType | command-line-parameter-command-injection.js:145:10:145:45 | "cmd.sh ... zzaType | -| command-line-parameter-command-injection.js:146:22:146:38 | program.pizzaType | command-line-parameter-command-injection.js:146:10:146:38 | "cmd.sh ... zzaType | +| actions.js:4:6:4:16 | process.env | actions.js:4:6:4:29 | process ... _DATA'] | provenance | | +| actions.js:7:15:7:15 | e | actions.js:8:10:8:10 | e | provenance | | +| actions.js:8:10:8:10 | e | actions.js:8:10:8:23 | e['TEST_DATA'] | provenance | | +| actions.js:12:6:12:16 | process.env | actions.js:7:15:7:15 | e | provenance | | +| command-line-parameter-command-injection.js:8:22:8:33 | process.argv | command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | provenance | | +| command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:11:14:11:17 | args | provenance | | +| command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:12:26:12:29 | args | provenance | | +| command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:14:18:14:21 | args | provenance | | +| command-line-parameter-command-injection.js:10:6:10:33 | args [ArrayElement] | command-line-parameter-command-injection.js:14:18:14:21 | args [ArrayElement] | provenance | | +| command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | provenance | | +| command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) [ArrayElement] | provenance | | +| command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | command-line-parameter-command-injection.js:10:6:10:33 | args | provenance | | +| command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) [ArrayElement] | command-line-parameter-command-injection.js:10:6:10:33 | args [ArrayElement] | provenance | | +| command-line-parameter-command-injection.js:11:14:11:17 | args | command-line-parameter-command-injection.js:11:14:11:20 | args[0] | provenance | | +| command-line-parameter-command-injection.js:12:26:12:29 | args | command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | provenance | | +| command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | provenance | | +| command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | provenance | | +| command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | provenance | | +| command-line-parameter-command-injection.js:14:18:14:21 | args | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | provenance | | +| command-line-parameter-command-injection.js:14:18:14:21 | args [ArrayElement] | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | provenance | | +| command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | provenance | | +| command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | provenance | | +| command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | provenance | | +| command-line-parameter-command-injection.js:18:6:18:24 | arg0 | command-line-parameter-command-injection.js:19:14:19:17 | arg0 | provenance | | +| command-line-parameter-command-injection.js:18:6:18:24 | arg0 | command-line-parameter-command-injection.js:20:26:20:29 | arg0 | provenance | | +| command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | provenance | | +| command-line-parameter-command-injection.js:20:26:20:29 | arg0 | command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | provenance | | +| command-line-parameter-command-injection.js:24:8:24:35 | args | command-line-parameter-command-injection.js:26:32:26:35 | args | provenance | | +| command-line-parameter-command-injection.js:24:8:24:35 | args | command-line-parameter-command-injection.js:27:32:27:35 | args | provenance | | +| command-line-parameter-command-injection.js:24:15:24:26 | process.argv | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | provenance | | +| command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | command-line-parameter-command-injection.js:24:8:24:35 | args | provenance | | +| command-line-parameter-command-injection.js:26:32:26:35 | args | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | provenance | | +| command-line-parameter-command-injection.js:27:32:27:35 | args | command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | provenance | | +| command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | provenance | | +| command-line-parameter-command-injection.js:30:21:30:46 | require ... rgs")() | command-line-parameter-command-injection.js:30:9:30:50 | "cmd.sh ... )().foo | provenance | | +| command-line-parameter-command-injection.js:32:21:32:41 | require ... ").argv | command-line-parameter-command-injection.js:32:9:32:45 | "cmd.sh ... rgv.foo | provenance | | +| command-line-parameter-command-injection.js:33:21:33:44 | require ... ").argv | command-line-parameter-command-injection.js:33:9:33:48 | "cmd.sh ... rgv.foo | provenance | | +| command-line-parameter-command-injection.js:36:6:39:7 | args | command-line-parameter-command-injection.js:41:22:41:25 | args | provenance | | +| command-line-parameter-command-injection.js:36:13:39:7 | require ... \\t\\t.argv | command-line-parameter-command-injection.js:36:6:39:7 | args | provenance | | +| command-line-parameter-command-injection.js:41:22:41:25 | args | command-line-parameter-command-injection.js:41:10:41:25 | "cmd.sh " + args | provenance | | +| command-line-parameter-command-injection.js:43:22:43:58 | require ... parse() | command-line-parameter-command-injection.js:43:10:43:62 | "cmd.sh ... e().foo | provenance | | +| command-line-parameter-command-injection.js:47:8:53:12 | args | command-line-parameter-command-injection.js:55:22:55:25 | args | provenance | | +| command-line-parameter-command-injection.js:48:3:50:3 | argv: { ... rgs\\n\\t\\t} | command-line-parameter-command-injection.js:48:9:50:3 | {\\n\\t\\t\\t...args\\n\\t\\t} | provenance | | +| command-line-parameter-command-injection.js:48:9:50:3 | {\\n\\t\\t\\t...args\\n\\t\\t} | command-line-parameter-command-injection.js:47:8:53:12 | args | provenance | | +| command-line-parameter-command-injection.js:55:22:55:25 | args | command-line-parameter-command-injection.js:55:10:55:25 | "cmd.sh " + args | provenance | | +| command-line-parameter-command-injection.js:57:6:57:37 | tainted1 | command-line-parameter-command-injection.js:61:11:61:18 | tainted1 | provenance | | +| command-line-parameter-command-injection.js:57:17:57:37 | require ... ').argv | command-line-parameter-command-injection.js:57:6:57:37 | tainted1 | provenance | | +| command-line-parameter-command-injection.js:58:6:58:40 | tainted2 | command-line-parameter-command-injection.js:62:11:62:18 | tainted2 | provenance | | +| command-line-parameter-command-injection.js:58:17:58:40 | require ... parse() | command-line-parameter-command-injection.js:58:6:58:40 | tainted2 | provenance | | +| command-line-parameter-command-injection.js:60:8:60:56 | {taint1 ... 2rest}} [taint1] | command-line-parameter-command-injection.js:60:9:60:31 | taint1: ... t1rest} | provenance | | +| command-line-parameter-command-injection.js:60:8:60:56 | {taint1 ... 2rest}} [taint2] | command-line-parameter-command-injection.js:60:33:60:55 | taint2: ... t2rest} | provenance | | +| command-line-parameter-command-injection.js:60:8:63:2 | taint1rest | command-line-parameter-command-injection.js:65:22:65:31 | taint1rest | provenance | | +| command-line-parameter-command-injection.js:60:8:63:2 | taint2rest | command-line-parameter-command-injection.js:66:22:66:31 | taint2rest | provenance | | +| command-line-parameter-command-injection.js:60:9:60:31 | taint1: ... t1rest} | command-line-parameter-command-injection.js:60:17:60:31 | {...taint1rest} | provenance | | +| command-line-parameter-command-injection.js:60:17:60:31 | {...taint1rest} | command-line-parameter-command-injection.js:60:8:63:2 | taint1rest | provenance | | +| command-line-parameter-command-injection.js:60:33:60:55 | taint2: ... t2rest} | command-line-parameter-command-injection.js:60:41:60:55 | {...taint2rest} | provenance | | +| command-line-parameter-command-injection.js:60:41:60:55 | {...taint2rest} | command-line-parameter-command-injection.js:60:8:63:2 | taint2rest | provenance | | +| command-line-parameter-command-injection.js:60:60:63:2 | {\\n\\t\\ttai ... ted2\\n\\t} [taint1] | command-line-parameter-command-injection.js:60:8:60:56 | {taint1 ... 2rest}} [taint1] | provenance | | +| command-line-parameter-command-injection.js:60:60:63:2 | {\\n\\t\\ttai ... ted2\\n\\t} [taint2] | command-line-parameter-command-injection.js:60:8:60:56 | {taint1 ... 2rest}} [taint2] | provenance | | +| command-line-parameter-command-injection.js:61:11:61:18 | tainted1 | command-line-parameter-command-injection.js:60:60:63:2 | {\\n\\t\\ttai ... ted2\\n\\t} [taint1] | provenance | | +| command-line-parameter-command-injection.js:62:11:62:18 | tainted2 | command-line-parameter-command-injection.js:60:60:63:2 | {\\n\\t\\ttai ... ted2\\n\\t} [taint2] | provenance | | +| command-line-parameter-command-injection.js:65:22:65:31 | taint1rest | command-line-parameter-command-injection.js:65:10:65:31 | "cmd.sh ... nt1rest | provenance | | +| command-line-parameter-command-injection.js:66:22:66:31 | taint2rest | command-line-parameter-command-injection.js:66:10:66:31 | "cmd.sh ... nt2rest | provenance | | +| command-line-parameter-command-injection.js:68:6:68:16 | {...taint3} | command-line-parameter-command-injection.js:68:6:68:40 | taint3 | provenance | | +| command-line-parameter-command-injection.js:68:6:68:40 | taint3 | command-line-parameter-command-injection.js:69:22:69:27 | taint3 | provenance | | +| command-line-parameter-command-injection.js:68:20:68:40 | require ... ').argv | command-line-parameter-command-injection.js:68:6:68:16 | {...taint3} | provenance | | +| command-line-parameter-command-injection.js:69:22:69:27 | taint3 | command-line-parameter-command-injection.js:69:10:69:27 | "cmd.sh " + taint3 | provenance | | +| command-line-parameter-command-injection.js:71:6:71:16 | [...taint4] | command-line-parameter-command-injection.js:71:6:71:40 | taint4 | provenance | | +| command-line-parameter-command-injection.js:71:6:71:40 | taint4 | command-line-parameter-command-injection.js:72:22:72:27 | taint4 | provenance | | +| command-line-parameter-command-injection.js:71:20:71:40 | require ... ').argv | command-line-parameter-command-injection.js:71:6:71:16 | [...taint4] | provenance | | +| command-line-parameter-command-injection.js:72:22:72:27 | taint4 | command-line-parameter-command-injection.js:72:10:72:27 | "cmd.sh " + taint4 | provenance | | +| command-line-parameter-command-injection.js:76:8:76:35 | argv | command-line-parameter-command-injection.js:79:31:79:34 | argv | provenance | | +| command-line-parameter-command-injection.js:76:15:76:26 | process.argv | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | provenance | | +| command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | command-line-parameter-command-injection.js:76:8:76:35 | argv | provenance | | +| command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | command-line-parameter-command-injection.js:79:10:79:39 | "cmd.sh ... gv).foo | provenance | | +| command-line-parameter-command-injection.js:79:31:79:34 | argv | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | provenance | | +| command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | command-line-parameter-command-injection.js:82:10:82:54 | "cmd.sh ... 2)).foo | provenance | | +| command-line-parameter-command-injection.js:82:29:82:40 | process.argv | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | provenance | | +| command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | provenance | | +| command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | command-line-parameter-command-injection.js:85:10:85:59 | "cmd.sh ... 2)).foo | provenance | | +| command-line-parameter-command-injection.js:85:34:85:45 | process.argv | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | provenance | | +| command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | provenance | | +| command-line-parameter-command-injection.js:88:6:88:37 | flags | command-line-parameter-command-injection.js:89:22:89:26 | flags | provenance | | +| command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | command-line-parameter-command-injection.js:88:6:88:37 | flags | provenance | | +| command-line-parameter-command-injection.js:88:25:88:36 | process.argv | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | provenance | | +| command-line-parameter-command-injection.js:89:22:89:26 | flags | command-line-parameter-command-injection.js:89:10:89:30 | "cmd.sh ... ags.foo | provenance | | +| command-line-parameter-command-injection.js:91:6:91:38 | flags | command-line-parameter-command-injection.js:92:22:92:26 | flags | provenance | | +| command-line-parameter-command-injection.js:91:14:91:38 | require ... .spec}) | command-line-parameter-command-injection.js:91:6:91:38 | flags | provenance | | +| command-line-parameter-command-injection.js:92:22:92:26 | flags | command-line-parameter-command-injection.js:92:10:92:30 | "cmd.sh ... ags.foo | provenance | | +| command-line-parameter-command-injection.js:102:22:102:40 | parser.parse_args() | command-line-parameter-command-injection.js:102:10:102:44 | "cmd.sh ... s().foo | provenance | | +| command-line-parameter-command-injection.js:107:8:107:51 | options | command-line-parameter-command-injection.js:108:22:108:28 | options | provenance | | +| command-line-parameter-command-injection.js:107:18:107:51 | command ... itions) | command-line-parameter-command-injection.js:107:8:107:51 | options | provenance | | +| command-line-parameter-command-injection.js:108:22:108:28 | options | command-line-parameter-command-injection.js:108:10:108:32 | "cmd.sh ... ons.foo | provenance | | +| command-line-parameter-command-injection.js:114:8:114:52 | cli | command-line-parameter-command-injection.js:116:22:116:24 | cli | provenance | | +| command-line-parameter-command-injection.js:114:14:114:52 | meow(`h ... lags}}) | command-line-parameter-command-injection.js:114:8:114:52 | cli | provenance | | +| command-line-parameter-command-injection.js:116:22:116:24 | cli | command-line-parameter-command-injection.js:116:10:116:33 | "cmd.sh ... nput[0] | provenance | | +| command-line-parameter-command-injection.js:122:6:122:46 | opts | command-line-parameter-command-injection.js:124:22:124:25 | opts | provenance | | +| command-line-parameter-command-injection.js:122:13:122:46 | dashdas ... tions}) | command-line-parameter-command-injection.js:122:6:122:46 | opts | provenance | | +| command-line-parameter-command-injection.js:124:22:124:25 | opts | command-line-parameter-command-injection.js:124:10:124:29 | "cmd.sh " + opts.foo | provenance | | +| command-line-parameter-command-injection.js:127:6:127:26 | opts | command-line-parameter-command-injection.js:129:22:129:25 | opts | provenance | | +| command-line-parameter-command-injection.js:127:13:127:26 | parser.parse() | command-line-parameter-command-injection.js:127:6:127:26 | opts | provenance | | +| command-line-parameter-command-injection.js:129:22:129:25 | opts | command-line-parameter-command-injection.js:129:10:129:29 | "cmd.sh " + opts.foo | provenance | | +| command-line-parameter-command-injection.js:133:8:133:41 | program | command-line-parameter-command-injection.js:137:22:137:28 | program | provenance | | +| command-line-parameter-command-injection.js:133:10:133:16 | program | command-line-parameter-command-injection.js:133:8:133:41 | program | provenance | | +| command-line-parameter-command-injection.js:136:22:136:35 | program.opts() | command-line-parameter-command-injection.js:136:10:136:45 | "cmd.sh ... zzaType | provenance | | +| command-line-parameter-command-injection.js:136:22:136:45 | program ... zzaType | command-line-parameter-command-injection.js:136:10:136:45 | "cmd.sh ... zzaType | provenance | | +| command-line-parameter-command-injection.js:137:22:137:28 | program | command-line-parameter-command-injection.js:137:10:137:38 | "cmd.sh ... zzaType | provenance | | +| command-line-parameter-command-injection.js:137:22:137:38 | program.pizzaType | command-line-parameter-command-injection.js:137:10:137:38 | "cmd.sh ... zzaType | provenance | | +| command-line-parameter-command-injection.js:145:22:145:35 | program.opts() | command-line-parameter-command-injection.js:145:10:145:45 | "cmd.sh ... zzaType | provenance | | +| command-line-parameter-command-injection.js:145:22:145:45 | program ... zzaType | command-line-parameter-command-injection.js:145:10:145:45 | "cmd.sh ... zzaType | provenance | | +| command-line-parameter-command-injection.js:146:22:146:38 | program.pizzaType | command-line-parameter-command-injection.js:146:10:146:38 | "cmd.sh ... zzaType | provenance | | nodes | actions.js:4:6:4:16 | process.env | semmle.label | process.env | | actions.js:4:6:4:29 | process ... _DATA'] | semmle.label | process ... _DATA'] | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/ShellCommandInjectionFromEnvironment/ShellCommandInjectionFromEnvironment.expected b/javascript/ql/test/query-tests/Security/CWE-078/ShellCommandInjectionFromEnvironment/ShellCommandInjectionFromEnvironment.expected index c231dc9d885..046d83da058 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/ShellCommandInjectionFromEnvironment/ShellCommandInjectionFromEnvironment.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/ShellCommandInjectionFromEnvironment/ShellCommandInjectionFromEnvironment.expected @@ -1,10 +1,10 @@ edges -| tst_shell-command-injection-from-environment.js:6:26:6:53 | path.jo ... "temp") | tst_shell-command-injection-from-environment.js:6:14:6:53 | 'rm -rf ... "temp") | -| tst_shell-command-injection-from-environment.js:6:36:6:44 | __dirname | tst_shell-command-injection-from-environment.js:6:26:6:53 | path.jo ... "temp") | -| tst_shell-command-injection-from-environment.js:8:26:8:53 | path.jo ... "temp") | tst_shell-command-injection-from-environment.js:8:14:8:53 | 'rm -rf ... "temp") | -| tst_shell-command-injection-from-environment.js:8:36:8:44 | __dirname | tst_shell-command-injection-from-environment.js:8:26:8:53 | path.jo ... "temp") | -| tst_shell-command-injection-from-environment.js:9:30:9:57 | path.jo ... "temp") | tst_shell-command-injection-from-environment.js:9:18:9:57 | 'rm -rf ... "temp") | -| tst_shell-command-injection-from-environment.js:9:40:9:48 | __dirname | tst_shell-command-injection-from-environment.js:9:30:9:57 | path.jo ... "temp") | +| tst_shell-command-injection-from-environment.js:6:26:6:53 | path.jo ... "temp") | tst_shell-command-injection-from-environment.js:6:14:6:53 | 'rm -rf ... "temp") | provenance | | +| tst_shell-command-injection-from-environment.js:6:36:6:44 | __dirname | tst_shell-command-injection-from-environment.js:6:26:6:53 | path.jo ... "temp") | provenance | | +| tst_shell-command-injection-from-environment.js:8:26:8:53 | path.jo ... "temp") | tst_shell-command-injection-from-environment.js:8:14:8:53 | 'rm -rf ... "temp") | provenance | | +| tst_shell-command-injection-from-environment.js:8:36:8:44 | __dirname | tst_shell-command-injection-from-environment.js:8:26:8:53 | path.jo ... "temp") | provenance | | +| tst_shell-command-injection-from-environment.js:9:30:9:57 | path.jo ... "temp") | tst_shell-command-injection-from-environment.js:9:18:9:57 | 'rm -rf ... "temp") | provenance | | +| tst_shell-command-injection-from-environment.js:9:40:9:48 | __dirname | tst_shell-command-injection-from-environment.js:9:30:9:57 | path.jo ... "temp") | provenance | | nodes | tst_shell-command-injection-from-environment.js:6:14:6:53 | 'rm -rf ... "temp") | semmle.label | 'rm -rf ... "temp") | | tst_shell-command-injection-from-environment.js:6:26:6:53 | path.jo ... "temp") | semmle.label | path.jo ... "temp") | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected index 4755cc2a0ae..cf74ed30547 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected @@ -1,144 +1,144 @@ edges -| lib/isImported.js:5:49:5:52 | name | lib/isImported.js:6:22:6:25 | name | -| lib/lib2.js:3:28:3:31 | name | lib/lib2.js:4:22:4:25 | name | -| lib/lib2.js:7:32:7:35 | name | lib/lib2.js:8:22:8:25 | name | -| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:22:4:25 | name | -| lib/lib.js:10:32:10:35 | name | lib/lib.js:11:22:11:25 | name | -| lib/lib.js:14:36:14:39 | name | lib/lib.js:15:22:15:25 | name | -| lib/lib.js:19:34:19:37 | name | lib/lib.js:20:22:20:25 | name | -| lib/lib.js:26:35:26:38 | name | lib/lib.js:27:22:27:25 | name | -| lib/lib.js:34:14:34:17 | name | lib/lib.js:35:23:35:26 | name | -| lib/lib.js:37:13:37:16 | name | lib/lib.js:38:23:38:26 | name | -| lib/lib.js:40:6:40:9 | name | lib/lib.js:41:23:41:26 | name | -| lib/lib.js:49:31:49:34 | name | lib/lib.js:50:47:50:50 | name | -| lib/lib.js:53:33:53:36 | name | lib/lib.js:54:25:54:28 | name | -| lib/lib.js:53:33:53:36 | name | lib/lib.js:57:25:57:28 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:65:22:65:25 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:69:27:69:30 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:71:28:71:31 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:73:21:73:24 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:75:20:75:23 | name | -| lib/lib.js:64:41:64:44 | name | lib/lib.js:77:28:77:31 | name | -| lib/lib.js:82:35:82:38 | name | lib/lib.js:83:22:83:25 | name | -| lib/lib.js:82:35:82:38 | name | lib/lib.js:86:13:86:16 | name | -| lib/lib.js:82:35:82:38 | name | lib/lib.js:89:21:89:24 | name | -| lib/lib.js:82:35:82:38 | name | lib/lib.js:91:28:91:31 | name | -| lib/lib.js:91:28:91:31 | name | lib/lib.js:91:21:91:38 | "\\"" + name + "\\"" | -| lib/lib.js:97:35:97:38 | name | lib/lib.js:98:35:98:38 | name | -| lib/lib.js:97:35:97:38 | name | lib/lib.js:100:37:100:40 | name | -| lib/lib.js:97:35:97:38 | name | lib/lib.js:102:46:102:49 | name | -| lib/lib.js:97:35:97:38 | name | lib/lib.js:108:41:108:44 | name | -| lib/lib.js:111:34:111:37 | name | lib/lib.js:112:22:112:25 | name | -| lib/lib.js:120:33:120:36 | name | lib/lib.js:121:22:121:25 | name | -| lib/lib.js:130:6:130:9 | name | lib/lib.js:131:23:131:26 | name | -| lib/lib.js:148:37:148:40 | name | lib/lib.js:149:24:149:27 | name | -| lib/lib.js:155:38:155:41 | name | lib/lib.js:161:25:161:28 | name | -| lib/lib.js:170:41:170:44 | name | lib/lib.js:173:20:173:23 | name | -| lib/lib.js:177:38:177:41 | name | lib/lib.js:181:21:181:24 | name | -| lib/lib.js:181:6:181:52 | broken | lib/lib.js:182:22:182:27 | broken | -| lib/lib.js:181:21:181:24 | name | lib/lib.js:181:21:181:46 | name.re ... "'\\''") | -| lib/lib.js:181:21:181:24 | name | lib/lib.js:181:21:181:46 | name.re ... "'\\''") | -| lib/lib.js:181:21:181:46 | name.re ... "'\\''") | lib/lib.js:181:6:181:52 | broken | -| lib/lib.js:186:34:186:37 | name | lib/lib.js:187:22:187:25 | name | -| lib/lib.js:186:34:186:37 | name | lib/lib.js:190:23:190:26 | name | -| lib/lib.js:196:45:196:48 | name | lib/lib.js:197:22:197:25 | name | -| lib/lib.js:196:45:196:48 | name | lib/lib.js:200:23:200:26 | name | -| lib/lib.js:206:45:206:48 | name | lib/lib.js:207:22:207:25 | name | -| lib/lib.js:206:45:206:48 | name | lib/lib.js:212:23:212:26 | name | -| lib/lib.js:216:39:216:42 | name | lib/lib.js:217:22:217:25 | name | -| lib/lib.js:216:39:216:42 | name | lib/lib.js:220:23:220:26 | name | -| lib/lib.js:216:39:216:42 | name | lib/lib.js:224:22:224:25 | name | -| lib/lib.js:227:39:227:42 | name | lib/lib.js:228:22:228:25 | name | -| lib/lib.js:227:39:227:42 | name | lib/lib.js:236:22:236:25 | name | -| lib/lib.js:239:28:239:28 | s | lib/lib.js:245:9:245:9 | s | -| lib/lib.js:248:42:248:45 | name | lib/lib.js:249:22:249:25 | name | -| lib/lib.js:248:42:248:45 | name | lib/lib.js:251:27:251:30 | name | -| lib/lib.js:251:6:251:31 | cleaned | lib/lib.js:253:22:253:28 | cleaned | -| lib/lib.js:251:16:251:31 | cleanInput(name) | lib/lib.js:251:6:251:31 | cleaned | -| lib/lib.js:251:27:251:30 | name | lib/lib.js:239:28:239:28 | s | -| lib/lib.js:251:27:251:30 | name | lib/lib.js:251:16:251:31 | cleanInput(name) | -| lib/lib.js:257:35:257:38 | name | lib/lib.js:258:22:258:25 | name | -| lib/lib.js:257:35:257:38 | name | lib/lib.js:261:30:261:33 | name | -| lib/lib.js:267:46:267:48 | obj | lib/lib.js:268:22:268:24 | obj | -| lib/lib.js:268:22:268:24 | obj | lib/lib.js:268:22:268:32 | obj.version | -| lib/lib.js:276:8:276:11 | opts | lib/lib.js:277:23:277:26 | opts | -| lib/lib.js:276:8:276:11 | opts | lib/lib.js:279:19:279:22 | opts | -| lib/lib.js:277:23:277:26 | opts | lib/lib.js:277:23:277:30 | opts.bla | -| lib/lib.js:279:3:279:6 | [post update] this [opts, bla] | lib/lib.js:281:23:281:26 | this [opts, bla] | -| lib/lib.js:279:3:279:11 | [post update] this.opts [bla] | lib/lib.js:279:3:279:6 | [post update] this [opts, bla] | -| lib/lib.js:279:19:279:22 | opts | lib/lib.js:279:19:279:26 | opts.bla | -| lib/lib.js:279:19:279:26 | opts.bla | lib/lib.js:279:3:279:11 | [post update] this.opts [bla] | -| lib/lib.js:281:23:281:26 | this [opts, bla] | lib/lib.js:281:23:281:31 | this.opts [bla] | -| lib/lib.js:281:23:281:31 | this.opts [bla] | lib/lib.js:281:23:281:35 | this.opts.bla | -| lib/lib.js:307:39:307:42 | name | lib/lib.js:308:23:308:26 | name | -| lib/lib.js:314:40:314:43 | name | lib/lib.js:315:22:315:25 | name | -| lib/lib.js:314:40:314:43 | name | lib/lib.js:320:23:320:26 | name | -| lib/lib.js:324:40:324:42 | arg | lib/lib.js:325:49:325:51 | arg | -| lib/lib.js:329:13:329:13 | x | lib/lib.js:330:9:330:9 | x | -| lib/lib.js:339:39:339:39 | n | lib/lib.js:340:25:340:25 | n | -| lib/lib.js:340:25:340:25 | n | lib/lib.js:329:13:329:13 | x | -| lib/lib.js:340:25:340:25 | n | lib/lib.js:340:22:340:26 | id(n) | -| lib/lib.js:349:29:349:34 | unsafe | lib/lib.js:351:22:351:27 | unsafe | -| lib/lib.js:405:39:405:42 | name | lib/lib.js:406:22:406:25 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:415:22:415:25 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:417:28:417:31 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:418:25:418:28 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:419:32:419:35 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:420:29:420:32 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:424:24:424:27 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:426:11:426:14 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:426:11:426:14 | name | -| lib/lib.js:414:40:414:43 | name | lib/lib.js:428:36:428:39 | name | -| lib/lib.js:425:6:425:13 | arr | lib/lib.js:427:14:427:16 | arr | -| lib/lib.js:426:2:426:4 | [post update] arr | lib/lib.js:425:6:425:13 | arr | -| lib/lib.js:426:11:426:14 | name | lib/lib.js:426:2:426:4 | [post update] arr | -| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:428:14:428:58 | build(" ... + '-') | -| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:431:23:431:26 | last | -| lib/lib.js:428:36:428:39 | name | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | -| lib/lib.js:431:23:431:26 | last | lib/lib.js:436:19:436:22 | last | -| lib/lib.js:431:23:431:26 | last | lib/lib.js:436:19:436:22 | last | -| lib/lib.js:432:6:432:13 | arr | lib/lib.js:437:9:437:11 | arr | -| lib/lib.js:436:10:436:12 | [post update] arr | lib/lib.js:432:6:432:13 | arr | -| lib/lib.js:436:19:436:22 | last | lib/lib.js:436:10:436:12 | [post update] arr | -| lib/lib.js:441:39:441:42 | name | lib/lib.js:442:24:442:27 | name | -| lib/lib.js:446:20:446:23 | name | lib/lib.js:447:25:447:28 | name | -| lib/lib.js:477:33:477:38 | config | lib/lib.js:478:27:478:32 | config | -| lib/lib.js:478:27:478:32 | config | lib/lib.js:478:27:478:46 | config.installedPath | -| lib/lib.js:482:40:482:43 | name | lib/lib.js:483:30:483:33 | name | -| lib/lib.js:498:45:498:48 | name | lib/lib.js:499:31:499:34 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:510:22:510:25 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:513:23:513:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:519:23:519:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:525:23:525:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:531:23:531:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:537:23:537:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:543:23:543:26 | name | -| lib/lib.js:509:39:509:42 | name | lib/lib.js:545:23:545:26 | name | -| lib/lib.js:550:39:550:42 | name | lib/lib.js:555:33:555:36 | name | -| lib/lib.js:550:39:550:42 | name | lib/lib.js:555:33:555:36 | name | -| lib/lib.js:551:33:551:36 | args | lib/lib.js:552:23:552:26 | args | -| lib/lib.js:555:25:555:37 | ["-rf", name] | lib/lib.js:551:33:551:36 | args | -| lib/lib.js:555:33:555:36 | name | lib/lib.js:555:25:555:37 | ["-rf", name] | -| lib/lib.js:558:41:558:44 | name | lib/lib.js:560:26:560:29 | name | -| lib/lib.js:558:41:558:44 | name | lib/lib.js:562:26:562:29 | name | -| lib/lib.js:558:41:558:44 | name | lib/lib.js:566:26:566:29 | name | -| lib/lib.js:572:41:572:44 | name | lib/lib.js:573:22:573:25 | name | -| lib/lib.js:572:41:572:44 | name | lib/lib.js:579:25:579:28 | name | -| lib/lib.js:572:41:572:44 | name | lib/lib.js:590:29:590:32 | name | -| lib/lib.js:572:41:572:44 | name | lib/lib.js:593:25:593:28 | name | -| lib/lib.js:608:42:608:45 | name | lib/lib.js:609:22:609:25 | name | -| lib/lib.js:608:42:608:45 | name | lib/lib.js:626:29:626:32 | name | -| lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | -| lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | -| lib/subLib2/special-file.js:3:28:3:31 | name | lib/subLib2/special-file.js:4:22:4:25 | name | -| lib/subLib3/my-file.ts:3:28:3:31 | name | lib/subLib3/my-file.ts:4:22:4:25 | name | -| lib/subLib4/index.js:6:32:6:35 | name | lib/subLib4/index.js:7:18:7:21 | name | -| lib/subLib4/index.js:7:18:7:21 | name | lib/subLib4/subsub.js:3:28:3:31 | name | -| lib/subLib4/subsub.js:3:28:3:31 | name | lib/subLib4/subsub.js:4:22:4:25 | name | -| lib/subLib/amdSub.js:3:28:3:31 | name | lib/subLib/amdSub.js:4:22:4:25 | name | -| lib/subLib/index.js:3:28:3:31 | name | lib/subLib/index.js:4:22:4:25 | name | -| lib/subLib/index.js:7:32:7:35 | name | lib/subLib/index.js:8:22:8:25 | name | -| lib/subLib/index.js:13:44:13:46 | arr | lib/subLib/index.js:14:22:14:24 | arr | +| lib/isImported.js:5:49:5:52 | name | lib/isImported.js:6:22:6:25 | name | provenance | | +| lib/lib2.js:3:28:3:31 | name | lib/lib2.js:4:22:4:25 | name | provenance | | +| lib/lib2.js:7:32:7:35 | name | lib/lib2.js:8:22:8:25 | name | provenance | | +| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:22:4:25 | name | provenance | | +| lib/lib.js:10:32:10:35 | name | lib/lib.js:11:22:11:25 | name | provenance | | +| lib/lib.js:14:36:14:39 | name | lib/lib.js:15:22:15:25 | name | provenance | | +| lib/lib.js:19:34:19:37 | name | lib/lib.js:20:22:20:25 | name | provenance | | +| lib/lib.js:26:35:26:38 | name | lib/lib.js:27:22:27:25 | name | provenance | | +| lib/lib.js:34:14:34:17 | name | lib/lib.js:35:23:35:26 | name | provenance | | +| lib/lib.js:37:13:37:16 | name | lib/lib.js:38:23:38:26 | name | provenance | | +| lib/lib.js:40:6:40:9 | name | lib/lib.js:41:23:41:26 | name | provenance | | +| lib/lib.js:49:31:49:34 | name | lib/lib.js:50:47:50:50 | name | provenance | | +| lib/lib.js:53:33:53:36 | name | lib/lib.js:54:25:54:28 | name | provenance | | +| lib/lib.js:53:33:53:36 | name | lib/lib.js:57:25:57:28 | name | provenance | | +| lib/lib.js:64:41:64:44 | name | lib/lib.js:65:22:65:25 | name | provenance | | +| lib/lib.js:64:41:64:44 | name | lib/lib.js:69:27:69:30 | name | provenance | | +| lib/lib.js:64:41:64:44 | name | lib/lib.js:71:28:71:31 | name | provenance | | +| lib/lib.js:64:41:64:44 | name | lib/lib.js:73:21:73:24 | name | provenance | | +| lib/lib.js:64:41:64:44 | name | lib/lib.js:75:20:75:23 | name | provenance | | +| lib/lib.js:64:41:64:44 | name | lib/lib.js:77:28:77:31 | name | provenance | | +| lib/lib.js:82:35:82:38 | name | lib/lib.js:83:22:83:25 | name | provenance | | +| lib/lib.js:82:35:82:38 | name | lib/lib.js:86:13:86:16 | name | provenance | | +| lib/lib.js:82:35:82:38 | name | lib/lib.js:89:21:89:24 | name | provenance | | +| lib/lib.js:82:35:82:38 | name | lib/lib.js:91:28:91:31 | name | provenance | | +| lib/lib.js:91:28:91:31 | name | lib/lib.js:91:21:91:38 | "\\"" + name + "\\"" | provenance | | +| lib/lib.js:97:35:97:38 | name | lib/lib.js:98:35:98:38 | name | provenance | | +| lib/lib.js:97:35:97:38 | name | lib/lib.js:100:37:100:40 | name | provenance | | +| lib/lib.js:97:35:97:38 | name | lib/lib.js:102:46:102:49 | name | provenance | | +| lib/lib.js:97:35:97:38 | name | lib/lib.js:108:41:108:44 | name | provenance | | +| lib/lib.js:111:34:111:37 | name | lib/lib.js:112:22:112:25 | name | provenance | | +| lib/lib.js:120:33:120:36 | name | lib/lib.js:121:22:121:25 | name | provenance | | +| lib/lib.js:130:6:130:9 | name | lib/lib.js:131:23:131:26 | name | provenance | | +| lib/lib.js:148:37:148:40 | name | lib/lib.js:149:24:149:27 | name | provenance | | +| lib/lib.js:155:38:155:41 | name | lib/lib.js:161:25:161:28 | name | provenance | | +| lib/lib.js:170:41:170:44 | name | lib/lib.js:173:20:173:23 | name | provenance | | +| lib/lib.js:177:38:177:41 | name | lib/lib.js:181:21:181:24 | name | provenance | | +| lib/lib.js:181:6:181:52 | broken | lib/lib.js:182:22:182:27 | broken | provenance | | +| lib/lib.js:181:21:181:24 | name | lib/lib.js:181:21:181:46 | name.re ... "'\\''") | provenance | | +| lib/lib.js:181:21:181:24 | name | lib/lib.js:181:21:181:46 | name.re ... "'\\''") | provenance | | +| lib/lib.js:181:21:181:46 | name.re ... "'\\''") | lib/lib.js:181:6:181:52 | broken | provenance | | +| lib/lib.js:186:34:186:37 | name | lib/lib.js:187:22:187:25 | name | provenance | | +| lib/lib.js:186:34:186:37 | name | lib/lib.js:190:23:190:26 | name | provenance | | +| lib/lib.js:196:45:196:48 | name | lib/lib.js:197:22:197:25 | name | provenance | | +| lib/lib.js:196:45:196:48 | name | lib/lib.js:200:23:200:26 | name | provenance | | +| lib/lib.js:206:45:206:48 | name | lib/lib.js:207:22:207:25 | name | provenance | | +| lib/lib.js:206:45:206:48 | name | lib/lib.js:212:23:212:26 | name | provenance | | +| lib/lib.js:216:39:216:42 | name | lib/lib.js:217:22:217:25 | name | provenance | | +| lib/lib.js:216:39:216:42 | name | lib/lib.js:220:23:220:26 | name | provenance | | +| lib/lib.js:216:39:216:42 | name | lib/lib.js:224:22:224:25 | name | provenance | | +| lib/lib.js:227:39:227:42 | name | lib/lib.js:228:22:228:25 | name | provenance | | +| lib/lib.js:227:39:227:42 | name | lib/lib.js:236:22:236:25 | name | provenance | | +| lib/lib.js:239:28:239:28 | s | lib/lib.js:245:9:245:9 | s | provenance | | +| lib/lib.js:248:42:248:45 | name | lib/lib.js:249:22:249:25 | name | provenance | | +| lib/lib.js:248:42:248:45 | name | lib/lib.js:251:27:251:30 | name | provenance | | +| lib/lib.js:251:6:251:31 | cleaned | lib/lib.js:253:22:253:28 | cleaned | provenance | | +| lib/lib.js:251:16:251:31 | cleanInput(name) | lib/lib.js:251:6:251:31 | cleaned | provenance | | +| lib/lib.js:251:27:251:30 | name | lib/lib.js:239:28:239:28 | s | provenance | | +| lib/lib.js:251:27:251:30 | name | lib/lib.js:251:16:251:31 | cleanInput(name) | provenance | | +| lib/lib.js:257:35:257:38 | name | lib/lib.js:258:22:258:25 | name | provenance | | +| lib/lib.js:257:35:257:38 | name | lib/lib.js:261:30:261:33 | name | provenance | | +| lib/lib.js:267:46:267:48 | obj | lib/lib.js:268:22:268:24 | obj | provenance | | +| lib/lib.js:268:22:268:24 | obj | lib/lib.js:268:22:268:32 | obj.version | provenance | | +| lib/lib.js:276:8:276:11 | opts | lib/lib.js:277:23:277:26 | opts | provenance | | +| lib/lib.js:276:8:276:11 | opts | lib/lib.js:279:19:279:22 | opts | provenance | | +| lib/lib.js:277:23:277:26 | opts | lib/lib.js:277:23:277:30 | opts.bla | provenance | | +| lib/lib.js:279:3:279:6 | [post update] this [opts, bla] | lib/lib.js:281:23:281:26 | this [opts, bla] | provenance | | +| lib/lib.js:279:3:279:11 | [post update] this.opts [bla] | lib/lib.js:279:3:279:6 | [post update] this [opts, bla] | provenance | | +| lib/lib.js:279:19:279:22 | opts | lib/lib.js:279:19:279:26 | opts.bla | provenance | | +| lib/lib.js:279:19:279:26 | opts.bla | lib/lib.js:279:3:279:11 | [post update] this.opts [bla] | provenance | | +| lib/lib.js:281:23:281:26 | this [opts, bla] | lib/lib.js:281:23:281:31 | this.opts [bla] | provenance | | +| lib/lib.js:281:23:281:31 | this.opts [bla] | lib/lib.js:281:23:281:35 | this.opts.bla | provenance | | +| lib/lib.js:307:39:307:42 | name | lib/lib.js:308:23:308:26 | name | provenance | | +| lib/lib.js:314:40:314:43 | name | lib/lib.js:315:22:315:25 | name | provenance | | +| lib/lib.js:314:40:314:43 | name | lib/lib.js:320:23:320:26 | name | provenance | | +| lib/lib.js:324:40:324:42 | arg | lib/lib.js:325:49:325:51 | arg | provenance | | +| lib/lib.js:329:13:329:13 | x | lib/lib.js:330:9:330:9 | x | provenance | | +| lib/lib.js:339:39:339:39 | n | lib/lib.js:340:25:340:25 | n | provenance | | +| lib/lib.js:340:25:340:25 | n | lib/lib.js:329:13:329:13 | x | provenance | | +| lib/lib.js:340:25:340:25 | n | lib/lib.js:340:22:340:26 | id(n) | provenance | | +| lib/lib.js:349:29:349:34 | unsafe | lib/lib.js:351:22:351:27 | unsafe | provenance | | +| lib/lib.js:405:39:405:42 | name | lib/lib.js:406:22:406:25 | name | provenance | | +| lib/lib.js:414:40:414:43 | name | lib/lib.js:415:22:415:25 | name | provenance | | +| lib/lib.js:414:40:414:43 | name | lib/lib.js:417:28:417:31 | name | provenance | | +| lib/lib.js:414:40:414:43 | name | lib/lib.js:418:25:418:28 | name | provenance | | +| lib/lib.js:414:40:414:43 | name | lib/lib.js:419:32:419:35 | name | provenance | | +| lib/lib.js:414:40:414:43 | name | lib/lib.js:420:29:420:32 | name | provenance | | +| lib/lib.js:414:40:414:43 | name | lib/lib.js:424:24:424:27 | name | provenance | | +| lib/lib.js:414:40:414:43 | name | lib/lib.js:426:11:426:14 | name | provenance | | +| lib/lib.js:414:40:414:43 | name | lib/lib.js:426:11:426:14 | name | provenance | | +| lib/lib.js:414:40:414:43 | name | lib/lib.js:428:36:428:39 | name | provenance | | +| lib/lib.js:425:6:425:13 | arr | lib/lib.js:427:14:427:16 | arr | provenance | | +| lib/lib.js:426:2:426:4 | [post update] arr | lib/lib.js:425:6:425:13 | arr | provenance | | +| lib/lib.js:426:11:426:14 | name | lib/lib.js:426:2:426:4 | [post update] arr | provenance | | +| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:428:14:428:58 | build(" ... + '-') | provenance | | +| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:431:23:431:26 | last | provenance | | +| lib/lib.js:428:36:428:39 | name | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | provenance | | +| lib/lib.js:431:23:431:26 | last | lib/lib.js:436:19:436:22 | last | provenance | | +| lib/lib.js:431:23:431:26 | last | lib/lib.js:436:19:436:22 | last | provenance | | +| lib/lib.js:432:6:432:13 | arr | lib/lib.js:437:9:437:11 | arr | provenance | | +| lib/lib.js:436:10:436:12 | [post update] arr | lib/lib.js:432:6:432:13 | arr | provenance | | +| lib/lib.js:436:19:436:22 | last | lib/lib.js:436:10:436:12 | [post update] arr | provenance | | +| lib/lib.js:441:39:441:42 | name | lib/lib.js:442:24:442:27 | name | provenance | | +| lib/lib.js:446:20:446:23 | name | lib/lib.js:447:25:447:28 | name | provenance | | +| lib/lib.js:477:33:477:38 | config | lib/lib.js:478:27:478:32 | config | provenance | | +| lib/lib.js:478:27:478:32 | config | lib/lib.js:478:27:478:46 | config.installedPath | provenance | | +| lib/lib.js:482:40:482:43 | name | lib/lib.js:483:30:483:33 | name | provenance | | +| lib/lib.js:498:45:498:48 | name | lib/lib.js:499:31:499:34 | name | provenance | | +| lib/lib.js:509:39:509:42 | name | lib/lib.js:510:22:510:25 | name | provenance | | +| lib/lib.js:509:39:509:42 | name | lib/lib.js:513:23:513:26 | name | provenance | | +| lib/lib.js:509:39:509:42 | name | lib/lib.js:519:23:519:26 | name | provenance | | +| lib/lib.js:509:39:509:42 | name | lib/lib.js:525:23:525:26 | name | provenance | | +| lib/lib.js:509:39:509:42 | name | lib/lib.js:531:23:531:26 | name | provenance | | +| lib/lib.js:509:39:509:42 | name | lib/lib.js:537:23:537:26 | name | provenance | | +| lib/lib.js:509:39:509:42 | name | lib/lib.js:543:23:543:26 | name | provenance | | +| lib/lib.js:509:39:509:42 | name | lib/lib.js:545:23:545:26 | name | provenance | | +| lib/lib.js:550:39:550:42 | name | lib/lib.js:555:33:555:36 | name | provenance | | +| lib/lib.js:550:39:550:42 | name | lib/lib.js:555:33:555:36 | name | provenance | | +| lib/lib.js:551:33:551:36 | args | lib/lib.js:552:23:552:26 | args | provenance | | +| lib/lib.js:555:25:555:37 | ["-rf", name] | lib/lib.js:551:33:551:36 | args | provenance | | +| lib/lib.js:555:33:555:36 | name | lib/lib.js:555:25:555:37 | ["-rf", name] | provenance | | +| lib/lib.js:558:41:558:44 | name | lib/lib.js:560:26:560:29 | name | provenance | | +| lib/lib.js:558:41:558:44 | name | lib/lib.js:562:26:562:29 | name | provenance | | +| lib/lib.js:558:41:558:44 | name | lib/lib.js:566:26:566:29 | name | provenance | | +| lib/lib.js:572:41:572:44 | name | lib/lib.js:573:22:573:25 | name | provenance | | +| lib/lib.js:572:41:572:44 | name | lib/lib.js:579:25:579:28 | name | provenance | | +| lib/lib.js:572:41:572:44 | name | lib/lib.js:590:29:590:32 | name | provenance | | +| lib/lib.js:572:41:572:44 | name | lib/lib.js:593:25:593:28 | name | provenance | | +| lib/lib.js:608:42:608:45 | name | lib/lib.js:609:22:609:25 | name | provenance | | +| lib/lib.js:608:42:608:45 | name | lib/lib.js:626:29:626:32 | name | provenance | | +| lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | provenance | | +| lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | provenance | | +| lib/subLib2/special-file.js:3:28:3:31 | name | lib/subLib2/special-file.js:4:22:4:25 | name | provenance | | +| lib/subLib3/my-file.ts:3:28:3:31 | name | lib/subLib3/my-file.ts:4:22:4:25 | name | provenance | | +| lib/subLib4/index.js:6:32:6:35 | name | lib/subLib4/index.js:7:18:7:21 | name | provenance | | +| lib/subLib4/index.js:7:18:7:21 | name | lib/subLib4/subsub.js:3:28:3:31 | name | provenance | | +| lib/subLib4/subsub.js:3:28:3:31 | name | lib/subLib4/subsub.js:4:22:4:25 | name | provenance | | +| lib/subLib/amdSub.js:3:28:3:31 | name | lib/subLib/amdSub.js:4:22:4:25 | name | provenance | | +| lib/subLib/index.js:3:28:3:31 | name | lib/subLib/index.js:4:22:4:25 | name | provenance | | +| lib/subLib/index.js:7:32:7:35 | name | lib/subLib/index.js:8:22:8:25 | name | provenance | | +| lib/subLib/index.js:13:44:13:46 | arr | lib/subLib/index.js:14:22:14:24 | arr | provenance | | nodes | lib/isImported.js:5:49:5:52 | name | semmle.label | name | | lib/isImported.js:6:22:6:25 | name | semmle.label | name | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/UnsafeDynamicMethodAccess/UnsafeDynamicMethodAccess.expected b/javascript/ql/test/query-tests/Security/CWE-094/UnsafeDynamicMethodAccess/UnsafeDynamicMethodAccess.expected index 4a5f9141a99..f5bbd2e9a7b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/UnsafeDynamicMethodAccess/UnsafeDynamicMethodAccess.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/UnsafeDynamicMethodAccess/UnsafeDynamicMethodAccess.expected @@ -1,30 +1,30 @@ edges -| example.js:9:37:9:38 | ev | example.js:10:30:10:31 | ev | -| example.js:10:9:10:37 | message | example.js:13:12:13:18 | message | -| example.js:10:19:10:37 | JSON.parse(ev.data) | example.js:10:9:10:37 | message | -| example.js:10:30:10:31 | ev | example.js:10:30:10:36 | ev.data | -| example.js:10:30:10:36 | ev.data | example.js:10:19:10:37 | JSON.parse(ev.data) | -| example.js:13:12:13:18 | message | example.js:13:12:13:23 | message.name | -| example.js:13:12:13:23 | message.name | example.js:13:5:13:24 | window[message.name] | -| tst.js:3:37:3:38 | ev | tst.js:4:30:4:31 | ev | -| tst.js:3:37:3:38 | ev | tst.js:15:12:15:13 | ev | -| tst.js:4:9:4:37 | message | tst.js:5:12:5:18 | message | -| tst.js:4:9:4:37 | message | tst.js:6:16:6:22 | message | -| tst.js:4:9:4:37 | message | tst.js:11:7:11:13 | message | -| tst.js:4:9:4:37 | message | tst.js:21:17:21:23 | message | -| tst.js:4:19:4:37 | JSON.parse(ev.data) | tst.js:4:9:4:37 | message | -| tst.js:4:30:4:31 | ev | tst.js:4:30:4:36 | ev.data | -| tst.js:4:30:4:36 | ev.data | tst.js:4:19:4:37 | JSON.parse(ev.data) | -| tst.js:5:12:5:18 | message | tst.js:5:12:5:23 | message.name | -| tst.js:5:12:5:23 | message.name | tst.js:5:5:5:24 | window[message.name] | -| tst.js:6:16:6:22 | message | tst.js:6:16:6:27 | message.name | -| tst.js:6:16:6:27 | message.name | tst.js:6:9:6:28 | window[message.name] | -| tst.js:11:7:11:13 | message | tst.js:11:7:11:18 | message.name | -| tst.js:11:7:11:18 | message.name | tst.js:11:5:11:19 | f[message.name] | -| tst.js:15:12:15:13 | ev | tst.js:15:5:15:14 | window[ev] | -| tst.js:21:12:21:28 | '' + message.name | tst.js:21:5:21:29 | window[ ... e.name] | -| tst.js:21:17:21:23 | message | tst.js:21:17:21:28 | message.name | -| tst.js:21:17:21:28 | message.name | tst.js:21:12:21:28 | '' + message.name | +| example.js:9:37:9:38 | ev | example.js:10:30:10:31 | ev | provenance | | +| example.js:10:9:10:37 | message | example.js:13:12:13:18 | message | provenance | | +| example.js:10:19:10:37 | JSON.parse(ev.data) | example.js:10:9:10:37 | message | provenance | | +| example.js:10:30:10:31 | ev | example.js:10:30:10:36 | ev.data | provenance | | +| example.js:10:30:10:36 | ev.data | example.js:10:19:10:37 | JSON.parse(ev.data) | provenance | | +| example.js:13:12:13:18 | message | example.js:13:12:13:23 | message.name | provenance | | +| example.js:13:12:13:23 | message.name | example.js:13:5:13:24 | window[message.name] | provenance | | +| tst.js:3:37:3:38 | ev | tst.js:4:30:4:31 | ev | provenance | | +| tst.js:3:37:3:38 | ev | tst.js:15:12:15:13 | ev | provenance | | +| tst.js:4:9:4:37 | message | tst.js:5:12:5:18 | message | provenance | | +| tst.js:4:9:4:37 | message | tst.js:6:16:6:22 | message | provenance | | +| tst.js:4:9:4:37 | message | tst.js:11:7:11:13 | message | provenance | | +| tst.js:4:9:4:37 | message | tst.js:21:17:21:23 | message | provenance | | +| tst.js:4:19:4:37 | JSON.parse(ev.data) | tst.js:4:9:4:37 | message | provenance | | +| tst.js:4:30:4:31 | ev | tst.js:4:30:4:36 | ev.data | provenance | | +| tst.js:4:30:4:36 | ev.data | tst.js:4:19:4:37 | JSON.parse(ev.data) | provenance | | +| tst.js:5:12:5:18 | message | tst.js:5:12:5:23 | message.name | provenance | | +| tst.js:5:12:5:23 | message.name | tst.js:5:5:5:24 | window[message.name] | provenance | | +| tst.js:6:16:6:22 | message | tst.js:6:16:6:27 | message.name | provenance | | +| tst.js:6:16:6:27 | message.name | tst.js:6:9:6:28 | window[message.name] | provenance | | +| tst.js:11:7:11:13 | message | tst.js:11:7:11:18 | message.name | provenance | | +| tst.js:11:7:11:18 | message.name | tst.js:11:5:11:19 | f[message.name] | provenance | | +| tst.js:15:12:15:13 | ev | tst.js:15:5:15:14 | window[ev] | provenance | | +| tst.js:21:12:21:28 | '' + message.name | tst.js:21:5:21:29 | window[ ... e.name] | provenance | | +| tst.js:21:17:21:23 | message | tst.js:21:17:21:28 | message.name | provenance | | +| tst.js:21:17:21:28 | message.name | tst.js:21:12:21:28 | '' + message.name | provenance | | nodes | example.js:9:37:9:38 | ev | semmle.label | ev | | example.js:10:9:10:37 | message | semmle.label | message | diff --git a/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected b/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected index c5a5a9ac206..c6c416c93e0 100644 --- a/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected +++ b/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected @@ -1,10 +1,10 @@ edges -| PostMessageStar2.js:4:7:4:15 | data [foo] | PostMessageStar2.js:8:29:8:32 | data [foo] | -| PostMessageStar2.js:4:7:4:15 | data [foo] | PostMessageStar2.js:9:29:9:32 | data [foo] | -| PostMessageStar2.js:5:3:5:6 | [post update] data [foo] | PostMessageStar2.js:4:7:4:15 | data [foo] | -| PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:5:3:5:6 | [post update] data [foo] | -| PostMessageStar2.js:8:29:8:32 | data [foo] | PostMessageStar2.js:8:29:8:32 | data | -| PostMessageStar2.js:9:29:9:32 | data [foo] | PostMessageStar2.js:9:29:9:36 | data.foo | +| PostMessageStar2.js:4:7:4:15 | data [foo] | PostMessageStar2.js:8:29:8:32 | data [foo] | provenance | | +| PostMessageStar2.js:4:7:4:15 | data [foo] | PostMessageStar2.js:9:29:9:32 | data [foo] | provenance | | +| PostMessageStar2.js:5:3:5:6 | [post update] data [foo] | PostMessageStar2.js:4:7:4:15 | data [foo] | provenance | | +| PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:5:3:5:6 | [post update] data [foo] | provenance | | +| PostMessageStar2.js:8:29:8:32 | data [foo] | PostMessageStar2.js:8:29:8:32 | data | provenance | | +| PostMessageStar2.js:9:29:9:32 | data [foo] | PostMessageStar2.js:9:29:9:36 | data.foo | provenance | | nodes | PostMessageStar2.js:1:27:1:34 | password | semmle.label | password | | PostMessageStar2.js:4:7:4:15 | data [foo] | semmle.label | data [foo] | diff --git a/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected b/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected index ad32c9ea18e..0b9cb037451 100644 --- a/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected +++ b/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected @@ -1,7 +1,7 @@ edges -| tst.js:3:5:3:24 | secretText | tst.js:11:17:11:26 | secretText | -| tst.js:3:5:3:24 | secretText | tst.js:22:21:22:30 | secretText | -| tst.js:3:18:3:24 | trusted | tst.js:3:5:3:24 | secretText | +| tst.js:3:5:3:24 | secretText | tst.js:11:17:11:26 | secretText | provenance | | +| tst.js:3:5:3:24 | secretText | tst.js:22:21:22:30 | secretText | provenance | | +| tst.js:3:18:3:24 | trusted | tst.js:3:5:3:24 | secretText | provenance | | nodes | tst.js:3:5:3:24 | secretText | semmle.label | secretText | | tst.js:3:18:3:24 | trusted | semmle.label | trusted | diff --git a/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected b/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected index 8d4e9c108fb..7337287c748 100644 --- a/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected +++ b/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected @@ -1,36 +1,36 @@ edges -| tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | -| tst.js:19:9:19:36 | suffix | tst.js:20:31:20:36 | suffix | -| tst.js:19:18:19:30 | Math.random() | tst.js:19:18:19:36 | Math.random() % 255 | -| tst.js:19:18:19:36 | Math.random() % 255 | tst.js:19:9:19:36 | suffix | -| tst.js:20:31:20:36 | suffix | tst.js:20:20:20:36 | "prefix" + suffix | -| tst.js:28:9:28:26 | pw | tst.js:29:20:29:21 | pw | -| tst.js:28:14:28:26 | Math.random() | tst.js:28:9:28:26 | pw | -| tst.js:41:21:41:33 | Math.random() | tst.js:41:20:41:33 | !Math.random() | -| tst.js:61:22:61:34 | Math.random() | tst.js:61:17:61:34 | '' + Math.random() | -| tst.js:66:29:66:41 | Math.random() | tst.js:66:18:66:42 | Math.fl ... ndom()) | -| tst.js:71:9:71:48 | rand | tst.js:72:34:72:37 | rand | -| tst.js:71:16:71:48 | Math.fl ... 999999) | tst.js:71:9:71:48 | rand | -| tst.js:71:27:71:39 | Math.random() | tst.js:71:27:71:47 | Math.ra ... 9999999 | -| tst.js:71:27:71:47 | Math.ra ... 9999999 | tst.js:71:16:71:48 | Math.fl ... 999999) | -| tst.js:72:9:72:48 | concat | tst.js:73:23:73:28 | concat | -| tst.js:72:18:72:48 | ts.toSt ... tring() | tst.js:72:9:72:48 | concat | -| tst.js:72:34:72:37 | rand | tst.js:72:34:72:48 | rand.toString() | -| tst.js:72:34:72:48 | rand.toString() | tst.js:72:18:72:48 | ts.toSt ... tring() | -| tst.js:77:16:77:21 | secret | tst.js:77:16:77:21 | secret | -| tst.js:80:7:80:19 | Math.random() | tst.js:77:16:77:21 | secret | -| tst.js:115:27:115:39 | Math.random() | tst.js:115:27:115:55 | Math.ra ... 000_000 | -| tst.js:115:27:115:55 | Math.ra ... 000_000 | tst.js:115:16:115:56 | Math.fl ... 00_000) | -| tst.js:116:33:116:45 | Math.random() | tst.js:116:33:116:61 | Math.ra ... 000_000 | -| tst.js:116:33:116:61 | Math.ra ... 000_000 | tst.js:116:22:116:62 | Math.fl ... 00_000) | -| tst.js:117:26:117:38 | Math.random() | tst.js:117:26:117:54 | Math.ra ... 000_000 | -| tst.js:117:26:117:54 | Math.ra ... 000_000 | tst.js:117:15:117:55 | Math.fl ... 00_000) | -| tst.js:118:34:118:46 | Math.random() | tst.js:118:34:118:62 | Math.ra ... 000_000 | -| tst.js:118:34:118:62 | Math.ra ... 000_000 | tst.js:118:23:118:63 | Math.fl ... 00_000) | -| tst.js:136:21:136:67 | chars[M ... ength)] | tst.js:136:9:136:67 | password | -| tst.js:136:27:136:66 | Math.fl ... length) | tst.js:136:21:136:67 | chars[M ... ength)] | -| tst.js:136:38:136:50 | Math.random() | tst.js:136:38:136:65 | Math.ra ... .length | -| tst.js:136:38:136:65 | Math.ra ... .length | tst.js:136:27:136:66 | Math.fl ... length) | +| tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | provenance | | +| tst.js:19:9:19:36 | suffix | tst.js:20:31:20:36 | suffix | provenance | | +| tst.js:19:18:19:30 | Math.random() | tst.js:19:18:19:36 | Math.random() % 255 | provenance | | +| tst.js:19:18:19:36 | Math.random() % 255 | tst.js:19:9:19:36 | suffix | provenance | | +| tst.js:20:31:20:36 | suffix | tst.js:20:20:20:36 | "prefix" + suffix | provenance | | +| tst.js:28:9:28:26 | pw | tst.js:29:20:29:21 | pw | provenance | | +| tst.js:28:14:28:26 | Math.random() | tst.js:28:9:28:26 | pw | provenance | | +| tst.js:41:21:41:33 | Math.random() | tst.js:41:20:41:33 | !Math.random() | provenance | | +| tst.js:61:22:61:34 | Math.random() | tst.js:61:17:61:34 | '' + Math.random() | provenance | | +| tst.js:66:29:66:41 | Math.random() | tst.js:66:18:66:42 | Math.fl ... ndom()) | provenance | | +| tst.js:71:9:71:48 | rand | tst.js:72:34:72:37 | rand | provenance | | +| tst.js:71:16:71:48 | Math.fl ... 999999) | tst.js:71:9:71:48 | rand | provenance | | +| tst.js:71:27:71:39 | Math.random() | tst.js:71:27:71:47 | Math.ra ... 9999999 | provenance | | +| tst.js:71:27:71:47 | Math.ra ... 9999999 | tst.js:71:16:71:48 | Math.fl ... 999999) | provenance | | +| tst.js:72:9:72:48 | concat | tst.js:73:23:73:28 | concat | provenance | | +| tst.js:72:18:72:48 | ts.toSt ... tring() | tst.js:72:9:72:48 | concat | provenance | | +| tst.js:72:34:72:37 | rand | tst.js:72:34:72:48 | rand.toString() | provenance | | +| tst.js:72:34:72:48 | rand.toString() | tst.js:72:18:72:48 | ts.toSt ... tring() | provenance | | +| tst.js:77:16:77:21 | secret | tst.js:77:16:77:21 | secret | provenance | | +| tst.js:80:7:80:19 | Math.random() | tst.js:77:16:77:21 | secret | provenance | | +| tst.js:115:27:115:39 | Math.random() | tst.js:115:27:115:55 | Math.ra ... 000_000 | provenance | | +| tst.js:115:27:115:55 | Math.ra ... 000_000 | tst.js:115:16:115:56 | Math.fl ... 00_000) | provenance | | +| tst.js:116:33:116:45 | Math.random() | tst.js:116:33:116:61 | Math.ra ... 000_000 | provenance | | +| tst.js:116:33:116:61 | Math.ra ... 000_000 | tst.js:116:22:116:62 | Math.fl ... 00_000) | provenance | | +| tst.js:117:26:117:38 | Math.random() | tst.js:117:26:117:54 | Math.ra ... 000_000 | provenance | | +| tst.js:117:26:117:54 | Math.ra ... 000_000 | tst.js:117:15:117:55 | Math.fl ... 00_000) | provenance | | +| tst.js:118:34:118:46 | Math.random() | tst.js:118:34:118:62 | Math.ra ... 000_000 | provenance | | +| tst.js:118:34:118:62 | Math.ra ... 000_000 | tst.js:118:23:118:63 | Math.fl ... 00_000) | provenance | | +| tst.js:136:21:136:67 | chars[M ... ength)] | tst.js:136:9:136:67 | password | provenance | | +| tst.js:136:27:136:66 | Math.fl ... length) | tst.js:136:21:136:67 | chars[M ... ength)] | provenance | | +| tst.js:136:38:136:50 | Math.random() | tst.js:136:38:136:65 | Math.ra ... .length | provenance | | +| tst.js:136:38:136:65 | Math.ra ... .length | tst.js:136:27:136:66 | Math.fl ... length) | provenance | | nodes | tst.js:2:20:2:32 | Math.random() | semmle.label | Math.random() | | tst.js:6:20:6:43 | "prefix ... andom() | semmle.label | "prefix ... andom() | diff --git a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected index a1806eb239f..12f0b7bb5a7 100644 --- a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected +++ b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected @@ -1,42 +1,42 @@ edges -| HardcodedCredentials.js:18:16:18:30 | "user:hgfedcba" | HardcodedCredentials.js:20:36:20:51 | getCredentials() | -| HardcodedCredentials.js:171:11:171:25 | USER | HardcodedCredentials.js:173:35:173:38 | USER | -| HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:11:171:25 | USER | -| HardcodedCredentials.js:172:11:172:25 | PASS | HardcodedCredentials.js:173:43:173:46 | PASS | -| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:172:11:172:25 | PASS | -| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:178:39:178:42 | AUTH | -| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:188:39:188:42 | AUTH | -| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:195:46:195:49 | AUTH | -| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:204:44:204:47 | AUTH | -| HardcodedCredentials.js:173:18:173:49 | base64. ... PASS}`) | HardcodedCredentials.js:173:11:173:49 | AUTH | -| HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | HardcodedCredentials.js:173:18:173:49 | base64. ... PASS}`) | -| HardcodedCredentials.js:173:35:173:38 | USER | HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | -| HardcodedCredentials.js:173:43:173:46 | PASS | HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | -| HardcodedCredentials.js:178:39:178:42 | AUTH | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | -| HardcodedCredentials.js:188:39:188:42 | AUTH | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | -| HardcodedCredentials.js:195:46:195:49 | AUTH | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | -| HardcodedCredentials.js:204:44:204:47 | AUTH | HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` | -| HardcodedCredentials.js:214:11:214:25 | USER | HardcodedCredentials.js:216:35:216:38 | USER | -| HardcodedCredentials.js:214:18:214:25 | 'sdsdag' | HardcodedCredentials.js:214:11:214:25 | USER | -| HardcodedCredentials.js:215:11:215:25 | PASS | HardcodedCredentials.js:216:43:216:46 | PASS | -| HardcodedCredentials.js:215:18:215:25 | 'sdsdag' | HardcodedCredentials.js:215:11:215:25 | PASS | -| HardcodedCredentials.js:216:11:216:49 | AUTH | HardcodedCredentials.js:221:46:221:49 | AUTH | -| HardcodedCredentials.js:216:18:216:49 | base64. ... PASS}`) | HardcodedCredentials.js:216:11:216:49 | AUTH | -| HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | HardcodedCredentials.js:216:18:216:49 | base64. ... PASS}`) | -| HardcodedCredentials.js:216:35:216:38 | USER | HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | -| HardcodedCredentials.js:216:43:216:46 | PASS | HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | -| HardcodedCredentials.js:221:46:221:49 | AUTH | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | -| HardcodedCredentials.js:231:11:231:29 | username | HardcodedCredentials.js:237:47:237:54 | username | -| HardcodedCredentials.js:231:22:231:29 | 'sdsdag' | HardcodedCredentials.js:231:11:231:29 | username | -| HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) | HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | -| HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') | -| HardcodedCredentials.js:237:47:237:54 | username | HardcodedCredentials.js:237:47:237:71 | usernam ... assword | -| HardcodedCredentials.js:237:47:237:71 | usernam ... assword | HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) | -| HardcodedCredentials.js:245:9:245:44 | privateKey | HardcodedCredentials.js:246:42:246:51 | privateKey | -| HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:245:9:245:44 | privateKey | -| HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | HardcodedCredentials.js:268:30:268:73 | `${foo ... Token}` | -| HardcodedCredentials.js:268:39:268:46 | 'Bearer' | HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | -| HardcodedCredentials.js:268:50:268:56 | 'OAuth' | HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | +| HardcodedCredentials.js:18:16:18:30 | "user:hgfedcba" | HardcodedCredentials.js:20:36:20:51 | getCredentials() | provenance | | +| HardcodedCredentials.js:171:11:171:25 | USER | HardcodedCredentials.js:173:35:173:38 | USER | provenance | | +| HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:11:171:25 | USER | provenance | | +| HardcodedCredentials.js:172:11:172:25 | PASS | HardcodedCredentials.js:173:43:173:46 | PASS | provenance | | +| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:172:11:172:25 | PASS | provenance | | +| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:178:39:178:42 | AUTH | provenance | | +| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:188:39:188:42 | AUTH | provenance | | +| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:195:46:195:49 | AUTH | provenance | | +| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:204:44:204:47 | AUTH | provenance | | +| HardcodedCredentials.js:173:18:173:49 | base64. ... PASS}`) | HardcodedCredentials.js:173:11:173:49 | AUTH | provenance | | +| HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | HardcodedCredentials.js:173:18:173:49 | base64. ... PASS}`) | provenance | | +| HardcodedCredentials.js:173:35:173:38 | USER | HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | provenance | | +| HardcodedCredentials.js:173:43:173:46 | PASS | HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | provenance | | +| HardcodedCredentials.js:178:39:178:42 | AUTH | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | provenance | | +| HardcodedCredentials.js:188:39:188:42 | AUTH | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | provenance | | +| HardcodedCredentials.js:195:46:195:49 | AUTH | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | provenance | | +| HardcodedCredentials.js:204:44:204:47 | AUTH | HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` | provenance | | +| HardcodedCredentials.js:214:11:214:25 | USER | HardcodedCredentials.js:216:35:216:38 | USER | provenance | | +| HardcodedCredentials.js:214:18:214:25 | 'sdsdag' | HardcodedCredentials.js:214:11:214:25 | USER | provenance | | +| HardcodedCredentials.js:215:11:215:25 | PASS | HardcodedCredentials.js:216:43:216:46 | PASS | provenance | | +| HardcodedCredentials.js:215:18:215:25 | 'sdsdag' | HardcodedCredentials.js:215:11:215:25 | PASS | provenance | | +| HardcodedCredentials.js:216:11:216:49 | AUTH | HardcodedCredentials.js:221:46:221:49 | AUTH | provenance | | +| HardcodedCredentials.js:216:18:216:49 | base64. ... PASS}`) | HardcodedCredentials.js:216:11:216:49 | AUTH | provenance | | +| HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | HardcodedCredentials.js:216:18:216:49 | base64. ... PASS}`) | provenance | | +| HardcodedCredentials.js:216:35:216:38 | USER | HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | provenance | | +| HardcodedCredentials.js:216:43:216:46 | PASS | HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | provenance | | +| HardcodedCredentials.js:221:46:221:49 | AUTH | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | provenance | | +| HardcodedCredentials.js:231:11:231:29 | username | HardcodedCredentials.js:237:47:237:54 | username | provenance | | +| HardcodedCredentials.js:231:22:231:29 | 'sdsdag' | HardcodedCredentials.js:231:11:231:29 | username | provenance | | +| HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) | HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | provenance | | +| HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') | provenance | | +| HardcodedCredentials.js:237:47:237:54 | username | HardcodedCredentials.js:237:47:237:71 | usernam ... assword | provenance | | +| HardcodedCredentials.js:237:47:237:71 | usernam ... assword | HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) | provenance | | +| HardcodedCredentials.js:245:9:245:44 | privateKey | HardcodedCredentials.js:246:42:246:51 | privateKey | provenance | | +| HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:245:9:245:44 | privateKey | provenance | | +| HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | HardcodedCredentials.js:268:30:268:73 | `${foo ... Token}` | provenance | | +| HardcodedCredentials.js:268:39:268:46 | 'Bearer' | HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | provenance | | +| HardcodedCredentials.js:268:50:268:56 | 'OAuth' | HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | provenance | | nodes | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | semmle.label | 'dbuser' | | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | semmle.label | 'hgfedcba' | diff --git a/javascript/ql/test/query-tests/Security/CWE-829/InsecureDownload.expected b/javascript/ql/test/query-tests/Security/CWE-829/InsecureDownload.expected index 8e0f2f5af59..d697f55bdd7 100644 --- a/javascript/ql/test/query-tests/Security/CWE-829/InsecureDownload.expected +++ b/javascript/ql/test/query-tests/Security/CWE-829/InsecureDownload.expected @@ -22,22 +22,22 @@ nodes | insecure-download.js:48:12:48:38 | "http:/ ... unsafe" | semmle.label | "http:/ ... unsafe" | | insecure-download.js:52:11:52:45 | "http:/ ... nknown" | semmle.label | "http:/ ... nknown" | edges -| insecure-download.js:4:28:4:36 | installer [url] | insecure-download.js:5:16:5:24 | installer [url] | -| insecure-download.js:5:16:5:24 | installer [url] | insecure-download.js:5:16:5:28 | installer.url | -| insecure-download.js:7:9:11:5 | constants [buildTools, installerUrl] | insecure-download.js:13:28:13:36 | constants [buildTools, installerUrl] | -| insecure-download.js:7:21:11:5 | {\\n ... }\\n } [buildTools, installerUrl] | insecure-download.js:7:9:11:5 | constants [buildTools, installerUrl] | -| insecure-download.js:8:21:10:9 | {\\n ... } [installerUrl] | insecure-download.js:7:21:11:5 | {\\n ... }\\n } [buildTools, installerUrl] | -| insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | insecure-download.js:8:21:10:9 | {\\n ... } [installerUrl] | -| insecure-download.js:13:15:13:47 | buildTools [installerUrl] | insecure-download.js:15:18:15:27 | buildTools [installerUrl] | -| insecure-download.js:13:28:13:36 | constants [buildTools, installerUrl] | insecure-download.js:13:28:13:47 | constants.buildTools [installerUrl] | -| insecure-download.js:13:28:13:47 | constants.buildTools [installerUrl] | insecure-download.js:13:15:13:47 | buildTools [installerUrl] | -| insecure-download.js:14:16:16:9 | {\\n ... } [url] | insecure-download.js:19:19:19:46 | getBuil ... rPath() [url] | -| insecure-download.js:15:18:15:27 | buildTools [installerUrl] | insecure-download.js:15:18:15:40 | buildTo ... llerUrl | -| insecure-download.js:15:18:15:40 | buildTo ... llerUrl | insecure-download.js:14:16:16:9 | {\\n ... } [url] | -| insecure-download.js:19:19:19:46 | getBuil ... rPath() [url] | insecure-download.js:4:28:4:36 | installer [url] | -| insecure-download.js:36:9:36:45 | url | insecure-download.js:37:23:37:25 | url | -| insecure-download.js:36:9:36:45 | url | insecure-download.js:39:26:39:28 | url | -| insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | insecure-download.js:36:9:36:45 | url | +| insecure-download.js:4:28:4:36 | installer [url] | insecure-download.js:5:16:5:24 | installer [url] | provenance | | +| insecure-download.js:5:16:5:24 | installer [url] | insecure-download.js:5:16:5:28 | installer.url | provenance | | +| insecure-download.js:7:9:11:5 | constants [buildTools, installerUrl] | insecure-download.js:13:28:13:36 | constants [buildTools, installerUrl] | provenance | | +| insecure-download.js:7:21:11:5 | {\\n ... }\\n } [buildTools, installerUrl] | insecure-download.js:7:9:11:5 | constants [buildTools, installerUrl] | provenance | | +| insecure-download.js:8:21:10:9 | {\\n ... } [installerUrl] | insecure-download.js:7:21:11:5 | {\\n ... }\\n } [buildTools, installerUrl] | provenance | | +| insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | insecure-download.js:8:21:10:9 | {\\n ... } [installerUrl] | provenance | | +| insecure-download.js:13:15:13:47 | buildTools [installerUrl] | insecure-download.js:15:18:15:27 | buildTools [installerUrl] | provenance | | +| insecure-download.js:13:28:13:36 | constants [buildTools, installerUrl] | insecure-download.js:13:28:13:47 | constants.buildTools [installerUrl] | provenance | | +| insecure-download.js:13:28:13:47 | constants.buildTools [installerUrl] | insecure-download.js:13:15:13:47 | buildTools [installerUrl] | provenance | | +| insecure-download.js:14:16:16:9 | {\\n ... } [url] | insecure-download.js:19:19:19:46 | getBuil ... rPath() [url] | provenance | | +| insecure-download.js:15:18:15:27 | buildTools [installerUrl] | insecure-download.js:15:18:15:40 | buildTo ... llerUrl | provenance | | +| insecure-download.js:15:18:15:40 | buildTo ... llerUrl | insecure-download.js:14:16:16:9 | {\\n ... } [url] | provenance | | +| insecure-download.js:19:19:19:46 | getBuil ... rPath() [url] | insecure-download.js:4:28:4:36 | installer [url] | provenance | | +| insecure-download.js:36:9:36:45 | url | insecure-download.js:37:23:37:25 | url | provenance | | +| insecure-download.js:36:9:36:45 | url | insecure-download.js:39:26:39:28 | url | provenance | | +| insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | insecure-download.js:36:9:36:45 | url | provenance | | subpaths #select | insecure-download.js:5:16:5:28 | installer.url | insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | insecure-download.js:5:16:5:28 | installer.url | $@ of sensitive file from $@. | insecure-download.js:5:9:5:44 | nugget( ... => { }) | Download | insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | HTTP source | diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/PrototypePollutingFunction.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/PrototypePollutingFunction.expected index e9cf5fe90f6..185775d7dac 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/PrototypePollutingFunction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/PrototypePollutingFunction.expected @@ -634,700 +634,700 @@ nodes | tests.js:605:40:605:50 | source[key] | semmle.label | source[key] | | tests.js:605:47:605:49 | key | semmle.label | key | edges -| examples/PrototypePollutingFunction.js:1:16:1:18 | dst | examples/PrototypePollutingFunction.js:5:19:5:21 | dst | -| examples/PrototypePollutingFunction.js:1:16:1:18 | dst | examples/PrototypePollutingFunction.js:7:13:7:15 | dst | -| examples/PrototypePollutingFunction.js:1:21:1:23 | src | examples/PrototypePollutingFunction.js:5:29:5:31 | src | -| examples/PrototypePollutingFunction.js:1:21:1:23 | src | examples/PrototypePollutingFunction.js:7:24:7:26 | src | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:5:23:5:25 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:5:33:5:35 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:28:7:30 | key | -| examples/PrototypePollutingFunction.js:5:19:5:21 | dst | examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | -| examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | examples/PrototypePollutingFunction.js:1:16:1:18 | dst | -| examples/PrototypePollutingFunction.js:5:23:5:25 | key | examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | -| examples/PrototypePollutingFunction.js:5:29:5:31 | src | examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | -| examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction.js:5:33:5:35 | key | examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | -| examples/PrototypePollutingFunction.js:7:24:7:26 | src | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction.js:7:28:7:30 | key | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed2.js:6:29:6:31 | src | -| examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed2.js:8:24:8:26 | src | -| examples/PrototypePollutingFunction_fixed2.js:6:29:6:31 | src | examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | -| examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction_fixed2.js:8:24:8:26 | src | examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed.js:5:29:5:31 | src | -| examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed.js:7:24:7:26 | src | -| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:17:7:19 | key | -| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | -| examples/PrototypePollutingFunction_fixed.js:5:29:5:31 | src | examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | -| examples/PrototypePollutingFunction_fixed.js:7:24:7:26 | src | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | -| examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | -| path-assignment.js:8:13:8:25 | key | path-assignment.js:13:29:13:31 | key | -| path-assignment.js:8:13:8:25 | key | path-assignment.js:15:20:15:22 | key | -| path-assignment.js:8:19:8:25 | keys[i] | path-assignment.js:8:13:8:25 | key | -| path-assignment.js:13:13:13:32 | target | path-assignment.js:13:22:13:27 | target | -| path-assignment.js:13:13:13:32 | target | path-assignment.js:15:13:15:18 | target | -| path-assignment.js:13:22:13:27 | target | path-assignment.js:13:22:13:32 | target[key] | -| path-assignment.js:13:22:13:32 | target[key] | path-assignment.js:13:13:13:32 | target | -| path-assignment.js:13:29:13:31 | key | path-assignment.js:13:22:13:32 | target[key] | -| path-assignment.js:41:13:41:25 | key | path-assignment.js:42:25:42:27 | key | -| path-assignment.js:41:13:41:25 | key | path-assignment.js:42:39:42:41 | key | -| path-assignment.js:41:19:41:25 | keys[i] | path-assignment.js:41:13:41:25 | key | -| path-assignment.js:42:9:42:48 | target | path-assignment.js:42:18:42:23 | target | -| path-assignment.js:42:9:42:48 | target | path-assignment.js:42:32:42:37 | target | -| path-assignment.js:42:9:42:48 | target | path-assignment.js:44:5:44:10 | target | -| path-assignment.js:42:32:42:37 | target | path-assignment.js:42:32:42:42 | target[key] | -| path-assignment.js:42:32:42:42 | target[key] | path-assignment.js:42:9:42:48 | target | -| path-assignment.js:42:32:42:42 | target[key] | path-assignment.js:42:32:42:48 | target[key] \|\| {} | -| path-assignment.js:42:39:42:41 | key | path-assignment.js:42:32:42:42 | target[key] | -| path-assignment.js:58:13:58:25 | key | path-assignment.js:59:25:59:27 | key | -| path-assignment.js:58:13:58:25 | key | path-assignment.js:59:39:59:41 | key | -| path-assignment.js:58:19:58:25 | keys[i] | path-assignment.js:58:13:58:25 | key | -| path-assignment.js:59:9:59:48 | target | path-assignment.js:59:18:59:23 | target | -| path-assignment.js:59:9:59:48 | target | path-assignment.js:59:32:59:37 | target | -| path-assignment.js:59:9:59:48 | target | path-assignment.js:61:5:61:10 | target | -| path-assignment.js:59:32:59:37 | target | path-assignment.js:59:32:59:42 | target[key] | -| path-assignment.js:59:32:59:42 | target[key] | path-assignment.js:59:9:59:48 | target | -| path-assignment.js:59:32:59:42 | target[key] | path-assignment.js:59:32:59:48 | target[key] \|\| {} | -| path-assignment.js:59:39:59:41 | key | path-assignment.js:59:32:59:42 | target[key] | -| path-assignment.js:68:13:68:25 | key | path-assignment.js:69:25:69:27 | key | -| path-assignment.js:68:13:68:25 | key | path-assignment.js:69:39:69:41 | key | -| path-assignment.js:68:19:68:25 | keys[i] | path-assignment.js:68:13:68:25 | key | -| path-assignment.js:69:9:69:48 | target | path-assignment.js:69:18:69:23 | target | -| path-assignment.js:69:9:69:48 | target | path-assignment.js:69:32:69:37 | target | -| path-assignment.js:69:9:69:48 | target | path-assignment.js:71:5:71:10 | target | -| path-assignment.js:69:32:69:37 | target | path-assignment.js:69:32:69:42 | target[key] | -| path-assignment.js:69:32:69:42 | target[key] | path-assignment.js:69:9:69:48 | target | -| path-assignment.js:69:32:69:42 | target[key] | path-assignment.js:69:32:69:48 | target[key] \|\| {} | -| path-assignment.js:69:39:69:41 | key | path-assignment.js:69:32:69:42 | target[key] | -| tests.js:3:25:3:27 | dst | tests.js:6:28:6:30 | dst | -| tests.js:3:25:3:27 | dst | tests.js:8:13:8:15 | dst | -| tests.js:3:30:3:32 | src | tests.js:6:38:6:40 | src | -| tests.js:3:30:3:32 | src | tests.js:8:24:8:26 | src | -| tests.js:4:14:4:16 | key | tests.js:6:32:6:34 | key | -| tests.js:4:14:4:16 | key | tests.js:6:42:6:44 | key | -| tests.js:4:14:4:16 | key | tests.js:8:17:8:19 | key | -| tests.js:4:14:4:16 | key | tests.js:8:28:8:30 | key | -| tests.js:6:28:6:30 | dst | tests.js:6:28:6:35 | dst[key] | -| tests.js:6:28:6:35 | dst[key] | tests.js:3:25:3:27 | dst | -| tests.js:6:32:6:34 | key | tests.js:6:28:6:35 | dst[key] | -| tests.js:6:38:6:40 | src | tests.js:6:38:6:45 | src[key] | -| tests.js:6:38:6:45 | src[key] | tests.js:3:30:3:32 | src | -| tests.js:6:42:6:44 | key | tests.js:6:38:6:45 | src[key] | -| tests.js:8:24:8:26 | src | tests.js:8:24:8:31 | src[key] | -| tests.js:8:28:8:30 | key | tests.js:8:24:8:31 | src[key] | -| tests.js:13:24:13:26 | dst | tests.js:16:27:16:29 | dst | -| tests.js:13:24:13:26 | dst | tests.js:18:13:18:15 | dst | -| tests.js:13:29:13:31 | src | tests.js:14:17:14:19 | src | -| tests.js:14:17:14:19 | src | tests.js:16:37:16:39 | src | -| tests.js:14:17:14:19 | src | tests.js:18:24:18:26 | src | -| tests.js:14:30:14:32 | key | tests.js:16:31:16:33 | key | -| tests.js:14:30:14:32 | key | tests.js:16:41:16:43 | key | -| tests.js:14:30:14:32 | key | tests.js:18:17:18:19 | key | -| tests.js:14:30:14:32 | key | tests.js:18:28:18:30 | key | -| tests.js:16:27:16:29 | dst | tests.js:16:27:16:34 | dst[key] | -| tests.js:16:27:16:34 | dst[key] | tests.js:13:24:13:26 | dst | -| tests.js:16:31:16:33 | key | tests.js:16:27:16:34 | dst[key] | -| tests.js:16:37:16:39 | src | tests.js:16:37:16:44 | src[key] | -| tests.js:16:37:16:44 | src[key] | tests.js:13:29:13:31 | src | -| tests.js:16:41:16:43 | key | tests.js:16:37:16:44 | src[key] | -| tests.js:18:24:18:26 | src | tests.js:18:24:18:31 | src[key] | -| tests.js:18:28:18:30 | key | tests.js:18:24:18:31 | src[key] | -| tests.js:23:19:23:21 | dst | tests.js:26:25:26:27 | dst | -| tests.js:25:18:25:20 | key | tests.js:26:37:26:39 | key | -| tests.js:25:18:25:20 | key | tests.js:26:43:26:45 | key | -| tests.js:26:25:26:27 | dst | tests.js:31:22:31:24 | dst | -| tests.js:26:30:26:40 | source[key] | tests.js:31:27:31:31 | value | -| tests.js:26:37:26:39 | key | tests.js:26:30:26:40 | source[key] | -| tests.js:26:43:26:45 | key | tests.js:31:34:31:36 | key | -| tests.js:31:22:31:24 | dst | tests.js:32:20:32:22 | dst | -| tests.js:31:22:31:24 | dst | tests.js:36:9:36:11 | dst | -| tests.js:31:27:31:31 | value | tests.js:36:20:36:24 | value | -| tests.js:31:34:31:36 | key | tests.js:32:24:32:26 | key | -| tests.js:31:34:31:36 | key | tests.js:36:13:36:15 | key | -| tests.js:32:9:32:27 | dstValue | tests.js:34:18:34:25 | dstValue | -| tests.js:32:20:32:22 | dst | tests.js:32:20:32:27 | dst[key] | -| tests.js:32:20:32:27 | dst[key] | tests.js:32:9:32:27 | dstValue | -| tests.js:32:24:32:26 | key | tests.js:32:20:32:27 | dst[key] | -| tests.js:34:18:34:25 | dstValue | tests.js:23:19:23:21 | dst | -| tests.js:40:27:40:29 | dst | tests.js:44:30:44:32 | dst | -| tests.js:40:27:40:29 | dst | tests.js:46:13:46:15 | dst | -| tests.js:40:32:40:34 | src | tests.js:44:40:44:42 | src | -| tests.js:40:32:40:34 | src | tests.js:46:24:46:26 | src | -| tests.js:41:14:41:16 | key | tests.js:44:34:44:36 | key | -| tests.js:41:14:41:16 | key | tests.js:44:44:44:46 | key | -| tests.js:41:14:41:16 | key | tests.js:46:17:46:19 | key | -| tests.js:41:14:41:16 | key | tests.js:46:28:46:30 | key | -| tests.js:44:30:44:32 | dst | tests.js:44:30:44:37 | dst[key] | -| tests.js:44:30:44:37 | dst[key] | tests.js:40:27:40:29 | dst | -| tests.js:44:34:44:36 | key | tests.js:44:30:44:37 | dst[key] | -| tests.js:44:40:44:42 | src | tests.js:44:40:44:47 | src[key] | -| tests.js:44:40:44:47 | src[key] | tests.js:40:32:40:34 | src | -| tests.js:44:44:44:46 | key | tests.js:44:40:44:47 | src[key] | -| tests.js:46:24:46:26 | src | tests.js:46:24:46:31 | src[key] | -| tests.js:46:28:46:30 | key | tests.js:46:24:46:31 | src[key] | -| tests.js:51:26:51:28 | dst | tests.js:55:29:55:31 | dst | -| tests.js:51:26:51:28 | dst | tests.js:57:13:57:15 | dst | -| tests.js:51:31:51:33 | src | tests.js:55:39:55:41 | src | -| tests.js:51:31:51:33 | src | tests.js:57:24:57:26 | src | -| tests.js:52:14:52:16 | key | tests.js:55:33:55:35 | key | -| tests.js:52:14:52:16 | key | tests.js:55:43:55:45 | key | -| tests.js:52:14:52:16 | key | tests.js:57:17:57:19 | key | -| tests.js:52:14:52:16 | key | tests.js:57:28:57:30 | key | -| tests.js:55:29:55:31 | dst | tests.js:55:29:55:36 | dst[key] | -| tests.js:55:29:55:36 | dst[key] | tests.js:51:26:51:28 | dst | -| tests.js:55:33:55:35 | key | tests.js:55:29:55:36 | dst[key] | -| tests.js:55:39:55:41 | src | tests.js:55:39:55:46 | src[key] | -| tests.js:55:39:55:46 | src[key] | tests.js:51:31:51:33 | src | -| tests.js:55:43:55:45 | key | tests.js:55:39:55:46 | src[key] | -| tests.js:57:24:57:26 | src | tests.js:57:24:57:31 | src[key] | -| tests.js:57:28:57:30 | key | tests.js:57:24:57:31 | src[key] | -| tests.js:62:33:62:35 | src | tests.js:66:41:66:43 | src | -| tests.js:62:33:62:35 | src | tests.js:68:24:68:26 | src | -| tests.js:66:41:66:43 | src | tests.js:66:41:66:48 | src[key] | -| tests.js:66:41:66:48 | src[key] | tests.js:62:33:62:35 | src | -| tests.js:68:24:68:26 | src | tests.js:68:24:68:31 | src[key] | -| tests.js:77:27:77:29 | src | tests.js:81:39:81:41 | src | -| tests.js:77:27:77:29 | src | tests.js:83:28:83:30 | src | -| tests.js:81:39:81:41 | src | tests.js:81:39:81:46 | src[key] | -| tests.js:81:39:81:46 | src[key] | tests.js:77:27:77:29 | src | -| tests.js:83:28:83:30 | src | tests.js:83:28:83:35 | src[key] | -| tests.js:89:34:89:36 | src | tests.js:94:42:94:44 | src | -| tests.js:89:34:89:36 | src | tests.js:96:24:96:26 | src | -| tests.js:90:14:90:16 | key | tests.js:96:17:96:19 | key | -| tests.js:90:14:90:16 | key | tests.js:96:28:96:30 | key | -| tests.js:94:42:94:44 | src | tests.js:94:42:94:49 | src[key] | -| tests.js:94:42:94:49 | src[key] | tests.js:89:34:89:36 | src | -| tests.js:96:24:96:26 | src | tests.js:96:24:96:31 | src[key] | -| tests.js:96:28:96:30 | key | tests.js:96:24:96:31 | src[key] | -| tests.js:101:32:101:34 | dst | tests.js:107:35:107:37 | dst | -| tests.js:101:32:101:34 | dst | tests.js:109:13:109:15 | dst | -| tests.js:101:37:101:39 | src | tests.js:107:45:107:47 | src | -| tests.js:101:37:101:39 | src | tests.js:109:24:109:26 | src | -| tests.js:102:14:102:16 | key | tests.js:107:39:107:41 | key | -| tests.js:102:14:102:16 | key | tests.js:107:49:107:51 | key | -| tests.js:102:14:102:16 | key | tests.js:109:17:109:19 | key | -| tests.js:102:14:102:16 | key | tests.js:109:28:109:30 | key | -| tests.js:107:35:107:37 | dst | tests.js:107:35:107:42 | dst[key] | -| tests.js:107:35:107:42 | dst[key] | tests.js:101:32:101:34 | dst | -| tests.js:107:39:107:41 | key | tests.js:107:35:107:42 | dst[key] | -| tests.js:107:45:107:47 | src | tests.js:107:45:107:52 | src[key] | -| tests.js:107:45:107:52 | src[key] | tests.js:101:37:101:39 | src | -| tests.js:107:49:107:51 | key | tests.js:107:45:107:52 | src[key] | -| tests.js:109:24:109:26 | src | tests.js:109:24:109:31 | src[key] | -| tests.js:109:28:109:30 | key | tests.js:109:24:109:31 | src[key] | -| tests.js:116:41:116:43 | src | tests.js:119:49:119:51 | src | -| tests.js:116:41:116:43 | src | tests.js:121:24:121:26 | src | -| tests.js:117:14:117:16 | key | tests.js:121:17:121:19 | key | -| tests.js:117:14:117:16 | key | tests.js:121:28:121:30 | key | -| tests.js:119:49:119:51 | src | tests.js:119:49:119:56 | src[key] | -| tests.js:119:49:119:56 | src[key] | tests.js:116:41:116:43 | src | -| tests.js:121:24:121:26 | src | tests.js:121:24:121:31 | src[key] | -| tests.js:121:28:121:30 | key | tests.js:121:24:121:31 | src[key] | -| tests.js:149:31:149:33 | dst | tests.js:152:22:152:24 | dst | -| tests.js:149:31:149:33 | dst | tests.js:154:13:154:15 | dst | -| tests.js:149:36:149:38 | src | tests.js:152:27:152:29 | src | -| tests.js:149:36:149:38 | src | tests.js:154:24:154:26 | src | -| tests.js:150:14:150:16 | key | tests.js:152:32:152:34 | key | -| tests.js:150:14:150:16 | key | tests.js:154:17:154:19 | key | -| tests.js:150:14:150:16 | key | tests.js:154:28:154:30 | key | -| tests.js:152:22:152:24 | dst | tests.js:160:37:160:39 | dst | -| tests.js:152:27:152:29 | src | tests.js:160:42:160:44 | src | -| tests.js:152:32:152:34 | key | tests.js:160:47:160:49 | key | -| tests.js:154:24:154:26 | src | tests.js:154:24:154:31 | src[key] | -| tests.js:154:28:154:30 | key | tests.js:154:24:154:31 | src[key] | -| tests.js:159:36:159:38 | dst | tests.js:160:26:160:28 | dst | -| tests.js:159:41:159:43 | src | tests.js:160:31:160:33 | src | -| tests.js:160:26:160:28 | dst | tests.js:149:31:149:33 | dst | -| tests.js:160:31:160:33 | src | tests.js:149:36:149:38 | src | -| tests.js:160:37:160:39 | dst | tests.js:161:35:161:37 | dst | -| tests.js:160:42:160:44 | src | tests.js:161:45:161:47 | src | -| tests.js:160:47:160:49 | key | tests.js:161:39:161:41 | key | -| tests.js:160:47:160:49 | key | tests.js:161:49:161:51 | key | -| tests.js:161:35:161:37 | dst | tests.js:161:35:161:42 | dst[key] | -| tests.js:161:35:161:42 | dst[key] | tests.js:159:36:159:38 | dst | -| tests.js:161:39:161:41 | key | tests.js:161:35:161:42 | dst[key] | -| tests.js:161:45:161:47 | src | tests.js:161:45:161:52 | src[key] | -| tests.js:161:45:161:52 | src[key] | tests.js:159:41:159:43 | src | -| tests.js:161:49:161:51 | key | tests.js:161:45:161:52 | src[key] | -| tests.js:165:37:165:39 | src | tests.js:169:45:169:47 | src | -| tests.js:165:37:165:39 | src | tests.js:171:24:171:26 | src | -| tests.js:166:14:166:16 | key | tests.js:169:49:169:51 | key | -| tests.js:166:14:166:16 | key | tests.js:171:17:171:19 | key | -| tests.js:166:14:166:16 | key | tests.js:171:28:171:30 | key | -| tests.js:169:45:169:47 | src | tests.js:169:45:169:52 | src[key] | -| tests.js:169:45:169:52 | src[key] | tests.js:165:37:165:39 | src | -| tests.js:169:49:169:51 | key | tests.js:169:45:169:52 | src[key] | -| tests.js:171:24:171:26 | src | tests.js:171:24:171:31 | src[key] | -| tests.js:171:28:171:30 | key | tests.js:171:24:171:31 | src[key] | -| tests.js:178:33:178:35 | src | tests.js:182:41:182:43 | src | -| tests.js:178:33:178:35 | src | tests.js:184:24:184:26 | src | -| tests.js:182:41:182:43 | src | tests.js:182:41:182:48 | src[key] | -| tests.js:182:41:182:48 | src[key] | tests.js:178:33:178:35 | src | -| tests.js:184:24:184:26 | src | tests.js:184:24:184:31 | src[key] | -| tests.js:189:32:189:34 | dst | tests.js:194:35:194:37 | dst | -| tests.js:189:32:189:34 | dst | tests.js:196:13:196:15 | dst | -| tests.js:189:37:189:39 | src | tests.js:194:45:194:47 | src | -| tests.js:189:37:189:39 | src | tests.js:196:24:196:26 | src | -| tests.js:192:13:192:25 | key | tests.js:194:39:194:41 | key | -| tests.js:192:13:192:25 | key | tests.js:194:49:194:51 | key | -| tests.js:192:13:192:25 | key | tests.js:196:17:196:19 | key | -| tests.js:192:13:192:25 | key | tests.js:196:28:196:30 | key | -| tests.js:192:19:192:25 | keys[i] | tests.js:192:13:192:25 | key | -| tests.js:194:35:194:37 | dst | tests.js:194:35:194:42 | dst[key] | -| tests.js:194:35:194:42 | dst[key] | tests.js:189:32:189:34 | dst | -| tests.js:194:39:194:41 | key | tests.js:194:35:194:42 | dst[key] | -| tests.js:194:45:194:47 | src | tests.js:194:45:194:52 | src[key] | -| tests.js:194:45:194:52 | src[key] | tests.js:189:37:189:39 | src | -| tests.js:194:49:194:51 | key | tests.js:194:45:194:52 | src[key] | -| tests.js:196:24:196:26 | src | tests.js:196:24:196:31 | src[key] | -| tests.js:196:28:196:30 | key | tests.js:196:24:196:31 | src[key] | -| tests.js:201:39:201:41 | dst | tests.js:206:42:206:44 | dst | -| tests.js:201:39:201:41 | dst | tests.js:208:13:208:15 | dst | -| tests.js:201:44:201:46 | src | tests.js:206:56:206:58 | src | -| tests.js:201:44:201:46 | src | tests.js:208:28:208:30 | src | -| tests.js:206:42:206:44 | dst | tests.js:206:42:206:53 | dst[keys[i]] | -| tests.js:206:42:206:53 | dst[keys[i]] | tests.js:201:39:201:41 | dst | -| tests.js:206:46:206:52 | keys[i] | tests.js:206:42:206:53 | dst[keys[i]] | -| tests.js:206:56:206:58 | src | tests.js:206:56:206:67 | src[keys[i]] | -| tests.js:206:56:206:67 | src[keys[i]] | tests.js:201:44:201:46 | src | -| tests.js:206:60:206:66 | keys[i] | tests.js:206:56:206:67 | src[keys[i]] | -| tests.js:208:28:208:30 | src | tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:208:32:208:38 | keys[i] | tests.js:208:28:208:39 | src[keys[i]] | -| tests.js:213:23:213:26 | key1 | tests.js:217:9:217:12 | key1 | -| tests.js:213:29:213:32 | key2 | tests.js:217:15:217:18 | key2 | -| tests.js:213:35:213:39 | value | tests.js:217:23:217:27 | value | -| tests.js:217:9:217:12 | key1 | tests.js:217:5:217:13 | map[key1] | -| tests.js:223:14:223:16 | key | tests.js:224:23:224:25 | key | -| tests.js:223:14:223:16 | key | tests.js:224:38:224:40 | key | -| tests.js:223:14:223:16 | key | tests.js:225:28:225:30 | key | -| tests.js:223:14:223:16 | key | tests.js:225:38:225:40 | key | -| tests.js:224:23:224:25 | key | tests.js:213:23:213:26 | key1 | -| tests.js:224:33:224:41 | data[key] | tests.js:213:35:213:39 | value | -| tests.js:224:38:224:40 | key | tests.js:224:33:224:41 | data[key] | -| tests.js:225:28:225:30 | key | tests.js:213:29:213:32 | key2 | -| tests.js:225:33:225:41 | data[key] | tests.js:213:35:213:39 | value | -| tests.js:225:38:225:40 | key | tests.js:225:33:225:41 | data[key] | -| tests.js:229:26:229:29 | key1 | tests.js:233:9:233:12 | key1 | -| tests.js:229:32:229:35 | key2 | tests.js:233:15:233:18 | key2 | -| tests.js:229:38:229:42 | value | tests.js:233:23:233:27 | value | -| tests.js:233:9:233:12 | key1 | tests.js:233:5:233:13 | map[key1] | -| tests.js:238:14:238:16 | key | tests.js:239:24:239:26 | key | -| tests.js:238:14:238:16 | key | tests.js:239:39:239:41 | key | -| tests.js:238:14:238:16 | key | tests.js:240:31:240:33 | key | -| tests.js:238:14:238:16 | key | tests.js:240:41:240:43 | key | -| tests.js:239:24:239:26 | key | tests.js:229:26:229:29 | key1 | -| tests.js:239:34:239:42 | data[key] | tests.js:229:38:229:42 | value | -| tests.js:239:39:239:41 | key | tests.js:239:34:239:42 | data[key] | -| tests.js:240:31:240:33 | key | tests.js:229:32:229:35 | key2 | -| tests.js:240:36:240:44 | data[key] | tests.js:229:38:229:42 | value | -| tests.js:240:41:240:43 | key | tests.js:240:36:240:44 | data[key] | -| tests.js:263:27:263:29 | dst | tests.js:268:30:268:32 | dst | -| tests.js:263:27:263:29 | dst | tests.js:270:13:270:15 | dst | -| tests.js:265:13:265:26 | key | tests.js:268:34:268:36 | key | -| tests.js:265:13:265:26 | key | tests.js:270:17:270:19 | key | -| tests.js:265:19:265:26 | entry[0] | tests.js:265:13:265:26 | key | -| tests.js:266:13:266:28 | value | tests.js:270:24:270:28 | value | -| tests.js:266:21:266:28 | entry[1] | tests.js:266:13:266:28 | value | -| tests.js:268:30:268:32 | dst | tests.js:268:30:268:37 | dst[key] | -| tests.js:268:30:268:37 | dst[key] | tests.js:263:27:263:29 | dst | -| tests.js:268:34:268:36 | key | tests.js:268:30:268:37 | dst[key] | -| tests.js:275:27:275:29 | dst | tests.js:278:30:278:32 | dst | -| tests.js:275:27:275:29 | dst | tests.js:280:13:280:15 | dst | -| tests.js:275:32:275:34 | src | tests.js:276:21:276:23 | src | -| tests.js:276:21:276:23 | src | tests.js:278:40:278:42 | src | -| tests.js:276:21:276:23 | src | tests.js:280:24:280:26 | src | -| tests.js:276:34:276:36 | key | tests.js:278:34:278:36 | key | -| tests.js:276:34:276:36 | key | tests.js:278:44:278:46 | key | -| tests.js:276:34:276:36 | key | tests.js:280:17:280:19 | key | -| tests.js:276:34:276:36 | key | tests.js:280:28:280:30 | key | -| tests.js:278:30:278:32 | dst | tests.js:278:30:278:37 | dst[key] | -| tests.js:278:30:278:37 | dst[key] | tests.js:275:27:275:29 | dst | -| tests.js:278:34:278:36 | key | tests.js:278:30:278:37 | dst[key] | -| tests.js:278:40:278:42 | src | tests.js:278:40:278:47 | src[key] | -| tests.js:278:40:278:47 | src[key] | tests.js:275:32:275:34 | src | -| tests.js:278:44:278:46 | key | tests.js:278:40:278:47 | src[key] | -| tests.js:280:24:280:26 | src | tests.js:280:24:280:31 | src[key] | -| tests.js:280:28:280:30 | key | tests.js:280:24:280:31 | src[key] | -| tests.js:301:27:301:29 | dst | tests.js:306:34:306:36 | dst | -| tests.js:301:27:301:29 | dst | tests.js:308:17:308:19 | dst | -| tests.js:301:32:301:34 | src | tests.js:304:25:304:27 | src | -| tests.js:302:14:302:16 | key | tests.js:304:29:304:31 | key | -| tests.js:302:14:302:16 | key | tests.js:306:38:306:40 | key | -| tests.js:302:14:302:16 | key | tests.js:308:21:308:23 | key | -| tests.js:304:17:304:32 | value | tests.js:306:44:306:48 | value | -| tests.js:304:17:304:32 | value | tests.js:306:44:306:48 | value | -| tests.js:304:17:304:32 | value | tests.js:308:28:308:32 | value | -| tests.js:304:17:304:32 | value | tests.js:308:28:308:32 | value | -| tests.js:304:17:304:32 | value | tests.js:308:28:308:32 | value | -| tests.js:304:25:304:27 | src | tests.js:304:25:304:32 | src[key] | -| tests.js:304:25:304:32 | src[key] | tests.js:304:17:304:32 | value | -| tests.js:304:25:304:32 | src[key] | tests.js:304:17:304:32 | value | -| tests.js:304:25:304:32 | src[key] | tests.js:304:17:304:32 | value | -| tests.js:304:29:304:31 | key | tests.js:304:25:304:32 | src[key] | -| tests.js:304:29:304:31 | key | tests.js:304:25:304:32 | src[key] | -| tests.js:306:34:306:36 | dst | tests.js:306:34:306:41 | dst[key] | -| tests.js:306:34:306:41 | dst[key] | tests.js:301:27:301:29 | dst | -| tests.js:306:38:306:40 | key | tests.js:306:34:306:41 | dst[key] | -| tests.js:306:44:306:48 | value | tests.js:301:32:301:34 | src | -| tests.js:306:44:306:48 | value | tests.js:301:32:301:34 | src | -| tests.js:314:31:314:33 | dst | tests.js:320:38:320:40 | dst | -| tests.js:314:31:314:33 | dst | tests.js:322:17:322:19 | dst | -| tests.js:314:36:314:38 | src | tests.js:318:25:318:27 | src | -| tests.js:315:14:315:16 | key | tests.js:318:29:318:31 | key | -| tests.js:315:14:315:16 | key | tests.js:320:42:320:44 | key | -| tests.js:315:14:315:16 | key | tests.js:322:21:322:23 | key | -| tests.js:318:17:318:32 | value | tests.js:320:48:320:52 | value | -| tests.js:318:17:318:32 | value | tests.js:320:48:320:52 | value | -| tests.js:318:17:318:32 | value | tests.js:322:28:322:32 | value | -| tests.js:318:17:318:32 | value | tests.js:322:28:322:32 | value | -| tests.js:318:17:318:32 | value | tests.js:322:28:322:32 | value | -| tests.js:318:25:318:27 | src | tests.js:318:25:318:32 | src[key] | -| tests.js:318:25:318:32 | src[key] | tests.js:318:17:318:32 | value | -| tests.js:318:25:318:32 | src[key] | tests.js:318:17:318:32 | value | -| tests.js:318:25:318:32 | src[key] | tests.js:318:17:318:32 | value | -| tests.js:318:29:318:31 | key | tests.js:318:25:318:32 | src[key] | -| tests.js:318:29:318:31 | key | tests.js:318:25:318:32 | src[key] | -| tests.js:320:38:320:40 | dst | tests.js:320:38:320:45 | dst[key] | -| tests.js:320:38:320:45 | dst[key] | tests.js:314:31:314:33 | dst | -| tests.js:320:42:320:44 | key | tests.js:320:38:320:45 | dst[key] | -| tests.js:320:48:320:52 | value | tests.js:314:36:314:38 | src | -| tests.js:320:48:320:52 | value | tests.js:314:36:314:38 | src | -| tests.js:328:25:328:27 | dst | tests.js:336:32:336:34 | dst | -| tests.js:328:25:328:27 | dst | tests.js:338:17:338:19 | dst | -| tests.js:328:30:328:32 | src | tests.js:336:42:336:44 | src | -| tests.js:328:30:328:32 | src | tests.js:338:28:338:30 | src | -| tests.js:329:14:329:16 | key | tests.js:336:36:336:38 | key | -| tests.js:329:14:329:16 | key | tests.js:336:46:336:48 | key | -| tests.js:329:14:329:16 | key | tests.js:338:21:338:23 | key | -| tests.js:329:14:329:16 | key | tests.js:338:32:338:34 | key | -| tests.js:336:32:336:34 | dst | tests.js:336:32:336:39 | dst[key] | -| tests.js:336:32:336:39 | dst[key] | tests.js:328:25:328:27 | dst | -| tests.js:336:36:336:38 | key | tests.js:336:32:336:39 | dst[key] | -| tests.js:336:42:336:44 | src | tests.js:336:42:336:49 | src[key] | -| tests.js:336:42:336:49 | src[key] | tests.js:328:30:328:32 | src | -| tests.js:336:46:336:48 | key | tests.js:336:42:336:49 | src[key] | -| tests.js:338:28:338:30 | src | tests.js:338:28:338:35 | src[key] | -| tests.js:338:32:338:34 | key | tests.js:338:28:338:35 | src[key] | -| tests.js:348:32:348:37 | target | tests.js:349:26:349:31 | target | -| tests.js:348:32:348:37 | target | tests.js:361:12:361:17 | target | -| tests.js:348:40:348:45 | source | tests.js:349:54:349:59 | source | -| tests.js:348:40:348:45 | source | tests.js:350:21:350:26 | source | -| tests.js:349:26:349:31 | target | tests.js:355:17:355:22 | target | -| tests.js:349:26:349:31 | target | tests.js:355:53:355:58 | target | -| tests.js:349:26:349:31 | target | tests.js:357:17:357:22 | target | -| tests.js:349:26:349:31 | target | tests.js:361:12:361:17 | target | -| tests.js:349:54:349:59 | source | tests.js:350:21:350:26 | source | -| tests.js:350:21:350:26 | source | tests.js:355:66:355:71 | source | -| tests.js:350:21:350:26 | source | tests.js:357:31:357:36 | source | -| tests.js:350:37:350:39 | key | tests.js:355:24:355:26 | key | -| tests.js:350:37:350:39 | key | tests.js:355:60:355:62 | key | -| tests.js:350:37:350:39 | key | tests.js:357:24:357:26 | key | -| tests.js:350:37:350:39 | key | tests.js:357:38:357:40 | key | -| tests.js:355:53:355:58 | target | tests.js:355:53:355:63 | target[key] | -| tests.js:355:53:355:63 | target[key] | tests.js:348:32:348:37 | target | -| tests.js:355:53:355:63 | target[key] | tests.js:355:31:355:86 | mergePl ... ptions) | -| tests.js:355:60:355:62 | key | tests.js:355:53:355:63 | target[key] | -| tests.js:355:66:355:71 | source | tests.js:355:66:355:76 | source[key] | -| tests.js:355:66:355:76 | source[key] | tests.js:348:40:348:45 | source | -| tests.js:357:31:357:36 | source | tests.js:357:31:357:41 | source[key] | -| tests.js:357:38:357:40 | key | tests.js:357:31:357:41 | source[key] | -| tests.js:364:41:364:46 | target | tests.js:377:12:377:17 | target | -| tests.js:364:49:364:54 | source | tests.js:371:75:371:80 | source | -| tests.js:364:49:364:54 | source | tests.js:373:31:373:36 | source | -| tests.js:366:18:366:20 | key | tests.js:371:24:371:26 | key | -| tests.js:366:18:366:20 | key | tests.js:371:69:371:71 | key | -| tests.js:366:18:366:20 | key | tests.js:373:24:373:26 | key | -| tests.js:366:18:366:20 | key | tests.js:373:38:373:40 | key | -| tests.js:371:62:371:72 | target[key] | tests.js:364:41:364:46 | target | -| tests.js:371:62:371:72 | target[key] | tests.js:371:31:371:95 | mergePl ... ptions) | -| tests.js:371:69:371:71 | key | tests.js:371:62:371:72 | target[key] | -| tests.js:371:75:371:80 | source | tests.js:371:75:371:85 | source[key] | -| tests.js:371:75:371:85 | source[key] | tests.js:364:49:364:54 | source | -| tests.js:373:31:373:36 | source | tests.js:373:31:373:41 | source[key] | -| tests.js:373:38:373:40 | key | tests.js:373:31:373:41 | source[key] | -| tests.js:380:22:380:24 | obj | tests.js:383:27:383:29 | obj | -| tests.js:380:27:380:34 | callback [dst] | tests.js:383:13:383:20 | callback [dst] | -| tests.js:380:27:380:34 | callback [dst] | tests.js:383:13:383:20 | callback [dst] | -| tests.js:380:27:380:34 | callback [dst] | tests.js:383:13:383:20 | callback [dst] | -| tests.js:380:27:380:34 | callback [dst] | tests.js:383:13:383:20 | callback [dst] | -| tests.js:380:27:380:34 | callback [src] | tests.js:383:13:383:20 | callback [src] | -| tests.js:381:14:381:16 | key | tests.js:383:22:383:24 | key | -| tests.js:381:14:381:16 | key | tests.js:383:31:383:33 | key | -| tests.js:383:13:383:20 | callback [dst] | tests.js:391:32:391:34 | dst | -| tests.js:383:13:383:20 | callback [dst] | tests.js:391:32:391:34 | dst | -| tests.js:383:13:383:20 | callback [dst] | tests.js:393:13:393:15 | dst | -| tests.js:383:13:383:20 | callback [dst] | tests.js:393:13:393:15 | dst | -| tests.js:383:13:383:20 | callback [dst] | tests.js:401:33:401:35 | dst | -| tests.js:383:13:383:20 | callback [dst] | tests.js:401:33:401:35 | dst | -| tests.js:383:13:383:20 | callback [dst] | tests.js:403:13:403:15 | dst | -| tests.js:383:13:383:20 | callback [dst] | tests.js:403:13:403:15 | dst | -| tests.js:383:13:383:20 | callback [src] | tests.js:391:42:391:44 | src | -| tests.js:383:13:383:20 | callback [src] | tests.js:393:24:393:26 | src | -| tests.js:383:22:383:24 | key | tests.js:389:22:389:24 | key | -| tests.js:383:22:383:24 | key | tests.js:399:23:399:25 | key | -| tests.js:383:27:383:29 | obj | tests.js:383:27:383:34 | obj[key] | -| tests.js:383:27:383:34 | obj[key] | tests.js:399:28:399:32 | value | -| tests.js:383:31:383:33 | key | tests.js:383:27:383:34 | obj[key] | -| tests.js:388:29:388:31 | dst | tests.js:380:27:380:34 | callback [dst] | -| tests.js:388:29:388:31 | dst | tests.js:380:27:380:34 | callback [dst] | -| tests.js:388:29:388:31 | dst | tests.js:391:32:391:34 | dst | -| tests.js:388:29:388:31 | dst | tests.js:391:32:391:34 | dst | -| tests.js:388:29:388:31 | dst | tests.js:393:13:393:15 | dst | -| tests.js:388:29:388:31 | dst | tests.js:393:13:393:15 | dst | -| tests.js:388:34:388:36 | src | tests.js:389:17:389:19 | src | -| tests.js:389:17:389:19 | src | tests.js:380:27:380:34 | callback [src] | -| tests.js:389:17:389:19 | src | tests.js:391:42:391:44 | src | -| tests.js:389:17:389:19 | src | tests.js:393:24:393:26 | src | -| tests.js:389:22:389:24 | key | tests.js:391:36:391:38 | key | -| tests.js:389:22:389:24 | key | tests.js:391:46:391:48 | key | -| tests.js:389:22:389:24 | key | tests.js:393:17:393:19 | key | -| tests.js:389:22:389:24 | key | tests.js:393:28:393:30 | key | -| tests.js:391:32:391:34 | dst | tests.js:391:32:391:39 | dst[key] | -| tests.js:391:32:391:34 | dst | tests.js:391:32:391:39 | dst[key] | -| tests.js:391:32:391:39 | dst[key] | tests.js:388:29:388:31 | dst | -| tests.js:391:32:391:39 | dst[key] | tests.js:388:29:388:31 | dst | -| tests.js:391:36:391:38 | key | tests.js:391:32:391:39 | dst[key] | -| tests.js:391:36:391:38 | key | tests.js:391:32:391:39 | dst[key] | -| tests.js:391:42:391:44 | src | tests.js:391:42:391:49 | src[key] | -| tests.js:391:42:391:49 | src[key] | tests.js:388:34:388:36 | src | -| tests.js:391:46:391:48 | key | tests.js:391:42:391:49 | src[key] | -| tests.js:393:24:393:26 | src | tests.js:393:24:393:31 | src[key] | -| tests.js:393:28:393:30 | key | tests.js:393:24:393:31 | src[key] | -| tests.js:398:30:398:32 | dst | tests.js:380:27:380:34 | callback [dst] | -| tests.js:398:30:398:32 | dst | tests.js:380:27:380:34 | callback [dst] | -| tests.js:398:30:398:32 | dst | tests.js:401:33:401:35 | dst | -| tests.js:398:30:398:32 | dst | tests.js:401:33:401:35 | dst | -| tests.js:398:30:398:32 | dst | tests.js:403:13:403:15 | dst | -| tests.js:398:30:398:32 | dst | tests.js:403:13:403:15 | dst | -| tests.js:398:35:398:37 | src | tests.js:399:17:399:19 | src | -| tests.js:399:17:399:19 | src | tests.js:380:22:380:24 | obj | -| tests.js:399:23:399:25 | key | tests.js:401:37:401:39 | key | -| tests.js:399:23:399:25 | key | tests.js:403:17:403:19 | key | -| tests.js:399:28:399:32 | value | tests.js:401:43:401:47 | value | -| tests.js:399:28:399:32 | value | tests.js:403:24:403:28 | value | -| tests.js:401:33:401:35 | dst | tests.js:401:33:401:40 | dst[key] | -| tests.js:401:33:401:35 | dst | tests.js:401:33:401:40 | dst[key] | -| tests.js:401:33:401:40 | dst[key] | tests.js:398:30:398:32 | dst | -| tests.js:401:33:401:40 | dst[key] | tests.js:398:30:398:32 | dst | -| tests.js:401:37:401:39 | key | tests.js:401:33:401:40 | dst[key] | -| tests.js:401:37:401:39 | key | tests.js:401:33:401:40 | dst[key] | -| tests.js:401:43:401:47 | value | tests.js:398:35:398:37 | src | -| tests.js:408:22:408:24 | obj | tests.js:409:12:409:14 | obj | -| tests.js:408:27:408:29 | key | tests.js:409:16:409:18 | key | -| tests.js:409:12:409:14 | obj | tests.js:409:12:409:19 | obj[key] | -| tests.js:409:16:409:18 | key | tests.js:409:12:409:19 | obj[key] | -| tests.js:412:31:412:33 | dst | tests.js:415:34:415:36 | dst | -| tests.js:412:31:412:33 | dst | tests.js:419:13:419:15 | dst | -| tests.js:412:36:412:38 | src | tests.js:414:33:414:35 | src | -| tests.js:413:14:413:16 | key | tests.js:414:38:414:40 | key | -| tests.js:413:14:413:16 | key | tests.js:415:39:415:41 | key | -| tests.js:413:14:413:16 | key | tests.js:419:17:419:19 | key | -| tests.js:414:13:414:41 | value | tests.js:417:42:417:46 | value | -| tests.js:414:13:414:41 | value | tests.js:419:24:419:28 | value | -| tests.js:414:21:414:41 | wrapped ... c, key) | tests.js:414:13:414:41 | value | -| tests.js:414:33:414:35 | src | tests.js:408:22:408:24 | obj | -| tests.js:414:33:414:35 | src | tests.js:414:21:414:41 | wrapped ... c, key) | -| tests.js:414:38:414:40 | key | tests.js:408:27:408:29 | key | -| tests.js:414:38:414:40 | key | tests.js:414:21:414:41 | wrapped ... c, key) | -| tests.js:415:13:415:42 | target | tests.js:417:34:417:39 | target | -| tests.js:415:22:415:42 | wrapped ... t, key) | tests.js:415:13:415:42 | target | -| tests.js:415:34:415:36 | dst | tests.js:408:22:408:24 | obj | -| tests.js:415:34:415:36 | dst | tests.js:415:22:415:42 | wrapped ... t, key) | -| tests.js:415:39:415:41 | key | tests.js:408:27:408:29 | key | -| tests.js:415:39:415:41 | key | tests.js:415:22:415:42 | wrapped ... t, key) | -| tests.js:417:34:417:39 | target | tests.js:412:31:412:33 | dst | -| tests.js:417:42:417:46 | value | tests.js:412:36:412:38 | src | -| tests.js:424:25:424:27 | obj | tests.js:426:12:426:14 | obj | -| tests.js:424:30:424:32 | key | tests.js:426:16:426:18 | key | -| tests.js:426:12:426:14 | obj | tests.js:426:12:426:19 | obj[key] | -| tests.js:426:16:426:18 | key | tests.js:426:12:426:19 | obj[key] | -| tests.js:429:34:429:36 | dst | tests.js:432:37:432:39 | dst | -| tests.js:429:34:429:36 | dst | tests.js:436:13:436:15 | dst | -| tests.js:429:39:429:41 | src | tests.js:431:36:431:38 | src | -| tests.js:430:14:430:16 | key | tests.js:431:41:431:43 | key | -| tests.js:430:14:430:16 | key | tests.js:432:42:432:44 | key | -| tests.js:430:14:430:16 | key | tests.js:436:17:436:19 | key | -| tests.js:431:13:431:44 | value | tests.js:434:45:434:49 | value | -| tests.js:431:13:431:44 | value | tests.js:436:24:436:28 | value | -| tests.js:431:21:431:44 | almostS ... c, key) | tests.js:431:13:431:44 | value | -| tests.js:431:36:431:38 | src | tests.js:424:25:424:27 | obj | -| tests.js:431:36:431:38 | src | tests.js:431:21:431:44 | almostS ... c, key) | -| tests.js:431:41:431:43 | key | tests.js:424:30:424:32 | key | -| tests.js:431:41:431:43 | key | tests.js:431:21:431:44 | almostS ... c, key) | -| tests.js:432:13:432:45 | target | tests.js:434:37:434:42 | target | -| tests.js:432:22:432:45 | almostS ... t, key) | tests.js:432:13:432:45 | target | -| tests.js:432:37:432:39 | dst | tests.js:424:25:424:27 | obj | -| tests.js:432:37:432:39 | dst | tests.js:432:22:432:45 | almostS ... t, key) | -| tests.js:432:42:432:44 | key | tests.js:424:30:424:32 | key | -| tests.js:432:42:432:44 | key | tests.js:432:22:432:45 | almostS ... t, key) | -| tests.js:434:37:434:42 | target | tests.js:429:34:429:36 | dst | -| tests.js:434:45:434:49 | value | tests.js:429:39:429:41 | src | -| tests.js:441:19:441:21 | obj | tests.js:443:12:443:14 | obj | -| tests.js:443:12:443:14 | obj | tests.js:443:12:443:19 | obj[key] | -| tests.js:446:33:446:35 | src | tests.js:448:30:448:32 | src | -| tests.js:447:14:447:16 | key | tests.js:453:17:453:19 | key | -| tests.js:448:13:448:38 | value | tests.js:451:39:451:43 | value | -| tests.js:448:13:448:38 | value | tests.js:453:24:453:28 | value | -| tests.js:448:21:448:38 | safeRead(src, key) | tests.js:448:13:448:38 | value | -| tests.js:448:30:448:32 | src | tests.js:441:19:441:21 | obj | -| tests.js:448:30:448:32 | src | tests.js:448:21:448:38 | safeRead(src, key) | -| tests.js:451:39:451:43 | value | tests.js:446:33:446:35 | src | -| tests.js:458:26:458:28 | dst | tests.js:462:29:462:31 | dst | -| tests.js:458:26:458:28 | dst | tests.js:465:30:465:32 | dst | -| tests.js:458:26:458:28 | dst | tests.js:466:30:466:32 | dst | -| tests.js:458:26:458:28 | dst | tests.js:467:30:467:32 | dst | -| tests.js:458:31:458:33 | src | tests.js:460:12:460:14 | src | -| tests.js:460:12:460:14 | src | tests.js:462:39:462:41 | src | -| tests.js:460:12:460:14 | src | tests.js:465:41:465:43 | src | -| tests.js:460:18:460:22 | value | tests.js:467:41:467:45 | value | -| tests.js:460:25:460:27 | key | tests.js:462:33:462:35 | key | -| tests.js:460:25:460:27 | key | tests.js:462:43:462:45 | key | -| tests.js:460:25:460:27 | key | tests.js:465:34:465:36 | key | -| tests.js:460:25:460:27 | key | tests.js:465:45:465:47 | key | -| tests.js:460:25:460:27 | key | tests.js:466:34:466:36 | key | -| tests.js:460:25:460:27 | key | tests.js:466:43:466:45 | key | -| tests.js:460:25:460:27 | key | tests.js:467:34:467:36 | key | -| tests.js:462:29:462:31 | dst | tests.js:462:29:462:36 | dst[key] | -| tests.js:462:29:462:36 | dst[key] | tests.js:458:26:458:28 | dst | -| tests.js:462:33:462:35 | key | tests.js:462:29:462:36 | dst[key] | -| tests.js:462:39:462:41 | src | tests.js:462:39:462:46 | src[key] | -| tests.js:462:39:462:46 | src[key] | tests.js:458:31:458:33 | src | -| tests.js:462:43:462:45 | key | tests.js:462:39:462:46 | src[key] | -| tests.js:465:41:465:43 | src | tests.js:465:41:465:48 | src[key] | -| tests.js:465:45:465:47 | key | tests.js:465:41:465:48 | src[key] | -| tests.js:466:43:466:45 | key | tests.js:466:41:466:46 | o[key] | -| tests.js:472:38:472:40 | dst | tests.js:475:41:475:43 | dst | -| tests.js:472:38:472:40 | dst | tests.js:477:13:477:15 | dst | -| tests.js:473:18:473:22 | value | tests.js:477:24:477:28 | value | -| tests.js:473:25:473:27 | key | tests.js:475:45:475:47 | key | -| tests.js:473:25:473:27 | key | tests.js:477:17:477:19 | key | -| tests.js:475:41:475:43 | dst | tests.js:475:41:475:48 | dst[key] | -| tests.js:475:41:475:48 | dst[key] | tests.js:472:38:472:40 | dst | -| tests.js:475:45:475:47 | key | tests.js:475:41:475:48 | dst[key] | -| tests.js:483:26:483:28 | dst | tests.js:487:29:487:31 | dst | -| tests.js:483:26:483:28 | dst | tests.js:489:13:489:15 | dst | -| tests.js:483:31:483:33 | src | tests.js:487:39:487:41 | src | -| tests.js:483:31:483:33 | src | tests.js:489:24:489:26 | src | -| tests.js:483:31:483:33 | src | tests.js:489:24:489:26 | src | -| tests.js:484:14:484:16 | key | tests.js:487:33:487:35 | key | -| tests.js:484:14:484:16 | key | tests.js:487:43:487:45 | key | -| tests.js:484:14:484:16 | key | tests.js:489:17:489:19 | key | -| tests.js:484:14:484:16 | key | tests.js:489:28:489:30 | key | -| tests.js:487:29:487:31 | dst | tests.js:487:29:487:36 | dst[key] | -| tests.js:487:29:487:36 | dst[key] | tests.js:483:26:483:28 | dst | -| tests.js:487:33:487:35 | key | tests.js:487:29:487:36 | dst[key] | -| tests.js:487:39:487:41 | src | tests.js:487:39:487:46 | src[key] | -| tests.js:487:39:487:46 | src[key] | tests.js:483:31:483:33 | src | -| tests.js:487:39:487:46 | src[key] | tests.js:483:31:483:33 | src | -| tests.js:487:39:487:46 | src[key] | tests.js:483:31:483:33 | src | -| tests.js:487:43:487:45 | key | tests.js:487:39:487:46 | src[key] | -| tests.js:489:24:489:26 | src | tests.js:489:24:489:31 | src[key] | -| tests.js:489:28:489:30 | key | tests.js:489:24:489:31 | src[key] | -| tests.js:494:32:494:34 | src | tests.js:498:21:498:23 | src | -| tests.js:495:14:495:16 | key | tests.js:498:25:498:27 | key | -| tests.js:495:14:495:16 | key | tests.js:502:17:502:19 | key | -| tests.js:498:13:498:28 | value | tests.js:500:38:500:42 | value | -| tests.js:498:13:498:28 | value | tests.js:500:38:500:42 | value | -| tests.js:498:13:498:28 | value | tests.js:502:24:502:28 | value | -| tests.js:498:13:498:28 | value | tests.js:502:24:502:28 | value | -| tests.js:498:13:498:28 | value | tests.js:502:24:502:28 | value | -| tests.js:498:21:498:23 | src | tests.js:498:21:498:28 | src[key] | -| tests.js:498:21:498:28 | src[key] | tests.js:498:13:498:28 | value | -| tests.js:498:21:498:28 | src[key] | tests.js:498:13:498:28 | value | -| tests.js:498:21:498:28 | src[key] | tests.js:498:13:498:28 | value | -| tests.js:498:25:498:27 | key | tests.js:498:21:498:28 | src[key] | -| tests.js:500:38:500:42 | value | tests.js:494:32:494:34 | src | -| tests.js:500:38:500:42 | value | tests.js:494:32:494:34 | src | -| tests.js:508:30:508:32 | dst | tests.js:513:33:513:35 | dst | -| tests.js:508:30:508:32 | dst | tests.js:517:35:517:37 | dst | -| tests.js:508:35:508:37 | src | tests.js:513:43:513:45 | src | -| tests.js:508:35:508:37 | src | tests.js:516:32:516:34 | src | -| tests.js:511:13:511:25 | key | tests.js:513:37:513:39 | key | -| tests.js:511:13:511:25 | key | tests.js:513:47:513:49 | key | -| tests.js:511:13:511:25 | key | tests.js:516:36:516:38 | key | -| tests.js:511:13:511:25 | key | tests.js:517:40:517:42 | key | -| tests.js:511:19:511:25 | keys[i] | tests.js:511:13:511:25 | key | -| tests.js:513:33:513:35 | dst | tests.js:513:33:513:40 | dst[key] | -| tests.js:513:33:513:40 | dst[key] | tests.js:508:30:508:32 | dst | -| tests.js:513:37:513:39 | key | tests.js:513:33:513:40 | dst[key] | -| tests.js:513:43:513:45 | src | tests.js:513:43:513:50 | src[key] | -| tests.js:513:43:513:50 | src[key] | tests.js:508:35:508:37 | src | -| tests.js:513:47:513:49 | key | tests.js:513:43:513:50 | src[key] | -| tests.js:516:32:516:34 | src | tests.js:516:32:516:39 | src[key] | -| tests.js:516:36:516:38 | key | tests.js:516:32:516:39 | src[key] | -| tests.js:525:14:525:16 | key | tests.js:529:17:529:19 | key | -| tests.js:525:14:525:16 | key | tests.js:529:28:529:30 | key | -| tests.js:529:28:529:30 | key | tests.js:529:24:529:31 | src[key] | -| tests.js:534:31:534:33 | obj | tests.js:538:27:538:29 | obj | -| tests.js:534:36:534:43 | callback [dst] | tests.js:538:9:538:16 | callback [dst] | -| tests.js:538:9:538:16 | callback [dst] | tests.js:545:33:545:35 | dst | -| tests.js:538:9:538:16 | callback [dst] | tests.js:547:13:547:15 | dst | -| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key | -| tests.js:538:27:538:29 | obj | tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value | -| tests.js:538:31:538:37 | keys[i] | tests.js:538:27:538:38 | obj[keys[i]] | -| tests.js:542:30:542:32 | dst | tests.js:534:36:534:43 | callback [dst] | -| tests.js:542:30:542:32 | dst | tests.js:545:33:545:35 | dst | -| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst | -| tests.js:542:35:542:37 | src | tests.js:543:26:543:28 | src | -| tests.js:543:26:543:28 | src | tests.js:534:31:534:33 | obj | -| tests.js:543:32:543:34 | key | tests.js:545:37:545:39 | key | -| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key | -| tests.js:543:37:543:41 | value | tests.js:545:43:545:47 | value | -| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value | -| tests.js:545:33:545:35 | dst | tests.js:545:33:545:40 | dst[key] | -| tests.js:545:33:545:40 | dst[key] | tests.js:542:30:542:32 | dst | -| tests.js:545:37:545:39 | key | tests.js:545:33:545:40 | dst[key] | -| tests.js:545:43:545:47 | value | tests.js:542:35:542:37 | src | -| tests.js:552:35:552:37 | src | tests.js:557:43:557:45 | src | -| tests.js:552:35:552:37 | src | tests.js:559:24:559:26 | src | -| tests.js:553:14:553:16 | key | tests.js:559:17:559:19 | key | -| tests.js:553:14:553:16 | key | tests.js:559:28:559:30 | key | -| tests.js:557:43:557:45 | src | tests.js:557:43:557:50 | src[key] | -| tests.js:557:43:557:50 | src[key] | tests.js:552:35:552:37 | src | -| tests.js:559:24:559:26 | src | tests.js:559:24:559:31 | src[key] | -| tests.js:559:28:559:30 | key | tests.js:559:24:559:31 | src[key] | -| tests.js:564:35:564:37 | src | tests.js:569:43:569:45 | src | -| tests.js:564:35:564:37 | src | tests.js:571:24:571:26 | src | -| tests.js:565:14:565:16 | key | tests.js:571:17:571:19 | key | -| tests.js:565:14:565:16 | key | tests.js:571:28:571:30 | key | -| tests.js:569:43:569:45 | src | tests.js:569:43:569:50 | src[key] | -| tests.js:569:43:569:50 | src[key] | tests.js:564:35:564:37 | src | -| tests.js:571:24:571:26 | src | tests.js:571:24:571:31 | src[key] | -| tests.js:571:28:571:30 | key | tests.js:571:24:571:31 | src[key] | -| tests.js:576:30:576:32 | src | tests.js:580:38:580:40 | src | -| tests.js:576:30:576:32 | src | tests.js:582:24:582:26 | src | -| tests.js:577:14:577:16 | key | tests.js:582:17:582:19 | key | -| tests.js:577:14:577:16 | key | tests.js:582:28:582:30 | key | -| tests.js:580:38:580:40 | src | tests.js:580:38:580:45 | src[key] | -| tests.js:580:38:580:45 | src[key] | tests.js:576:30:576:32 | src | -| tests.js:582:24:582:26 | src | tests.js:582:24:582:31 | src[key] | -| tests.js:582:28:582:30 | key | tests.js:582:24:582:31 | src[key] | -| tests.js:591:25:591:27 | obj | tests.js:592:7:592:9 | obj | -| tests.js:591:25:591:27 | obj | tests.js:592:21:592:23 | obj | -| tests.js:592:7:592:9 | obj | tests.js:592:21:592:23 | obj | -| tests.js:592:7:592:9 | obj | tests.js:593:10:593:12 | obj | -| tests.js:592:21:592:23 | obj | tests.js:593:10:593:12 | obj | -| tests.js:600:31:600:34 | dest | tests.js:603:34:603:37 | dest | -| tests.js:600:31:600:34 | dest | tests.js:605:13:605:16 | dest | -| tests.js:600:37:600:42 | source | tests.js:603:45:603:50 | source | -| tests.js:600:37:600:42 | source | tests.js:605:40:605:45 | source | -| tests.js:601:16:601:18 | key | tests.js:603:39:603:41 | key | -| tests.js:601:16:601:18 | key | tests.js:603:52:603:54 | key | -| tests.js:601:16:601:18 | key | tests.js:605:18:605:20 | key | -| tests.js:601:16:601:18 | key | tests.js:605:47:605:49 | key | -| tests.js:603:34:603:37 | dest | tests.js:603:34:603:42 | dest[key] | -| tests.js:603:34:603:42 | dest[key] | tests.js:600:31:600:34 | dest | -| tests.js:603:39:603:41 | key | tests.js:603:34:603:42 | dest[key] | -| tests.js:603:45:603:50 | source | tests.js:603:45:603:55 | source[key] | -| tests.js:603:45:603:55 | source[key] | tests.js:600:37:600:42 | source | -| tests.js:603:52:603:54 | key | tests.js:603:45:603:55 | source[key] | -| tests.js:605:40:605:45 | source | tests.js:605:40:605:50 | source[key] | -| tests.js:605:40:605:50 | source[key] | tests.js:591:25:591:27 | obj | -| tests.js:605:40:605:50 | source[key] | tests.js:605:25:605:51 | capture ... e[key]) | -| tests.js:605:47:605:49 | key | tests.js:605:40:605:50 | source[key] | +| examples/PrototypePollutingFunction.js:1:16:1:18 | dst | examples/PrototypePollutingFunction.js:5:19:5:21 | dst | provenance | | +| examples/PrototypePollutingFunction.js:1:16:1:18 | dst | examples/PrototypePollutingFunction.js:7:13:7:15 | dst | provenance | | +| examples/PrototypePollutingFunction.js:1:21:1:23 | src | examples/PrototypePollutingFunction.js:5:29:5:31 | src | provenance | | +| examples/PrototypePollutingFunction.js:1:21:1:23 | src | examples/PrototypePollutingFunction.js:7:24:7:26 | src | provenance | | +| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:5:23:5:25 | key | provenance | | +| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:5:33:5:35 | key | provenance | | +| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:17:7:19 | key | provenance | | +| examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:28:7:30 | key | provenance | | +| examples/PrototypePollutingFunction.js:5:19:5:21 | dst | examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | provenance | | +| examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | examples/PrototypePollutingFunction.js:1:16:1:18 | dst | provenance | | +| examples/PrototypePollutingFunction.js:5:23:5:25 | key | examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | provenance | | +| examples/PrototypePollutingFunction.js:5:29:5:31 | src | examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | provenance | | +| examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction.js:1:21:1:23 | src | provenance | | +| examples/PrototypePollutingFunction.js:5:33:5:35 | key | examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | provenance | | +| examples/PrototypePollutingFunction.js:7:24:7:26 | src | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | provenance | | +| examples/PrototypePollutingFunction.js:7:28:7:30 | key | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | provenance | | +| examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed2.js:6:29:6:31 | src | provenance | | +| examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed2.js:8:24:8:26 | src | provenance | | +| examples/PrototypePollutingFunction_fixed2.js:6:29:6:31 | src | examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | provenance | | +| examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | provenance | | +| examples/PrototypePollutingFunction_fixed2.js:8:24:8:26 | src | examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | provenance | | +| examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed.js:5:29:5:31 | src | provenance | | +| examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed.js:7:24:7:26 | src | provenance | | +| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:17:7:19 | key | provenance | | +| examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | provenance | | +| examples/PrototypePollutingFunction_fixed.js:5:29:5:31 | src | examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | provenance | | +| examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | provenance | | +| examples/PrototypePollutingFunction_fixed.js:7:24:7:26 | src | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | provenance | | +| examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | provenance | | +| path-assignment.js:8:13:8:25 | key | path-assignment.js:13:29:13:31 | key | provenance | | +| path-assignment.js:8:13:8:25 | key | path-assignment.js:15:20:15:22 | key | provenance | | +| path-assignment.js:8:19:8:25 | keys[i] | path-assignment.js:8:13:8:25 | key | provenance | | +| path-assignment.js:13:13:13:32 | target | path-assignment.js:13:22:13:27 | target | provenance | | +| path-assignment.js:13:13:13:32 | target | path-assignment.js:15:13:15:18 | target | provenance | | +| path-assignment.js:13:22:13:27 | target | path-assignment.js:13:22:13:32 | target[key] | provenance | | +| path-assignment.js:13:22:13:32 | target[key] | path-assignment.js:13:13:13:32 | target | provenance | | +| path-assignment.js:13:29:13:31 | key | path-assignment.js:13:22:13:32 | target[key] | provenance | | +| path-assignment.js:41:13:41:25 | key | path-assignment.js:42:25:42:27 | key | provenance | | +| path-assignment.js:41:13:41:25 | key | path-assignment.js:42:39:42:41 | key | provenance | | +| path-assignment.js:41:19:41:25 | keys[i] | path-assignment.js:41:13:41:25 | key | provenance | | +| path-assignment.js:42:9:42:48 | target | path-assignment.js:42:18:42:23 | target | provenance | | +| path-assignment.js:42:9:42:48 | target | path-assignment.js:42:32:42:37 | target | provenance | | +| path-assignment.js:42:9:42:48 | target | path-assignment.js:44:5:44:10 | target | provenance | | +| path-assignment.js:42:32:42:37 | target | path-assignment.js:42:32:42:42 | target[key] | provenance | | +| path-assignment.js:42:32:42:42 | target[key] | path-assignment.js:42:9:42:48 | target | provenance | | +| path-assignment.js:42:32:42:42 | target[key] | path-assignment.js:42:32:42:48 | target[key] \|\| {} | provenance | | +| path-assignment.js:42:39:42:41 | key | path-assignment.js:42:32:42:42 | target[key] | provenance | | +| path-assignment.js:58:13:58:25 | key | path-assignment.js:59:25:59:27 | key | provenance | | +| path-assignment.js:58:13:58:25 | key | path-assignment.js:59:39:59:41 | key | provenance | | +| path-assignment.js:58:19:58:25 | keys[i] | path-assignment.js:58:13:58:25 | key | provenance | | +| path-assignment.js:59:9:59:48 | target | path-assignment.js:59:18:59:23 | target | provenance | | +| path-assignment.js:59:9:59:48 | target | path-assignment.js:59:32:59:37 | target | provenance | | +| path-assignment.js:59:9:59:48 | target | path-assignment.js:61:5:61:10 | target | provenance | | +| path-assignment.js:59:32:59:37 | target | path-assignment.js:59:32:59:42 | target[key] | provenance | | +| path-assignment.js:59:32:59:42 | target[key] | path-assignment.js:59:9:59:48 | target | provenance | | +| path-assignment.js:59:32:59:42 | target[key] | path-assignment.js:59:32:59:48 | target[key] \|\| {} | provenance | | +| path-assignment.js:59:39:59:41 | key | path-assignment.js:59:32:59:42 | target[key] | provenance | | +| path-assignment.js:68:13:68:25 | key | path-assignment.js:69:25:69:27 | key | provenance | | +| path-assignment.js:68:13:68:25 | key | path-assignment.js:69:39:69:41 | key | provenance | | +| path-assignment.js:68:19:68:25 | keys[i] | path-assignment.js:68:13:68:25 | key | provenance | | +| path-assignment.js:69:9:69:48 | target | path-assignment.js:69:18:69:23 | target | provenance | | +| path-assignment.js:69:9:69:48 | target | path-assignment.js:69:32:69:37 | target | provenance | | +| path-assignment.js:69:9:69:48 | target | path-assignment.js:71:5:71:10 | target | provenance | | +| path-assignment.js:69:32:69:37 | target | path-assignment.js:69:32:69:42 | target[key] | provenance | | +| path-assignment.js:69:32:69:42 | target[key] | path-assignment.js:69:9:69:48 | target | provenance | | +| path-assignment.js:69:32:69:42 | target[key] | path-assignment.js:69:32:69:48 | target[key] \|\| {} | provenance | | +| path-assignment.js:69:39:69:41 | key | path-assignment.js:69:32:69:42 | target[key] | provenance | | +| tests.js:3:25:3:27 | dst | tests.js:6:28:6:30 | dst | provenance | | +| tests.js:3:25:3:27 | dst | tests.js:8:13:8:15 | dst | provenance | | +| tests.js:3:30:3:32 | src | tests.js:6:38:6:40 | src | provenance | | +| tests.js:3:30:3:32 | src | tests.js:8:24:8:26 | src | provenance | | +| tests.js:4:14:4:16 | key | tests.js:6:32:6:34 | key | provenance | | +| tests.js:4:14:4:16 | key | tests.js:6:42:6:44 | key | provenance | | +| tests.js:4:14:4:16 | key | tests.js:8:17:8:19 | key | provenance | | +| tests.js:4:14:4:16 | key | tests.js:8:28:8:30 | key | provenance | | +| tests.js:6:28:6:30 | dst | tests.js:6:28:6:35 | dst[key] | provenance | | +| tests.js:6:28:6:35 | dst[key] | tests.js:3:25:3:27 | dst | provenance | | +| tests.js:6:32:6:34 | key | tests.js:6:28:6:35 | dst[key] | provenance | | +| tests.js:6:38:6:40 | src | tests.js:6:38:6:45 | src[key] | provenance | | +| tests.js:6:38:6:45 | src[key] | tests.js:3:30:3:32 | src | provenance | | +| tests.js:6:42:6:44 | key | tests.js:6:38:6:45 | src[key] | provenance | | +| tests.js:8:24:8:26 | src | tests.js:8:24:8:31 | src[key] | provenance | | +| tests.js:8:28:8:30 | key | tests.js:8:24:8:31 | src[key] | provenance | | +| tests.js:13:24:13:26 | dst | tests.js:16:27:16:29 | dst | provenance | | +| tests.js:13:24:13:26 | dst | tests.js:18:13:18:15 | dst | provenance | | +| tests.js:13:29:13:31 | src | tests.js:14:17:14:19 | src | provenance | | +| tests.js:14:17:14:19 | src | tests.js:16:37:16:39 | src | provenance | | +| tests.js:14:17:14:19 | src | tests.js:18:24:18:26 | src | provenance | | +| tests.js:14:30:14:32 | key | tests.js:16:31:16:33 | key | provenance | | +| tests.js:14:30:14:32 | key | tests.js:16:41:16:43 | key | provenance | | +| tests.js:14:30:14:32 | key | tests.js:18:17:18:19 | key | provenance | | +| tests.js:14:30:14:32 | key | tests.js:18:28:18:30 | key | provenance | | +| tests.js:16:27:16:29 | dst | tests.js:16:27:16:34 | dst[key] | provenance | | +| tests.js:16:27:16:34 | dst[key] | tests.js:13:24:13:26 | dst | provenance | | +| tests.js:16:31:16:33 | key | tests.js:16:27:16:34 | dst[key] | provenance | | +| tests.js:16:37:16:39 | src | tests.js:16:37:16:44 | src[key] | provenance | | +| tests.js:16:37:16:44 | src[key] | tests.js:13:29:13:31 | src | provenance | | +| tests.js:16:41:16:43 | key | tests.js:16:37:16:44 | src[key] | provenance | | +| tests.js:18:24:18:26 | src | tests.js:18:24:18:31 | src[key] | provenance | | +| tests.js:18:28:18:30 | key | tests.js:18:24:18:31 | src[key] | provenance | | +| tests.js:23:19:23:21 | dst | tests.js:26:25:26:27 | dst | provenance | | +| tests.js:25:18:25:20 | key | tests.js:26:37:26:39 | key | provenance | | +| tests.js:25:18:25:20 | key | tests.js:26:43:26:45 | key | provenance | | +| tests.js:26:25:26:27 | dst | tests.js:31:22:31:24 | dst | provenance | | +| tests.js:26:30:26:40 | source[key] | tests.js:31:27:31:31 | value | provenance | | +| tests.js:26:37:26:39 | key | tests.js:26:30:26:40 | source[key] | provenance | | +| tests.js:26:43:26:45 | key | tests.js:31:34:31:36 | key | provenance | | +| tests.js:31:22:31:24 | dst | tests.js:32:20:32:22 | dst | provenance | | +| tests.js:31:22:31:24 | dst | tests.js:36:9:36:11 | dst | provenance | | +| tests.js:31:27:31:31 | value | tests.js:36:20:36:24 | value | provenance | | +| tests.js:31:34:31:36 | key | tests.js:32:24:32:26 | key | provenance | | +| tests.js:31:34:31:36 | key | tests.js:36:13:36:15 | key | provenance | | +| tests.js:32:9:32:27 | dstValue | tests.js:34:18:34:25 | dstValue | provenance | | +| tests.js:32:20:32:22 | dst | tests.js:32:20:32:27 | dst[key] | provenance | | +| tests.js:32:20:32:27 | dst[key] | tests.js:32:9:32:27 | dstValue | provenance | | +| tests.js:32:24:32:26 | key | tests.js:32:20:32:27 | dst[key] | provenance | | +| tests.js:34:18:34:25 | dstValue | tests.js:23:19:23:21 | dst | provenance | | +| tests.js:40:27:40:29 | dst | tests.js:44:30:44:32 | dst | provenance | | +| tests.js:40:27:40:29 | dst | tests.js:46:13:46:15 | dst | provenance | | +| tests.js:40:32:40:34 | src | tests.js:44:40:44:42 | src | provenance | | +| tests.js:40:32:40:34 | src | tests.js:46:24:46:26 | src | provenance | | +| tests.js:41:14:41:16 | key | tests.js:44:34:44:36 | key | provenance | | +| tests.js:41:14:41:16 | key | tests.js:44:44:44:46 | key | provenance | | +| tests.js:41:14:41:16 | key | tests.js:46:17:46:19 | key | provenance | | +| tests.js:41:14:41:16 | key | tests.js:46:28:46:30 | key | provenance | | +| tests.js:44:30:44:32 | dst | tests.js:44:30:44:37 | dst[key] | provenance | | +| tests.js:44:30:44:37 | dst[key] | tests.js:40:27:40:29 | dst | provenance | | +| tests.js:44:34:44:36 | key | tests.js:44:30:44:37 | dst[key] | provenance | | +| tests.js:44:40:44:42 | src | tests.js:44:40:44:47 | src[key] | provenance | | +| tests.js:44:40:44:47 | src[key] | tests.js:40:32:40:34 | src | provenance | | +| tests.js:44:44:44:46 | key | tests.js:44:40:44:47 | src[key] | provenance | | +| tests.js:46:24:46:26 | src | tests.js:46:24:46:31 | src[key] | provenance | | +| tests.js:46:28:46:30 | key | tests.js:46:24:46:31 | src[key] | provenance | | +| tests.js:51:26:51:28 | dst | tests.js:55:29:55:31 | dst | provenance | | +| tests.js:51:26:51:28 | dst | tests.js:57:13:57:15 | dst | provenance | | +| tests.js:51:31:51:33 | src | tests.js:55:39:55:41 | src | provenance | | +| tests.js:51:31:51:33 | src | tests.js:57:24:57:26 | src | provenance | | +| tests.js:52:14:52:16 | key | tests.js:55:33:55:35 | key | provenance | | +| tests.js:52:14:52:16 | key | tests.js:55:43:55:45 | key | provenance | | +| tests.js:52:14:52:16 | key | tests.js:57:17:57:19 | key | provenance | | +| tests.js:52:14:52:16 | key | tests.js:57:28:57:30 | key | provenance | | +| tests.js:55:29:55:31 | dst | tests.js:55:29:55:36 | dst[key] | provenance | | +| tests.js:55:29:55:36 | dst[key] | tests.js:51:26:51:28 | dst | provenance | | +| tests.js:55:33:55:35 | key | tests.js:55:29:55:36 | dst[key] | provenance | | +| tests.js:55:39:55:41 | src | tests.js:55:39:55:46 | src[key] | provenance | | +| tests.js:55:39:55:46 | src[key] | tests.js:51:31:51:33 | src | provenance | | +| tests.js:55:43:55:45 | key | tests.js:55:39:55:46 | src[key] | provenance | | +| tests.js:57:24:57:26 | src | tests.js:57:24:57:31 | src[key] | provenance | | +| tests.js:57:28:57:30 | key | tests.js:57:24:57:31 | src[key] | provenance | | +| tests.js:62:33:62:35 | src | tests.js:66:41:66:43 | src | provenance | | +| tests.js:62:33:62:35 | src | tests.js:68:24:68:26 | src | provenance | | +| tests.js:66:41:66:43 | src | tests.js:66:41:66:48 | src[key] | provenance | | +| tests.js:66:41:66:48 | src[key] | tests.js:62:33:62:35 | src | provenance | | +| tests.js:68:24:68:26 | src | tests.js:68:24:68:31 | src[key] | provenance | | +| tests.js:77:27:77:29 | src | tests.js:81:39:81:41 | src | provenance | | +| tests.js:77:27:77:29 | src | tests.js:83:28:83:30 | src | provenance | | +| tests.js:81:39:81:41 | src | tests.js:81:39:81:46 | src[key] | provenance | | +| tests.js:81:39:81:46 | src[key] | tests.js:77:27:77:29 | src | provenance | | +| tests.js:83:28:83:30 | src | tests.js:83:28:83:35 | src[key] | provenance | | +| tests.js:89:34:89:36 | src | tests.js:94:42:94:44 | src | provenance | | +| tests.js:89:34:89:36 | src | tests.js:96:24:96:26 | src | provenance | | +| tests.js:90:14:90:16 | key | tests.js:96:17:96:19 | key | provenance | | +| tests.js:90:14:90:16 | key | tests.js:96:28:96:30 | key | provenance | | +| tests.js:94:42:94:44 | src | tests.js:94:42:94:49 | src[key] | provenance | | +| tests.js:94:42:94:49 | src[key] | tests.js:89:34:89:36 | src | provenance | | +| tests.js:96:24:96:26 | src | tests.js:96:24:96:31 | src[key] | provenance | | +| tests.js:96:28:96:30 | key | tests.js:96:24:96:31 | src[key] | provenance | | +| tests.js:101:32:101:34 | dst | tests.js:107:35:107:37 | dst | provenance | | +| tests.js:101:32:101:34 | dst | tests.js:109:13:109:15 | dst | provenance | | +| tests.js:101:37:101:39 | src | tests.js:107:45:107:47 | src | provenance | | +| tests.js:101:37:101:39 | src | tests.js:109:24:109:26 | src | provenance | | +| tests.js:102:14:102:16 | key | tests.js:107:39:107:41 | key | provenance | | +| tests.js:102:14:102:16 | key | tests.js:107:49:107:51 | key | provenance | | +| tests.js:102:14:102:16 | key | tests.js:109:17:109:19 | key | provenance | | +| tests.js:102:14:102:16 | key | tests.js:109:28:109:30 | key | provenance | | +| tests.js:107:35:107:37 | dst | tests.js:107:35:107:42 | dst[key] | provenance | | +| tests.js:107:35:107:42 | dst[key] | tests.js:101:32:101:34 | dst | provenance | | +| tests.js:107:39:107:41 | key | tests.js:107:35:107:42 | dst[key] | provenance | | +| tests.js:107:45:107:47 | src | tests.js:107:45:107:52 | src[key] | provenance | | +| tests.js:107:45:107:52 | src[key] | tests.js:101:37:101:39 | src | provenance | | +| tests.js:107:49:107:51 | key | tests.js:107:45:107:52 | src[key] | provenance | | +| tests.js:109:24:109:26 | src | tests.js:109:24:109:31 | src[key] | provenance | | +| tests.js:109:28:109:30 | key | tests.js:109:24:109:31 | src[key] | provenance | | +| tests.js:116:41:116:43 | src | tests.js:119:49:119:51 | src | provenance | | +| tests.js:116:41:116:43 | src | tests.js:121:24:121:26 | src | provenance | | +| tests.js:117:14:117:16 | key | tests.js:121:17:121:19 | key | provenance | | +| tests.js:117:14:117:16 | key | tests.js:121:28:121:30 | key | provenance | | +| tests.js:119:49:119:51 | src | tests.js:119:49:119:56 | src[key] | provenance | | +| tests.js:119:49:119:56 | src[key] | tests.js:116:41:116:43 | src | provenance | | +| tests.js:121:24:121:26 | src | tests.js:121:24:121:31 | src[key] | provenance | | +| tests.js:121:28:121:30 | key | tests.js:121:24:121:31 | src[key] | provenance | | +| tests.js:149:31:149:33 | dst | tests.js:152:22:152:24 | dst | provenance | | +| tests.js:149:31:149:33 | dst | tests.js:154:13:154:15 | dst | provenance | | +| tests.js:149:36:149:38 | src | tests.js:152:27:152:29 | src | provenance | | +| tests.js:149:36:149:38 | src | tests.js:154:24:154:26 | src | provenance | | +| tests.js:150:14:150:16 | key | tests.js:152:32:152:34 | key | provenance | | +| tests.js:150:14:150:16 | key | tests.js:154:17:154:19 | key | provenance | | +| tests.js:150:14:150:16 | key | tests.js:154:28:154:30 | key | provenance | | +| tests.js:152:22:152:24 | dst | tests.js:160:37:160:39 | dst | provenance | | +| tests.js:152:27:152:29 | src | tests.js:160:42:160:44 | src | provenance | | +| tests.js:152:32:152:34 | key | tests.js:160:47:160:49 | key | provenance | | +| tests.js:154:24:154:26 | src | tests.js:154:24:154:31 | src[key] | provenance | | +| tests.js:154:28:154:30 | key | tests.js:154:24:154:31 | src[key] | provenance | | +| tests.js:159:36:159:38 | dst | tests.js:160:26:160:28 | dst | provenance | | +| tests.js:159:41:159:43 | src | tests.js:160:31:160:33 | src | provenance | | +| tests.js:160:26:160:28 | dst | tests.js:149:31:149:33 | dst | provenance | | +| tests.js:160:31:160:33 | src | tests.js:149:36:149:38 | src | provenance | | +| tests.js:160:37:160:39 | dst | tests.js:161:35:161:37 | dst | provenance | | +| tests.js:160:42:160:44 | src | tests.js:161:45:161:47 | src | provenance | | +| tests.js:160:47:160:49 | key | tests.js:161:39:161:41 | key | provenance | | +| tests.js:160:47:160:49 | key | tests.js:161:49:161:51 | key | provenance | | +| tests.js:161:35:161:37 | dst | tests.js:161:35:161:42 | dst[key] | provenance | | +| tests.js:161:35:161:42 | dst[key] | tests.js:159:36:159:38 | dst | provenance | | +| tests.js:161:39:161:41 | key | tests.js:161:35:161:42 | dst[key] | provenance | | +| tests.js:161:45:161:47 | src | tests.js:161:45:161:52 | src[key] | provenance | | +| tests.js:161:45:161:52 | src[key] | tests.js:159:41:159:43 | src | provenance | | +| tests.js:161:49:161:51 | key | tests.js:161:45:161:52 | src[key] | provenance | | +| tests.js:165:37:165:39 | src | tests.js:169:45:169:47 | src | provenance | | +| tests.js:165:37:165:39 | src | tests.js:171:24:171:26 | src | provenance | | +| tests.js:166:14:166:16 | key | tests.js:169:49:169:51 | key | provenance | | +| tests.js:166:14:166:16 | key | tests.js:171:17:171:19 | key | provenance | | +| tests.js:166:14:166:16 | key | tests.js:171:28:171:30 | key | provenance | | +| tests.js:169:45:169:47 | src | tests.js:169:45:169:52 | src[key] | provenance | | +| tests.js:169:45:169:52 | src[key] | tests.js:165:37:165:39 | src | provenance | | +| tests.js:169:49:169:51 | key | tests.js:169:45:169:52 | src[key] | provenance | | +| tests.js:171:24:171:26 | src | tests.js:171:24:171:31 | src[key] | provenance | | +| tests.js:171:28:171:30 | key | tests.js:171:24:171:31 | src[key] | provenance | | +| tests.js:178:33:178:35 | src | tests.js:182:41:182:43 | src | provenance | | +| tests.js:178:33:178:35 | src | tests.js:184:24:184:26 | src | provenance | | +| tests.js:182:41:182:43 | src | tests.js:182:41:182:48 | src[key] | provenance | | +| tests.js:182:41:182:48 | src[key] | tests.js:178:33:178:35 | src | provenance | | +| tests.js:184:24:184:26 | src | tests.js:184:24:184:31 | src[key] | provenance | | +| tests.js:189:32:189:34 | dst | tests.js:194:35:194:37 | dst | provenance | | +| tests.js:189:32:189:34 | dst | tests.js:196:13:196:15 | dst | provenance | | +| tests.js:189:37:189:39 | src | tests.js:194:45:194:47 | src | provenance | | +| tests.js:189:37:189:39 | src | tests.js:196:24:196:26 | src | provenance | | +| tests.js:192:13:192:25 | key | tests.js:194:39:194:41 | key | provenance | | +| tests.js:192:13:192:25 | key | tests.js:194:49:194:51 | key | provenance | | +| tests.js:192:13:192:25 | key | tests.js:196:17:196:19 | key | provenance | | +| tests.js:192:13:192:25 | key | tests.js:196:28:196:30 | key | provenance | | +| tests.js:192:19:192:25 | keys[i] | tests.js:192:13:192:25 | key | provenance | | +| tests.js:194:35:194:37 | dst | tests.js:194:35:194:42 | dst[key] | provenance | | +| tests.js:194:35:194:42 | dst[key] | tests.js:189:32:189:34 | dst | provenance | | +| tests.js:194:39:194:41 | key | tests.js:194:35:194:42 | dst[key] | provenance | | +| tests.js:194:45:194:47 | src | tests.js:194:45:194:52 | src[key] | provenance | | +| tests.js:194:45:194:52 | src[key] | tests.js:189:37:189:39 | src | provenance | | +| tests.js:194:49:194:51 | key | tests.js:194:45:194:52 | src[key] | provenance | | +| tests.js:196:24:196:26 | src | tests.js:196:24:196:31 | src[key] | provenance | | +| tests.js:196:28:196:30 | key | tests.js:196:24:196:31 | src[key] | provenance | | +| tests.js:201:39:201:41 | dst | tests.js:206:42:206:44 | dst | provenance | | +| tests.js:201:39:201:41 | dst | tests.js:208:13:208:15 | dst | provenance | | +| tests.js:201:44:201:46 | src | tests.js:206:56:206:58 | src | provenance | | +| tests.js:201:44:201:46 | src | tests.js:208:28:208:30 | src | provenance | | +| tests.js:206:42:206:44 | dst | tests.js:206:42:206:53 | dst[keys[i]] | provenance | | +| tests.js:206:42:206:53 | dst[keys[i]] | tests.js:201:39:201:41 | dst | provenance | | +| tests.js:206:46:206:52 | keys[i] | tests.js:206:42:206:53 | dst[keys[i]] | provenance | | +| tests.js:206:56:206:58 | src | tests.js:206:56:206:67 | src[keys[i]] | provenance | | +| tests.js:206:56:206:67 | src[keys[i]] | tests.js:201:44:201:46 | src | provenance | | +| tests.js:206:60:206:66 | keys[i] | tests.js:206:56:206:67 | src[keys[i]] | provenance | | +| tests.js:208:28:208:30 | src | tests.js:208:28:208:39 | src[keys[i]] | provenance | | +| tests.js:208:32:208:38 | keys[i] | tests.js:208:28:208:39 | src[keys[i]] | provenance | | +| tests.js:213:23:213:26 | key1 | tests.js:217:9:217:12 | key1 | provenance | | +| tests.js:213:29:213:32 | key2 | tests.js:217:15:217:18 | key2 | provenance | | +| tests.js:213:35:213:39 | value | tests.js:217:23:217:27 | value | provenance | | +| tests.js:217:9:217:12 | key1 | tests.js:217:5:217:13 | map[key1] | provenance | | +| tests.js:223:14:223:16 | key | tests.js:224:23:224:25 | key | provenance | | +| tests.js:223:14:223:16 | key | tests.js:224:38:224:40 | key | provenance | | +| tests.js:223:14:223:16 | key | tests.js:225:28:225:30 | key | provenance | | +| tests.js:223:14:223:16 | key | tests.js:225:38:225:40 | key | provenance | | +| tests.js:224:23:224:25 | key | tests.js:213:23:213:26 | key1 | provenance | | +| tests.js:224:33:224:41 | data[key] | tests.js:213:35:213:39 | value | provenance | | +| tests.js:224:38:224:40 | key | tests.js:224:33:224:41 | data[key] | provenance | | +| tests.js:225:28:225:30 | key | tests.js:213:29:213:32 | key2 | provenance | | +| tests.js:225:33:225:41 | data[key] | tests.js:213:35:213:39 | value | provenance | | +| tests.js:225:38:225:40 | key | tests.js:225:33:225:41 | data[key] | provenance | | +| tests.js:229:26:229:29 | key1 | tests.js:233:9:233:12 | key1 | provenance | | +| tests.js:229:32:229:35 | key2 | tests.js:233:15:233:18 | key2 | provenance | | +| tests.js:229:38:229:42 | value | tests.js:233:23:233:27 | value | provenance | | +| tests.js:233:9:233:12 | key1 | tests.js:233:5:233:13 | map[key1] | provenance | | +| tests.js:238:14:238:16 | key | tests.js:239:24:239:26 | key | provenance | | +| tests.js:238:14:238:16 | key | tests.js:239:39:239:41 | key | provenance | | +| tests.js:238:14:238:16 | key | tests.js:240:31:240:33 | key | provenance | | +| tests.js:238:14:238:16 | key | tests.js:240:41:240:43 | key | provenance | | +| tests.js:239:24:239:26 | key | tests.js:229:26:229:29 | key1 | provenance | | +| tests.js:239:34:239:42 | data[key] | tests.js:229:38:229:42 | value | provenance | | +| tests.js:239:39:239:41 | key | tests.js:239:34:239:42 | data[key] | provenance | | +| tests.js:240:31:240:33 | key | tests.js:229:32:229:35 | key2 | provenance | | +| tests.js:240:36:240:44 | data[key] | tests.js:229:38:229:42 | value | provenance | | +| tests.js:240:41:240:43 | key | tests.js:240:36:240:44 | data[key] | provenance | | +| tests.js:263:27:263:29 | dst | tests.js:268:30:268:32 | dst | provenance | | +| tests.js:263:27:263:29 | dst | tests.js:270:13:270:15 | dst | provenance | | +| tests.js:265:13:265:26 | key | tests.js:268:34:268:36 | key | provenance | | +| tests.js:265:13:265:26 | key | tests.js:270:17:270:19 | key | provenance | | +| tests.js:265:19:265:26 | entry[0] | tests.js:265:13:265:26 | key | provenance | | +| tests.js:266:13:266:28 | value | tests.js:270:24:270:28 | value | provenance | | +| tests.js:266:21:266:28 | entry[1] | tests.js:266:13:266:28 | value | provenance | | +| tests.js:268:30:268:32 | dst | tests.js:268:30:268:37 | dst[key] | provenance | | +| tests.js:268:30:268:37 | dst[key] | tests.js:263:27:263:29 | dst | provenance | | +| tests.js:268:34:268:36 | key | tests.js:268:30:268:37 | dst[key] | provenance | | +| tests.js:275:27:275:29 | dst | tests.js:278:30:278:32 | dst | provenance | | +| tests.js:275:27:275:29 | dst | tests.js:280:13:280:15 | dst | provenance | | +| tests.js:275:32:275:34 | src | tests.js:276:21:276:23 | src | provenance | | +| tests.js:276:21:276:23 | src | tests.js:278:40:278:42 | src | provenance | | +| tests.js:276:21:276:23 | src | tests.js:280:24:280:26 | src | provenance | | +| tests.js:276:34:276:36 | key | tests.js:278:34:278:36 | key | provenance | | +| tests.js:276:34:276:36 | key | tests.js:278:44:278:46 | key | provenance | | +| tests.js:276:34:276:36 | key | tests.js:280:17:280:19 | key | provenance | | +| tests.js:276:34:276:36 | key | tests.js:280:28:280:30 | key | provenance | | +| tests.js:278:30:278:32 | dst | tests.js:278:30:278:37 | dst[key] | provenance | | +| tests.js:278:30:278:37 | dst[key] | tests.js:275:27:275:29 | dst | provenance | | +| tests.js:278:34:278:36 | key | tests.js:278:30:278:37 | dst[key] | provenance | | +| tests.js:278:40:278:42 | src | tests.js:278:40:278:47 | src[key] | provenance | | +| tests.js:278:40:278:47 | src[key] | tests.js:275:32:275:34 | src | provenance | | +| tests.js:278:44:278:46 | key | tests.js:278:40:278:47 | src[key] | provenance | | +| tests.js:280:24:280:26 | src | tests.js:280:24:280:31 | src[key] | provenance | | +| tests.js:280:28:280:30 | key | tests.js:280:24:280:31 | src[key] | provenance | | +| tests.js:301:27:301:29 | dst | tests.js:306:34:306:36 | dst | provenance | | +| tests.js:301:27:301:29 | dst | tests.js:308:17:308:19 | dst | provenance | | +| tests.js:301:32:301:34 | src | tests.js:304:25:304:27 | src | provenance | | +| tests.js:302:14:302:16 | key | tests.js:304:29:304:31 | key | provenance | | +| tests.js:302:14:302:16 | key | tests.js:306:38:306:40 | key | provenance | | +| tests.js:302:14:302:16 | key | tests.js:308:21:308:23 | key | provenance | | +| tests.js:304:17:304:32 | value | tests.js:306:44:306:48 | value | provenance | | +| tests.js:304:17:304:32 | value | tests.js:306:44:306:48 | value | provenance | | +| tests.js:304:17:304:32 | value | tests.js:308:28:308:32 | value | provenance | | +| tests.js:304:17:304:32 | value | tests.js:308:28:308:32 | value | provenance | | +| tests.js:304:17:304:32 | value | tests.js:308:28:308:32 | value | provenance | | +| tests.js:304:25:304:27 | src | tests.js:304:25:304:32 | src[key] | provenance | | +| tests.js:304:25:304:32 | src[key] | tests.js:304:17:304:32 | value | provenance | | +| tests.js:304:25:304:32 | src[key] | tests.js:304:17:304:32 | value | provenance | | +| tests.js:304:25:304:32 | src[key] | tests.js:304:17:304:32 | value | provenance | | +| tests.js:304:29:304:31 | key | tests.js:304:25:304:32 | src[key] | provenance | | +| tests.js:304:29:304:31 | key | tests.js:304:25:304:32 | src[key] | provenance | | +| tests.js:306:34:306:36 | dst | tests.js:306:34:306:41 | dst[key] | provenance | | +| tests.js:306:34:306:41 | dst[key] | tests.js:301:27:301:29 | dst | provenance | | +| tests.js:306:38:306:40 | key | tests.js:306:34:306:41 | dst[key] | provenance | | +| tests.js:306:44:306:48 | value | tests.js:301:32:301:34 | src | provenance | | +| tests.js:306:44:306:48 | value | tests.js:301:32:301:34 | src | provenance | | +| tests.js:314:31:314:33 | dst | tests.js:320:38:320:40 | dst | provenance | | +| tests.js:314:31:314:33 | dst | tests.js:322:17:322:19 | dst | provenance | | +| tests.js:314:36:314:38 | src | tests.js:318:25:318:27 | src | provenance | | +| tests.js:315:14:315:16 | key | tests.js:318:29:318:31 | key | provenance | | +| tests.js:315:14:315:16 | key | tests.js:320:42:320:44 | key | provenance | | +| tests.js:315:14:315:16 | key | tests.js:322:21:322:23 | key | provenance | | +| tests.js:318:17:318:32 | value | tests.js:320:48:320:52 | value | provenance | | +| tests.js:318:17:318:32 | value | tests.js:320:48:320:52 | value | provenance | | +| tests.js:318:17:318:32 | value | tests.js:322:28:322:32 | value | provenance | | +| tests.js:318:17:318:32 | value | tests.js:322:28:322:32 | value | provenance | | +| tests.js:318:17:318:32 | value | tests.js:322:28:322:32 | value | provenance | | +| tests.js:318:25:318:27 | src | tests.js:318:25:318:32 | src[key] | provenance | | +| tests.js:318:25:318:32 | src[key] | tests.js:318:17:318:32 | value | provenance | | +| tests.js:318:25:318:32 | src[key] | tests.js:318:17:318:32 | value | provenance | | +| tests.js:318:25:318:32 | src[key] | tests.js:318:17:318:32 | value | provenance | | +| tests.js:318:29:318:31 | key | tests.js:318:25:318:32 | src[key] | provenance | | +| tests.js:318:29:318:31 | key | tests.js:318:25:318:32 | src[key] | provenance | | +| tests.js:320:38:320:40 | dst | tests.js:320:38:320:45 | dst[key] | provenance | | +| tests.js:320:38:320:45 | dst[key] | tests.js:314:31:314:33 | dst | provenance | | +| tests.js:320:42:320:44 | key | tests.js:320:38:320:45 | dst[key] | provenance | | +| tests.js:320:48:320:52 | value | tests.js:314:36:314:38 | src | provenance | | +| tests.js:320:48:320:52 | value | tests.js:314:36:314:38 | src | provenance | | +| tests.js:328:25:328:27 | dst | tests.js:336:32:336:34 | dst | provenance | | +| tests.js:328:25:328:27 | dst | tests.js:338:17:338:19 | dst | provenance | | +| tests.js:328:30:328:32 | src | tests.js:336:42:336:44 | src | provenance | | +| tests.js:328:30:328:32 | src | tests.js:338:28:338:30 | src | provenance | | +| tests.js:329:14:329:16 | key | tests.js:336:36:336:38 | key | provenance | | +| tests.js:329:14:329:16 | key | tests.js:336:46:336:48 | key | provenance | | +| tests.js:329:14:329:16 | key | tests.js:338:21:338:23 | key | provenance | | +| tests.js:329:14:329:16 | key | tests.js:338:32:338:34 | key | provenance | | +| tests.js:336:32:336:34 | dst | tests.js:336:32:336:39 | dst[key] | provenance | | +| tests.js:336:32:336:39 | dst[key] | tests.js:328:25:328:27 | dst | provenance | | +| tests.js:336:36:336:38 | key | tests.js:336:32:336:39 | dst[key] | provenance | | +| tests.js:336:42:336:44 | src | tests.js:336:42:336:49 | src[key] | provenance | | +| tests.js:336:42:336:49 | src[key] | tests.js:328:30:328:32 | src | provenance | | +| tests.js:336:46:336:48 | key | tests.js:336:42:336:49 | src[key] | provenance | | +| tests.js:338:28:338:30 | src | tests.js:338:28:338:35 | src[key] | provenance | | +| tests.js:338:32:338:34 | key | tests.js:338:28:338:35 | src[key] | provenance | | +| tests.js:348:32:348:37 | target | tests.js:349:26:349:31 | target | provenance | | +| tests.js:348:32:348:37 | target | tests.js:361:12:361:17 | target | provenance | | +| tests.js:348:40:348:45 | source | tests.js:349:54:349:59 | source | provenance | | +| tests.js:348:40:348:45 | source | tests.js:350:21:350:26 | source | provenance | | +| tests.js:349:26:349:31 | target | tests.js:355:17:355:22 | target | provenance | | +| tests.js:349:26:349:31 | target | tests.js:355:53:355:58 | target | provenance | | +| tests.js:349:26:349:31 | target | tests.js:357:17:357:22 | target | provenance | | +| tests.js:349:26:349:31 | target | tests.js:361:12:361:17 | target | provenance | | +| tests.js:349:54:349:59 | source | tests.js:350:21:350:26 | source | provenance | | +| tests.js:350:21:350:26 | source | tests.js:355:66:355:71 | source | provenance | | +| tests.js:350:21:350:26 | source | tests.js:357:31:357:36 | source | provenance | | +| tests.js:350:37:350:39 | key | tests.js:355:24:355:26 | key | provenance | | +| tests.js:350:37:350:39 | key | tests.js:355:60:355:62 | key | provenance | | +| tests.js:350:37:350:39 | key | tests.js:357:24:357:26 | key | provenance | | +| tests.js:350:37:350:39 | key | tests.js:357:38:357:40 | key | provenance | | +| tests.js:355:53:355:58 | target | tests.js:355:53:355:63 | target[key] | provenance | | +| tests.js:355:53:355:63 | target[key] | tests.js:348:32:348:37 | target | provenance | | +| tests.js:355:53:355:63 | target[key] | tests.js:355:31:355:86 | mergePl ... ptions) | provenance | | +| tests.js:355:60:355:62 | key | tests.js:355:53:355:63 | target[key] | provenance | | +| tests.js:355:66:355:71 | source | tests.js:355:66:355:76 | source[key] | provenance | | +| tests.js:355:66:355:76 | source[key] | tests.js:348:40:348:45 | source | provenance | | +| tests.js:357:31:357:36 | source | tests.js:357:31:357:41 | source[key] | provenance | | +| tests.js:357:38:357:40 | key | tests.js:357:31:357:41 | source[key] | provenance | | +| tests.js:364:41:364:46 | target | tests.js:377:12:377:17 | target | provenance | | +| tests.js:364:49:364:54 | source | tests.js:371:75:371:80 | source | provenance | | +| tests.js:364:49:364:54 | source | tests.js:373:31:373:36 | source | provenance | | +| tests.js:366:18:366:20 | key | tests.js:371:24:371:26 | key | provenance | | +| tests.js:366:18:366:20 | key | tests.js:371:69:371:71 | key | provenance | | +| tests.js:366:18:366:20 | key | tests.js:373:24:373:26 | key | provenance | | +| tests.js:366:18:366:20 | key | tests.js:373:38:373:40 | key | provenance | | +| tests.js:371:62:371:72 | target[key] | tests.js:364:41:364:46 | target | provenance | | +| tests.js:371:62:371:72 | target[key] | tests.js:371:31:371:95 | mergePl ... ptions) | provenance | | +| tests.js:371:69:371:71 | key | tests.js:371:62:371:72 | target[key] | provenance | | +| tests.js:371:75:371:80 | source | tests.js:371:75:371:85 | source[key] | provenance | | +| tests.js:371:75:371:85 | source[key] | tests.js:364:49:364:54 | source | provenance | | +| tests.js:373:31:373:36 | source | tests.js:373:31:373:41 | source[key] | provenance | | +| tests.js:373:38:373:40 | key | tests.js:373:31:373:41 | source[key] | provenance | | +| tests.js:380:22:380:24 | obj | tests.js:383:27:383:29 | obj | provenance | | +| tests.js:380:27:380:34 | callback [dst] | tests.js:383:13:383:20 | callback [dst] | provenance | | +| tests.js:380:27:380:34 | callback [dst] | tests.js:383:13:383:20 | callback [dst] | provenance | | +| tests.js:380:27:380:34 | callback [dst] | tests.js:383:13:383:20 | callback [dst] | provenance | | +| tests.js:380:27:380:34 | callback [dst] | tests.js:383:13:383:20 | callback [dst] | provenance | | +| tests.js:380:27:380:34 | callback [src] | tests.js:383:13:383:20 | callback [src] | provenance | | +| tests.js:381:14:381:16 | key | tests.js:383:22:383:24 | key | provenance | | +| tests.js:381:14:381:16 | key | tests.js:383:31:383:33 | key | provenance | | +| tests.js:383:13:383:20 | callback [dst] | tests.js:391:32:391:34 | dst | provenance | | +| tests.js:383:13:383:20 | callback [dst] | tests.js:391:32:391:34 | dst | provenance | | +| tests.js:383:13:383:20 | callback [dst] | tests.js:393:13:393:15 | dst | provenance | | +| tests.js:383:13:383:20 | callback [dst] | tests.js:393:13:393:15 | dst | provenance | | +| tests.js:383:13:383:20 | callback [dst] | tests.js:401:33:401:35 | dst | provenance | | +| tests.js:383:13:383:20 | callback [dst] | tests.js:401:33:401:35 | dst | provenance | | +| tests.js:383:13:383:20 | callback [dst] | tests.js:403:13:403:15 | dst | provenance | | +| tests.js:383:13:383:20 | callback [dst] | tests.js:403:13:403:15 | dst | provenance | | +| tests.js:383:13:383:20 | callback [src] | tests.js:391:42:391:44 | src | provenance | | +| tests.js:383:13:383:20 | callback [src] | tests.js:393:24:393:26 | src | provenance | | +| tests.js:383:22:383:24 | key | tests.js:389:22:389:24 | key | provenance | | +| tests.js:383:22:383:24 | key | tests.js:399:23:399:25 | key | provenance | | +| tests.js:383:27:383:29 | obj | tests.js:383:27:383:34 | obj[key] | provenance | | +| tests.js:383:27:383:34 | obj[key] | tests.js:399:28:399:32 | value | provenance | | +| tests.js:383:31:383:33 | key | tests.js:383:27:383:34 | obj[key] | provenance | | +| tests.js:388:29:388:31 | dst | tests.js:380:27:380:34 | callback [dst] | provenance | | +| tests.js:388:29:388:31 | dst | tests.js:380:27:380:34 | callback [dst] | provenance | | +| tests.js:388:29:388:31 | dst | tests.js:391:32:391:34 | dst | provenance | | +| tests.js:388:29:388:31 | dst | tests.js:391:32:391:34 | dst | provenance | | +| tests.js:388:29:388:31 | dst | tests.js:393:13:393:15 | dst | provenance | | +| tests.js:388:29:388:31 | dst | tests.js:393:13:393:15 | dst | provenance | | +| tests.js:388:34:388:36 | src | tests.js:389:17:389:19 | src | provenance | | +| tests.js:389:17:389:19 | src | tests.js:380:27:380:34 | callback [src] | provenance | | +| tests.js:389:17:389:19 | src | tests.js:391:42:391:44 | src | provenance | | +| tests.js:389:17:389:19 | src | tests.js:393:24:393:26 | src | provenance | | +| tests.js:389:22:389:24 | key | tests.js:391:36:391:38 | key | provenance | | +| tests.js:389:22:389:24 | key | tests.js:391:46:391:48 | key | provenance | | +| tests.js:389:22:389:24 | key | tests.js:393:17:393:19 | key | provenance | | +| tests.js:389:22:389:24 | key | tests.js:393:28:393:30 | key | provenance | | +| tests.js:391:32:391:34 | dst | tests.js:391:32:391:39 | dst[key] | provenance | | +| tests.js:391:32:391:34 | dst | tests.js:391:32:391:39 | dst[key] | provenance | | +| tests.js:391:32:391:39 | dst[key] | tests.js:388:29:388:31 | dst | provenance | | +| tests.js:391:32:391:39 | dst[key] | tests.js:388:29:388:31 | dst | provenance | | +| tests.js:391:36:391:38 | key | tests.js:391:32:391:39 | dst[key] | provenance | | +| tests.js:391:36:391:38 | key | tests.js:391:32:391:39 | dst[key] | provenance | | +| tests.js:391:42:391:44 | src | tests.js:391:42:391:49 | src[key] | provenance | | +| tests.js:391:42:391:49 | src[key] | tests.js:388:34:388:36 | src | provenance | | +| tests.js:391:46:391:48 | key | tests.js:391:42:391:49 | src[key] | provenance | | +| tests.js:393:24:393:26 | src | tests.js:393:24:393:31 | src[key] | provenance | | +| tests.js:393:28:393:30 | key | tests.js:393:24:393:31 | src[key] | provenance | | +| tests.js:398:30:398:32 | dst | tests.js:380:27:380:34 | callback [dst] | provenance | | +| tests.js:398:30:398:32 | dst | tests.js:380:27:380:34 | callback [dst] | provenance | | +| tests.js:398:30:398:32 | dst | tests.js:401:33:401:35 | dst | provenance | | +| tests.js:398:30:398:32 | dst | tests.js:401:33:401:35 | dst | provenance | | +| tests.js:398:30:398:32 | dst | tests.js:403:13:403:15 | dst | provenance | | +| tests.js:398:30:398:32 | dst | tests.js:403:13:403:15 | dst | provenance | | +| tests.js:398:35:398:37 | src | tests.js:399:17:399:19 | src | provenance | | +| tests.js:399:17:399:19 | src | tests.js:380:22:380:24 | obj | provenance | | +| tests.js:399:23:399:25 | key | tests.js:401:37:401:39 | key | provenance | | +| tests.js:399:23:399:25 | key | tests.js:403:17:403:19 | key | provenance | | +| tests.js:399:28:399:32 | value | tests.js:401:43:401:47 | value | provenance | | +| tests.js:399:28:399:32 | value | tests.js:403:24:403:28 | value | provenance | | +| tests.js:401:33:401:35 | dst | tests.js:401:33:401:40 | dst[key] | provenance | | +| tests.js:401:33:401:35 | dst | tests.js:401:33:401:40 | dst[key] | provenance | | +| tests.js:401:33:401:40 | dst[key] | tests.js:398:30:398:32 | dst | provenance | | +| tests.js:401:33:401:40 | dst[key] | tests.js:398:30:398:32 | dst | provenance | | +| tests.js:401:37:401:39 | key | tests.js:401:33:401:40 | dst[key] | provenance | | +| tests.js:401:37:401:39 | key | tests.js:401:33:401:40 | dst[key] | provenance | | +| tests.js:401:43:401:47 | value | tests.js:398:35:398:37 | src | provenance | | +| tests.js:408:22:408:24 | obj | tests.js:409:12:409:14 | obj | provenance | | +| tests.js:408:27:408:29 | key | tests.js:409:16:409:18 | key | provenance | | +| tests.js:409:12:409:14 | obj | tests.js:409:12:409:19 | obj[key] | provenance | | +| tests.js:409:16:409:18 | key | tests.js:409:12:409:19 | obj[key] | provenance | | +| tests.js:412:31:412:33 | dst | tests.js:415:34:415:36 | dst | provenance | | +| tests.js:412:31:412:33 | dst | tests.js:419:13:419:15 | dst | provenance | | +| tests.js:412:36:412:38 | src | tests.js:414:33:414:35 | src | provenance | | +| tests.js:413:14:413:16 | key | tests.js:414:38:414:40 | key | provenance | | +| tests.js:413:14:413:16 | key | tests.js:415:39:415:41 | key | provenance | | +| tests.js:413:14:413:16 | key | tests.js:419:17:419:19 | key | provenance | | +| tests.js:414:13:414:41 | value | tests.js:417:42:417:46 | value | provenance | | +| tests.js:414:13:414:41 | value | tests.js:419:24:419:28 | value | provenance | | +| tests.js:414:21:414:41 | wrapped ... c, key) | tests.js:414:13:414:41 | value | provenance | | +| tests.js:414:33:414:35 | src | tests.js:408:22:408:24 | obj | provenance | | +| tests.js:414:33:414:35 | src | tests.js:414:21:414:41 | wrapped ... c, key) | provenance | | +| tests.js:414:38:414:40 | key | tests.js:408:27:408:29 | key | provenance | | +| tests.js:414:38:414:40 | key | tests.js:414:21:414:41 | wrapped ... c, key) | provenance | | +| tests.js:415:13:415:42 | target | tests.js:417:34:417:39 | target | provenance | | +| tests.js:415:22:415:42 | wrapped ... t, key) | tests.js:415:13:415:42 | target | provenance | | +| tests.js:415:34:415:36 | dst | tests.js:408:22:408:24 | obj | provenance | | +| tests.js:415:34:415:36 | dst | tests.js:415:22:415:42 | wrapped ... t, key) | provenance | | +| tests.js:415:39:415:41 | key | tests.js:408:27:408:29 | key | provenance | | +| tests.js:415:39:415:41 | key | tests.js:415:22:415:42 | wrapped ... t, key) | provenance | | +| tests.js:417:34:417:39 | target | tests.js:412:31:412:33 | dst | provenance | | +| tests.js:417:42:417:46 | value | tests.js:412:36:412:38 | src | provenance | | +| tests.js:424:25:424:27 | obj | tests.js:426:12:426:14 | obj | provenance | | +| tests.js:424:30:424:32 | key | tests.js:426:16:426:18 | key | provenance | | +| tests.js:426:12:426:14 | obj | tests.js:426:12:426:19 | obj[key] | provenance | | +| tests.js:426:16:426:18 | key | tests.js:426:12:426:19 | obj[key] | provenance | | +| tests.js:429:34:429:36 | dst | tests.js:432:37:432:39 | dst | provenance | | +| tests.js:429:34:429:36 | dst | tests.js:436:13:436:15 | dst | provenance | | +| tests.js:429:39:429:41 | src | tests.js:431:36:431:38 | src | provenance | | +| tests.js:430:14:430:16 | key | tests.js:431:41:431:43 | key | provenance | | +| tests.js:430:14:430:16 | key | tests.js:432:42:432:44 | key | provenance | | +| tests.js:430:14:430:16 | key | tests.js:436:17:436:19 | key | provenance | | +| tests.js:431:13:431:44 | value | tests.js:434:45:434:49 | value | provenance | | +| tests.js:431:13:431:44 | value | tests.js:436:24:436:28 | value | provenance | | +| tests.js:431:21:431:44 | almostS ... c, key) | tests.js:431:13:431:44 | value | provenance | | +| tests.js:431:36:431:38 | src | tests.js:424:25:424:27 | obj | provenance | | +| tests.js:431:36:431:38 | src | tests.js:431:21:431:44 | almostS ... c, key) | provenance | | +| tests.js:431:41:431:43 | key | tests.js:424:30:424:32 | key | provenance | | +| tests.js:431:41:431:43 | key | tests.js:431:21:431:44 | almostS ... c, key) | provenance | | +| tests.js:432:13:432:45 | target | tests.js:434:37:434:42 | target | provenance | | +| tests.js:432:22:432:45 | almostS ... t, key) | tests.js:432:13:432:45 | target | provenance | | +| tests.js:432:37:432:39 | dst | tests.js:424:25:424:27 | obj | provenance | | +| tests.js:432:37:432:39 | dst | tests.js:432:22:432:45 | almostS ... t, key) | provenance | | +| tests.js:432:42:432:44 | key | tests.js:424:30:424:32 | key | provenance | | +| tests.js:432:42:432:44 | key | tests.js:432:22:432:45 | almostS ... t, key) | provenance | | +| tests.js:434:37:434:42 | target | tests.js:429:34:429:36 | dst | provenance | | +| tests.js:434:45:434:49 | value | tests.js:429:39:429:41 | src | provenance | | +| tests.js:441:19:441:21 | obj | tests.js:443:12:443:14 | obj | provenance | | +| tests.js:443:12:443:14 | obj | tests.js:443:12:443:19 | obj[key] | provenance | | +| tests.js:446:33:446:35 | src | tests.js:448:30:448:32 | src | provenance | | +| tests.js:447:14:447:16 | key | tests.js:453:17:453:19 | key | provenance | | +| tests.js:448:13:448:38 | value | tests.js:451:39:451:43 | value | provenance | | +| tests.js:448:13:448:38 | value | tests.js:453:24:453:28 | value | provenance | | +| tests.js:448:21:448:38 | safeRead(src, key) | tests.js:448:13:448:38 | value | provenance | | +| tests.js:448:30:448:32 | src | tests.js:441:19:441:21 | obj | provenance | | +| tests.js:448:30:448:32 | src | tests.js:448:21:448:38 | safeRead(src, key) | provenance | | +| tests.js:451:39:451:43 | value | tests.js:446:33:446:35 | src | provenance | | +| tests.js:458:26:458:28 | dst | tests.js:462:29:462:31 | dst | provenance | | +| tests.js:458:26:458:28 | dst | tests.js:465:30:465:32 | dst | provenance | | +| tests.js:458:26:458:28 | dst | tests.js:466:30:466:32 | dst | provenance | | +| tests.js:458:26:458:28 | dst | tests.js:467:30:467:32 | dst | provenance | | +| tests.js:458:31:458:33 | src | tests.js:460:12:460:14 | src | provenance | | +| tests.js:460:12:460:14 | src | tests.js:462:39:462:41 | src | provenance | | +| tests.js:460:12:460:14 | src | tests.js:465:41:465:43 | src | provenance | | +| tests.js:460:18:460:22 | value | tests.js:467:41:467:45 | value | provenance | | +| tests.js:460:25:460:27 | key | tests.js:462:33:462:35 | key | provenance | | +| tests.js:460:25:460:27 | key | tests.js:462:43:462:45 | key | provenance | | +| tests.js:460:25:460:27 | key | tests.js:465:34:465:36 | key | provenance | | +| tests.js:460:25:460:27 | key | tests.js:465:45:465:47 | key | provenance | | +| tests.js:460:25:460:27 | key | tests.js:466:34:466:36 | key | provenance | | +| tests.js:460:25:460:27 | key | tests.js:466:43:466:45 | key | provenance | | +| tests.js:460:25:460:27 | key | tests.js:467:34:467:36 | key | provenance | | +| tests.js:462:29:462:31 | dst | tests.js:462:29:462:36 | dst[key] | provenance | | +| tests.js:462:29:462:36 | dst[key] | tests.js:458:26:458:28 | dst | provenance | | +| tests.js:462:33:462:35 | key | tests.js:462:29:462:36 | dst[key] | provenance | | +| tests.js:462:39:462:41 | src | tests.js:462:39:462:46 | src[key] | provenance | | +| tests.js:462:39:462:46 | src[key] | tests.js:458:31:458:33 | src | provenance | | +| tests.js:462:43:462:45 | key | tests.js:462:39:462:46 | src[key] | provenance | | +| tests.js:465:41:465:43 | src | tests.js:465:41:465:48 | src[key] | provenance | | +| tests.js:465:45:465:47 | key | tests.js:465:41:465:48 | src[key] | provenance | | +| tests.js:466:43:466:45 | key | tests.js:466:41:466:46 | o[key] | provenance | | +| tests.js:472:38:472:40 | dst | tests.js:475:41:475:43 | dst | provenance | | +| tests.js:472:38:472:40 | dst | tests.js:477:13:477:15 | dst | provenance | | +| tests.js:473:18:473:22 | value | tests.js:477:24:477:28 | value | provenance | | +| tests.js:473:25:473:27 | key | tests.js:475:45:475:47 | key | provenance | | +| tests.js:473:25:473:27 | key | tests.js:477:17:477:19 | key | provenance | | +| tests.js:475:41:475:43 | dst | tests.js:475:41:475:48 | dst[key] | provenance | | +| tests.js:475:41:475:48 | dst[key] | tests.js:472:38:472:40 | dst | provenance | | +| tests.js:475:45:475:47 | key | tests.js:475:41:475:48 | dst[key] | provenance | | +| tests.js:483:26:483:28 | dst | tests.js:487:29:487:31 | dst | provenance | | +| tests.js:483:26:483:28 | dst | tests.js:489:13:489:15 | dst | provenance | | +| tests.js:483:31:483:33 | src | tests.js:487:39:487:41 | src | provenance | | +| tests.js:483:31:483:33 | src | tests.js:489:24:489:26 | src | provenance | | +| tests.js:483:31:483:33 | src | tests.js:489:24:489:26 | src | provenance | | +| tests.js:484:14:484:16 | key | tests.js:487:33:487:35 | key | provenance | | +| tests.js:484:14:484:16 | key | tests.js:487:43:487:45 | key | provenance | | +| tests.js:484:14:484:16 | key | tests.js:489:17:489:19 | key | provenance | | +| tests.js:484:14:484:16 | key | tests.js:489:28:489:30 | key | provenance | | +| tests.js:487:29:487:31 | dst | tests.js:487:29:487:36 | dst[key] | provenance | | +| tests.js:487:29:487:36 | dst[key] | tests.js:483:26:483:28 | dst | provenance | | +| tests.js:487:33:487:35 | key | tests.js:487:29:487:36 | dst[key] | provenance | | +| tests.js:487:39:487:41 | src | tests.js:487:39:487:46 | src[key] | provenance | | +| tests.js:487:39:487:46 | src[key] | tests.js:483:31:483:33 | src | provenance | | +| tests.js:487:39:487:46 | src[key] | tests.js:483:31:483:33 | src | provenance | | +| tests.js:487:39:487:46 | src[key] | tests.js:483:31:483:33 | src | provenance | | +| tests.js:487:43:487:45 | key | tests.js:487:39:487:46 | src[key] | provenance | | +| tests.js:489:24:489:26 | src | tests.js:489:24:489:31 | src[key] | provenance | | +| tests.js:489:28:489:30 | key | tests.js:489:24:489:31 | src[key] | provenance | | +| tests.js:494:32:494:34 | src | tests.js:498:21:498:23 | src | provenance | | +| tests.js:495:14:495:16 | key | tests.js:498:25:498:27 | key | provenance | | +| tests.js:495:14:495:16 | key | tests.js:502:17:502:19 | key | provenance | | +| tests.js:498:13:498:28 | value | tests.js:500:38:500:42 | value | provenance | | +| tests.js:498:13:498:28 | value | tests.js:500:38:500:42 | value | provenance | | +| tests.js:498:13:498:28 | value | tests.js:502:24:502:28 | value | provenance | | +| tests.js:498:13:498:28 | value | tests.js:502:24:502:28 | value | provenance | | +| tests.js:498:13:498:28 | value | tests.js:502:24:502:28 | value | provenance | | +| tests.js:498:21:498:23 | src | tests.js:498:21:498:28 | src[key] | provenance | | +| tests.js:498:21:498:28 | src[key] | tests.js:498:13:498:28 | value | provenance | | +| tests.js:498:21:498:28 | src[key] | tests.js:498:13:498:28 | value | provenance | | +| tests.js:498:21:498:28 | src[key] | tests.js:498:13:498:28 | value | provenance | | +| tests.js:498:25:498:27 | key | tests.js:498:21:498:28 | src[key] | provenance | | +| tests.js:500:38:500:42 | value | tests.js:494:32:494:34 | src | provenance | | +| tests.js:500:38:500:42 | value | tests.js:494:32:494:34 | src | provenance | | +| tests.js:508:30:508:32 | dst | tests.js:513:33:513:35 | dst | provenance | | +| tests.js:508:30:508:32 | dst | tests.js:517:35:517:37 | dst | provenance | | +| tests.js:508:35:508:37 | src | tests.js:513:43:513:45 | src | provenance | | +| tests.js:508:35:508:37 | src | tests.js:516:32:516:34 | src | provenance | | +| tests.js:511:13:511:25 | key | tests.js:513:37:513:39 | key | provenance | | +| tests.js:511:13:511:25 | key | tests.js:513:47:513:49 | key | provenance | | +| tests.js:511:13:511:25 | key | tests.js:516:36:516:38 | key | provenance | | +| tests.js:511:13:511:25 | key | tests.js:517:40:517:42 | key | provenance | | +| tests.js:511:19:511:25 | keys[i] | tests.js:511:13:511:25 | key | provenance | | +| tests.js:513:33:513:35 | dst | tests.js:513:33:513:40 | dst[key] | provenance | | +| tests.js:513:33:513:40 | dst[key] | tests.js:508:30:508:32 | dst | provenance | | +| tests.js:513:37:513:39 | key | tests.js:513:33:513:40 | dst[key] | provenance | | +| tests.js:513:43:513:45 | src | tests.js:513:43:513:50 | src[key] | provenance | | +| tests.js:513:43:513:50 | src[key] | tests.js:508:35:508:37 | src | provenance | | +| tests.js:513:47:513:49 | key | tests.js:513:43:513:50 | src[key] | provenance | | +| tests.js:516:32:516:34 | src | tests.js:516:32:516:39 | src[key] | provenance | | +| tests.js:516:36:516:38 | key | tests.js:516:32:516:39 | src[key] | provenance | | +| tests.js:525:14:525:16 | key | tests.js:529:17:529:19 | key | provenance | | +| tests.js:525:14:525:16 | key | tests.js:529:28:529:30 | key | provenance | | +| tests.js:529:28:529:30 | key | tests.js:529:24:529:31 | src[key] | provenance | | +| tests.js:534:31:534:33 | obj | tests.js:538:27:538:29 | obj | provenance | | +| tests.js:534:36:534:43 | callback [dst] | tests.js:538:9:538:16 | callback [dst] | provenance | | +| tests.js:538:9:538:16 | callback [dst] | tests.js:545:33:545:35 | dst | provenance | | +| tests.js:538:9:538:16 | callback [dst] | tests.js:547:13:547:15 | dst | provenance | | +| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key | provenance | | +| tests.js:538:27:538:29 | obj | tests.js:538:27:538:38 | obj[keys[i]] | provenance | | +| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value | provenance | | +| tests.js:538:31:538:37 | keys[i] | tests.js:538:27:538:38 | obj[keys[i]] | provenance | | +| tests.js:542:30:542:32 | dst | tests.js:534:36:534:43 | callback [dst] | provenance | | +| tests.js:542:30:542:32 | dst | tests.js:545:33:545:35 | dst | provenance | | +| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst | provenance | | +| tests.js:542:35:542:37 | src | tests.js:543:26:543:28 | src | provenance | | +| tests.js:543:26:543:28 | src | tests.js:534:31:534:33 | obj | provenance | | +| tests.js:543:32:543:34 | key | tests.js:545:37:545:39 | key | provenance | | +| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key | provenance | | +| tests.js:543:37:543:41 | value | tests.js:545:43:545:47 | value | provenance | | +| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value | provenance | | +| tests.js:545:33:545:35 | dst | tests.js:545:33:545:40 | dst[key] | provenance | | +| tests.js:545:33:545:40 | dst[key] | tests.js:542:30:542:32 | dst | provenance | | +| tests.js:545:37:545:39 | key | tests.js:545:33:545:40 | dst[key] | provenance | | +| tests.js:545:43:545:47 | value | tests.js:542:35:542:37 | src | provenance | | +| tests.js:552:35:552:37 | src | tests.js:557:43:557:45 | src | provenance | | +| tests.js:552:35:552:37 | src | tests.js:559:24:559:26 | src | provenance | | +| tests.js:553:14:553:16 | key | tests.js:559:17:559:19 | key | provenance | | +| tests.js:553:14:553:16 | key | tests.js:559:28:559:30 | key | provenance | | +| tests.js:557:43:557:45 | src | tests.js:557:43:557:50 | src[key] | provenance | | +| tests.js:557:43:557:50 | src[key] | tests.js:552:35:552:37 | src | provenance | | +| tests.js:559:24:559:26 | src | tests.js:559:24:559:31 | src[key] | provenance | | +| tests.js:559:28:559:30 | key | tests.js:559:24:559:31 | src[key] | provenance | | +| tests.js:564:35:564:37 | src | tests.js:569:43:569:45 | src | provenance | | +| tests.js:564:35:564:37 | src | tests.js:571:24:571:26 | src | provenance | | +| tests.js:565:14:565:16 | key | tests.js:571:17:571:19 | key | provenance | | +| tests.js:565:14:565:16 | key | tests.js:571:28:571:30 | key | provenance | | +| tests.js:569:43:569:45 | src | tests.js:569:43:569:50 | src[key] | provenance | | +| tests.js:569:43:569:50 | src[key] | tests.js:564:35:564:37 | src | provenance | | +| tests.js:571:24:571:26 | src | tests.js:571:24:571:31 | src[key] | provenance | | +| tests.js:571:28:571:30 | key | tests.js:571:24:571:31 | src[key] | provenance | | +| tests.js:576:30:576:32 | src | tests.js:580:38:580:40 | src | provenance | | +| tests.js:576:30:576:32 | src | tests.js:582:24:582:26 | src | provenance | | +| tests.js:577:14:577:16 | key | tests.js:582:17:582:19 | key | provenance | | +| tests.js:577:14:577:16 | key | tests.js:582:28:582:30 | key | provenance | | +| tests.js:580:38:580:40 | src | tests.js:580:38:580:45 | src[key] | provenance | | +| tests.js:580:38:580:45 | src[key] | tests.js:576:30:576:32 | src | provenance | | +| tests.js:582:24:582:26 | src | tests.js:582:24:582:31 | src[key] | provenance | | +| tests.js:582:28:582:30 | key | tests.js:582:24:582:31 | src[key] | provenance | | +| tests.js:591:25:591:27 | obj | tests.js:592:7:592:9 | obj | provenance | | +| tests.js:591:25:591:27 | obj | tests.js:592:21:592:23 | obj | provenance | | +| tests.js:592:7:592:9 | obj | tests.js:592:21:592:23 | obj | provenance | | +| tests.js:592:7:592:9 | obj | tests.js:593:10:593:12 | obj | provenance | | +| tests.js:592:21:592:23 | obj | tests.js:593:10:593:12 | obj | provenance | | +| tests.js:600:31:600:34 | dest | tests.js:603:34:603:37 | dest | provenance | | +| tests.js:600:31:600:34 | dest | tests.js:605:13:605:16 | dest | provenance | | +| tests.js:600:37:600:42 | source | tests.js:603:45:603:50 | source | provenance | | +| tests.js:600:37:600:42 | source | tests.js:605:40:605:45 | source | provenance | | +| tests.js:601:16:601:18 | key | tests.js:603:39:603:41 | key | provenance | | +| tests.js:601:16:601:18 | key | tests.js:603:52:603:54 | key | provenance | | +| tests.js:601:16:601:18 | key | tests.js:605:18:605:20 | key | provenance | | +| tests.js:601:16:601:18 | key | tests.js:605:47:605:49 | key | provenance | | +| tests.js:603:34:603:37 | dest | tests.js:603:34:603:42 | dest[key] | provenance | | +| tests.js:603:34:603:42 | dest[key] | tests.js:600:31:600:34 | dest | provenance | | +| tests.js:603:39:603:41 | key | tests.js:603:34:603:42 | dest[key] | provenance | | +| tests.js:603:45:603:50 | source | tests.js:603:45:603:55 | source[key] | provenance | | +| tests.js:603:45:603:55 | source[key] | tests.js:600:37:600:42 | source | provenance | | +| tests.js:603:52:603:54 | key | tests.js:603:45:603:55 | source[key] | provenance | | +| tests.js:605:40:605:45 | source | tests.js:605:40:605:50 | source[key] | provenance | | +| tests.js:605:40:605:50 | source[key] | tests.js:591:25:591:27 | obj | provenance | | +| tests.js:605:40:605:50 | source[key] | tests.js:605:25:605:51 | capture ... e[key]) | provenance | | +| tests.js:605:47:605:49 | key | tests.js:605:40:605:50 | source[key] | provenance | | subpaths | tests.js:355:53:355:63 | target[key] | tests.js:348:32:348:37 | target | tests.js:361:12:361:17 | target | tests.js:355:31:355:86 | mergePl ... ptions) | | tests.js:371:62:371:72 | target[key] | tests.js:364:41:364:46 | target | tests.js:377:12:377:17 | target | tests.js:371:31:371:95 | mergePl ... ptions) | From 102ca77acfa2afe84446abcb1e3214f7c5a98f11 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 25 Jun 2024 11:49:19 +0200 Subject: [PATCH 195/514] Switch to getLocation() in DataFlowCall --- .../dataflow/internal/DataFlowPrivate.qll | 36 ++++--------------- 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 330b0a59038..1e7e917695a 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -478,11 +478,7 @@ class DataFlowCall extends TDataFlowCall { this = MkSummaryCall(enclosingCallable, receiver) } - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - none() // Overridden in subclass - } + Location getLocation() { none() } // Overridden in subclass } private class OrdinaryCall extends DataFlowCall, MkOrdinaryCall { @@ -498,11 +494,7 @@ private class OrdinaryCall extends DataFlowCall, MkOrdinaryCall { override string toString() { result = node.toString() } - override predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - node.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } + override Location getLocation() { result = node.getLocation() } } private class PartialCall extends DataFlowCall, MkPartialCall { @@ -521,11 +513,7 @@ private class PartialCall extends DataFlowCall, MkPartialCall { override string toString() { result = node.toString() + " (as partial invocation)" } - override predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - node.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } + override Location getLocation() { result = node.getLocation() } } private class BoundCall extends DataFlowCall, MkBoundCall { @@ -542,11 +530,7 @@ private class BoundCall extends DataFlowCall, MkBoundCall { result = node.toString() + " (as call with " + boundArgs + " bound arguments)" } - override predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - node.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } + override Location getLocation() { result = node.getLocation() } } private class AccessorCall extends DataFlowCall, MkAccessorCall { @@ -560,11 +544,7 @@ private class AccessorCall extends DataFlowCall, MkAccessorCall { override string toString() { result = ref.toString() + " (as accessor call)" } - override predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - ref.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } + override Location getLocation() { result = ref.getLocation() } } class SummaryCall extends DataFlowCall, MkSummaryCall { @@ -598,11 +578,7 @@ private class ImpliedLambdaCall extends DataFlowCall, MkImpliedLambdaCall { override string toString() { result = "[implied lambda call] " + function } - override predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - function.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } + override Location getLocation() { result = function.getLocation() } override DataFlowCallable getEnclosingCallable() { result.asSourceCallable() = function.getEnclosingContainer() From 505c532af706433a4c598799eb6538b4b26368ea Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 25 Jun 2024 12:58:35 +0200 Subject: [PATCH 196/514] JS: Implement totalorder() --- .../dataflow/internal/DataFlowPrivate.qll | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 1e7e917695a..3d49e74a44e 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -196,6 +196,12 @@ class DataFlowCallable extends TDataFlowCallable { /** Gets the corresponding `LibraryCallable` if this is a library callable. */ LibraryCallable asLibraryCallable() { this = MkLibraryCallable(result) } + + int totalorder() { + result = TotalOrdering::astNodeId(this.asSourceCallable()).bitShiftLeft(1) + or + result = TotalOrdering::libraryCallableId(this.asLibraryCallable()).bitShiftLeft(1) + 1 + } } /** A callable defined in library code, identified by a unique string. */ @@ -456,6 +462,47 @@ private newtype TDataFlowCall = FlowSummaryImpl::Private::summaryCallbackRange(c, receiver) } +private module TotalOrdering { + private predicate astNodeRefl(AstNode x, AstNode y) { x = y } + + int astNodeId(AstNode n) = equivalenceRelation(astNodeRefl/2)(n, result) + + predicate dataFlowNodeId(DataFlow::Node node, int cls, int content) { + exists(AstNode n | + node = TValueNode(n) and cls = 1 and content = astNodeId(n) + or + node = TReflectiveCallNode(n, _) and cls = 2 and content = astNodeId(n) + ) + } + + predicate callId(DataFlowCall call, int cls, int child, int extra) { + exists(DataFlow::Node node | + call = MkOrdinaryCall(node) and dataFlowNodeId(node, cls - 1000, child) and extra = 0 + or + call = MkPartialCall(node, _) and dataFlowNodeId(node, cls - 2000, child) and extra = 0 + or + call = MkBoundCall(node, extra) and dataFlowNodeId(node, cls - 3000, child) + or + call = MkAccessorCall(node) and dataFlowNodeId(node, cls - 4000, child) and extra = 0 + ) + or + exists(Function f | + call = MkImpliedLambdaCall(f) and cls = 5000 and child = astNodeId(f) and extra = 0 + ) + or + exists( + FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver + | + call = MkSummaryCall(c, receiver) and + cls = 6000 and + c = rank[child](FlowSummaryImpl::Public::SummarizedCallable cs) and + extra = 0 + ) + } + + int libraryCallableId(LibraryCallable callable) { callable = rank[result](LibraryCallable c) } +} + class DataFlowCall extends TDataFlowCall { DataFlowCallable getEnclosingCallable() { none() } // Overridden in subclass @@ -479,6 +526,15 @@ class DataFlowCall extends TDataFlowCall { } Location getLocation() { none() } // Overridden in subclass + + int totalorder() { + this = + rank[result](DataFlowCall call, int x, int y, int z | + TotalOrdering::callId(call, x, y, z) + | + call order by x, y, z + ) + } } private class OrdinaryCall extends DataFlowCall, MkOrdinaryCall { From 64a9598b8934948e9b6ea9092a891c0a379a2cee Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 25 Jun 2024 13:00:47 +0200 Subject: [PATCH 197/514] JS: Update interface for isUnreachableInCall --- .../javascript/dataflow/internal/DataFlowPrivate.qll | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 3d49e74a44e..0a477ebcdbc 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1009,10 +1009,19 @@ predicate expectsContent(Node n, ContentSet c) { any(AdditionalFlowInternal flow).expectsContent(n, c) } +abstract class NodeRegion extends Unit { + NodeRegion() { none() } + + /** Holds if this region contains `n`. */ + predicate contains(Node n) { none() } + + int totalOrder() { none() } +} + /** * Holds if the node `n` is unreachable when the call context is `call`. */ -predicate isUnreachableInCall(Node n, DataFlowCall call) { +predicate isUnreachableInCall(NodeRegion n, DataFlowCall call) { none() // TODO: could be useful, but not currently implemented for JS } From 6c8fb61f60bf142f3a67a5b35d44bcb011bf6e99 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 25 Jun 2024 13:10:24 +0200 Subject: [PATCH 198/514] Js: Update FlowSummaryImpl.qll to make things compile --- .../dataflow/internal/sharedlib/FlowSummaryImpl.qll | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll index 6671fc229bc..4d4c0bad4b0 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll @@ -1276,10 +1276,12 @@ module Private { c = "Argument" or parseArg(c, ppos) ) or - exists(ReturnNodeExt ret | + exists( + ReturnNode ret // TODO: hacked to make this compile; need to switch to module in qlpack + | c = "ReturnValue" and ret = node.asNode() and - ret.getKind().(ValueReturnKind).getKind() = getReturnValueKind() and + ret.getKind() = getReturnValueKind() and mid.asCallable() = getNodeEnclosingCallable(ret) ) or From 6e32f27652013d52ff55e3545063aa7eccdc864d Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 25 Jun 2024 13:30:33 +0200 Subject: [PATCH 199/514] Rename predicates to be consistent with qlpack In preparation for migrating to the FlowSummary module in the qlpack, rename predicates to be consistent with the qlpack. --- .../ql/lib/semmle/javascript/dataflow/FlowSummary.qll | 2 +- .../javascript/dataflow/internal/FlowSummaryPrivate.qll | 8 ++++++-- .../dataflow/internal/sharedlib/FlowSummaryImpl.qll | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll b/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll index 426f8b75851..8c5c6479c10 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll @@ -84,7 +84,7 @@ abstract class SummarizedCallable extends LibraryCallable, Impl::Public::Summari DataFlow::ParameterNode getParameter(string s) { exists(ParameterPosition pos | DataFlowImplCommon::parameterNode(result, MkLibraryCallable(this), pos) and - s = getParameterPosition(pos) + s = encodeParameterPosition(pos) ) } } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index 58ab67ec8a7..ef4766c6f2b 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -286,11 +286,15 @@ string getMadRepresentationSpecific(SummaryComponent sc) { /** Gets the textual representation of a parameter position in the format used for flow summaries. */ bindingset[pos] -string getParameterPosition(ParameterPosition pos) { positionName(pos, result) and result != "any" } +string encodeParameterPosition(ParameterPosition pos) { + positionName(pos, result) and result != "any" +} /** Gets the textual representation of an argument position in the format used for flow summaries. */ bindingset[pos] -string getArgumentPosition(ArgumentPosition pos) { positionName(pos, result) and result != "any" } +string encodeArgumentPosition(ArgumentPosition pos) { + positionName(pos, result) and result != "any" +} /** Holds if input specification component `c` needs a reference. */ predicate inputNeedsReferenceSpecific(string c) { none() } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll index 4d4c0bad4b0..afcf7bb37a8 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll @@ -30,12 +30,12 @@ module Public { or exists(ArgumentPosition pos | this = TParameterSummaryComponent(pos) and - result = "Parameter[" + getArgumentPosition(pos) + "]" + result = "Parameter[" + encodeArgumentPosition(pos) + "]" ) or exists(ParameterPosition pos | this = TArgumentSummaryComponent(pos) and - result = "Argument[" + getParameterPosition(pos) + "]" + result = "Argument[" + encodeParameterPosition(pos) + "]" ) or exists(string synthetic | From f0d7c3a7f03ee9814ba66c5593c6392392418179 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 25 Jun 2024 13:33:06 +0200 Subject: [PATCH 200/514] Remove bindingsets --- .../semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll | 2 -- 1 file changed, 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index ef4766c6f2b..3ed037148d0 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -285,13 +285,11 @@ string getMadRepresentationSpecific(SummaryComponent sc) { } /** Gets the textual representation of a parameter position in the format used for flow summaries. */ -bindingset[pos] string encodeParameterPosition(ParameterPosition pos) { positionName(pos, result) and result != "any" } /** Gets the textual representation of an argument position in the format used for flow summaries. */ -bindingset[pos] string encodeArgumentPosition(ArgumentPosition pos) { positionName(pos, result) and result != "any" } From dd7aff555de18279c26212855fd5b09898c501ad Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 25 Jun 2024 13:35:49 +0200 Subject: [PATCH 201/514] Instantiate shared FlowSummary library --- .../javascript/dataflow/internal/FlowSummaryPrivate.qll | 3 +++ .../dataflow/internal/sharedlib/DataFlowArg.qll | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index 3ed037148d0..1d6c38b51e2 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -294,6 +294,9 @@ string encodeArgumentPosition(ArgumentPosition pos) { positionName(pos, result) and result != "any" } +/** Gets the return kind corresponding to specification `"ReturnValue"`. */ +ReturnKind getStandardReturnValueKind() { result = MkNormalReturnKind() } + /** Holds if input specification component `c` needs a reference. */ predicate inputNeedsReferenceSpecific(string c) { none() } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll index e3a85506307..fae8bb76fca 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll @@ -2,6 +2,7 @@ private import semmle.javascript.Locations private import DataFlowImplSpecific private import codeql.dataflow.DataFlow as SharedDataFlow private import codeql.dataflow.TaintTracking as SharedTaintTracking +private import codeql.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl module JSDataFlow implements SharedDataFlow::InputSig { import Private @@ -22,3 +23,11 @@ module JSDataFlow implements SharedDataFlow::InputSig { module JSTaintFlow implements SharedTaintTracking::InputSig { import semmle.javascript.dataflow.internal.TaintTrackingPrivate } + +module JSFlowSummary implements FlowSummaryImpl::InputSig { + private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate + import FlowSummaryPrivate + + // Explicitly implement signature members that have a default + predicate callbackSelfParameterPosition = FlowSummaryPrivate::callbackSelfParameterPosition/0; +} From 6b35a766a64c1c3187d458d5dbd3acef60f054ce Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 25 Jun 2024 14:20:56 +0200 Subject: [PATCH 202/514] Migrate to shared FlowSummary library --- .../javascript/dataflow/FlowSummary.qll | 74 +- .../dataflow/internal/DataFlowNode.qll | 6 +- .../dataflow/internal/DataFlowPrivate.qll | 43 +- .../dataflow/internal/FlowSummaryPrivate.qll | 46 +- .../internal/TaintTrackingPrivate.qll | 9 +- .../internal/sharedlib/FlowSummaryImpl.qll | 1496 +---------------- .../sharedlib/FlowSummaryImplSpecific.qll | 1 - 7 files changed, 72 insertions(+), 1603 deletions(-) delete mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImplSpecific.qll diff --git a/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll b/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll index 8c5c6479c10..51005bf44ca 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll @@ -2,81 +2,25 @@ private import javascript private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as Impl -private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImplSpecific +private import semmle.javascript.dataflow.internal.FlowSummaryPrivate private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon private import semmle.javascript.dataflow.internal.DataFlowPrivate -class SummaryComponent = Impl::Public::SummaryComponent; - -/** Provides predicates for constructing summary components. */ -module SummaryComponent { - private import Impl::Public::SummaryComponent as SC - - predicate parameter = SC::parameter/1; - - predicate argument = SC::argument/1; - - predicate content = SC::content/1; - - predicate withoutContent = SC::withoutContent/1; - - predicate withContent = SC::withContent/1; - - class SyntheticGlobal = SC::SyntheticGlobal; - - /** Gets a summary component that represents a receiver. */ - SummaryComponent receiver() { result = argument(MkThisParameter()) } - - /** Gets a summary component that represents the return value of a call. */ - SummaryComponent return() { result = SC::return(MkNormalReturnKind()) } - - /** Gets a summary component that represents the exception thrown from a call. */ - SummaryComponent exceptionalReturn() { result = SC::return(MkExceptionalReturnKind()) } -} - -class SummaryComponentStack = Impl::Public::SummaryComponentStack; - -/** Provides predicates for constructing stacks of summary components. */ -module SummaryComponentStack { - private import Impl::Public::SummaryComponentStack as SCS - - predicate singleton = SCS::singleton/1; - - predicate push = SCS::push/2; - - predicate argument = SCS::argument/1; - - /** Gets a singleton stack representing a receiver. */ - SummaryComponentStack receiver() { result = singleton(SummaryComponent::receiver()) } - - /** Gets a singleton stack representing the return value of a call. */ - SummaryComponentStack return() { result = singleton(SummaryComponent::return()) } - - /** Gets a singleton stack representing the exception thrown from a call. */ - SummaryComponentStack exceptionalReturn() { - result = singleton(SummaryComponent::exceptionalReturn()) - } -} - /** A callable with a flow summary, identified by a unique string. */ abstract class SummarizedCallable extends LibraryCallable, Impl::Public::SummarizedCallable { bindingset[this] SummarizedCallable() { any() } - /** - * Same as - * - * ```ql - * propagatesFlow( - * SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue - * ) - * ``` - * - * but uses an external (string) representation of the input and output stacks. - */ + // TODO: rename 'propagatesFlowExt' and/or override 'propagatesFlow' directly pragma[nomagic] predicate propagatesFlowExt(string input, string output, boolean preservesValue) { none() } + override predicate propagatesFlow( + string input, string output, boolean preservesValue, string model + ) { + this.propagatesFlowExt(input, output, preservesValue) and model = this + } + /** * Gets the synthesized parameter that results from an input specification * that starts with `Argument[s]` for this library callable. @@ -88,5 +32,3 @@ abstract class SummarizedCallable extends LibraryCallable, Impl::Public::Summari ) } } - -class RequiredSummaryComponentStack = Impl::Public::RequiredSummaryComponentStack; diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index c82c2cfdac5..5f80355f000 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -10,6 +10,7 @@ private import semmle.javascript.dataflow.internal.Contents::Private private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon private import semmle.javascript.dataflow.internal.DataFlowPrivate as DataFlowPrivate private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as FlowSummaryImpl +private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate private import semmle.javascript.dataflow.internal.VariableCapture as VariableCapture cached @@ -58,7 +59,10 @@ private module Cached { TConstructorThisPostUpdate(Constructor ctor) or TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or TFlowSummaryIntermediateAwaitStoreNode(FlowSummaryImpl::Private::SummaryNode sn) { - FlowSummaryImpl::Private::Steps::summaryStoreStep(sn, MkAwaited(), _) + // NOTE: This dependency goes through the 'Steps' module whose instantiation depends on the call graph, + // but the specific predicate we're referering to does not use that information. + // So it doesn't cause negative recursion but it might look a bit surprising. + FlowSummaryPrivate::Steps::summaryStoreStep(sn, MkAwaited(), _) } or TSynthCaptureNode(VariableCapture::VariableCaptureOutput::SynthesizedCaptureNode node) or TGenericSynthesizedNode(AstNode node, string tag, DataFlowPrivate::DataFlowCallable container) { diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 0a477ebcdbc..d768b6995b3 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -8,6 +8,8 @@ private import semmle.javascript.dataflow.internal.VariableCapture private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon private import semmle.javascript.internal.flow_summaries.AllFlowSummaries private import sharedlib.FlowSummaryImpl as FlowSummaryImpl +private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate +private import semmle.javascript.dataflow.FlowSummary as FlowSummary private import semmle.javascript.dataflow.internal.BarrierGuards class DataFlowSecondLevelScope = Unit; @@ -117,7 +119,8 @@ private DataFlow::Node getAnOutNodeImpl(DataFlowCall call, ReturnKind kind) { or kind = MkNormalReturnKind() and result = call.asAccessorCall().(DataFlow::PropRead) or - FlowSummaryImpl::Private::summaryOutNode(call, result.(FlowSummaryNode).getSummaryNode(), kind) + FlowSummaryImpl::Private::summaryOutNode(call.(SummaryCall).getReceiver(), + result.(FlowSummaryNode).getSummaryNode(), kind) } class ReturnNode extends DataFlow::Node { @@ -275,7 +278,8 @@ private predicate isArgumentNodeImpl(Node n, DataFlowCall call, ArgumentPosition // argument to setter (TODO: this has no post-update node) pos.asPositional() = 0 and n = call.asAccessorCall().(DataFlow::PropWrite).getRhs() or - FlowSummaryImpl::Private::summaryArgumentNode(call, n.(FlowSummaryNode).getSummaryNode(), pos) + FlowSummaryImpl::Private::summaryArgumentNode(call.(SummaryCall).getReceiver(), + n.(FlowSummaryNode).getSummaryNode(), pos) } predicate isArgumentNode(ArgumentNode n, DataFlowCall call, ArgumentPosition pos) { @@ -802,8 +806,8 @@ private predicate valuePreservingStep(Node node1, Node node2) { or node2 = FlowSteps::getThrowTarget(node1) or - FlowSummaryImpl::Private::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(), - node2.(FlowSummaryNode).getSummaryNode(), true) + FlowSummaryPrivate::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(), + node2.(FlowSummaryNode).getSummaryNode(), true, _) // TODO: preserve 'model' or // Step from post-update nodes to local sources of the pre-update node. This emulates how JS usually tracks side effects. exists(PostUpdateNode postUpdate | @@ -828,7 +832,7 @@ predicate simpleLocalFlowStep(Node node1, Node node2) { nodeGetEnclosingCallable(pragma[only_bind_out](node2)) or exists(FlowSummaryImpl::Private::SummaryNode input, FlowSummaryImpl::Private::SummaryNode output | - FlowSummaryImpl::Private::Steps::summaryStoreStep(input, MkAwaited(), output) and + FlowSummaryPrivate::Steps::summaryStoreStep(input, MkAwaited(), output) and node1 = TFlowSummaryNode(input) and ( node2 = TFlowSummaryNode(output) and @@ -837,7 +841,7 @@ predicate simpleLocalFlowStep(Node node1, Node node2) { node2 = TFlowSummaryIntermediateAwaitStoreNode(input) ) or - FlowSummaryImpl::Private::Steps::summaryReadStep(input, MkAwaited(), output) and + FlowSummaryPrivate::Steps::summaryReadStep(input, MkAwaited(), output) and node1 = TFlowSummaryNode(input) and node2 = TFlowSummaryNode(output) ) @@ -859,7 +863,7 @@ predicate jumpStep(Node node1, Node node2) { valuePreservingStep(node1, node2) and node1.getContainer() != node2.getContainer() or - FlowSummaryImpl::Private::Steps::summaryJumpStep(node1.(FlowSummaryNode).getSummaryNode(), + FlowSummaryPrivate::Steps::summaryJumpStep(node1.(FlowSummaryNode).getSummaryNode(), node2.(FlowSummaryNode).getSummaryNode()) or DataFlow::AdditionalFlowStep::jumpStep(node1, node2) @@ -882,8 +886,8 @@ predicate readStep(Node node1, ContentSet c, Node node2) { ) or exists(ContentSet contentSet | - FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), - contentSet, node2.(FlowSummaryNode).getSummaryNode()) + FlowSummaryPrivate::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), contentSet, + node2.(FlowSummaryNode).getSummaryNode()) | not isSpecialContentSet(contentSet) and c = contentSet @@ -894,7 +898,7 @@ predicate readStep(Node node1, ContentSet c, Node node2) { or // For deep reads, generate read edges with a self-loop exists(Node origin, ContentSet contentSet | - FlowSummaryImpl::Private::Steps::summaryReadStep(origin.(FlowSummaryNode).getSummaryNode(), + FlowSummaryPrivate::Steps::summaryReadStep(origin.(FlowSummaryNode).getSummaryNode(), contentSet, node2.(FlowSummaryNode).getSummaryNode()) and node1 = [origin, node2] | @@ -938,13 +942,13 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { node2 = tryGetPostUpdate(write.getBase()) ) or - FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c, + FlowSummaryPrivate::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c, node2.(FlowSummaryNode).getSummaryNode()) and not isSpecialContentSet(c) or // Store into Awaited exists(FlowSummaryImpl::Private::SummaryNode input, FlowSummaryImpl::Private::SummaryNode output | - FlowSummaryImpl::Private::Steps::summaryStoreStep(input, MkAwaited(), output) and + FlowSummaryPrivate::Steps::summaryStoreStep(input, MkAwaited(), output) and node1 = TFlowSummaryIntermediateAwaitStoreNode(input) and node2 = TFlowSummaryNode(output) and c = ContentSet::promiseValue() @@ -964,15 +968,14 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { * in `x.f = newValue`. */ predicate clearsContent(Node n, ContentSet c) { - FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c) + FlowSummaryPrivate::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c) or // Clear promise content before storing into promise value, to avoid creating nested promises n = TFlowSummaryIntermediateAwaitStoreNode(_) and c = MkPromiseFilter() or // After reading from Awaited, the output must not be stored in a promise content - FlowSummaryImpl::Private::Steps::summaryReadStep(_, MkAwaited(), - n.(FlowSummaryNode).getSummaryNode()) and + FlowSummaryPrivate::Steps::summaryReadStep(_, MkAwaited(), n.(FlowSummaryNode).getSummaryNode()) and c = MkPromiseFilter() or any(AdditionalFlowInternal flow).clearsContent(n, c) @@ -998,12 +1001,11 @@ predicate clearsContent(Node n, ContentSet c) { * at node `n`. */ predicate expectsContent(Node n, ContentSet c) { - FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c) + FlowSummaryPrivate::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c) or // After storing into Awaited, the result must be stored in a promise-content. // There is a value step from the input directly to this node, hence the need for expectsContent. - FlowSummaryImpl::Private::Steps::summaryStoreStep(_, MkAwaited(), - n.(FlowSummaryNode).getSummaryNode()) and + FlowSummaryPrivate::Steps::summaryStoreStep(_, MkAwaited(), n.(FlowSummaryNode).getSummaryNode()) and c = MkPromiseFilter() or any(AdditionalFlowInternal flow).expectsContent(n, c) @@ -1035,7 +1037,10 @@ int accessPathLimit() { result = 2 } * by default as a heuristic. */ predicate allowParameterReturnInSelf(ParameterNode p) { - FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(p) + exists(DataFlowCallable callable, ParameterPosition pos | + isParameterNodeImpl(p, callable, pos) and + FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(callable.asLibraryCallable(), pos) + ) or exists(Function f | VariableCaptureOutput::heuristicAllowInstanceParameterReturnInSelf(f) and diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index 1d6c38b51e2..d6877308786 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -70,11 +70,6 @@ DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { result = TAnyType() and exists(t) and exists(rk) } -/** Gets the type of synthetic global `sg`. */ -DataFlowType getSyntheticGlobalType(SummaryComponent::SyntheticGlobal sg) { - result = TAnyType() and exists(sg) -} - /** * Holds if an external flow summary exists for `c` with input specification * `input`, output specification `output`, kind `kind`, and provenance `provenance`. @@ -97,21 +92,21 @@ predicate summaryElement( predicate neutralSummaryElement(FlowSummary::SummarizedCallable c, string provenance) { none() } pragma[inline] -private SummaryComponent makeContentComponents( +private Private::SummaryComponent makeContentComponents( Private::AccessPathToken token, string name, ContentSet contents ) { token.getName() = name and - result = FlowSummary::SummaryComponent::content(contents) + result = Private::SummaryComponent::content(contents) or token.getName() = "With" + name and - result = FlowSummary::SummaryComponent::withContent(contents) + result = Private::SummaryComponent::withContent(contents) or token.getName() = "Without" + name and - result = FlowSummary::SummaryComponent::withoutContent(contents) + result = Private::SummaryComponent::withoutContent(contents) } pragma[inline] -private SummaryComponent makePropertyContentComponents( +private Private::SummaryComponent makePropertyContentComponents( Private::AccessPathToken token, string name, PropertyName content ) { result = makeContentComponents(token, name, ContentSet::property(content)) @@ -160,12 +155,12 @@ private ParameterPosition parsePosition(string operand) { * * This covers all the JS-specific components of a flow summary. */ -SummaryComponent interpretComponentSpecific(Private::AccessPathToken c) { +Private::SummaryComponent interpretComponentSpecific(Private::AccessPathToken c) { c.getName() = "Argument" and - result = FlowSummary::SummaryComponent::argument(parsePosition(c.getAnArgument())) + result = Private::SummaryComponent::argument(parsePosition(c.getAnArgument())) or c.getName() = "Parameter" and - result = FlowSummary::SummaryComponent::parameter(parsePosition(c.getAnArgument())) + result = Private::SummaryComponent::parameter(parsePosition(c.getAnArgument())) or result = makePropertyContentComponents(c, "Member", c.getAnArgument()) or @@ -210,20 +205,20 @@ SummaryComponent interpretComponentSpecific(Private::AccessPathToken c) { or c.getName() = "ReturnValue" and c.getAnArgument() = "exception" and - result = SummaryComponent::return(MkExceptionalReturnKind()) + result = Private::SummaryComponent::return(MkExceptionalReturnKind()) or // Awaited is mapped down to a combination steps that handle coercion and promise-flattening. c.getName() = "Awaited" and c.getNumArgument() = 0 and - result = SummaryComponent::content(MkAwaited()) + result = Private::SummaryComponent::content(MkAwaited()) or c.getName() = "AnyMemberDeep" and c.getNumArgument() = 0 and - result = SummaryComponent::content(MkAnyPropertyDeep()) + result = Private::SummaryComponent::content(MkAnyPropertyDeep()) or c.getName() = "ArrayElementDeep" and c.getNumArgument() = 0 and - result = SummaryComponent::content(MkArrayElementDeep()) + result = Private::SummaryComponent::content(MkArrayElementDeep()) } private string getMadStringFromContentSetAux(ContentSet cs) { @@ -272,13 +267,14 @@ private string getMadStringFromContentSet(ContentSet cs) { } /** Gets the textual representation of a summary component in the format used for MaD models. */ -string getMadRepresentationSpecific(SummaryComponent sc) { +string getMadRepresentationSpecific(Private::SummaryComponent sc) { exists(ContentSet cs | - sc = Private::TContentSummaryComponent(cs) and result = getMadStringFromContentSet(cs) + sc = Private::SummaryComponent::content(cs) and + result = getMadStringFromContentSet(cs) ) or exists(ReturnKind rk | - sc = Private::TReturnSummaryComponent(rk) and + sc = Private::SummaryComponent::return(rk) and not rk = getReturnValueKind() and result = "ReturnValue[" + rk + "]" ) @@ -368,3 +364,13 @@ bindingset[s] ParameterPosition parseArgBody(string s) { result = parseParamBody(s) // Currently these are identical } + +private module FlowSummaryStepInput implements Private::StepsInputSig { + DataFlowCall getACall(SummarizedCallable sc) { + exists(LibraryCallable callable | callable = sc | + result.asOrdinaryCall() = [callable.getACall(), callable.getACallSimple()] + ) + } +} + +module Steps = Private::Steps; diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index f60c4e0f5db..7b4d8a8e94b 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -2,20 +2,21 @@ private import javascript private import semmle.javascript.dataflow.internal.DataFlowPrivate private import semmle.javascript.dataflow.internal.Contents::Public private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as FlowSummaryImpl +private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate private import semmle.javascript.dataflow.internal.BarrierGuards cached predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { TaintTracking::AdditionalTaintStep::step(node1, node2) or - FlowSummaryImpl::Private::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(), - node2.(FlowSummaryNode).getSummaryNode(), false) + FlowSummaryPrivate::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(), + node2.(FlowSummaryNode).getSummaryNode(), false, _) // TODO: preserve 'model' parameter or // Convert steps into and out of array elements to plain taint steps - FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), + FlowSummaryPrivate::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), ContentSet::arrayElement(), node2.(FlowSummaryNode).getSummaryNode()) or - FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), + FlowSummaryPrivate::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), ContentSet::arrayElement(), node2.(FlowSummaryNode).getSummaryNode()) } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll index afcf7bb37a8..bf370eb9a27 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll @@ -1,1492 +1,4 @@ -/** - * Provides classes and predicates for defining flow summaries. - * - * The definitions in this file are language-independent, and language-specific - * definitions are passed in via the `DataFlowImplSpecific` and - * `FlowSummaryImplSpecific` modules. - */ - -private import FlowSummaryImplSpecific -private import DataFlowImplSpecific::Private -private import DataFlowImplSpecific::Public -private import DataFlowImplCommon -private import codeql.util.Unit - -// TODO: switch to the shared implementation of FlowSummaryImpl.qll -/** Provides classes and predicates for defining flow summaries. */ -module Public { - private import Private - - /** - * A component used in a flow summary. - * - * Either a parameter or an argument at a given position, a specific - * content type, or a return kind. - */ - class SummaryComponent extends TSummaryComponent { - /** Gets a textual representation of this component used for MaD models. */ - string getMadRepresentation() { - result = getMadRepresentationSpecific(this) - or - exists(ArgumentPosition pos | - this = TParameterSummaryComponent(pos) and - result = "Parameter[" + encodeArgumentPosition(pos) + "]" - ) - or - exists(ParameterPosition pos | - this = TArgumentSummaryComponent(pos) and - result = "Argument[" + encodeParameterPosition(pos) + "]" - ) - or - exists(string synthetic | - this = TSyntheticGlobalSummaryComponent(synthetic) and - result = "SyntheticGlobal[" + synthetic + "]" - ) - or - this = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" - } - - /** Gets a textual representation of this summary component. */ - string toString() { result = this.getMadRepresentation() } - } - - /** Provides predicates for constructing summary components. */ - module SummaryComponent { - /** Gets a summary component for content `c`. */ - SummaryComponent content(ContentSet c) { result = TContentSummaryComponent(c) } - - /** Gets a summary component where data is not allowed to be stored in `c`. */ - SummaryComponent withoutContent(ContentSet c) { result = TWithoutContentSummaryComponent(c) } - - /** Gets a summary component where data must be stored in `c`. */ - SummaryComponent withContent(ContentSet c) { result = TWithContentSummaryComponent(c) } - - /** Gets a summary component for a parameter at position `pos`. */ - SummaryComponent parameter(ArgumentPosition pos) { result = TParameterSummaryComponent(pos) } - - /** Gets a summary component for an argument at position `pos`. */ - SummaryComponent argument(ParameterPosition pos) { result = TArgumentSummaryComponent(pos) } - - /** Gets a summary component for a return of kind `rk`. */ - SummaryComponent return(ReturnKind rk) { result = TReturnSummaryComponent(rk) } - - /** Gets a summary component for synthetic global `sg`. */ - SummaryComponent syntheticGlobal(SyntheticGlobal sg) { - result = TSyntheticGlobalSummaryComponent(sg) - } - - /** - * A synthetic global. This represents some form of global state, which - * summaries can read and write individually. - */ - abstract class SyntheticGlobal extends string { - bindingset[this] - SyntheticGlobal() { any() } - } - } - - /** - * A (non-empty) stack of summary components. - * - * A stack is used to represent where data is read from (input) or where it - * is written to (output). For example, an input stack `[Field f, Argument 0]` - * means that data is read from field `f` from the `0`th argument, while an - * output stack `[Field g, Return]` means that data is written to the field - * `g` of the returned object. - */ - class SummaryComponentStack extends TSummaryComponentStack { - /** Gets the head of this stack. */ - SummaryComponent head() { - this = TSingletonSummaryComponentStack(result) or - this = TConsSummaryComponentStack(result, _) - } - - /** Gets the tail of this stack, if any. */ - SummaryComponentStack tail() { this = TConsSummaryComponentStack(_, result) } - - /** Gets the length of this stack. */ - int length() { - this = TSingletonSummaryComponentStack(_) and result = 1 - or - result = 1 + this.tail().length() - } - - /** Gets the stack obtained by dropping the first `i` elements, if any. */ - SummaryComponentStack drop(int i) { - i = 0 and result = this - or - result = this.tail().drop(i - 1) - } - - /** Holds if this stack contains summary component `c`. */ - predicate contains(SummaryComponent c) { c = this.drop(_).head() } - - /** Gets the bottom element of this stack. */ - SummaryComponent bottom() { - this = TSingletonSummaryComponentStack(result) or result = this.tail().bottom() - } - - /** Gets a textual representation of this stack used for MaD models. */ - string getMadRepresentation() { - exists(SummaryComponent head, SummaryComponentStack tail | - head = this.head() and - tail = this.tail() and - result = tail.getMadRepresentation() + "." + head.getMadRepresentation() - ) - or - exists(SummaryComponent c | - this = TSingletonSummaryComponentStack(c) and - result = c.getMadRepresentation() - ) - } - - /** Gets a textual representation of this stack. */ - string toString() { result = this.getMadRepresentation() } - } - - /** Provides predicates for constructing stacks of summary components. */ - module SummaryComponentStack { - /** Gets a singleton stack containing `c`. */ - SummaryComponentStack singleton(SummaryComponent c) { - result = TSingletonSummaryComponentStack(c) - } - - /** - * Gets the stack obtained by pushing `head` onto `tail`. - * - * Make sure to override `RequiredSummaryComponentStack::required()` in order - * to ensure that the constructed stack exists. - */ - SummaryComponentStack push(SummaryComponent head, SummaryComponentStack tail) { - result = TConsSummaryComponentStack(head, tail) - } - - /** Gets a singleton stack for an argument at position `pos`. */ - SummaryComponentStack argument(ParameterPosition pos) { - result = singleton(SummaryComponent::argument(pos)) - } - - /** Gets a singleton stack representing a return of kind `rk`. */ - SummaryComponentStack return(ReturnKind rk) { result = singleton(SummaryComponent::return(rk)) } - } - - /** - * A class that exists for QL technical reasons only (the IPA type used - * to represent component stacks needs to be bounded). - */ - class RequiredSummaryComponentStack extends Unit { - /** - * Holds if the stack obtained by pushing `head` onto `tail` is required. - */ - abstract predicate required(SummaryComponent head, SummaryComponentStack tail); - } - - /** - * Gets the valid model origin values. - */ - private string getValidModelOrigin() { - result = - [ - "ai", // AI (machine learning) - "df", // Dataflow (model generator) - "tb", // Type based (model generator) - "hq", // Heuristic query - ] - } - - /** - * A class used to represent provenance values for MaD models. - * - * The provenance value is a string of the form `origin-verification` - * (or just `manual`), where `origin` is a value indicating the - * origin of the model, and `verification` is a value indicating, how - * the model was verified. - * - * Examples could be: - * - `df-generated`: A model produced by the model generator, but not verified by a human. - * - `ai-manual`: A model produced by AI, but verified by a human. - */ - class Provenance extends string { - private string verification; - - Provenance() { - exists(string origin | origin = getValidModelOrigin() | - this = origin + "-" + verification and - verification = ["manual", "generated"] - ) - or - this = verification and verification = "manual" - } - - /** - * Holds if this is a valid generated provenance value. - */ - predicate isGenerated() { verification = "generated" } - - /** - * Holds if this is a valid manual provenance value. - */ - predicate isManual() { verification = "manual" } - } - - /** A callable with a flow summary. */ - abstract class SummarizedCallable extends SummarizedCallableBase { - bindingset[this] - SummarizedCallable() { any() } - - /** - * Holds if data may flow from `input` to `output` through this callable. - * - * `preservesValue` indicates whether this is a value-preserving step - * or a taint-step. - * - * Input specifications are restricted to stacks that end with - * `SummaryComponent::argument(_)`, preceded by zero or more - * `SummaryComponent::return(_)` or `SummaryComponent::content(_)` components. - * - * Output specifications are restricted to stacks that end with - * `SummaryComponent::return(_)` or `SummaryComponent::argument(_)`. - * - * Output stacks ending with `SummaryComponent::return(_)` can be preceded by zero - * or more `SummaryComponent::content(_)` components. - * - * Output stacks ending with `SummaryComponent::argument(_)` can be preceded by an - * optional `SummaryComponent::parameter(_)` component, which in turn can be preceded - * by zero or more `SummaryComponent::content(_)` components. - */ - pragma[nomagic] - predicate propagatesFlow( - SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue - ) { - none() - } - - /** - * Holds if there exists a generated summary that applies to this callable. - */ - final predicate hasGeneratedModel() { - exists(Provenance p | p.isGenerated() and this.hasProvenance(p)) - } - - /** - * Holds if all the summaries that apply to this callable are auto generated and not manually created. - * That is, only apply generated models, when there are no manual models. - */ - final predicate applyGeneratedModel() { - this.hasGeneratedModel() and - not this.hasManualModel() - } - - /** - * Holds if there exists a manual summary that applies to this callable. - */ - final predicate hasManualModel() { - exists(Provenance p | p.isManual() and this.hasProvenance(p)) - } - - /** - * Holds if there exists a manual summary that applies to this callable. - * Always apply manual models if they exist. - */ - final predicate applyManualModel() { this.hasManualModel() } - - /** - * Holds if there exists a summary that applies to this callable - * that has provenance `provenance`. - */ - predicate hasProvenance(Provenance provenance) { provenance = "manual" } - } - - /** - * A callable where there is no flow via the callable. - */ - class NeutralSummaryCallable extends NeutralCallable { - NeutralSummaryCallable() { this.getKind() = "summary" } - } - - /** - * A callable that has a neutral model. - */ - class NeutralCallable extends NeutralCallableBase { - private string kind; - private Provenance provenance; - - NeutralCallable() { neutralElement(this, kind, provenance) } - - /** - * Holds if the neutral is auto generated. - */ - final predicate hasGeneratedModel() { provenance.isGenerated() } - - /** - * Holds if there exists a manual neutral that applies to this callable. - */ - final predicate hasManualModel() { provenance.isManual() } - - /** - * Holds if the neutral has provenance `p`. - */ - predicate hasProvenance(Provenance p) { p = provenance } - - /** - * Gets the kind of the neutral. - */ - string getKind() { result = kind } - } -} - -/** - * Provides predicates for compiling flow summaries down to atomic local steps, - * read steps, and store steps. - */ -module Private { - private import Public - private import codeql.dataflow.internal.AccessPathSyntax - - newtype TSummaryComponent = - TContentSummaryComponent(ContentSet c) or - TParameterSummaryComponent(ArgumentPosition pos) or - TArgumentSummaryComponent(ParameterPosition pos) or - TReturnSummaryComponent(ReturnKind rk) or - TSyntheticGlobalSummaryComponent(SummaryComponent::SyntheticGlobal sg) or - TWithoutContentSummaryComponent(ContentSet c) or - TWithContentSummaryComponent(ContentSet c) - - private TParameterSummaryComponent callbackSelfParam() { - result = TParameterSummaryComponent(callbackSelfParameterPosition()) - } - - newtype TSummaryComponentStack = - TSingletonSummaryComponentStack(SummaryComponent c) or - TConsSummaryComponentStack(SummaryComponent head, SummaryComponentStack tail) { - any(RequiredSummaryComponentStack x).required(head, tail) - or - any(RequiredSummaryComponentStack x).required(TParameterSummaryComponent(_), tail) and - head = callbackSelfParam() - or - derivedFluentFlowPush(_, _, _, head, tail, _) - } - - pragma[nomagic] - private predicate summary( - SummarizedCallable c, SummaryComponentStack input, SummaryComponentStack output, - boolean preservesValue - ) { - c.propagatesFlow(input, output, preservesValue) - or - // observe side effects of callbacks on input arguments - c.propagatesFlow(output, input, preservesValue) and - preservesValue = true and - isCallbackParameter(input) and - isContentOfArgument(output, _) - or - // flow from the receiver of a callback into the instance-parameter - exists(SummaryComponentStack s, SummaryComponentStack callbackRef | - c.propagatesFlow(s, _, _) or c.propagatesFlow(_, s, _) - | - callbackRef = s.drop(_) and - (isCallbackParameter(callbackRef) or callbackRef.head() = TReturnSummaryComponent(_)) and - input = callbackRef.tail() and - output = TConsSummaryComponentStack(callbackSelfParam(), input) and - preservesValue = true - ) - or - exists(SummaryComponentStack arg, SummaryComponentStack return | - derivedFluentFlow(c, input, arg, return, preservesValue) - | - arg.length() = 1 and - output = return - or - exists(SummaryComponent head, SummaryComponentStack tail | - derivedFluentFlowPush(c, input, arg, head, tail, 0) and - output = SummaryComponentStack::push(head, tail) - ) - ) - or - // Chain together summaries where values get passed into callbacks along the way - exists(SummaryComponentStack mid, boolean preservesValue1, boolean preservesValue2 | - c.propagatesFlow(input, mid, preservesValue1) and - c.propagatesFlow(mid, output, preservesValue2) and - mid.drop(mid.length() - 2) = - SummaryComponentStack::push(TParameterSummaryComponent(_), - SummaryComponentStack::singleton(TArgumentSummaryComponent(_))) and - preservesValue = preservesValue1.booleanAnd(preservesValue2) - ) - } - - /** - * Holds if `c` has a flow summary from `input` to `arg`, where `arg` - * writes to (contents of) arguments at position `pos`, and `c` has a - * value-preserving flow summary from the arguments at position `pos` - * to a return value (`return`). - * - * In such a case, we derive flow from `input` to (contents of) the return - * value. - * - * As an example, this simplifies modeling of fluent methods: - * for `StringBuilder.append(x)` with a specified value flow from qualifier to - * return value and taint flow from argument 0 to the qualifier, then this - * allows us to infer taint flow from argument 0 to the return value. - */ - pragma[nomagic] - private predicate derivedFluentFlow( - SummarizedCallable c, SummaryComponentStack input, SummaryComponentStack arg, - SummaryComponentStack return, boolean preservesValue - ) { - exists(ParameterPosition pos | - summary(c, input, arg, preservesValue) and - isContentOfArgument(arg, pos) and - summary(c, SummaryComponentStack::argument(pos), return, true) and - return.bottom() = TReturnSummaryComponent(_) - ) - } - - pragma[nomagic] - private predicate derivedFluentFlowPush( - SummarizedCallable c, SummaryComponentStack input, SummaryComponentStack arg, - SummaryComponent head, SummaryComponentStack tail, int i - ) { - derivedFluentFlow(c, input, arg, tail, _) and - head = arg.drop(i).head() and - i = arg.length() - 2 - or - exists(SummaryComponent head0, SummaryComponentStack tail0 | - derivedFluentFlowPush(c, input, arg, head0, tail0, i + 1) and - head = arg.drop(i).head() and - tail = SummaryComponentStack::push(head0, tail0) - ) - } - - private predicate isCallbackParameter(SummaryComponentStack s) { - s.head() = TParameterSummaryComponent(_) and exists(s.tail()) - } - - private predicate isContentOfArgument(SummaryComponentStack s, ParameterPosition pos) { - s.head() = TContentSummaryComponent(_) and isContentOfArgument(s.tail(), pos) - or - s = SummaryComponentStack::argument(pos) - } - - private predicate outputState(SummarizedCallable c, SummaryComponentStack s) { - summary(c, _, s, _) - or - exists(SummaryComponentStack out | - outputState(c, out) and - out.head() = TContentSummaryComponent(_) and - s = out.tail() - ) - or - // Add the argument node corresponding to the requested post-update node - inputState(c, s) and isCallbackParameter(s) - } - - private predicate inputState(SummarizedCallable c, SummaryComponentStack s) { - summary(c, s, _, _) - or - exists(SummaryComponentStack inp | inputState(c, inp) and s = inp.tail()) - or - exists(SummaryComponentStack out | - outputState(c, out) and - out.head() = TParameterSummaryComponent(_) and - s = out.tail() - ) - or - // Add the post-update node corresponding to the requested argument node - outputState(c, s) and isCallbackParameter(s) - or - // Add the parameter node for parameter side-effects - outputState(c, s) and s = SummaryComponentStack::argument(_) - } - - private newtype TSummaryNodeState = - TSummaryNodeInputState(SummaryComponentStack s) { inputState(_, s) } or - TSummaryNodeOutputState(SummaryComponentStack s) { outputState(_, s) } - - /** - * A state used to break up (complex) flow summaries into atomic flow steps. - * For a flow summary - * - * ```ql - * propagatesFlow( - * SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue - * ) - * ``` - * - * the following states are used: - * - * - `TSummaryNodeInputState(SummaryComponentStack s)`: - * this state represents that the components in `s` _have been read_ from the - * input. - * - `TSummaryNodeOutputState(SummaryComponentStack s)`: - * this state represents that the components in `s` _remain to be written_ to - * the output. - */ - private class SummaryNodeState extends TSummaryNodeState { - /** Holds if this state is a valid input state for `c`. */ - pragma[nomagic] - predicate isInputState(SummarizedCallable c, SummaryComponentStack s) { - this = TSummaryNodeInputState(s) and - inputState(c, s) - } - - /** Holds if this state is a valid output state for `c`. */ - pragma[nomagic] - predicate isOutputState(SummarizedCallable c, SummaryComponentStack s) { - this = TSummaryNodeOutputState(s) and - outputState(c, s) - } - - /** Gets a textual representation of this state. */ - string toString() { - exists(SummaryComponentStack s | - this = TSummaryNodeInputState(s) and - result = "read: " + s - ) - or - exists(SummaryComponentStack s | - this = TSummaryNodeOutputState(s) and - result = "to write: " + s - ) - } - } - - private newtype TSummaryNode = - TSummaryInternalNode(SummarizedCallable c, SummaryNodeState state) { - summaryNodeRange(c, state) - } or - TSummaryParameterNode(SummarizedCallable c, ParameterPosition pos) { - summaryParameterNodeRange(c, pos) - } - - abstract class SummaryNode extends TSummaryNode { - abstract string toString(); - - abstract SummarizedCallable getSummarizedCallable(); - } - - private class SummaryInternalNode extends SummaryNode, TSummaryInternalNode { - private SummarizedCallable c; - private SummaryNodeState state; - - SummaryInternalNode() { this = TSummaryInternalNode(c, state) } - - override string toString() { result = "[summary] " + state + " in " + c } - - override SummarizedCallable getSummarizedCallable() { result = c } - } - - private class SummaryParamNode extends SummaryNode, TSummaryParameterNode { - private SummarizedCallable c; - private ParameterPosition pos; - - SummaryParamNode() { this = TSummaryParameterNode(c, pos) } - - override string toString() { result = "[summary param] " + pos + " in " + c } - - override SummarizedCallable getSummarizedCallable() { result = c } - } - - /** - * Holds if `state` represents having read from a parameter at position - * `pos` in `c`. In this case we are not synthesizing a data-flow node, - * but instead assume that a relevant parameter node already exists. - */ - private predicate parameterReadState( - SummarizedCallable c, SummaryNodeState state, ParameterPosition pos - ) { - state.isInputState(c, SummaryComponentStack::argument(pos)) - } - - /** - * Holds if a synthesized summary node is needed for the state `state` in summarized - * callable `c`. - */ - private predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) { - state.isInputState(c, _) and - not parameterReadState(c, state, _) - or - state.isOutputState(c, _) - } - - pragma[noinline] - private SummaryNode summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) { - exists(SummaryNodeState state | state.isInputState(c, s) | - result = TSummaryInternalNode(c, state) - or - exists(ParameterPosition pos | - parameterReadState(c, state, pos) and - result = TSummaryParameterNode(c, pos) - ) - ) - } - - pragma[noinline] - private SummaryNode summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) { - exists(SummaryNodeState state | - state.isOutputState(c, s) and - result = TSummaryInternalNode(c, state) - ) - } - - /** - * Holds if a write targets `post`, which is a post-update node for a - * parameter at position `pos` in `c`. - */ - private predicate isParameterPostUpdate( - SummaryNode post, SummarizedCallable c, ParameterPosition pos - ) { - post = summaryNodeOutputState(c, SummaryComponentStack::argument(pos)) - } - - /** Holds if a parameter node at position `pos` is required for `c`. */ - private predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { - parameterReadState(c, _, pos) - or - // Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context - any(SummaryNodeState state).isOutputState(c, SummaryComponentStack::argument(pos)) - } - - private predicate callbackOutput( - SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ReturnKind rk - ) { - any(SummaryNodeState state).isInputState(c, s) and - s.head() = TReturnSummaryComponent(rk) and - receiver = summaryNodeInputState(c, s.tail()) - } - - private predicate callbackInput( - SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ArgumentPosition pos - ) { - any(SummaryNodeState state).isOutputState(c, s) and - s.head() = TParameterSummaryComponent(pos) and - receiver = summaryNodeInputState(c, s.tail()) - } - - /** Holds if a call targeting `receiver` should be synthesized inside `c`. */ - predicate summaryCallbackRange(SummarizedCallable c, SummaryNode receiver) { - callbackOutput(c, _, receiver, _) - or - callbackInput(c, _, receiver, _) - } - - /** - * Gets the type of synthesized summary node `n`. - * - * The type is computed based on the language-specific predicates - * `getContentType()`, `getReturnType()`, `getCallbackParameterType()`, and - * `getCallbackReturnType()`. - */ - DataFlowType summaryNodeType(SummaryNode n) { - exists(SummaryNode pre | - summaryPostUpdateNode(n, pre) and - result = summaryNodeType(pre) - ) - or - exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() | - n = summaryNodeInputState(c, s) and - ( - exists(ContentSet cont | result = getContentType(cont) | - head = TContentSummaryComponent(cont) or - head = TWithContentSummaryComponent(cont) - ) - or - head = TWithoutContentSummaryComponent(_) and - result = summaryNodeType(summaryNodeInputState(c, s.tail())) - or - exists(ReturnKind rk | - head = TReturnSummaryComponent(rk) and - result = - getCallbackReturnType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c), - s.tail())), rk) - ) - or - exists(SummaryComponent::SyntheticGlobal sg | - head = TSyntheticGlobalSummaryComponent(sg) and - result = getSyntheticGlobalType(sg) - ) - or - exists(ParameterPosition pos | - head = TArgumentSummaryComponent(pos) and - result = getParameterType(c, pos) - ) - ) - or - n = summaryNodeOutputState(c, s) and - ( - exists(ContentSet cont | - head = TContentSummaryComponent(cont) and result = getContentType(cont) - ) - or - s.length() = 1 and - exists(ReturnKind rk | - head = TReturnSummaryComponent(rk) and - result = getReturnType(c, rk) - ) - or - exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) | - result = - getCallbackParameterType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c), - s.tail())), pos) - ) - or - exists(SummaryComponent::SyntheticGlobal sg | - head = TSyntheticGlobalSummaryComponent(sg) and - result = getSyntheticGlobalType(sg) - ) - ) - ) - } - - /** Holds if summary node `p` is a parameter with position `pos`. */ - predicate summaryParameterNode(SummaryNode p, ParameterPosition pos) { - p = TSummaryParameterNode(_, pos) - } - - /** Holds if summary node `out` contains output of kind `rk` from call `c`. */ - predicate summaryOutNode(DataFlowCall c, SummaryNode out, ReturnKind rk) { - exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver | - callbackOutput(callable, s, receiver, rk) and - out = summaryNodeInputState(callable, s) and - c = summaryDataFlowCall(receiver) - ) - } - - /** Holds if summary node `arg` is at position `pos` in the call `c`. */ - predicate summaryArgumentNode(DataFlowCall c, SummaryNode arg, ArgumentPosition pos) { - exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver | - callbackInput(callable, s, receiver, pos) and - arg = summaryNodeOutputState(callable, s) and - c = summaryDataFlowCall(receiver) - ) - } - - /** Holds if summary node `post` is a post-update node with pre-update node `pre`. */ - predicate summaryPostUpdateNode(SummaryNode post, SummaryNode pre) { - exists(SummarizedCallable c, ParameterPosition pos | - isParameterPostUpdate(post, c, pos) and - pre = TSummaryParameterNode(c, pos) - ) - or - exists(SummarizedCallable callable, SummaryComponentStack s | - callbackInput(callable, s, _, _) and - pre = summaryNodeOutputState(callable, s) and - post = summaryNodeInputState(callable, s) - ) - } - - /** Holds if summary node `ret` is a return node of kind `rk`. */ - predicate summaryReturnNode(SummaryNode ret, ReturnKind rk) { - exists(SummaryComponentStack s | - ret = summaryNodeOutputState(_, s) and - s = TSingletonSummaryComponentStack(TReturnSummaryComponent(rk)) - ) - } - - /** - * Holds if flow is allowed to pass from parameter `p`, to a return - * node, and back out to `p`. - */ - predicate summaryAllowParameterReturnInSelf(ParamNode p) { - exists(SummarizedCallable c, ParameterPosition ppos | - p.isParameterOf(inject(c), pragma[only_bind_into](ppos)) - | - exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents | - summary(c, inputContents, outputContents, _) and - inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and - outputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) - ) - ) - } - - /** Provides a compilation of flow summaries to atomic data-flow steps. */ - module Steps { - /** - * Holds if there is a local step from `pred` to `succ`, which is synthesized - * from a flow summary. - */ - predicate summaryLocalStep(SummaryNode pred, SummaryNode succ, boolean preservesValue) { - exists( - SummarizedCallable c, SummaryComponentStack inputContents, - SummaryComponentStack outputContents - | - summary(c, inputContents, outputContents, preservesValue) and - pred = summaryNodeInputState(c, inputContents) and - succ = summaryNodeOutputState(c, outputContents) - | - preservesValue = true - or - preservesValue = false and not summary(c, inputContents, outputContents, true) - ) - or - exists(SummarizedCallable c, SummaryComponentStack s | - pred = summaryNodeInputState(c, s.tail()) and - succ = summaryNodeInputState(c, s) and - s.head() = [SummaryComponent::withContent(_), SummaryComponent::withoutContent(_)] and - preservesValue = true - ) - } - - /** - * Holds if there is a read step of content `c` from `pred` to `succ`, which - * is synthesized from a flow summary. - */ - predicate summaryReadStep(SummaryNode pred, ContentSet c, SummaryNode succ) { - exists(SummarizedCallable sc, SummaryComponentStack s | - pred = summaryNodeInputState(sc, s.tail()) and - succ = summaryNodeInputState(sc, s) and - SummaryComponent::content(c) = s.head() - ) - } - - /** - * Holds if there is a store step of content `c` from `pred` to `succ`, which - * is synthesized from a flow summary. - */ - predicate summaryStoreStep(SummaryNode pred, ContentSet c, SummaryNode succ) { - exists(SummarizedCallable sc, SummaryComponentStack s | - pred = summaryNodeOutputState(sc, s) and - succ = summaryNodeOutputState(sc, s.tail()) and - SummaryComponent::content(c) = s.head() - ) - } - - /** - * Holds if there is a jump step from `pred` to `succ`, which is synthesized - * from a flow summary. - */ - predicate summaryJumpStep(SummaryNode pred, SummaryNode succ) { - exists(SummaryComponentStack s | - s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and - pred = summaryNodeOutputState(_, s) and - succ = summaryNodeInputState(_, s) - ) - } - - /** - * Holds if values stored inside content `c` are cleared at `n`. `n` is a - * synthesized summary node, so in order for values to be cleared at calls - * to the relevant method, it is important that flow does not pass over - * the argument, either via use-use flow or def-use flow. - * - * Example: - * - * ``` - * a.b = taint; - * a.clearB(); // assume we have a flow summary for `clearB` that clears `b` on the qualifier - * sink(a.b); - * ``` - * - * In the above, flow should not pass from `a` on the first line (or the second - * line) to `a` on the third line. Instead, there will be synthesized flow from - * `a` on line 2 to the post-update node for `a` on that line (via an intermediate - * node where field `b` is cleared). - */ - predicate summaryClearsContent(SummaryNode n, ContentSet c) { - exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | - n = TSummaryInternalNode(sc, state) and - state.isInputState(sc, stack) and - stack.head() = SummaryComponent::withoutContent(c) - ) - } - - /** - * Holds if the value that is being tracked is expected to be stored inside - * content `c` at `n`. - */ - predicate summaryExpectsContent(SummaryNode n, ContentSet c) { - exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | - n = TSummaryInternalNode(sc, state) and - state.isInputState(sc, stack) and - stack.head() = SummaryComponent::withContent(c) - ) - } - - pragma[noinline] - private predicate viableParam( - DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, SummaryParamNode p - ) { - exists(DataFlowCallable c | - c = inject(sc) and - p = TSummaryParameterNode(sc, ppos) and - c = viableCallable(call) - ) - } - - pragma[nomagic] - private SummaryParamNode summaryArgParam(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { - exists(ParameterPosition ppos | - argumentPositionMatch(call, arg, ppos) and - viableParam(call, sc, ppos, result) - ) - } - - /** - * Holds if `p` can reach `n` in a summarized callable, using only value-preserving - * local steps. `clearsOrExpects` records whether any node on the path from `p` to - * `n` either clears or expects contents. - */ - private predicate paramReachesLocal(SummaryParamNode p, SummaryNode n, boolean clearsOrExpects) { - viableParam(_, _, _, p) and - n = p and - clearsOrExpects = false - or - exists(SummaryNode mid, boolean clearsOrExpectsMid | - paramReachesLocal(p, mid, clearsOrExpectsMid) and - summaryLocalStep(mid, n, true) and - if - summaryClearsContent(n, _) or - summaryExpectsContent(n, _) - then clearsOrExpects = true - else clearsOrExpects = clearsOrExpectsMid - ) - } - - /** - * Holds if use-use flow starting from `arg` should be prohibited. - * - * This is the case when `arg` is the argument of a call that targets a - * flow summary where the corresponding parameter either clears contents - * or expects contents. - */ - pragma[nomagic] - predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) { - exists(SummaryParamNode p, ParameterPosition ppos, SummaryNode ret | - paramReachesLocal(p, ret, true) and - p = summaryArgParam(_, arg, sc) and - p = TSummaryParameterNode(_, pragma[only_bind_into](ppos)) and - isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos)) - ) - } - - pragma[nomagic] - private predicate summaryReturnNodeExt(SummaryNode ret, ReturnKindExt rk) { - summaryReturnNode(ret, rk.(ValueReturnKind).getKind()) - or - exists(SummaryParamNode p, SummaryNode pre, ParameterPosition pos | - paramReachesLocal(p, pre, _) and - summaryPostUpdateNode(ret, pre) and - p = TSummaryParameterNode(_, pos) and - rk.(ParamUpdateReturnKind).getPosition() = pos - ) - } - - bindingset[ret] - private SummaryParamNode summaryArgParamRetOut( - ArgNode arg, SummaryNode ret, OutNodeExt out, SummarizedCallable sc - ) { - exists(DataFlowCall call, ReturnKindExt rk | - result = summaryArgParam(call, arg, sc) and - summaryReturnNodeExt(ret, pragma[only_bind_into](rk)) and - out = pragma[only_bind_into](rk).getAnOutNode(call) - ) - } - - /** - * Holds if `arg` flows to `out` using a simple value-preserving flow - * summary, that is, a flow summary without reads and stores. - * - * NOTE: This step should not be used in global data-flow/taint-tracking, but may - * be useful to include in the exposed local data-flow/taint-tracking relations. - */ - predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) { - exists(ReturnKind rk, SummaryNode ret, DataFlowCall call | - summaryLocalStep(summaryArgParam(call, arg, sc), ret, true) and - summaryReturnNode(ret, pragma[only_bind_into](rk)) and - out = getAnOutNode(call, pragma[only_bind_into](rk)) - ) - } - - /** - * Holds if `arg` flows to `out` using a simple flow summary involving taint - * step, that is, a flow summary without reads and stores. - * - * NOTE: This step should not be used in global data-flow/taint-tracking, but may - * be useful to include in the exposed local data-flow/taint-tracking relations. - */ - predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) { - exists(SummaryNode ret | - summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, false) - ) - } - - /** - * Holds if there is a read(+taint) of `c` from `arg` to `out` using a - * flow summary. - * - * NOTE: This step should not be used in global data-flow/taint-tracking, but may - * be useful to include in the exposed local data-flow/taint-tracking relations. - */ - predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { - exists(SummaryNode mid, SummaryNode ret | - summaryReadStep(summaryArgParamRetOut(arg, ret, out, sc), c, mid) and - summaryLocalStep(mid, ret, _) - ) - } - - /** - * Holds if there is a (taint+)store of `arg` into content `c` of `out` using a - * flow summary. - * - * NOTE: This step should not be used in global data-flow/taint-tracking, but may - * be useful to include in the exposed local data-flow/taint-tracking relations. - */ - predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { - exists(SummaryNode mid, SummaryNode ret | - summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), mid, _) and - summaryStoreStep(mid, c, ret) - ) - } - } - - /** Holds if `spec` is a relevant external specification. */ - private predicate relevantSpec(string spec) { - summaryElement(_, spec, _, _, _) or - summaryElement(_, _, spec, _, _) or - sourceElement(_, spec, _, _) or - sinkElement(_, spec, _, _) - } - - import AccessPath - - /** - * Provides a means of translating externally (e.g., MaD) defined flow - * summaries into a `SummarizedCallable`s. - */ - module External { - /** Holds if specification component `token` parses as parameter `pos`. */ - predicate parseParam(AccessPathToken token, ArgumentPosition pos) { - token.getName() = "Parameter" and - pos = parseParamBody(token.getAnArgument()) - } - - /** Holds if specification component `token` parses as argument `pos`. */ - predicate parseArg(AccessPathToken token, ParameterPosition pos) { - token.getName() = "Argument" and - pos = parseArgBody(token.getAnArgument()) - } - - /** Holds if specification component `token` parses as synthetic global `sg`. */ - predicate parseSynthGlobal(AccessPathToken token, string sg) { - token.getName() = "SyntheticGlobal" and - sg = token.getAnArgument() - } - - private class SyntheticGlobalFromAccessPath extends SummaryComponent::SyntheticGlobal { - SyntheticGlobalFromAccessPath() { parseSynthGlobal(_, this) } - } - - private SummaryComponent interpretComponent(AccessPathToken token) { - exists(ParameterPosition pos | - parseArg(token, pos) and result = SummaryComponent::argument(pos) - ) - or - exists(ArgumentPosition pos | - parseParam(token, pos) and result = SummaryComponent::parameter(pos) - ) - or - token = "ReturnValue" and result = SummaryComponent::return(getReturnValueKind()) - or - exists(string sg | - parseSynthGlobal(token, sg) and result = SummaryComponent::syntheticGlobal(sg) - ) - or - result = interpretComponentSpecific(token) - } - - /** - * Holds if `spec` specifies summary component stack `stack`. - */ - predicate interpretSpec(AccessPath spec, SummaryComponentStack stack) { - interpretSpec(spec, spec.getNumToken(), stack) - } - - /** Holds if the first `n` tokens of `spec` resolves to `stack`. */ - private predicate interpretSpec(AccessPath spec, int n, SummaryComponentStack stack) { - n = 1 and - stack = SummaryComponentStack::singleton(interpretComponent(spec.getToken(0))) - or - exists(SummaryComponent head, SummaryComponentStack tail | - interpretSpec(spec, n, head, tail) and - stack = SummaryComponentStack::push(head, tail) - ) - } - - /** Holds if the first `n` tokens of `spec` resolves to `head` followed by `tail` */ - private predicate interpretSpec( - AccessPath spec, int n, SummaryComponent head, SummaryComponentStack tail - ) { - interpretSpec(spec, n - 1, tail) and - head = interpretComponent(spec.getToken(n - 1)) - } - - private class MkStack extends RequiredSummaryComponentStack { - override predicate required(SummaryComponent head, SummaryComponentStack tail) { - interpretSpec(_, _, head, tail) - } - } - - private class SummarizedCallableExternal extends SummarizedCallable { - SummarizedCallableExternal() { summaryElement(this, _, _, _, _) } - - private predicate relevantSummaryElementGenerated( - AccessPath inSpec, AccessPath outSpec, string kind - ) { - exists(Provenance provenance | - provenance.isGenerated() and - summaryElement(this, inSpec, outSpec, kind, provenance) - ) and - not this.applyManualModel() - } - - private predicate relevantSummaryElement(AccessPath inSpec, AccessPath outSpec, string kind) { - exists(Provenance provenance | - provenance.isManual() and - summaryElement(this, inSpec, outSpec, kind, provenance) - ) - or - this.relevantSummaryElementGenerated(inSpec, outSpec, kind) - } - - override predicate propagatesFlow( - SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue - ) { - exists(AccessPath inSpec, AccessPath outSpec, string kind | - this.relevantSummaryElement(inSpec, outSpec, kind) and - interpretSpec(inSpec, input) and - interpretSpec(outSpec, output) - | - kind = "value" and preservesValue = true - or - kind = "taint" and preservesValue = false - ) - } - - override predicate hasProvenance(Provenance provenance) { - summaryElement(this, _, _, _, provenance) - } - } - - /** Holds if component `c` of specification `spec` cannot be parsed. */ - predicate invalidSpecComponent(AccessPath spec, string c) { - c = spec.getToken(_) and - not exists(interpretComponent(c)) - } - - /** Holds if `provenance` is not a valid provenance value. */ - bindingset[provenance] - predicate invalidProvenance(string provenance) { not provenance instanceof Provenance } - - /** - * Holds if token `part` of specification `spec` has an invalid index. - * E.g., `Argument[-1]`. - */ - predicate invalidIndexComponent(AccessPath spec, AccessPathToken part) { - part = spec.getToken(_) and - part.getName() = ["Parameter", "Argument"] and - parseInt(part.getArgumentList()) < 0 - } - - private predicate inputNeedsReference(AccessPathToken c) { - c.getName() = "Argument" or - inputNeedsReferenceSpecific(c) - } - - private predicate outputNeedsReference(AccessPathToken c) { - c.getName() = ["Argument", "ReturnValue"] or - outputNeedsReferenceSpecific(c) - } - - private predicate sourceElementRef(InterpretNode ref, AccessPath output, string kind) { - exists(SourceOrSinkElement e | - sourceElement(e, output, kind, _) and - if outputNeedsReference(output.getToken(0)) - then e = ref.getCallTarget() - else e = ref.asElement() - ) - } - - private predicate sinkElementRef(InterpretNode ref, AccessPath input, string kind) { - exists(SourceOrSinkElement e | - sinkElement(e, input, kind, _) and - if inputNeedsReference(input.getToken(0)) - then e = ref.getCallTarget() - else e = ref.asElement() - ) - } - - /** Holds if the first `n` tokens of `output` resolve to the given interpretation. */ - private predicate interpretOutput( - AccessPath output, int n, InterpretNode ref, InterpretNode node - ) { - sourceElementRef(ref, output, _) and - n = 0 and - ( - if output = "" - then - // Allow language-specific interpretation of the empty access path - interpretOutputSpecific("", ref, node) - else node = ref - ) - or - exists(InterpretNode mid, AccessPathToken c | - interpretOutput(output, n - 1, ref, mid) and - c = output.getToken(n - 1) - | - exists(ArgumentPosition apos, ParameterPosition ppos | - node.asNode().(PostUpdateNode).getPreUpdateNode().(ArgNode).argumentOf(mid.asCall(), apos) and - parameterMatch(ppos, apos) - | - c = "Argument" or parseArg(c, ppos) - ) - or - exists(ArgumentPosition apos, ParameterPosition ppos | - node.asNode().(ParamNode).isParameterOf(mid.asCallable(), ppos) and - parameterMatch(ppos, apos) - | - c = "Parameter" or parseParam(c, apos) - ) - or - c = "ReturnValue" and - node.asNode() = getAnOutNodeExt(mid.asCall(), TValueReturn(getReturnValueKind())) - or - interpretOutputSpecific(c, mid, node) - ) - } - - /** Holds if the first `n` tokens of `input` resolve to the given interpretation. */ - private predicate interpretInput(AccessPath input, int n, InterpretNode ref, InterpretNode node) { - sinkElementRef(ref, input, _) and - n = 0 and - ( - if input = "" - then - // Allow language-specific interpretation of the empty access path - interpretInputSpecific("", ref, node) - else node = ref - ) - or - exists(InterpretNode mid, AccessPathToken c | - interpretInput(input, n - 1, ref, mid) and - c = input.getToken(n - 1) - | - exists(ArgumentPosition apos, ParameterPosition ppos | - node.asNode().(ArgNode).argumentOf(mid.asCall(), apos) and - parameterMatch(ppos, apos) - | - c = "Argument" or parseArg(c, ppos) - ) - or - exists( - ReturnNode ret // TODO: hacked to make this compile; need to switch to module in qlpack - | - c = "ReturnValue" and - ret = node.asNode() and - ret.getKind() = getReturnValueKind() and - mid.asCallable() = getNodeEnclosingCallable(ret) - ) - or - interpretInputSpecific(c, mid, node) - ) - } - - /** - * Holds if `node` is specified as a source with the given kind in a MaD flow - * model. - */ - predicate isSourceNode(InterpretNode node, string kind) { - exists(InterpretNode ref, AccessPath output | - sourceElementRef(ref, output, kind) and - interpretOutput(output, output.getNumToken(), ref, node) - ) - } - - /** - * Holds if `node` is specified as a sink with the given kind in a MaD flow - * model. - */ - predicate isSinkNode(InterpretNode node, string kind) { - exists(InterpretNode ref, AccessPath input | - sinkElementRef(ref, input, kind) and - interpretInput(input, input.getNumToken(), ref, node) - ) - } - } - - /** Provides a query predicate for outputting a set of relevant flow summaries. */ - module TestOutput { - /** A flow summary to include in the `summary/1` query predicate. */ - abstract class RelevantSummarizedCallable instanceof SummarizedCallable { - /** Gets the string representation of this callable used by `summary/1`. */ - abstract string getCallableCsv(); - - /** Holds if flow is propagated between `input` and `output`. */ - predicate relevantSummary( - SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue - ) { - super.propagatesFlow(input, output, preservesValue) - } - - string toString() { result = super.toString() } - } - - /** A model to include in the `neutral/1` query predicate. */ - abstract class RelevantNeutralCallable instanceof NeutralCallable { - /** Gets the string representation of this callable used by `neutral/1`. */ - abstract string getCallableCsv(); - - /** - * Gets the kind of the neutral. - */ - string getKind() { result = super.getKind() } - - string toString() { result = super.toString() } - } - - /** Render the kind in the format used in flow summaries. */ - private string renderKind(boolean preservesValue) { - preservesValue = true and result = "value" - or - preservesValue = false and result = "taint" - } - - private string renderProvenance(SummarizedCallable c) { - if c.applyManualModel() then result = "manual" else c.hasProvenance(result) - } - - private string renderProvenanceNeutral(NeutralCallable c) { - if c.hasManualModel() then result = "manual" else c.hasProvenance(result) - } - - /** - * A query predicate for outputting flow summaries in semi-colon separated format in QL tests. - * The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind;provenance", - * ext is hardcoded to empty. - */ - query predicate summary(string csv) { - exists( - RelevantSummarizedCallable c, SummaryComponentStack input, SummaryComponentStack output, - boolean preservesValue - | - c.relevantSummary(input, output, preservesValue) and - csv = - c.getCallableCsv() // Callable information - + input.getMadRepresentation() + ";" // input - + output.getMadRepresentation() + ";" // output - + renderKind(preservesValue) + ";" // kind - + renderProvenance(c) // provenance - ) - } - - /** - * Holds if a neutral model `csv` exists (semi-colon separated format). Used for testing purposes. - * The syntax is: "namespace;type;name;signature;kind;provenance"", - */ - query predicate neutral(string csv) { - exists(RelevantNeutralCallable c | - csv = - c.getCallableCsv() // Callable information - + c.getKind() + ";" // kind - + renderProvenanceNeutral(c) // provenance - ) - } - } - - /** - * Provides query predicates for rendering the generated data flow graph for - * a summarized callable. - * - * Import this module into a `.ql` file of `@kind graph` to render the graph. - * The graph is restricted to callables from `RelevantSummarizedCallable`. - */ - module RenderSummarizedCallable { - /** A summarized callable to include in the graph. */ - abstract class RelevantSummarizedCallable instanceof SummarizedCallable { - string toString() { result = super.toString() } - } - - private newtype TNodeOrCall = - MkNode(SummaryNode n) { - exists(RelevantSummarizedCallable c | - n = TSummaryInternalNode(c, _) - or - n = TSummaryParameterNode(c, _) - ) - } or - MkCall(DataFlowCall call) { - call = summaryDataFlowCall(_) and - call.getEnclosingCallable() = inject(any(RelevantSummarizedCallable c)) - } - - private class NodeOrCall extends TNodeOrCall { - SummaryNode asNode() { this = MkNode(result) } - - DataFlowCall asCall() { this = MkCall(result) } - - string toString() { - result = this.asNode().toString() - or - result = this.asCall().toString() - } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - filepath = "" and - startline = 0 and - startcolumn = 0 and - endline = 0 and - endcolumn = 0 - } - } - - query predicate nodes(NodeOrCall n, string key, string val) { - key = "semmle.label" and val = n.toString() - } - - private predicate edgesComponent(NodeOrCall a, NodeOrCall b, string value) { - exists(boolean preservesValue | - Private::Steps::summaryLocalStep(a.asNode(), b.asNode(), preservesValue) and - if preservesValue = true then value = "value" else value = "taint" - ) - or - exists(ContentSet c | - Private::Steps::summaryReadStep(a.asNode(), c, b.asNode()) and - value = "read (" + c + ")" - or - Private::Steps::summaryStoreStep(a.asNode(), c, b.asNode()) and - value = "store (" + c + ")" - or - Private::Steps::summaryClearsContent(a.asNode(), c) and - b = a and - value = "clear (" + c + ")" - or - Private::Steps::summaryExpectsContent(a.asNode(), c) and - b = a and - value = "expect (" + c + ")" - ) - or - summaryPostUpdateNode(b.asNode(), a.asNode()) and - value = "post-update" - or - b.asCall() = summaryDataFlowCall(a.asNode()) and - value = "receiver" - or - exists(ArgumentPosition pos | - summaryArgumentNode(b.asCall(), a.asNode(), pos) and - value = "argument (" + pos + ")" - ) - } - - query predicate edges(NodeOrCall a, NodeOrCall b, string key, string value) { - key = "semmle.label" and - value = strictconcat(string s | edgesComponent(a, b, s) | s, " / ") - } - } -} +private import semmle.javascript.Locations +private import codeql.dataflow.internal.FlowSummaryImpl +private import DataFlowArg +import Make diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImplSpecific.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImplSpecific.qll deleted file mode 100644 index 71b4db2f016..00000000000 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImplSpecific.qll +++ /dev/null @@ -1 +0,0 @@ -import semmle.javascript.dataflow.internal.FlowSummaryPrivate From 8c4e5e8876f6a3a3834a19552691d1dd2a69ee20 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 26 Jun 2024 13:16:10 +0200 Subject: [PATCH 203/514] Boilerplate implementation of default predicates from FlowSummaryImpl.qll --- .../dataflow/internal/FlowSummaryPrivate.qll | 94 +++++++++++++++++++ .../internal/sharedlib/DataFlowArg.qll | 20 ++++ 2 files changed, 114 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index d6877308786..f329057f72c 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -374,3 +374,97 @@ private module FlowSummaryStepInput implements Private::StepsInputSig { } module Steps = Private::Steps; + +/** + * Gets the textual representation of content `c` used in MaD. + * + * `arg` will be printed in square brackets (`[]`) after the result, unless + * `arg` is the empty string. + */ +string encodeContent(ContentSet c, string arg) { none() } + +/** + * Gets the textual representation of return kind `rk` used in MaD. + * + * `arg` will be printed in square brackets (`[]`) after the result, unless + * `arg` is the empty string. + */ +string encodeReturn(ReturnKind rk, string arg) { none() } + +/** + * Gets the textual representation of without-content `c` used in MaD. + * + * `arg` will be printed in square brackets (`[]`) after the result, unless + * `arg` is the empty string. + */ +string encodeWithoutContent(ContentSet c, string arg) { none() } + +/** + * Gets the textual representation of with-content `c` used in MaD. + * + * `arg` will be printed in square brackets (`[]`) after the result, unless + * `arg` is the empty string. + */ +string encodeWithContent(ContentSet c, string arg) { none() } + +/** + * Gets a parameter position corresponding to the unknown token `token`. + * + * The token is unknown because it could not be reverse-encoded using the + * `encodeParameterPosition` predicate. This is useful for example when a + * single token gives rise to multiple parameter positions, such as ranges + * `0..n`. + */ +bindingset[token] +ParameterPosition decodeUnknownParameterPosition(AccessPathSyntax::AccessPathTokenBase token) { + none() +} + +/** + * Gets an argument position corresponding to the unknown token `token`. + * + * The token is unknown because it could not be reverse-encoded using the + * `encodeArgumentPosition` predicate. This is useful for example when a + * single token gives rise to multiple argument positions, such as ranges + * `0..n`. + */ +bindingset[token] +ArgumentPosition decodeUnknownArgumentPosition(AccessPathSyntax::AccessPathTokenBase token) { + none() +} + +/** + * Gets a content corresponding to the unknown token `token`. + * + * The token is unknown because it could not be reverse-encoded using the + * `encodeContent` predicate. + */ +bindingset[token] +ContentSet decodeUnknownContent(AccessPathSyntax::AccessPathTokenBase token) { none() } + +/** + * Gets a return kind corresponding to the unknown token `token`. + * + * The token is unknown because it could not be reverse-encoded using the + * `encodeReturn` predicate. + */ +bindingset[token] +ReturnKind decodeUnknownReturn(AccessPathSyntax::AccessPathTokenBase token) { none() } + +/** + * Gets a without-content corresponding to the unknown token `token`. + * + * The token is unknown because it could not be reverse-encoded using the + * `encodeWithoutContent` predicate. + */ +bindingset[token] +ContentSet decodeUnknownWithoutContent(AccessPathSyntax::AccessPathTokenBase token) { none() } + +/** + * Gets a with-content corresponding to the unknown token `token`. + * + * The token is unknown because it could not be reverse-encoded using the + * `encodeWithContent` predicate. + */ +bindingset[token] +ContentSet decodeUnknownWithContent(AccessPathSyntax::AccessPathTokenBase token) { none() } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll index fae8bb76fca..c911461788d 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll @@ -30,4 +30,24 @@ module JSFlowSummary implements FlowSummaryImpl::InputSig // Explicitly implement signature members that have a default predicate callbackSelfParameterPosition = FlowSummaryPrivate::callbackSelfParameterPosition/0; + + predicate encodeContent = FlowSummaryPrivate::encodeContent/2; + + predicate encodeReturn = FlowSummaryPrivate::encodeReturn/2; + + predicate encodeWithoutContent = FlowSummaryPrivate::encodeWithoutContent/2; + + predicate encodeWithContent = FlowSummaryPrivate::encodeWithContent/2; + + predicate decodeUnknownParameterPosition = FlowSummaryPrivate::decodeUnknownParameterPosition/1; + + predicate decodeUnknownArgumentPosition = FlowSummaryPrivate::decodeUnknownArgumentPosition/1; + + predicate decodeUnknownContent = FlowSummaryPrivate::decodeUnknownContent/1; + + predicate decodeUnknownReturn = FlowSummaryPrivate::decodeUnknownReturn/1; + + predicate decodeUnknownWithoutContent = FlowSummaryPrivate::decodeUnknownWithoutContent/1; + + predicate decodeUnknownWithContent = FlowSummaryPrivate::decodeUnknownWithContent/1; } From 5811a3c5a6767fbf403a9770d3553098e0741ab1 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 26 Jun 2024 13:24:27 +0200 Subject: [PATCH 204/514] Port getMadStringFromContentSet -> encodeContent --- .../dataflow/internal/FlowSummaryPrivate.qll | 83 +++++++++---------- 1 file changed, 37 insertions(+), 46 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index f329057f72c..b2cbe31f90b 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -221,63 +221,62 @@ Private::SummaryComponent interpretComponentSpecific(Private::AccessPathToken c) result = Private::SummaryComponent::content(MkArrayElementDeep()) } -private string getMadStringFromContentSetAux(ContentSet cs) { +private string encodeContentAux(ContentSet cs, string arg) { cs = ContentSet::arrayElement() and - result = "ArrayElement" + result = "ArrayElement" and + arg = "" or cs = ContentSet::arrayElementUnknown() and - result = "ArrayElement[?]" + result = "ArrayElement" and + arg = "?" or exists(int n | cs = ContentSet::arrayElementLowerBound(n) and - result = "ArrayElement[" + n + "..]" and + result = "ArrayElement" and + arg = n + ".." and n > 0 // n=0 is just 'ArrayElement' or cs = ContentSet::arrayElementKnown(n) and - result = "ArrayElement[" + n + "]" + result = "ArrayElement" and + arg = n.toString() or n = cs.asPropertyName().toInt() and n >= 0 and - result = "ArrayElement[" + n + "!]" + result = "ArrayElement" and + arg = n + "!" ) or - cs = ContentSet::mapValueAll() and result = "MapValue" - or - cs = ContentSet::mapKey() and result = "MapKey" - or - cs = ContentSet::setElement() and result = "SetElement" - or - cs = ContentSet::iteratorElement() and result = "IteratorElement" - or - cs = ContentSet::iteratorError() and result = "IteratorError" - or - exists(string awaitedArg | - cs = getPromiseContent(awaitedArg) and - result = "Awaited[" + awaitedArg + "]" + arg = "" and + ( + cs = ContentSet::mapValueAll() and result = "MapValue" + or + cs = ContentSet::mapKey() and result = "MapKey" + or + cs = ContentSet::setElement() and result = "SetElement" + or + cs = ContentSet::iteratorElement() and result = "IteratorElement" + or + cs = ContentSet::iteratorError() and result = "IteratorError" ) or - cs = MkAwaited() and result = "Awaited" + cs = getPromiseContent(arg) and + result = "Awaited" + or + cs = MkAwaited() and result = "Awaited" and arg = "" } -private string getMadStringFromContentSet(ContentSet cs) { - result = getMadStringFromContentSetAux(cs) +/** + * Gets the textual representation of content `cs` used in MaD. + * + * `arg` will be printed in square brackets (`[]`) after the result, unless + * `arg` is the empty string. + */ +string encodeContent(ContentSet cs, string arg) { + result = encodeContentAux(cs, arg) or - not exists(getMadStringFromContentSetAux(cs)) and - result = "Member[" + cs.asSingleton() + "]" -} - -/** Gets the textual representation of a summary component in the format used for MaD models. */ -string getMadRepresentationSpecific(Private::SummaryComponent sc) { - exists(ContentSet cs | - sc = Private::SummaryComponent::content(cs) and - result = getMadStringFromContentSet(cs) - ) - or - exists(ReturnKind rk | - sc = Private::SummaryComponent::return(rk) and - not rk = getReturnValueKind() and - result = "ReturnValue[" + rk + "]" - ) + not exists(encodeContentAux(cs, _)) and + result = "Member" and + arg = cs.asSingleton().toString() } /** Gets the textual representation of a parameter position in the format used for flow summaries. */ @@ -375,14 +374,6 @@ private module FlowSummaryStepInput implements Private::StepsInputSig { module Steps = Private::Steps; -/** - * Gets the textual representation of content `c` used in MaD. - * - * `arg` will be printed in square brackets (`[]`) after the result, unless - * `arg` is the empty string. - */ -string encodeContent(ContentSet c, string arg) { none() } - /** * Gets the textual representation of return kind `rk` used in MaD. * From b0ea81276b7bfad799757c65a5617b1fa284bebf Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 26 Jun 2024 13:27:18 +0200 Subject: [PATCH 205/514] Implement encodeReturn --- .../javascript/dataflow/internal/FlowSummaryPrivate.qll | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index b2cbe31f90b..6886672049e 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -380,7 +380,14 @@ module Steps = Private::Steps; * `arg` will be printed in square brackets (`[]`) after the result, unless * `arg` is the empty string. */ -string encodeReturn(ReturnKind rk, string arg) { none() } +string encodeReturn(ReturnKind rk, string arg) { + result = "ReturnValue" and + ( + rk = MkNormalReturnKind() and arg = "" + or + rk = MkExceptionalReturnKind() and arg = "exception" + ) +} /** * Gets the textual representation of without-content `c` used in MaD. From 6c0c67dce47a07b55042d546dc7ed350513fff49 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 26 Jun 2024 13:28:48 +0200 Subject: [PATCH 206/514] Implement encodeWith/WithoutContent --- .../javascript/dataflow/internal/FlowSummaryPrivate.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index 6886672049e..89c282384d4 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -395,7 +395,7 @@ string encodeReturn(ReturnKind rk, string arg) { * `arg` will be printed in square brackets (`[]`) after the result, unless * `arg` is the empty string. */ -string encodeWithoutContent(ContentSet c, string arg) { none() } +string encodeWithoutContent(ContentSet c, string arg) { result = "Without" + encodeContent(c, arg) } /** * Gets the textual representation of with-content `c` used in MaD. @@ -403,7 +403,7 @@ string encodeWithoutContent(ContentSet c, string arg) { none() } * `arg` will be printed in square brackets (`[]`) after the result, unless * `arg` is the empty string. */ -string encodeWithContent(ContentSet c, string arg) { none() } +string encodeWithContent(ContentSet c, string arg) { result = "With" + encodeContent(c, arg) } /** * Gets a parameter position corresponding to the unknown token `token`. From 3bebd709b34731aa92966a49e97f7053b92ef476 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 26 Jun 2024 13:38:28 +0200 Subject: [PATCH 207/514] Handle AnyMemberDeep and ArrayElementDeep in encodeContent --- .../javascript/dataflow/internal/FlowSummaryPrivate.qll | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index 89c282384d4..dc0821b74b6 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -263,6 +263,10 @@ private string encodeContentAux(ContentSet cs, string arg) { result = "Awaited" or cs = MkAwaited() and result = "Awaited" and arg = "" + or + cs = MkAnyPropertyDeep() and result = "AnyMemberDeep" and arg = "" + or + cs = MkArrayElementDeep() and result = "ArrayElementDeep" and arg = "" } /** From e67e89dd70b246bb9f7bff86a3c854b570f5889f Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 26 Jun 2024 13:39:04 +0200 Subject: [PATCH 208/514] Implement decodeUnknownArgument/ParameterPosition --- .../javascript/dataflow/internal/FlowSummaryPrivate.qll | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index dc0821b74b6..54fae7d8a6d 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -419,7 +419,8 @@ string encodeWithContent(ContentSet c, string arg) { result = "With" + encodeCon */ bindingset[token] ParameterPosition decodeUnknownParameterPosition(AccessPathSyntax::AccessPathTokenBase token) { - none() + token.getName() = "Parameter" and + desugaredPositionName(result, token.getAnArgument()) } /** @@ -432,7 +433,8 @@ ParameterPosition decodeUnknownParameterPosition(AccessPathSyntax::AccessPathTok */ bindingset[token] ArgumentPosition decodeUnknownArgumentPosition(AccessPathSyntax::AccessPathTokenBase token) { - none() + token.getName() = "Argument" and + desugaredPositionName(result, token.getAnArgument()) } /** From fc7c2c5b1705ee256ae0ae842bfab47b29be909a Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 26 Jun 2024 13:48:51 +0200 Subject: [PATCH 209/514] Remove unused code --- .../dataflow/internal/FlowSummaryPrivate.qll | 239 ------------------ 1 file changed, 239 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index 54fae7d8a6d..1186c713e9a 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -5,113 +5,19 @@ private import javascript private import semmle.javascript.dataflow.internal.DataFlowPrivate private import semmle.javascript.dataflow.internal.Contents::Private -private import semmle.javascript.dataflow.FlowSummary as FlowSummary private import sharedlib.DataFlowImplCommon private import sharedlib.FlowSummaryImpl::Private as Private private import sharedlib.FlowSummaryImpl::Public private import codeql.dataflow.internal.AccessPathSyntax as AccessPathSyntax -private class Node = DataFlow::Node; - /** * A class of callables that are candidates for flow summary modeling. */ class SummarizedCallableBase = string; -/** - * A class of callables that are candidates for neutral modeling. - */ -class NeutralCallableBase = string; - -/** - * Holds if a neutral model exists for `c` of kind `kind` and with provenance `provenance`. - * Note: Neutral models have not been implemented for Javascript. - */ -predicate neutralElement(NeutralCallableBase c, string kind, string provenance) { none() } - -DataFlowCallable inject(SummarizedCallable c) { result.asLibraryCallable() = c } - /** Gets the parameter position representing a callback itself, if any. */ ArgumentPosition callbackSelfParameterPosition() { result.isFunctionSelfReference() } -/** Gets the synthesized data-flow call for `receiver`. */ -SummaryCall summaryDataFlowCall(Private::SummaryNode receiver) { receiver = result.getReceiver() } - -/** Gets the type of content `c`. */ -DataFlowType getContentType(ContentSet c) { result = TAnyType() and exists(c) } - -/** Gets the type of the parameter at the given position. */ -bindingset[c, pos] -DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) { - // TODO: we could assign a more precise type to the function self-reference parameter - result = TAnyType() and exists(c) and exists(pos) -} - -/** Gets the return type of kind `rk` for callable `c`. */ -bindingset[c, rk] -DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { - result = TAnyType() and exists(c) and exists(rk) -} - -/** - * Gets the type of the `i`th parameter in a synthesized call that targets a - * callback of type `t`. - */ -bindingset[t, pos] -DataFlowType getCallbackParameterType(DataFlowType t, ArgumentPosition pos) { - result = TAnyType() and exists(t) and exists(pos) -} - -/** - * Gets the return type of kind `rk` in a synthesized call that targets a - * callback of type `t`. - */ -DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { - result = TAnyType() and exists(t) and exists(rk) -} - -/** - * Holds if an external flow summary exists for `c` with input specification - * `input`, output specification `output`, kind `kind`, and provenance `provenance`. - */ -predicate summaryElement( - FlowSummary::SummarizedCallable c, string input, string output, string kind, string provenance -) { - exists(boolean preservesValue | - c.propagatesFlowExt(input, output, preservesValue) and - (if preservesValue = true then kind = "value" else kind = "taint") and - provenance = "manual" - ) -} - -/** - * Holds if a neutral summary model exists for `c` with provenance `provenance`, - * which means that there is no flow through `c`. - * Note. Neutral models have not been implemented for JS. - */ -predicate neutralSummaryElement(FlowSummary::SummarizedCallable c, string provenance) { none() } - -pragma[inline] -private Private::SummaryComponent makeContentComponents( - Private::AccessPathToken token, string name, ContentSet contents -) { - token.getName() = name and - result = Private::SummaryComponent::content(contents) - or - token.getName() = "With" + name and - result = Private::SummaryComponent::withContent(contents) - or - token.getName() = "Without" + name and - result = Private::SummaryComponent::withoutContent(contents) -} - -pragma[inline] -private Private::SummaryComponent makePropertyContentComponents( - Private::AccessPathToken token, string name, PropertyName content -) { - result = makeContentComponents(token, name, ContentSet::property(content)) -} - /** * Gets the content set corresponding to `Awaited[arg]`. */ @@ -145,82 +51,6 @@ private predicate desugaredPositionName(ParameterPosition pos, string operand) { pos.asPositional() = AccessPathSyntax::parseInt(operand) // parse closed intervals } -bindingset[operand] -private ParameterPosition parsePosition(string operand) { - positionName(result, operand) or desugaredPositionName(result, operand) -} - -/** - * Gets the summary component for specification component `c`, if any. - * - * This covers all the JS-specific components of a flow summary. - */ -Private::SummaryComponent interpretComponentSpecific(Private::AccessPathToken c) { - c.getName() = "Argument" and - result = Private::SummaryComponent::argument(parsePosition(c.getAnArgument())) - or - c.getName() = "Parameter" and - result = Private::SummaryComponent::parameter(parsePosition(c.getAnArgument())) - or - result = makePropertyContentComponents(c, "Member", c.getAnArgument()) - or - result = makeContentComponents(c, "Awaited", getPromiseContent(c.getAnArgument())) - or - c.getNumArgument() = 0 and - result = makeContentComponents(c, "ArrayElement", ContentSet::arrayElement()) - or - c.getAnArgument() = "?" and - result = makeContentComponents(c, "ArrayElement", ContentSet::arrayElementUnknown()) - or - exists(int n | - n = c.getAnArgument().toInt() and - result = makeContentComponents(c, "ArrayElement", ContentSet::arrayElementKnown(n)) - or - // ArrayElement[n!] refers to index n, and never the unknown content - c.getAnArgument().regexpCapture("(\\d+)!", 1).toInt() = n and - result = makePropertyContentComponents(c, "ArrayElement", n.toString()) - or - // ArrayElement[n..] refers to index n or greater - n = AccessPathSyntax::parseLowerBound(c.getAnArgument()) and - result = makeContentComponents(c, "ArrayElement", ContentSet::arrayElementLowerBoundFromInt(n)) - ) - or - c.getNumArgument() = 0 and - result = makeContentComponents(c, "SetElement", ContentSet::setElement()) - or - c.getNumArgument() = 0 and - result = makeContentComponents(c, "IteratorElement", ContentSet::iteratorElement()) - or - c.getNumArgument() = 0 and - result = makeContentComponents(c, "IteratorError", ContentSet::iteratorError()) - or - c.getNumArgument() = 0 and - result = makeContentComponents(c, "MapKey", ContentSet::mapKey()) - or - // - // Note: although it is supported internally, we currently do not expose a syntax for MapValue with a known key - // - c.getNumArgument() = 0 and - result = makeContentComponents(c, "MapValue", ContentSet::mapValueAll()) - or - c.getName() = "ReturnValue" and - c.getAnArgument() = "exception" and - result = Private::SummaryComponent::return(MkExceptionalReturnKind()) - or - // Awaited is mapped down to a combination steps that handle coercion and promise-flattening. - c.getName() = "Awaited" and - c.getNumArgument() = 0 and - result = Private::SummaryComponent::content(MkAwaited()) - or - c.getName() = "AnyMemberDeep" and - c.getNumArgument() = 0 and - result = Private::SummaryComponent::content(MkAnyPropertyDeep()) - or - c.getName() = "ArrayElementDeep" and - c.getNumArgument() = 0 and - result = Private::SummaryComponent::content(MkArrayElementDeep()) -} - private string encodeContentAux(ContentSet cs, string arg) { cs = ContentSet::arrayElement() and result = "ArrayElement" and @@ -296,78 +126,9 @@ string encodeArgumentPosition(ArgumentPosition pos) { /** Gets the return kind corresponding to specification `"ReturnValue"`. */ ReturnKind getStandardReturnValueKind() { result = MkNormalReturnKind() } -/** Holds if input specification component `c` needs a reference. */ -predicate inputNeedsReferenceSpecific(string c) { none() } - -/** Holds if output specification component `c` needs a reference. */ -predicate outputNeedsReferenceSpecific(string c) { none() } - /** Gets the return kind corresponding to specification `"ReturnValue"`. */ MkNormalReturnKind getReturnValueKind() { any() } -/** - * All definitions in this module are required by the shared implementation - * (for source/sink interpretation), but they are unused for JS, where - * we rely on API graphs instead. - */ -private module UnusedSourceSinkInterpretation { - /** - * Holds if an external source specification exists for `n` with output specification - * `output`, kind `kind`, and provenance `provenance`. - */ - predicate sourceElement(AstNode n, string output, string kind, string provenance) { none() } - - /** - * Holds if an external sink specification exists for `n` with input specification - * `input`, kind `kind` and provenance `provenance`. - */ - predicate sinkElement(AstNode n, string input, string kind, string provenance) { none() } - - class SourceOrSinkElement = AstNode; - - /** An entity used to interpret a source/sink specification. */ - class InterpretNode extends AstNode { - /** Gets the element that this node corresponds to, if any. */ - SourceOrSinkElement asElement() { none() } - - /** Gets the data-flow node that this node corresponds to, if any. */ - Node asNode() { none() } - - /** Gets the call that this node corresponds to, if any. */ - DataFlowCall asCall() { none() } - - /** Gets the callable that this node corresponds to, if any. */ - DataFlowCallable asCallable() { none() } - - /** Gets the target of this call, if any. */ - StmtContainer getCallTarget() { none() } - } - - /** Provides additional sink specification logic. */ - predicate interpretOutputSpecific(string c, InterpretNode mid, InterpretNode node) { none() } - - /** Provides additional source specification logic. */ - predicate interpretInputSpecific(string c, InterpretNode mid, InterpretNode node) { none() } -} - -import UnusedSourceSinkInterpretation - -/** Gets the argument position obtained by parsing `X` in `Parameter[X]`. */ -bindingset[s] -ArgumentPosition parseParamBody(string s) { - s = "this" and result.isThis() - or - s = "function" and result.isFunctionSelfReference() - or - result.asPositional() = AccessPathSyntax::parseInt(s) -} - -/** Gets the parameter position obtained by parsing `X` in `Argument[X]`. */ -bindingset[s] -ParameterPosition parseArgBody(string s) { - result = parseParamBody(s) // Currently these are identical -} - private module FlowSummaryStepInput implements Private::StepsInputSig { DataFlowCall getACall(SummarizedCallable sc) { exists(LibraryCallable callable | callable = sc | From 88edc06517aa6e4031d9c0ce8a092bf38a595bac Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 25 Jun 2024 15:27:30 +0200 Subject: [PATCH 210/514] Avoid bad join in compatibleTypesCached This is identical to the code in Ruby and seems to prevent a bad join ordering in a cached version of this predicate in DataFlowCommon --- .../javascript/dataflow/internal/DataFlowPrivate.qll | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index d768b6995b3..941ce88f3d9 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -373,13 +373,19 @@ predicate neverSkipInPathGraph(Node node) { string ppReprType(DataFlowType t) { none() } +pragma[inline] +private predicate compatibleTypesNonSymRefl(DataFlowType t1, DataFlowType t2) { + t1 != TAnyType() and + t2 = TAnyType() +} + pragma[inline] predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { t1 = t2 or - t1 instanceof TAnyType and exists(t2) + compatibleTypesNonSymRefl(t1, t2) or - t2 instanceof TAnyType and exists(t1) + compatibleTypesNonSymRefl(t2, t1) } predicate forceHighPrecision(Content c) { none() } From 53efb5837bf686aa9e265346dcaffa6aa79081d4 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 26 Jun 2024 11:34:01 +0200 Subject: [PATCH 211/514] JS: Update some tests with provenance columns Only includes the changes that purely contain the new provenance columns --- .../Security/CWE-918/SSRF.expected | 42 +- .../InterProceduralFlow/tests.expected | 21 - .../Templating/CodeInjection.expected | 64 +- .../UntrustedDataToExternalAPI.expected | 58 +- .../Security/CWE-022/ZipSlip/ZipSlip.expected | 26 +- .../CWE-073/TemplateObjectInjection.expected | 56 +- .../SecondOrderCommandInjection.expected | 14 +- .../UnsafeJQueryPlugin.expected | 116 +-- .../XssThroughDom/XssThroughDom.expected | 84 +-- .../CWE-089/typed/SqlInjection.expected | 24 +- .../CodeInjection/CodeInjection.expected | 80 +- .../HeuristicSourceCodeInjection.expected | 82 +- .../UnsafeCodeConstruction.expected | 8 +- .../UnsafeDynamicMethodAccess.expected | 32 +- ...completeHtmlAttributeSanitization.expected | 6 +- .../Security/CWE-117/LogInjection.expected | 130 ++-- .../CWE-200/FileAccessToHttp.expected | 94 +-- .../CWE-209/StackTraceExposure.expected | 14 +- .../CWE-312/CleartextLogging.expected | 132 ++-- .../CWE-312/CleartextStorage.expected | 10 +- .../CWE-338/InsecureRandomness.expected | 44 +- ...orsMisconfigurationForCredentials.expected | 6 +- .../CWE-377/InsecureTemporaryFile.expected | 24 +- .../CWE-400/ReDoS/PolynomialReDoS.expected | 702 +++++++++--------- .../RemotePropertyInjection.expected | 26 +- .../HardcodedDataInterpretedAsCode.expected | 34 +- .../ClientSideUrlRedirect.expected | 168 ++--- .../ServerSideUrlRedirect.expected | 86 +-- .../query-tests/Security/CWE-611/Xxe.expected | 8 +- ...tHeaderPoisoningInEmailGeneration.expected | 4 +- .../Security/CWE-643/XpathInjection.expected | 22 +- .../Security/CWE-730/RegExpInjection.expected | 88 +-- .../UnvalidatedDynamicMethodCall.expected | 108 +-- .../ResourceExhaustion.expected | 58 +- .../Security/CWE-776/XmlBomb.expected | 16 +- .../CWE-807/ConditionalBypass.expected | 30 +- .../CWE-834/LoopBoundInjection.expected | 36 +- ...onfusionThroughParameterTampering.expected | 74 +- .../CWE-912/HttpToFileAccess.expected | 16 +- .../PrototypePollutingAssignment.expected | 204 ++--- .../PrototypePollutingFunction.expected | 392 +++++----- .../PrototypePollutingMergeCall.expected | 50 +- .../CWE-918/ClientSideRequestForgery.expected | 24 +- .../Security/CWE-918/RequestForgery.expected | 96 +-- 44 files changed, 1694 insertions(+), 1715 deletions(-) diff --git a/javascript/ql/test/experimental/Security/CWE-918/SSRF.expected b/javascript/ql/test/experimental/Security/CWE-918/SSRF.expected index 6546ece2568..b2b293a6ca9 100644 --- a/javascript/ql/test/experimental/Security/CWE-918/SSRF.expected +++ b/javascript/ql/test/experimental/Security/CWE-918/SSRF.expected @@ -1,25 +1,25 @@ edges -| check-domain.js:16:9:16:27 | url | check-domain.js:17:13:17:15 | url | -| check-domain.js:16:15:16:27 | req.query.url | check-domain.js:16:9:16:27 | url | -| check-middleware.js:9:27:9:43 | req.query.tainted | check-middleware.js:9:13:9:43 | "test.c ... tainted | -| check-path.js:19:27:19:43 | req.query.tainted | check-path.js:19:13:19:43 | 'test.c ... tainted | -| check-path.js:23:27:23:43 | req.query.tainted | check-path.js:23:13:23:45 | `/addre ... inted}` | -| check-path.js:33:29:33:45 | req.query.tainted | check-path.js:33:15:33:45 | 'test.c ... tainted | -| check-path.js:37:29:37:45 | req.query.tainted | check-path.js:37:15:37:45 | 'test.c ... tainted | -| check-path.js:45:26:45:42 | req.query.tainted | check-path.js:45:13:45:44 | `${base ... inted}` | -| check-regex.js:16:29:16:45 | req.query.tainted | check-regex.js:16:15:16:45 | "test.c ... tainted | -| check-regex.js:24:25:24:42 | req.params.tainted | check-regex.js:24:15:24:42 | baseURL ... tainted | -| check-regex.js:31:29:31:45 | req.query.tainted | check-regex.js:31:15:31:45 | "test.c ... tainted | -| check-regex.js:34:25:34:42 | req.params.tainted | check-regex.js:34:15:34:42 | baseURL ... tainted | -| check-regex.js:41:27:41:43 | req.query.tainted | check-regex.js:41:13:41:43 | "test.c ... tainted | -| check-validator.js:15:29:15:45 | req.query.tainted | check-validator.js:15:15:15:45 | "test.c ... tainted | -| check-validator.js:27:29:27:45 | req.query.tainted | check-validator.js:27:15:27:45 | "test.c ... tainted | -| check-validator.js:50:29:50:45 | req.query.tainted | check-validator.js:50:15:50:45 | "test.c ... tainted | -| check-validator.js:54:9:54:37 | numberURL | check-validator.js:62:29:62:37 | numberURL | -| check-validator.js:54:21:54:37 | req.query.tainted | check-validator.js:54:9:54:37 | numberURL | -| check-validator.js:59:29:59:45 | req.query.tainted | check-validator.js:59:15:59:45 | "test.c ... tainted | -| check-validator.js:62:29:62:37 | numberURL | check-validator.js:62:15:62:37 | "test.c ... mberURL | -| check-validator.js:68:29:68:45 | req.query.tainted | check-validator.js:68:15:68:45 | "test.c ... tainted | +| check-domain.js:16:9:16:27 | url | check-domain.js:17:13:17:15 | url | provenance | | +| check-domain.js:16:15:16:27 | req.query.url | check-domain.js:16:9:16:27 | url | provenance | | +| check-middleware.js:9:27:9:43 | req.query.tainted | check-middleware.js:9:13:9:43 | "test.c ... tainted | provenance | | +| check-path.js:19:27:19:43 | req.query.tainted | check-path.js:19:13:19:43 | 'test.c ... tainted | provenance | | +| check-path.js:23:27:23:43 | req.query.tainted | check-path.js:23:13:23:45 | `/addre ... inted}` | provenance | | +| check-path.js:33:29:33:45 | req.query.tainted | check-path.js:33:15:33:45 | 'test.c ... tainted | provenance | | +| check-path.js:37:29:37:45 | req.query.tainted | check-path.js:37:15:37:45 | 'test.c ... tainted | provenance | | +| check-path.js:45:26:45:42 | req.query.tainted | check-path.js:45:13:45:44 | `${base ... inted}` | provenance | | +| check-regex.js:16:29:16:45 | req.query.tainted | check-regex.js:16:15:16:45 | "test.c ... tainted | provenance | | +| check-regex.js:24:25:24:42 | req.params.tainted | check-regex.js:24:15:24:42 | baseURL ... tainted | provenance | | +| check-regex.js:31:29:31:45 | req.query.tainted | check-regex.js:31:15:31:45 | "test.c ... tainted | provenance | | +| check-regex.js:34:25:34:42 | req.params.tainted | check-regex.js:34:15:34:42 | baseURL ... tainted | provenance | | +| check-regex.js:41:27:41:43 | req.query.tainted | check-regex.js:41:13:41:43 | "test.c ... tainted | provenance | | +| check-validator.js:15:29:15:45 | req.query.tainted | check-validator.js:15:15:15:45 | "test.c ... tainted | provenance | | +| check-validator.js:27:29:27:45 | req.query.tainted | check-validator.js:27:15:27:45 | "test.c ... tainted | provenance | | +| check-validator.js:50:29:50:45 | req.query.tainted | check-validator.js:50:15:50:45 | "test.c ... tainted | provenance | | +| check-validator.js:54:9:54:37 | numberURL | check-validator.js:62:29:62:37 | numberURL | provenance | | +| check-validator.js:54:21:54:37 | req.query.tainted | check-validator.js:54:9:54:37 | numberURL | provenance | | +| check-validator.js:59:29:59:45 | req.query.tainted | check-validator.js:59:15:59:45 | "test.c ... tainted | provenance | | +| check-validator.js:62:29:62:37 | numberURL | check-validator.js:62:15:62:37 | "test.c ... mberURL | provenance | | +| check-validator.js:68:29:68:45 | req.query.tainted | check-validator.js:68:15:68:45 | "test.c ... tainted | provenance | | nodes | check-domain.js:16:9:16:27 | url | semmle.label | url | | check-domain.js:16:15:16:27 | req.query.url | semmle.label | req.query.url | diff --git a/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected b/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected index aab7951f480..81321780859 100644 --- a/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected +++ b/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected @@ -48,12 +48,6 @@ dataFlow | partial.js:6:15:6:24 | "tainted2" | partial.js:42:15:42:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:48:15:48:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:54:15:54:15 | y | -| promises.js:2:16:2:24 | "tainted" | promises.js:7:16:7:18 | val | -| promises.js:2:16:2:24 | "tainted" | promises.js:38:32:38:32 | v | -| promises.js:11:22:11:31 | "resolved" | promises.js:19:20:19:20 | v | -| promises.js:12:22:12:31 | "rejected" | promises.js:21:20:21:20 | v | -| promises.js:12:22:12:31 | "rejected" | promises.js:24:20:24:20 | v | -| promises.js:32:24:32:37 | "also tainted" | promises.js:38:32:38:32 | v | | properties2.js:7:14:7:21 | "source" | properties2.js:8:12:8:24 | foo(source).p | | properties2.js:7:14:7:21 | "source" | properties2.js:17:13:17:15 | o.p | | properties2.js:7:14:7:21 | "source" | properties2.js:33:13:33:20 | getP(o3) | @@ -67,7 +61,6 @@ dataFlow | tst2.js:6:24:6:37 | "also tainted" | tst2.js:11:15:11:24 | g(source2) | | tst6.mjs:12:14:12:21 | "source" | tst6.mjs:14:12:14:16 | a.m() | | tst6.mjs:16:15:16:23 | "source2" | tst6.mjs:18:13:18:24 | a.m.call(a2) | -| tst.js:2:17:2:22 | "src1" | tst.js:28:20:28:22 | elt | | tst.js:2:17:2:22 | "src1" | tst.js:39:17:39:17 | x | | tst.js:2:17:2:22 | "src1" | tst.js:41:19:41:19 | x | | tst.js:2:17:2:22 | "src1" | tst.js:45:17:45:17 | x | @@ -133,12 +126,6 @@ taintTracking | partial.js:6:15:6:24 | "tainted2" | partial.js:42:15:42:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:48:15:48:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:54:15:54:15 | y | -| promises.js:2:16:2:24 | "tainted" | promises.js:7:16:7:18 | val | -| promises.js:2:16:2:24 | "tainted" | promises.js:38:32:38:32 | v | -| promises.js:11:22:11:31 | "resolved" | promises.js:19:20:19:20 | v | -| promises.js:12:22:12:31 | "rejected" | promises.js:21:20:21:20 | v | -| promises.js:12:22:12:31 | "rejected" | promises.js:24:20:24:20 | v | -| promises.js:32:24:32:37 | "also tainted" | promises.js:38:32:38:32 | v | | properties2.js:7:14:7:21 | "source" | properties2.js:8:12:8:24 | foo(source).p | | properties2.js:7:14:7:21 | "source" | properties2.js:17:13:17:15 | o.p | | properties2.js:7:14:7:21 | "source" | properties2.js:33:13:33:20 | getP(o3) | @@ -167,7 +154,6 @@ taintTracking | tst.js:2:17:2:22 | "src1" | tst.js:19:16:19:34 | JSON.parse(source1) | | tst.js:2:17:2:22 | "src1" | tst.js:20:16:20:37 | JSON.st ... sink10) | | tst.js:2:17:2:22 | "src1" | tst.js:24:16:24:18 | foo | -| tst.js:2:17:2:22 | "src1" | tst.js:28:20:28:22 | elt | | tst.js:2:17:2:22 | "src1" | tst.js:30:20:30:22 | ary | | tst.js:2:17:2:22 | "src1" | tst.js:36:16:36:24 | dict[key] | | tst.js:2:17:2:22 | "src1" | tst.js:39:17:39:17 | x | @@ -237,12 +223,6 @@ germanFlow | partial.js:6:15:6:24 | "tainted2" | partial.js:42:15:42:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:48:15:48:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:54:15:54:15 | y | -| promises.js:2:16:2:24 | "tainted" | promises.js:7:16:7:18 | val | -| promises.js:2:16:2:24 | "tainted" | promises.js:38:32:38:32 | v | -| promises.js:11:22:11:31 | "resolved" | promises.js:19:20:19:20 | v | -| promises.js:12:22:12:31 | "rejected" | promises.js:21:20:21:20 | v | -| promises.js:12:22:12:31 | "rejected" | promises.js:24:20:24:20 | v | -| promises.js:32:24:32:37 | "also tainted" | promises.js:38:32:38:32 | v | | properties2.js:7:14:7:21 | "source" | properties2.js:8:12:8:24 | foo(source).p | | properties2.js:7:14:7:21 | "source" | properties2.js:17:13:17:15 | o.p | | properties2.js:7:14:7:21 | "source" | properties2.js:33:13:33:20 | getP(o3) | @@ -256,7 +236,6 @@ germanFlow | tst2.js:6:24:6:37 | "also tainted" | tst2.js:11:15:11:24 | g(source2) | | tst6.mjs:12:14:12:21 | "source" | tst6.mjs:14:12:14:16 | a.m() | | tst6.mjs:16:15:16:23 | "source2" | tst6.mjs:18:13:18:24 | a.m.call(a2) | -| tst.js:2:17:2:22 | "src1" | tst.js:28:20:28:22 | elt | | tst.js:2:17:2:22 | "src1" | tst.js:39:17:39:17 | x | | tst.js:2:17:2:22 | "src1" | tst.js:41:19:41:19 | x | | tst.js:2:17:2:22 | "src1" | tst.js:45:17:45:17 | x | diff --git a/javascript/ql/test/library-tests/frameworks/Templating/CodeInjection.expected b/javascript/ql/test/library-tests/frameworks/Templating/CodeInjection.expected index de308fdabdf..c84c79bbc83 100644 --- a/javascript/ql/test/library-tests/frameworks/Templating/CodeInjection.expected +++ b/javascript/ql/test/library-tests/frameworks/Templating/CodeInjection.expected @@ -1,36 +1,36 @@ edges -| app.js:15:30:15:58 | req.que ... tedCode | views/ejs_sinks.ejs:13:43:13:61 | dataInGeneratedCode | -| app.js:17:25:17:48 | req.que ... shSink1 | views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 | -| app.js:19:35:19:68 | req.que ... rString | views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString | -| app.js:34:30:34:58 | req.que ... tedCode | views/hbs_sinks.hbs:25:42:25:60 | dataInGeneratedCode | -| app.js:36:25:36:48 | req.que ... shSink1 | views/hbs_sinks.hbs:28:22:28:35 | backslashSink1 | -| app.js:38:35:38:68 | req.que ... rString | views/hbs_sinks.hbs:33:42:33:65 | dataInE ... rString | -| app.js:53:30:53:58 | req.que ... tedCode | views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode | -| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | -| app.js:56:25:56:48 | req.que ... shSink1 | views/njk_sinks.njk:17:22:17:35 | backslashSink1 | -| app.js:58:35:58:68 | req.que ... rString | views/njk_sinks.njk:22:42:22:65 | dataInE ... rString | -| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | -| app.js:65:22:65:42 | req.que ... pedHtml | views/angularjs_include.ejs:2:9:2:19 | escapedHtml | -| app.js:65:22:65:42 | req.que ... pedHtml | views/angularjs_sinks.ejs:3:13:3:23 | escapedHtml | -| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:9:3:15 | rawHtml | -| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | -| views/angularjs_include.ejs:2:9:2:19 | escapedHtml | views/angularjs_include.ejs:2:5:2:22 | <%= escapedHtml %> | -| views/angularjs_include.ejs:3:9:3:15 | rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | -| views/angularjs_sinks.ejs:3:13:3:23 | escapedHtml | views/angularjs_sinks.ejs:3:9:3:26 | <%= escapedHtml %> | -| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | -| views/ejs_sinks.ejs:13:43:13:61 | dataInGeneratedCode | views/ejs_sinks.ejs:13:39:13:64 | <%= dataInGeneratedCode %> | -| views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 | views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> | -| views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString | views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> | -| views/hbs_sinks.hbs:25:42:25:60 | dataInGeneratedCode | views/hbs_sinks.hbs:25:39:25:63 | {{ dataInGeneratedCode }} | -| views/hbs_sinks.hbs:28:22:28:35 | backslashSink1 | views/hbs_sinks.hbs:28:19:28:38 | {{ backslashSink1 }} | -| views/hbs_sinks.hbs:33:42:33:65 | dataInE ... rString | views/hbs_sinks.hbs:33:39:33:68 | {{ dataInEventHandlerString }} | -| views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode | views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} | -| views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | views/njk_sinks.njk:14:45:14:73 | dataInG ... \| safe | -| views/njk_sinks.njk:14:45:14:73 | dataInG ... \| safe | views/njk_sinks.njk:14:42:14:76 | {{ dataInGeneratedCodeRaw \| safe }} | -| views/njk_sinks.njk:17:22:17:35 | backslashSink1 | views/njk_sinks.njk:17:19:17:38 | {{ backslashSink1 }} | -| views/njk_sinks.njk:22:42:22:65 | dataInE ... rString | views/njk_sinks.njk:22:39:22:68 | {{ dataInEventHandlerString }} | -| views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | views/njk_sinks.njk:23:42:23:75 | dataInE ... \| safe | -| views/njk_sinks.njk:23:42:23:75 | dataInE ... \| safe | views/njk_sinks.njk:23:39:23:78 | {{ dataInEventHandlerStringRaw \| safe }} | +| app.js:15:30:15:58 | req.que ... tedCode | views/ejs_sinks.ejs:13:43:13:61 | dataInGeneratedCode | provenance | | +| app.js:17:25:17:48 | req.que ... shSink1 | views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 | provenance | | +| app.js:19:35:19:68 | req.que ... rString | views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString | provenance | | +| app.js:34:30:34:58 | req.que ... tedCode | views/hbs_sinks.hbs:25:42:25:60 | dataInGeneratedCode | provenance | | +| app.js:36:25:36:48 | req.que ... shSink1 | views/hbs_sinks.hbs:28:22:28:35 | backslashSink1 | provenance | | +| app.js:38:35:38:68 | req.que ... rString | views/hbs_sinks.hbs:33:42:33:65 | dataInE ... rString | provenance | | +| app.js:53:30:53:58 | req.que ... tedCode | views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode | provenance | | +| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | provenance | | +| app.js:56:25:56:48 | req.que ... shSink1 | views/njk_sinks.njk:17:22:17:35 | backslashSink1 | provenance | | +| app.js:58:35:58:68 | req.que ... rString | views/njk_sinks.njk:22:42:22:65 | dataInE ... rString | provenance | | +| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | provenance | | +| app.js:65:22:65:42 | req.que ... pedHtml | views/angularjs_include.ejs:2:9:2:19 | escapedHtml | provenance | | +| app.js:65:22:65:42 | req.que ... pedHtml | views/angularjs_sinks.ejs:3:13:3:23 | escapedHtml | provenance | | +| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:9:3:15 | rawHtml | provenance | | +| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | provenance | | +| views/angularjs_include.ejs:2:9:2:19 | escapedHtml | views/angularjs_include.ejs:2:5:2:22 | <%= escapedHtml %> | provenance | | +| views/angularjs_include.ejs:3:9:3:15 | rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | provenance | | +| views/angularjs_sinks.ejs:3:13:3:23 | escapedHtml | views/angularjs_sinks.ejs:3:9:3:26 | <%= escapedHtml %> | provenance | | +| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | provenance | | +| views/ejs_sinks.ejs:13:43:13:61 | dataInGeneratedCode | views/ejs_sinks.ejs:13:39:13:64 | <%= dataInGeneratedCode %> | provenance | | +| views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 | views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> | provenance | | +| views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString | views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> | provenance | | +| views/hbs_sinks.hbs:25:42:25:60 | dataInGeneratedCode | views/hbs_sinks.hbs:25:39:25:63 | {{ dataInGeneratedCode }} | provenance | | +| views/hbs_sinks.hbs:28:22:28:35 | backslashSink1 | views/hbs_sinks.hbs:28:19:28:38 | {{ backslashSink1 }} | provenance | | +| views/hbs_sinks.hbs:33:42:33:65 | dataInE ... rString | views/hbs_sinks.hbs:33:39:33:68 | {{ dataInEventHandlerString }} | provenance | | +| views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode | views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} | provenance | | +| views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | views/njk_sinks.njk:14:45:14:73 | dataInG ... \| safe | provenance | | +| views/njk_sinks.njk:14:45:14:73 | dataInG ... \| safe | views/njk_sinks.njk:14:42:14:76 | {{ dataInGeneratedCodeRaw \| safe }} | provenance | | +| views/njk_sinks.njk:17:22:17:35 | backslashSink1 | views/njk_sinks.njk:17:19:17:38 | {{ backslashSink1 }} | provenance | | +| views/njk_sinks.njk:22:42:22:65 | dataInE ... rString | views/njk_sinks.njk:22:39:22:68 | {{ dataInEventHandlerString }} | provenance | | +| views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | views/njk_sinks.njk:23:42:23:75 | dataInE ... \| safe | provenance | | +| views/njk_sinks.njk:23:42:23:75 | dataInE ... \| safe | views/njk_sinks.njk:23:39:23:78 | {{ dataInEventHandlerStringRaw \| safe }} | provenance | | nodes | app.js:15:30:15:58 | req.que ... tedCode | semmle.label | req.que ... tedCode | | app.js:17:25:17:48 | req.que ... shSink1 | semmle.label | req.que ... shSink1 | diff --git a/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected b/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected index c523b2dabd0..d7e0636b554 100644 --- a/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected +++ b/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected @@ -1,33 +1,33 @@ edges -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:5:13:5:21 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:6:17:6:25 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:7:16:7:24 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:8:31:8:39 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:9:18:9:26 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:11:20:11:28 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:15:16:15:24 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:33:14:33:22 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:34:34:34:42 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:43:8:43:16 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:44:8:44:16 | untrusted | -| tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | -| tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] [1] | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | -| tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | -| tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] [1] | -| tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } [y, z] | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } | -| tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } [z] | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } [y, z] | -| tst-UntrustedDataToExternalAPI.js:15:16:15:24 | untrusted | tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } [z] | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [x] | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [x] | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [y] | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [y] | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [z] | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [z] | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | -| tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [x] | -| tst-UntrustedDataToExternalAPI.js:43:8:43:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [y] | -| tst-UntrustedDataToExternalAPI.js:44:8:44:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [z] | +| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:5:13:5:21 | untrusted | provenance | | +| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:6:17:6:25 | untrusted | provenance | | +| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:7:16:7:24 | untrusted | provenance | | +| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:8:31:8:39 | untrusted | provenance | | +| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:9:18:9:26 | untrusted | provenance | | +| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | provenance | | +| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:11:20:11:28 | untrusted | provenance | | +| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:15:16:15:24 | untrusted | provenance | | +| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:33:14:33:22 | untrusted | provenance | | +| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:34:34:34:42 | untrusted | provenance | | +| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted | provenance | | +| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:43:8:43:16 | untrusted | provenance | | +| tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:44:8:44:16 | untrusted | provenance | | +| tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | provenance | | +| tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] [1] | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | provenance | | +| tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | provenance | | +| tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] [1] | provenance | | +| tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } [y, z] | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } | provenance | | +| tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } [z] | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } [y, z] | provenance | | +| tst-UntrustedDataToExternalAPI.js:15:16:15:24 | untrusted | tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } [z] | provenance | | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [x] | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | provenance | | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [x] | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | provenance | | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [y] | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | provenance | | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [y] | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | provenance | | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [z] | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | provenance | | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [z] | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | provenance | | +| tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [x] | provenance | | +| tst-UntrustedDataToExternalAPI.js:43:8:43:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [y] | provenance | | +| tst-UntrustedDataToExternalAPI.js:44:8:44:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [z] | provenance | | nodes | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | semmle.label | untrusted | | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | semmle.label | window.name | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/ZipSlip/ZipSlip.expected b/javascript/ql/test/query-tests/Security/CWE-022/ZipSlip/ZipSlip.expected index 9b147acdd88..67e38f937ba 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/ZipSlip/ZipSlip.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/ZipSlip/ZipSlip.expected @@ -23,19 +23,19 @@ nodes | ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | semmle.label | entry.path | | ZipSlipBadUnzipper.js:8:37:8:44 | fileName | semmle.label | fileName | edges -| ZipSlipBad2.js:5:9:5:46 | fileName | ZipSlipBad2.js:6:22:6:29 | fileName | -| ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | ZipSlipBad2.js:5:9:5:46 | fileName | -| ZipSlipBad2.js:5:37:5:46 | entry.path | ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | -| ZipSlipBad.js:7:11:7:31 | fileName | ZipSlipBad.js:8:37:8:44 | fileName | -| ZipSlipBad.js:7:22:7:31 | entry.path | ZipSlipBad.js:7:11:7:31 | fileName | -| ZipSlipBad.js:15:11:15:31 | fileName | ZipSlipBad.js:16:30:16:37 | fileName | -| ZipSlipBad.js:15:22:15:31 | entry.path | ZipSlipBad.js:15:11:15:31 | fileName | -| ZipSlipBad.js:22:11:22:31 | fileName | ZipSlipBad.js:23:28:23:35 | fileName | -| ZipSlipBad.js:22:22:22:31 | entry.path | ZipSlipBad.js:22:11:22:31 | fileName | -| ZipSlipBad.js:30:14:30:17 | name | ZipSlipBad.js:31:26:31:29 | name | -| ZipSlipBad.js:34:16:34:19 | name | ZipSlipBad.js:35:26:35:29 | name | -| ZipSlipBadUnzipper.js:7:9:7:29 | fileName | ZipSlipBadUnzipper.js:8:37:8:44 | fileName | -| ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | ZipSlipBadUnzipper.js:7:9:7:29 | fileName | +| ZipSlipBad2.js:5:9:5:46 | fileName | ZipSlipBad2.js:6:22:6:29 | fileName | provenance | | +| ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | ZipSlipBad2.js:5:9:5:46 | fileName | provenance | | +| ZipSlipBad2.js:5:37:5:46 | entry.path | ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | provenance | Config | +| ZipSlipBad.js:7:11:7:31 | fileName | ZipSlipBad.js:8:37:8:44 | fileName | provenance | | +| ZipSlipBad.js:7:22:7:31 | entry.path | ZipSlipBad.js:7:11:7:31 | fileName | provenance | | +| ZipSlipBad.js:15:11:15:31 | fileName | ZipSlipBad.js:16:30:16:37 | fileName | provenance | | +| ZipSlipBad.js:15:22:15:31 | entry.path | ZipSlipBad.js:15:11:15:31 | fileName | provenance | | +| ZipSlipBad.js:22:11:22:31 | fileName | ZipSlipBad.js:23:28:23:35 | fileName | provenance | | +| ZipSlipBad.js:22:22:22:31 | entry.path | ZipSlipBad.js:22:11:22:31 | fileName | provenance | | +| ZipSlipBad.js:30:14:30:17 | name | ZipSlipBad.js:31:26:31:29 | name | provenance | | +| ZipSlipBad.js:34:16:34:19 | name | ZipSlipBad.js:35:26:35:29 | name | provenance | | +| ZipSlipBadUnzipper.js:7:9:7:29 | fileName | ZipSlipBadUnzipper.js:8:37:8:44 | fileName | provenance | | +| ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | ZipSlipBadUnzipper.js:7:9:7:29 | fileName | provenance | | subpaths #select | AdmZipBad.js:6:24:6:41 | zipEntry.entryName | AdmZipBad.js:6:24:6:41 | zipEntry.entryName | AdmZipBad.js:6:24:6:41 | zipEntry.entryName | Unsanitized archive entry, which may contain '..', is used in a $@. | AdmZipBad.js:6:24:6:41 | zipEntry.entryName | file system operation | diff --git a/javascript/ql/test/query-tests/Security/CWE-073/TemplateObjectInjection.expected b/javascript/ql/test/query-tests/Security/CWE-073/TemplateObjectInjection.expected index 3ba1cc1d2d9..8be388d5ad9 100644 --- a/javascript/ql/test/query-tests/Security/CWE-073/TemplateObjectInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-073/TemplateObjectInjection.expected @@ -36,34 +36,34 @@ nodes | tst.js:29:28:29:42 | JSON.parse(str) | semmle.label | JSON.parse(str) | | tst.js:29:39:29:41 | str | semmle.label | str | edges -| tst2.js:6:9:6:46 | bodyParameter | tst2.js:7:28:7:40 | bodyParameter | -| tst2.js:6:25:6:32 | req.body | tst2.js:6:25:6:46 | req.bod ... rameter | -| tst2.js:6:25:6:46 | req.bod ... rameter | tst2.js:6:9:6:46 | bodyParameter | -| tst2.js:26:9:26:46 | bodyParameter | tst2.js:27:28:27:40 | bodyParameter | -| tst2.js:26:25:26:32 | req.body | tst2.js:26:25:26:46 | req.bod ... rameter | -| tst2.js:26:25:26:46 | req.bod ... rameter | tst2.js:26:9:26:46 | bodyParameter | -| tst2.js:34:9:34:46 | bodyParameter | tst2.js:35:28:35:40 | bodyParameter | -| tst2.js:34:25:34:32 | req.body | tst2.js:34:25:34:46 | req.bod ... rameter | -| tst2.js:34:25:34:46 | req.bod ... rameter | tst2.js:34:9:34:46 | bodyParameter | -| tst2.js:42:9:42:46 | bodyParameter | tst2.js:43:28:43:40 | bodyParameter | -| tst2.js:42:25:42:32 | req.body | tst2.js:42:25:42:46 | req.bod ... rameter | -| tst2.js:42:25:42:46 | req.bod ... rameter | tst2.js:42:9:42:46 | bodyParameter | -| tst2.js:51:9:51:46 | bodyParameter | tst2.js:52:28:52:40 | bodyParameter | -| tst2.js:51:25:51:32 | req.body | tst2.js:51:25:51:46 | req.bod ... rameter | -| tst2.js:51:25:51:46 | req.bod ... rameter | tst2.js:51:9:51:46 | bodyParameter | -| tst.js:7:9:7:46 | bodyParameter | tst.js:10:28:10:40 | bodyParameter | -| tst.js:7:25:7:32 | req.body | tst.js:7:25:7:46 | req.bod ... rameter | -| tst.js:7:25:7:46 | req.bod ... rameter | tst.js:7:9:7:46 | bodyParameter | -| tst.js:8:9:8:49 | queryParameter | tst.js:11:28:11:41 | queryParameter | -| tst.js:8:9:8:49 | queryParameter | tst.js:20:19:20:32 | queryParameter | -| tst.js:8:26:8:49 | req.que ... rameter | tst.js:8:9:8:49 | queryParameter | -| tst.js:20:19:20:32 | queryParameter | tst.js:23:24:23:26 | obj | -| tst.js:23:24:23:26 | obj | tst.js:24:28:24:30 | obj | -| tst.js:23:24:23:26 | obj | tst.js:26:17:26:19 | obj | -| tst.js:26:11:26:24 | str | tst.js:29:39:29:41 | str | -| tst.js:26:17:26:19 | obj | tst.js:26:17:26:24 | obj + "" | -| tst.js:26:17:26:24 | obj + "" | tst.js:26:11:26:24 | str | -| tst.js:29:39:29:41 | str | tst.js:29:28:29:42 | JSON.parse(str) | +| tst2.js:6:9:6:46 | bodyParameter | tst2.js:7:28:7:40 | bodyParameter | provenance | | +| tst2.js:6:25:6:32 | req.body | tst2.js:6:25:6:46 | req.bod ... rameter | provenance | Config | +| tst2.js:6:25:6:46 | req.bod ... rameter | tst2.js:6:9:6:46 | bodyParameter | provenance | | +| tst2.js:26:9:26:46 | bodyParameter | tst2.js:27:28:27:40 | bodyParameter | provenance | | +| tst2.js:26:25:26:32 | req.body | tst2.js:26:25:26:46 | req.bod ... rameter | provenance | Config | +| tst2.js:26:25:26:46 | req.bod ... rameter | tst2.js:26:9:26:46 | bodyParameter | provenance | | +| tst2.js:34:9:34:46 | bodyParameter | tst2.js:35:28:35:40 | bodyParameter | provenance | | +| tst2.js:34:25:34:32 | req.body | tst2.js:34:25:34:46 | req.bod ... rameter | provenance | Config | +| tst2.js:34:25:34:46 | req.bod ... rameter | tst2.js:34:9:34:46 | bodyParameter | provenance | | +| tst2.js:42:9:42:46 | bodyParameter | tst2.js:43:28:43:40 | bodyParameter | provenance | | +| tst2.js:42:25:42:32 | req.body | tst2.js:42:25:42:46 | req.bod ... rameter | provenance | Config | +| tst2.js:42:25:42:46 | req.bod ... rameter | tst2.js:42:9:42:46 | bodyParameter | provenance | | +| tst2.js:51:9:51:46 | bodyParameter | tst2.js:52:28:52:40 | bodyParameter | provenance | | +| tst2.js:51:25:51:32 | req.body | tst2.js:51:25:51:46 | req.bod ... rameter | provenance | Config | +| tst2.js:51:25:51:46 | req.bod ... rameter | tst2.js:51:9:51:46 | bodyParameter | provenance | | +| tst.js:7:9:7:46 | bodyParameter | tst.js:10:28:10:40 | bodyParameter | provenance | | +| tst.js:7:25:7:32 | req.body | tst.js:7:25:7:46 | req.bod ... rameter | provenance | Config | +| tst.js:7:25:7:46 | req.bod ... rameter | tst.js:7:9:7:46 | bodyParameter | provenance | | +| tst.js:8:9:8:49 | queryParameter | tst.js:11:28:11:41 | queryParameter | provenance | | +| tst.js:8:9:8:49 | queryParameter | tst.js:20:19:20:32 | queryParameter | provenance | | +| tst.js:8:26:8:49 | req.que ... rameter | tst.js:8:9:8:49 | queryParameter | provenance | | +| tst.js:20:19:20:32 | queryParameter | tst.js:23:24:23:26 | obj | provenance | | +| tst.js:23:24:23:26 | obj | tst.js:24:28:24:30 | obj | provenance | | +| tst.js:23:24:23:26 | obj | tst.js:26:17:26:19 | obj | provenance | | +| tst.js:26:11:26:24 | str | tst.js:29:39:29:41 | str | provenance | | +| tst.js:26:17:26:19 | obj | tst.js:26:17:26:24 | obj + "" | provenance | Config | +| tst.js:26:17:26:24 | obj + "" | tst.js:26:11:26:24 | str | provenance | | +| tst.js:29:39:29:41 | str | tst.js:29:28:29:42 | JSON.parse(str) | provenance | Config | subpaths #select | routes.js:2:23:2:30 | req.body | routes.js:2:23:2:30 | req.body | routes.js:2:23:2:30 | req.body | Template object depends on a $@. | routes.js:2:23:2:30 | req.body | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/SecondOrderCommandInjection/SecondOrderCommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/SecondOrderCommandInjection/SecondOrderCommandInjection.expected index 8f18ce1aa09..e449f163d46 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/SecondOrderCommandInjection/SecondOrderCommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/SecondOrderCommandInjection/SecondOrderCommandInjection.expected @@ -13,13 +13,13 @@ nodes | second-order.js:42:31:42:46 | req.query.remote | semmle.label | req.query.remote | | second-order.js:44:18:44:31 | req.query.args | semmle.label | req.query.args | edges -| second-order.js:6:9:6:33 | remote | second-order.js:7:33:7:38 | remote | -| second-order.js:6:9:6:33 | remote | second-order.js:9:29:9:34 | remote | -| second-order.js:6:9:6:33 | remote | second-order.js:11:33:11:38 | remote | -| second-order.js:6:9:6:33 | remote | second-order.js:26:35:26:40 | remote | -| second-order.js:6:18:6:33 | req.query.remote | second-order.js:6:9:6:33 | remote | -| second-order.js:13:9:13:31 | myArgs | second-order.js:15:19:15:24 | myArgs | -| second-order.js:13:18:13:31 | req.query.args | second-order.js:13:9:13:31 | myArgs | +| second-order.js:6:9:6:33 | remote | second-order.js:7:33:7:38 | remote | provenance | | +| second-order.js:6:9:6:33 | remote | second-order.js:9:29:9:34 | remote | provenance | | +| second-order.js:6:9:6:33 | remote | second-order.js:11:33:11:38 | remote | provenance | | +| second-order.js:6:9:6:33 | remote | second-order.js:26:35:26:40 | remote | provenance | | +| second-order.js:6:18:6:33 | req.query.remote | second-order.js:6:9:6:33 | remote | provenance | | +| second-order.js:13:9:13:31 | myArgs | second-order.js:15:19:15:24 | myArgs | provenance | | +| second-order.js:13:18:13:31 | req.query.args | second-order.js:13:9:13:31 | myArgs | provenance | | subpaths #select | second-order.js:7:33:7:38 | remote | second-order.js:6:18:6:33 | req.query.remote | second-order.js:7:33:7:38 | remote | Command line argument that depends on $@ can execute an arbitrary command if --upload-pack is used with git. | second-order.js:6:18:6:33 | req.query.remote | a user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/UnsafeJQueryPlugin.expected b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/UnsafeJQueryPlugin.expected index 296f89e05af..cf7af63c122 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/UnsafeJQueryPlugin.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/UnsafeJQueryPlugin.expected @@ -1,62 +1,62 @@ edges -| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:3:5:3:11 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:5:5:5:11 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:7:17:7:23 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:11:16:11:22 | options | -| unsafe-jquery-plugin.js:5:5:5:11 | options | unsafe-jquery-plugin.js:5:5:5:18 | options.target | -| unsafe-jquery-plugin.js:5:5:5:11 | options | unsafe-jquery-plugin.js:5:5:5:18 | options.target | -| unsafe-jquery-plugin.js:5:5:5:18 | options.target | unsafe-jquery-plugin.js:11:16:11:29 | options.target | -| unsafe-jquery-plugin.js:7:17:7:23 | options | unsafe-jquery-plugin.js:7:17:7:30 | options.target | -| unsafe-jquery-plugin.js:7:17:7:30 | options.target | unsafe-jquery-plugin.js:11:16:11:29 | options.target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:22:6:22:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:30:6:30:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:36:6:36:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:40:6:40:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:48:6:48:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:52:6:52:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:60:6:60:11 | target | -| unsafe-jquery-plugin.js:11:16:11:22 | options | unsafe-jquery-plugin.js:11:16:11:29 | options.target | -| unsafe-jquery-plugin.js:11:16:11:29 | options.target | unsafe-jquery-plugin.js:11:7:11:29 | target | -| unsafe-jquery-plugin.js:71:38:71:44 | options | unsafe-jquery-plugin.js:72:5:72:11 | options | -| unsafe-jquery-plugin.js:72:5:72:11 | options | unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | -| unsafe-jquery-plugin.js:76:38:76:44 | options | unsafe-jquery-plugin.js:77:17:77:23 | options | -| unsafe-jquery-plugin.js:77:17:77:23 | options | unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | -| unsafe-jquery-plugin.js:101:38:101:44 | options | unsafe-jquery-plugin.js:105:6:105:12 | options | -| unsafe-jquery-plugin.js:102:3:105:13 | options | unsafe-jquery-plugin.js:107:5:107:11 | options | -| unsafe-jquery-plugin.js:102:13:105:13 | $.exten ... ptions) | unsafe-jquery-plugin.js:102:3:105:13 | options | -| unsafe-jquery-plugin.js:105:6:105:12 | options | unsafe-jquery-plugin.js:102:13:105:13 | $.exten ... ptions) | -| unsafe-jquery-plugin.js:107:5:107:11 | options | unsafe-jquery-plugin.js:107:5:107:18 | options.target | -| unsafe-jquery-plugin.js:114:38:114:44 | options | unsafe-jquery-plugin.js:115:51:115:57 | options | -| unsafe-jquery-plugin.js:115:3:115:58 | options | unsafe-jquery-plugin.js:117:5:117:11 | options | -| unsafe-jquery-plugin.js:115:13:115:58 | $.exten ... ptions) | unsafe-jquery-plugin.js:115:3:115:58 | options | -| unsafe-jquery-plugin.js:115:51:115:57 | options | unsafe-jquery-plugin.js:115:13:115:58 | $.exten ... ptions) | -| unsafe-jquery-plugin.js:117:5:117:11 | options | unsafe-jquery-plugin.js:117:5:117:18 | options.target | -| unsafe-jquery-plugin.js:121:40:121:46 | options | unsafe-jquery-plugin.js:122:5:122:11 | options | -| unsafe-jquery-plugin.js:122:5:122:11 | options | unsafe-jquery-plugin.js:122:5:122:18 | options.target | -| unsafe-jquery-plugin.js:126:33:126:39 | options | unsafe-jquery-plugin.js:127:6:127:12 | options | -| unsafe-jquery-plugin.js:127:6:127:12 | options | unsafe-jquery-plugin.js:127:6:127:19 | options.target | -| unsafe-jquery-plugin.js:131:34:131:40 | options | unsafe-jquery-plugin.js:132:5:132:11 | options | -| unsafe-jquery-plugin.js:132:5:132:11 | options | unsafe-jquery-plugin.js:132:5:132:18 | options.target | -| unsafe-jquery-plugin.js:135:36:135:42 | options | unsafe-jquery-plugin.js:136:5:136:11 | options | -| unsafe-jquery-plugin.js:136:5:136:11 | options | unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | -| unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:154:16:154:22 | options | -| unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:156:3:156:9 | options | -| unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:157:44:157:50 | options | -| unsafe-jquery-plugin.js:154:16:154:22 | options | unsafe-jquery-plugin.js:154:16:154:29 | options.target | -| unsafe-jquery-plugin.js:154:16:154:29 | options.target | unsafe-jquery-plugin.js:156:3:156:16 | options.target | -| unsafe-jquery-plugin.js:154:16:154:29 | options.target | unsafe-jquery-plugin.js:157:44:157:57 | options.target | -| unsafe-jquery-plugin.js:156:3:156:9 | options | unsafe-jquery-plugin.js:156:3:156:16 | options.target | -| unsafe-jquery-plugin.js:156:3:156:16 | options.target | unsafe-jquery-plugin.js:157:44:157:57 | options.target | -| unsafe-jquery-plugin.js:157:44:157:50 | options | unsafe-jquery-plugin.js:157:44:157:57 | options.target | -| unsafe-jquery-plugin.js:157:44:157:57 | options.target | unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | -| unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:165:16:165:22 | options | -| unsafe-jquery-plugin.js:165:7:165:29 | target | unsafe-jquery-plugin.js:170:6:170:11 | target | -| unsafe-jquery-plugin.js:165:16:165:22 | options | unsafe-jquery-plugin.js:165:7:165:29 | target | -| unsafe-jquery-plugin.js:178:27:178:33 | options | unsafe-jquery-plugin.js:179:5:179:11 | options | -| unsafe-jquery-plugin.js:179:5:179:11 | options | unsafe-jquery-plugin.js:179:5:179:18 | options.target | -| unsafe-jquery-plugin.js:185:28:185:34 | options | unsafe-jquery-plugin.js:186:21:186:27 | options | -| unsafe-jquery-plugin.js:186:21:186:27 | options | unsafe-jquery-plugin.js:186:21:186:30 | options.of | -| unsafe-jquery-plugin.js:186:21:186:30 | options.of | unsafe-jquery-plugin.js:192:19:192:28 | options.of | +| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:3:5:3:11 | options | provenance | | +| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:5:5:5:11 | options | provenance | | +| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:7:17:7:23 | options | provenance | | +| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:11:16:11:22 | options | provenance | | +| unsafe-jquery-plugin.js:5:5:5:11 | options | unsafe-jquery-plugin.js:5:5:5:18 | options.target | provenance | | +| unsafe-jquery-plugin.js:5:5:5:11 | options | unsafe-jquery-plugin.js:5:5:5:18 | options.target | provenance | | +| unsafe-jquery-plugin.js:5:5:5:18 | options.target | unsafe-jquery-plugin.js:11:16:11:29 | options.target | provenance | Config | +| unsafe-jquery-plugin.js:7:17:7:23 | options | unsafe-jquery-plugin.js:7:17:7:30 | options.target | provenance | | +| unsafe-jquery-plugin.js:7:17:7:30 | options.target | unsafe-jquery-plugin.js:11:16:11:29 | options.target | provenance | Config | +| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:22:6:22:11 | target | provenance | | +| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:30:6:30:11 | target | provenance | | +| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:36:6:36:11 | target | provenance | | +| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:40:6:40:11 | target | provenance | | +| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:48:6:48:11 | target | provenance | | +| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:52:6:52:11 | target | provenance | | +| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:60:6:60:11 | target | provenance | | +| unsafe-jquery-plugin.js:11:16:11:22 | options | unsafe-jquery-plugin.js:11:16:11:29 | options.target | provenance | | +| unsafe-jquery-plugin.js:11:16:11:29 | options.target | unsafe-jquery-plugin.js:11:7:11:29 | target | provenance | | +| unsafe-jquery-plugin.js:71:38:71:44 | options | unsafe-jquery-plugin.js:72:5:72:11 | options | provenance | | +| unsafe-jquery-plugin.js:72:5:72:11 | options | unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | provenance | | +| unsafe-jquery-plugin.js:76:38:76:44 | options | unsafe-jquery-plugin.js:77:17:77:23 | options | provenance | | +| unsafe-jquery-plugin.js:77:17:77:23 | options | unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | provenance | | +| unsafe-jquery-plugin.js:101:38:101:44 | options | unsafe-jquery-plugin.js:105:6:105:12 | options | provenance | | +| unsafe-jquery-plugin.js:102:3:105:13 | options | unsafe-jquery-plugin.js:107:5:107:11 | options | provenance | | +| unsafe-jquery-plugin.js:102:13:105:13 | $.exten ... ptions) | unsafe-jquery-plugin.js:102:3:105:13 | options | provenance | | +| unsafe-jquery-plugin.js:105:6:105:12 | options | unsafe-jquery-plugin.js:102:13:105:13 | $.exten ... ptions) | provenance | | +| unsafe-jquery-plugin.js:107:5:107:11 | options | unsafe-jquery-plugin.js:107:5:107:18 | options.target | provenance | | +| unsafe-jquery-plugin.js:114:38:114:44 | options | unsafe-jquery-plugin.js:115:51:115:57 | options | provenance | | +| unsafe-jquery-plugin.js:115:3:115:58 | options | unsafe-jquery-plugin.js:117:5:117:11 | options | provenance | | +| unsafe-jquery-plugin.js:115:13:115:58 | $.exten ... ptions) | unsafe-jquery-plugin.js:115:3:115:58 | options | provenance | | +| unsafe-jquery-plugin.js:115:51:115:57 | options | unsafe-jquery-plugin.js:115:13:115:58 | $.exten ... ptions) | provenance | | +| unsafe-jquery-plugin.js:117:5:117:11 | options | unsafe-jquery-plugin.js:117:5:117:18 | options.target | provenance | | +| unsafe-jquery-plugin.js:121:40:121:46 | options | unsafe-jquery-plugin.js:122:5:122:11 | options | provenance | | +| unsafe-jquery-plugin.js:122:5:122:11 | options | unsafe-jquery-plugin.js:122:5:122:18 | options.target | provenance | | +| unsafe-jquery-plugin.js:126:33:126:39 | options | unsafe-jquery-plugin.js:127:6:127:12 | options | provenance | | +| unsafe-jquery-plugin.js:127:6:127:12 | options | unsafe-jquery-plugin.js:127:6:127:19 | options.target | provenance | | +| unsafe-jquery-plugin.js:131:34:131:40 | options | unsafe-jquery-plugin.js:132:5:132:11 | options | provenance | | +| unsafe-jquery-plugin.js:132:5:132:11 | options | unsafe-jquery-plugin.js:132:5:132:18 | options.target | provenance | | +| unsafe-jquery-plugin.js:135:36:135:42 | options | unsafe-jquery-plugin.js:136:5:136:11 | options | provenance | | +| unsafe-jquery-plugin.js:136:5:136:11 | options | unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | provenance | | +| unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:154:16:154:22 | options | provenance | | +| unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:156:3:156:9 | options | provenance | | +| unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:157:44:157:50 | options | provenance | | +| unsafe-jquery-plugin.js:154:16:154:22 | options | unsafe-jquery-plugin.js:154:16:154:29 | options.target | provenance | | +| unsafe-jquery-plugin.js:154:16:154:29 | options.target | unsafe-jquery-plugin.js:156:3:156:16 | options.target | provenance | Config | +| unsafe-jquery-plugin.js:154:16:154:29 | options.target | unsafe-jquery-plugin.js:157:44:157:57 | options.target | provenance | Config | +| unsafe-jquery-plugin.js:156:3:156:9 | options | unsafe-jquery-plugin.js:156:3:156:16 | options.target | provenance | | +| unsafe-jquery-plugin.js:156:3:156:16 | options.target | unsafe-jquery-plugin.js:157:44:157:57 | options.target | provenance | Config | +| unsafe-jquery-plugin.js:157:44:157:50 | options | unsafe-jquery-plugin.js:157:44:157:57 | options.target | provenance | | +| unsafe-jquery-plugin.js:157:44:157:57 | options.target | unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | provenance | | +| unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:165:16:165:22 | options | provenance | | +| unsafe-jquery-plugin.js:165:7:165:29 | target | unsafe-jquery-plugin.js:170:6:170:11 | target | provenance | | +| unsafe-jquery-plugin.js:165:16:165:22 | options | unsafe-jquery-plugin.js:165:7:165:29 | target | provenance | | +| unsafe-jquery-plugin.js:178:27:178:33 | options | unsafe-jquery-plugin.js:179:5:179:11 | options | provenance | | +| unsafe-jquery-plugin.js:179:5:179:11 | options | unsafe-jquery-plugin.js:179:5:179:18 | options.target | provenance | | +| unsafe-jquery-plugin.js:185:28:185:34 | options | unsafe-jquery-plugin.js:186:21:186:27 | options | provenance | | +| unsafe-jquery-plugin.js:186:21:186:27 | options | unsafe-jquery-plugin.js:186:21:186:30 | options.of | provenance | | +| unsafe-jquery-plugin.js:186:21:186:30 | options.of | unsafe-jquery-plugin.js:192:19:192:28 | options.of | provenance | Config | nodes | unsafe-jquery-plugin.js:2:38:2:44 | options | semmle.label | options | | unsafe-jquery-plugin.js:3:5:3:11 | options | semmle.label | options | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected index 156b4b7e2f2..5880071e4e0 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected @@ -1,46 +1,46 @@ edges -| forms.js:8:23:8:28 | values | forms.js:9:31:9:36 | values | -| forms.js:9:31:9:36 | values | forms.js:9:31:9:40 | values.foo | -| forms.js:11:24:11:29 | values | forms.js:12:31:12:36 | values | -| forms.js:12:31:12:36 | values | forms.js:12:31:12:40 | values.bar | -| forms.js:24:15:24:20 | values | forms.js:25:23:25:28 | values | -| forms.js:25:23:25:28 | values | forms.js:25:23:25:34 | values.email | -| forms.js:28:20:28:25 | values | forms.js:29:23:29:28 | values | -| forms.js:29:23:29:28 | values | forms.js:29:23:29:34 | values.email | -| forms.js:34:11:34:53 | values | forms.js:35:19:35:24 | values | -| forms.js:34:13:34:18 | values | forms.js:34:11:34:53 | values | -| forms.js:35:19:35:24 | values | forms.js:35:19:35:30 | values.email | -| forms.js:44:21:44:26 | values | forms.js:45:21:45:26 | values | -| forms.js:45:21:45:26 | values | forms.js:45:21:45:33 | values.stooge | -| forms.js:71:21:71:24 | data | forms.js:72:19:72:22 | data | -| forms.js:72:19:72:22 | data | forms.js:72:19:72:27 | data.name | -| forms.js:92:17:92:36 | values | forms.js:93:25:93:30 | values | -| forms.js:92:26:92:36 | getValues() | forms.js:92:17:92:36 | values | -| forms.js:93:25:93:30 | values | forms.js:93:25:93:35 | values.name | -| xss-through-dom.js:73:9:73:41 | selector | xss-through-dom.js:77:4:77:11 | selector | -| xss-through-dom.js:73:20:73:41 | $("inpu ... 0).name | xss-through-dom.js:73:9:73:41 | selector | -| xss-through-dom.js:84:8:84:30 | text | xss-through-dom.js:86:33:86:36 | text | -| xss-through-dom.js:84:8:84:30 | text | xss-through-dom.js:87:36:87:39 | text | -| xss-through-dom.js:84:15:84:30 | $("text").text() | xss-through-dom.js:84:8:84:30 | text | -| xss-through-dom.js:86:33:86:36 | text | xss-through-dom.js:86:16:86:37 | anser.a ... l(text) | -| xss-through-dom.js:87:36:87:39 | text | xss-through-dom.js:87:16:87:40 | new ans ... s(text) | -| xss-through-dom.js:109:45:109:55 | this.el.src | xss-through-dom.js:109:31:109:70 | "" | -| xss-through-dom.js:114:11:114:52 | src | xss-through-dom.js:115:16:115:18 | src | -| xss-through-dom.js:114:11:114:52 | src | xss-through-dom.js:117:26:117:28 | src | -| xss-through-dom.js:114:17:114:52 | documen ... k").src | xss-through-dom.js:114:11:114:52 | src | -| xss-through-dom.js:120:23:120:37 | ev.target.files | xss-through-dom.js:120:23:120:45 | ev.targ ... 0].name | -| xss-through-dom.js:122:53:122:67 | ev.target.files | xss-through-dom.js:122:53:122:70 | ev.target.files[0] | -| xss-through-dom.js:122:53:122:70 | ev.target.files[0] | xss-through-dom.js:122:33:122:71 | URL.cre ... les[0]) | -| xss-through-dom.js:130:6:130:68 | linkText | xss-through-dom.js:131:19:131:26 | linkText | -| xss-through-dom.js:130:6:130:68 | linkText | xss-through-dom.js:132:16:132:23 | linkText | -| xss-through-dom.js:130:17:130:37 | wSelect ... tring() | xss-through-dom.js:130:6:130:68 | linkText | -| xss-through-dom.js:130:42:130:62 | dSelect ... tring() | xss-through-dom.js:130:6:130:68 | linkText | -| xss-through-dom.js:139:11:139:52 | src | xss-through-dom.js:140:19:140:21 | src | -| xss-through-dom.js:139:11:139:52 | src | xss-through-dom.js:141:25:141:27 | src | -| xss-through-dom.js:139:11:139:52 | src | xss-through-dom.js:150:24:150:26 | src | -| xss-through-dom.js:139:17:139:52 | documen ... k").src | xss-through-dom.js:139:11:139:52 | src | -| xss-through-dom.js:154:25:154:27 | msg | xss-through-dom.js:155:27:155:29 | msg | -| xss-through-dom.js:159:34:159:52 | $("textarea").val() | xss-through-dom.js:154:25:154:27 | msg | +| forms.js:8:23:8:28 | values | forms.js:9:31:9:36 | values | provenance | | +| forms.js:9:31:9:36 | values | forms.js:9:31:9:40 | values.foo | provenance | | +| forms.js:11:24:11:29 | values | forms.js:12:31:12:36 | values | provenance | | +| forms.js:12:31:12:36 | values | forms.js:12:31:12:40 | values.bar | provenance | | +| forms.js:24:15:24:20 | values | forms.js:25:23:25:28 | values | provenance | | +| forms.js:25:23:25:28 | values | forms.js:25:23:25:34 | values.email | provenance | | +| forms.js:28:20:28:25 | values | forms.js:29:23:29:28 | values | provenance | | +| forms.js:29:23:29:28 | values | forms.js:29:23:29:34 | values.email | provenance | | +| forms.js:34:11:34:53 | values | forms.js:35:19:35:24 | values | provenance | | +| forms.js:34:13:34:18 | values | forms.js:34:11:34:53 | values | provenance | | +| forms.js:35:19:35:24 | values | forms.js:35:19:35:30 | values.email | provenance | | +| forms.js:44:21:44:26 | values | forms.js:45:21:45:26 | values | provenance | | +| forms.js:45:21:45:26 | values | forms.js:45:21:45:33 | values.stooge | provenance | | +| forms.js:71:21:71:24 | data | forms.js:72:19:72:22 | data | provenance | | +| forms.js:72:19:72:22 | data | forms.js:72:19:72:27 | data.name | provenance | | +| forms.js:92:17:92:36 | values | forms.js:93:25:93:30 | values | provenance | | +| forms.js:92:26:92:36 | getValues() | forms.js:92:17:92:36 | values | provenance | | +| forms.js:93:25:93:30 | values | forms.js:93:25:93:35 | values.name | provenance | | +| xss-through-dom.js:73:9:73:41 | selector | xss-through-dom.js:77:4:77:11 | selector | provenance | | +| xss-through-dom.js:73:20:73:41 | $("inpu ... 0).name | xss-through-dom.js:73:9:73:41 | selector | provenance | | +| xss-through-dom.js:84:8:84:30 | text | xss-through-dom.js:86:33:86:36 | text | provenance | | +| xss-through-dom.js:84:8:84:30 | text | xss-through-dom.js:87:36:87:39 | text | provenance | | +| xss-through-dom.js:84:15:84:30 | $("text").text() | xss-through-dom.js:84:8:84:30 | text | provenance | | +| xss-through-dom.js:86:33:86:36 | text | xss-through-dom.js:86:16:86:37 | anser.a ... l(text) | provenance | | +| xss-through-dom.js:87:36:87:39 | text | xss-through-dom.js:87:16:87:40 | new ans ... s(text) | provenance | | +| xss-through-dom.js:109:45:109:55 | this.el.src | xss-through-dom.js:109:31:109:70 | "" | provenance | | +| xss-through-dom.js:114:11:114:52 | src | xss-through-dom.js:115:16:115:18 | src | provenance | | +| xss-through-dom.js:114:11:114:52 | src | xss-through-dom.js:117:26:117:28 | src | provenance | | +| xss-through-dom.js:114:17:114:52 | documen ... k").src | xss-through-dom.js:114:11:114:52 | src | provenance | | +| xss-through-dom.js:120:23:120:37 | ev.target.files | xss-through-dom.js:120:23:120:45 | ev.targ ... 0].name | provenance | | +| xss-through-dom.js:122:53:122:67 | ev.target.files | xss-through-dom.js:122:53:122:70 | ev.target.files[0] | provenance | | +| xss-through-dom.js:122:53:122:70 | ev.target.files[0] | xss-through-dom.js:122:33:122:71 | URL.cre ... les[0]) | provenance | Config | +| xss-through-dom.js:130:6:130:68 | linkText | xss-through-dom.js:131:19:131:26 | linkText | provenance | | +| xss-through-dom.js:130:6:130:68 | linkText | xss-through-dom.js:132:16:132:23 | linkText | provenance | | +| xss-through-dom.js:130:17:130:37 | wSelect ... tring() | xss-through-dom.js:130:6:130:68 | linkText | provenance | | +| xss-through-dom.js:130:42:130:62 | dSelect ... tring() | xss-through-dom.js:130:6:130:68 | linkText | provenance | | +| xss-through-dom.js:139:11:139:52 | src | xss-through-dom.js:140:19:140:21 | src | provenance | | +| xss-through-dom.js:139:11:139:52 | src | xss-through-dom.js:141:25:141:27 | src | provenance | | +| xss-through-dom.js:139:11:139:52 | src | xss-through-dom.js:150:24:150:26 | src | provenance | | +| xss-through-dom.js:139:17:139:52 | documen ... k").src | xss-through-dom.js:139:11:139:52 | src | provenance | | +| xss-through-dom.js:154:25:154:27 | msg | xss-through-dom.js:155:27:155:29 | msg | provenance | | +| xss-through-dom.js:159:34:159:52 | $("textarea").val() | xss-through-dom.js:154:25:154:27 | msg | provenance | | nodes | forms.js:8:23:8:28 | values | semmle.label | values | | forms.js:9:31:9:36 | values | semmle.label | values | diff --git a/javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected index 174dcaf344a..5446a4da85a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected @@ -14,18 +14,18 @@ nodes | typedClient.ts:23:27:23:35 | { id: v } | semmle.label | { id: v } | | typedClient.ts:23:33:23:33 | v | semmle.label | v | edges -| typedClient.ts:13:7:13:32 | v | typedClient.ts:14:30:14:30 | v | -| typedClient.ts:13:11:13:32 | JSON.pa ... body.x) | typedClient.ts:13:7:13:32 | v | -| typedClient.ts:13:22:13:29 | req.body | typedClient.ts:13:22:13:31 | req.body.x | -| typedClient.ts:13:22:13:31 | req.body.x | typedClient.ts:13:11:13:32 | JSON.pa ... body.x) | -| typedClient.ts:14:30:14:30 | v | typedClient.ts:14:24:14:32 | { id: v } | -| typedClient.ts:21:7:21:32 | v | typedClient.ts:22:33:22:33 | v | -| typedClient.ts:21:7:21:32 | v | typedClient.ts:23:33:23:33 | v | -| typedClient.ts:21:11:21:32 | JSON.pa ... body.x) | typedClient.ts:21:7:21:32 | v | -| typedClient.ts:21:22:21:29 | req.body | typedClient.ts:21:22:21:31 | req.body.x | -| typedClient.ts:21:22:21:31 | req.body.x | typedClient.ts:21:11:21:32 | JSON.pa ... body.x) | -| typedClient.ts:22:33:22:33 | v | typedClient.ts:22:27:22:35 | { id: v } | -| typedClient.ts:23:33:23:33 | v | typedClient.ts:23:27:23:35 | { id: v } | +| typedClient.ts:13:7:13:32 | v | typedClient.ts:14:30:14:30 | v | provenance | | +| typedClient.ts:13:11:13:32 | JSON.pa ... body.x) | typedClient.ts:13:7:13:32 | v | provenance | | +| typedClient.ts:13:22:13:29 | req.body | typedClient.ts:13:22:13:31 | req.body.x | provenance | Config | +| typedClient.ts:13:22:13:31 | req.body.x | typedClient.ts:13:11:13:32 | JSON.pa ... body.x) | provenance | Config | +| typedClient.ts:14:30:14:30 | v | typedClient.ts:14:24:14:32 | { id: v } | provenance | Config | +| typedClient.ts:21:7:21:32 | v | typedClient.ts:22:33:22:33 | v | provenance | | +| typedClient.ts:21:7:21:32 | v | typedClient.ts:23:33:23:33 | v | provenance | | +| typedClient.ts:21:11:21:32 | JSON.pa ... body.x) | typedClient.ts:21:7:21:32 | v | provenance | | +| typedClient.ts:21:22:21:29 | req.body | typedClient.ts:21:22:21:31 | req.body.x | provenance | Config | +| typedClient.ts:21:22:21:31 | req.body.x | typedClient.ts:21:11:21:32 | JSON.pa ... body.x) | provenance | Config | +| typedClient.ts:22:33:22:33 | v | typedClient.ts:22:27:22:35 | { id: v } | provenance | Config | +| typedClient.ts:23:33:23:33 | v | typedClient.ts:23:27:23:35 | { id: v } | provenance | Config | subpaths #select | typedClient.ts:14:24:14:32 | { id: v } | typedClient.ts:13:22:13:29 | req.body | typedClient.ts:14:24:14:32 | { id: v } | This query object depends on a $@. | typedClient.ts:13:22:13:29 | req.body | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected index 10d2e8e6f18..e536c54dbd2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected @@ -1,44 +1,44 @@ edges -| NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | -| NoSQLCodeInjection.js:19:36:19:43 | req.body | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | -| NoSQLCodeInjection.js:22:36:22:43 | req.body | NoSQLCodeInjection.js:22:24:22:48 | "name = ... dy.name | -| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | -| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | -| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | -| express.js:26:9:26:35 | taint | express.js:27:34:27:38 | taint | -| express.js:26:17:26:35 | req.param("wobble") | express.js:26:9:26:35 | taint | -| express.js:34:9:34:35 | taint | express.js:43:15:43:19 | taint | -| express.js:34:17:34:35 | req.param("wobble") | express.js:34:9:34:35 | taint | -| express.js:49:30:49:32 | msg | express.js:50:10:50:12 | msg | -| react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:10:23:10:29 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:20:17:20:23 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:21:16:21:22 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:22:18:22:24 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:23:17:23:23 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:24:18:24:24 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:25:16:25:22 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:26:27:26:33 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:27:21:27:27 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:28:17:28:23 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:29:24:29:30 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:30:21:30:27 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:31:19:31:25 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:32:16:32:22 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:33:17:33:23 | tainted | -| template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:18:9:18:31 | tainted | -| tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | -| tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | -| tst.js:23:11:23:32 | documen ... on.hash | tst.js:23:11:23:45 | documen ... ring(1) | -| tst.js:23:11:23:45 | documen ... ring(1) | tst.js:23:6:23:46 | atob(do ... ing(1)) | -| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | -| tst.js:29:9:29:82 | source | tst.js:31:18:31:23 | source | -| tst.js:29:9:29:82 | source | tst.js:33:14:33:19 | source | -| tst.js:29:9:29:82 | source | tst.js:35:28:35:33 | source | -| tst.js:29:9:29:82 | source | tst.js:37:33:37:38 | source | -| tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") | -| tst.js:29:18:29:82 | documen ... , "$1") | tst.js:29:9:29:82 | source | +| NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | provenance | | +| NoSQLCodeInjection.js:19:36:19:43 | req.body | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | provenance | | +| NoSQLCodeInjection.js:22:36:22:43 | req.body | NoSQLCodeInjection.js:22:24:22:48 | "name = ... dy.name | provenance | | +| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | provenance | | +| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | provenance | | +| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | provenance | | +| express.js:26:9:26:35 | taint | express.js:27:34:27:38 | taint | provenance | | +| express.js:26:17:26:35 | req.param("wobble") | express.js:26:9:26:35 | taint | provenance | | +| express.js:34:9:34:35 | taint | express.js:43:15:43:19 | taint | provenance | | +| express.js:34:17:34:35 | req.param("wobble") | express.js:34:9:34:35 | taint | provenance | | +| express.js:49:30:49:32 | msg | express.js:50:10:50:12 | msg | provenance | | +| react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted | provenance | | +| react-native.js:7:7:7:33 | tainted | react-native.js:10:23:10:29 | tainted | provenance | | +| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:20:17:20:23 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:21:16:21:22 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:22:18:22:24 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:23:17:23:23 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:24:18:24:24 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:25:16:25:22 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:26:27:26:33 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:27:21:27:27 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:28:17:28:23 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:29:24:29:30 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:30:21:30:27 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:31:19:31:25 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:32:16:32:22 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:33:17:33:23 | tainted | provenance | | +| template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:18:9:18:31 | tainted | provenance | | +| tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | provenance | | +| tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | provenance | | +| tst.js:23:11:23:32 | documen ... on.hash | tst.js:23:11:23:45 | documen ... ring(1) | provenance | | +| tst.js:23:11:23:45 | documen ... ring(1) | tst.js:23:6:23:46 | atob(do ... ing(1)) | provenance | | +| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | provenance | | +| tst.js:29:9:29:82 | source | tst.js:31:18:31:23 | source | provenance | | +| tst.js:29:9:29:82 | source | tst.js:33:14:33:19 | source | provenance | | +| tst.js:29:9:29:82 | source | tst.js:35:28:35:33 | source | provenance | | +| tst.js:29:9:29:82 | source | tst.js:37:33:37:38 | source | provenance | | +| tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") | provenance | | +| tst.js:29:18:29:82 | documen ... , "$1") | tst.js:29:9:29:82 | source | provenance | | nodes | NoSQLCodeInjection.js:18:24:18:31 | req.body | semmle.label | req.body | | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | semmle.label | req.body.query | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected index cdeea504be4..2be7dc659f2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected @@ -1,45 +1,45 @@ edges -| NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | -| NoSQLCodeInjection.js:19:36:19:43 | req.body | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | -| NoSQLCodeInjection.js:22:36:22:43 | req.body | NoSQLCodeInjection.js:22:24:22:48 | "name = ... dy.name | -| eslint-escope-build.js:20:22:20:22 | c | eslint-escope-build.js:21:16:21:16 | c | -| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | -| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | -| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | -| express.js:26:9:26:35 | taint | express.js:27:34:27:38 | taint | -| express.js:26:17:26:35 | req.param("wobble") | express.js:26:9:26:35 | taint | -| express.js:34:9:34:35 | taint | express.js:43:15:43:19 | taint | -| express.js:34:17:34:35 | req.param("wobble") | express.js:34:9:34:35 | taint | -| express.js:49:30:49:32 | msg | express.js:50:10:50:12 | msg | -| react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:10:23:10:29 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:20:17:20:23 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:21:16:21:22 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:22:18:22:24 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:23:17:23:23 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:24:18:24:24 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:25:16:25:22 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:26:27:26:33 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:27:21:27:27 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:28:17:28:23 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:29:24:29:30 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:30:21:30:27 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:31:19:31:25 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:32:16:32:22 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:33:17:33:23 | tainted | -| template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:18:9:18:31 | tainted | -| tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | -| tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | -| tst.js:23:11:23:32 | documen ... on.hash | tst.js:23:11:23:45 | documen ... ring(1) | -| tst.js:23:11:23:45 | documen ... ring(1) | tst.js:23:6:23:46 | atob(do ... ing(1)) | -| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | -| tst.js:29:9:29:82 | source | tst.js:31:18:31:23 | source | -| tst.js:29:9:29:82 | source | tst.js:33:14:33:19 | source | -| tst.js:29:9:29:82 | source | tst.js:35:28:35:33 | source | -| tst.js:29:9:29:82 | source | tst.js:37:33:37:38 | source | -| tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") | -| tst.js:29:18:29:82 | documen ... , "$1") | tst.js:29:9:29:82 | source | +| NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | provenance | | +| NoSQLCodeInjection.js:19:36:19:43 | req.body | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | provenance | | +| NoSQLCodeInjection.js:22:36:22:43 | req.body | NoSQLCodeInjection.js:22:24:22:48 | "name = ... dy.name | provenance | | +| eslint-escope-build.js:20:22:20:22 | c | eslint-escope-build.js:21:16:21:16 | c | provenance | | +| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | provenance | | +| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | provenance | | +| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | provenance | | +| express.js:26:9:26:35 | taint | express.js:27:34:27:38 | taint | provenance | | +| express.js:26:17:26:35 | req.param("wobble") | express.js:26:9:26:35 | taint | provenance | | +| express.js:34:9:34:35 | taint | express.js:43:15:43:19 | taint | provenance | | +| express.js:34:17:34:35 | req.param("wobble") | express.js:34:9:34:35 | taint | provenance | | +| express.js:49:30:49:32 | msg | express.js:50:10:50:12 | msg | provenance | | +| react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted | provenance | | +| react-native.js:7:7:7:33 | tainted | react-native.js:10:23:10:29 | tainted | provenance | | +| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:20:17:20:23 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:21:16:21:22 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:22:18:22:24 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:23:17:23:23 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:24:18:24:24 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:25:16:25:22 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:26:27:26:33 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:27:21:27:27 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:28:17:28:23 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:29:24:29:30 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:30:21:30:27 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:31:19:31:25 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:32:16:32:22 | tainted | provenance | | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:33:17:33:23 | tainted | provenance | | +| template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:18:9:18:31 | tainted | provenance | | +| tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | provenance | | +| tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | provenance | | +| tst.js:23:11:23:32 | documen ... on.hash | tst.js:23:11:23:45 | documen ... ring(1) | provenance | | +| tst.js:23:11:23:45 | documen ... ring(1) | tst.js:23:6:23:46 | atob(do ... ing(1)) | provenance | | +| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | provenance | | +| tst.js:29:9:29:82 | source | tst.js:31:18:31:23 | source | provenance | | +| tst.js:29:9:29:82 | source | tst.js:33:14:33:19 | source | provenance | | +| tst.js:29:9:29:82 | source | tst.js:35:28:35:33 | source | provenance | | +| tst.js:29:9:29:82 | source | tst.js:37:33:37:38 | source | provenance | | +| tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") | provenance | | +| tst.js:29:18:29:82 | documen ... , "$1") | tst.js:29:9:29:82 | source | provenance | | nodes | NoSQLCodeInjection.js:18:24:18:31 | req.body | semmle.label | req.body | | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | semmle.label | req.body.query | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected index a54acabbb64..868f2a28744 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected @@ -1,8 +1,8 @@ edges -| lib/index.js:1:35:1:38 | data | lib/index.js:2:21:2:24 | data | -| lib/index.js:5:35:5:38 | name | lib/index.js:6:26:6:29 | name | -| lib/index.js:13:38:13:41 | data | lib/index.js:14:21:14:24 | data | -| lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | +| lib/index.js:1:35:1:38 | data | lib/index.js:2:21:2:24 | data | provenance | | +| lib/index.js:5:35:5:38 | name | lib/index.js:6:26:6:29 | name | provenance | | +| lib/index.js:13:38:13:41 | data | lib/index.js:14:21:14:24 | data | provenance | | +| lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | provenance | | nodes | lib/index.js:1:35:1:38 | data | semmle.label | data | | lib/index.js:2:21:2:24 | data | semmle.label | data | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/UnsafeDynamicMethodAccess/UnsafeDynamicMethodAccess.expected b/javascript/ql/test/query-tests/Security/CWE-094/UnsafeDynamicMethodAccess/UnsafeDynamicMethodAccess.expected index f5bbd2e9a7b..8511b6bcaf6 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/UnsafeDynamicMethodAccess/UnsafeDynamicMethodAccess.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/UnsafeDynamicMethodAccess/UnsafeDynamicMethodAccess.expected @@ -2,10 +2,10 @@ edges | example.js:9:37:9:38 | ev | example.js:10:30:10:31 | ev | provenance | | | example.js:10:9:10:37 | message | example.js:13:12:13:18 | message | provenance | | | example.js:10:19:10:37 | JSON.parse(ev.data) | example.js:10:9:10:37 | message | provenance | | -| example.js:10:30:10:31 | ev | example.js:10:30:10:36 | ev.data | provenance | | -| example.js:10:30:10:36 | ev.data | example.js:10:19:10:37 | JSON.parse(ev.data) | provenance | | -| example.js:13:12:13:18 | message | example.js:13:12:13:23 | message.name | provenance | | -| example.js:13:12:13:23 | message.name | example.js:13:5:13:24 | window[message.name] | provenance | | +| example.js:10:30:10:31 | ev | example.js:10:30:10:36 | ev.data | provenance | Config | +| example.js:10:30:10:36 | ev.data | example.js:10:19:10:37 | JSON.parse(ev.data) | provenance | Config | +| example.js:13:12:13:18 | message | example.js:13:12:13:23 | message.name | provenance | Config | +| example.js:13:12:13:23 | message.name | example.js:13:5:13:24 | window[message.name] | provenance | Config | | tst.js:3:37:3:38 | ev | tst.js:4:30:4:31 | ev | provenance | | | tst.js:3:37:3:38 | ev | tst.js:15:12:15:13 | ev | provenance | | | tst.js:4:9:4:37 | message | tst.js:5:12:5:18 | message | provenance | | @@ -13,18 +13,18 @@ edges | tst.js:4:9:4:37 | message | tst.js:11:7:11:13 | message | provenance | | | tst.js:4:9:4:37 | message | tst.js:21:17:21:23 | message | provenance | | | tst.js:4:19:4:37 | JSON.parse(ev.data) | tst.js:4:9:4:37 | message | provenance | | -| tst.js:4:30:4:31 | ev | tst.js:4:30:4:36 | ev.data | provenance | | -| tst.js:4:30:4:36 | ev.data | tst.js:4:19:4:37 | JSON.parse(ev.data) | provenance | | -| tst.js:5:12:5:18 | message | tst.js:5:12:5:23 | message.name | provenance | | -| tst.js:5:12:5:23 | message.name | tst.js:5:5:5:24 | window[message.name] | provenance | | -| tst.js:6:16:6:22 | message | tst.js:6:16:6:27 | message.name | provenance | | -| tst.js:6:16:6:27 | message.name | tst.js:6:9:6:28 | window[message.name] | provenance | | -| tst.js:11:7:11:13 | message | tst.js:11:7:11:18 | message.name | provenance | | -| tst.js:11:7:11:18 | message.name | tst.js:11:5:11:19 | f[message.name] | provenance | | -| tst.js:15:12:15:13 | ev | tst.js:15:5:15:14 | window[ev] | provenance | | -| tst.js:21:12:21:28 | '' + message.name | tst.js:21:5:21:29 | window[ ... e.name] | provenance | | -| tst.js:21:17:21:23 | message | tst.js:21:17:21:28 | message.name | provenance | | -| tst.js:21:17:21:28 | message.name | tst.js:21:12:21:28 | '' + message.name | provenance | | +| tst.js:4:30:4:31 | ev | tst.js:4:30:4:36 | ev.data | provenance | Config | +| tst.js:4:30:4:36 | ev.data | tst.js:4:19:4:37 | JSON.parse(ev.data) | provenance | Config | +| tst.js:5:12:5:18 | message | tst.js:5:12:5:23 | message.name | provenance | Config | +| tst.js:5:12:5:23 | message.name | tst.js:5:5:5:24 | window[message.name] | provenance | Config | +| tst.js:6:16:6:22 | message | tst.js:6:16:6:27 | message.name | provenance | Config | +| tst.js:6:16:6:27 | message.name | tst.js:6:9:6:28 | window[message.name] | provenance | Config | +| tst.js:11:7:11:13 | message | tst.js:11:7:11:18 | message.name | provenance | Config | +| tst.js:11:7:11:18 | message.name | tst.js:11:5:11:19 | f[message.name] | provenance | Config | +| tst.js:15:12:15:13 | ev | tst.js:15:5:15:14 | window[ev] | provenance | Config | +| tst.js:21:12:21:28 | '' + message.name | tst.js:21:5:21:29 | window[ ... e.name] | provenance | Config | +| tst.js:21:17:21:23 | message | tst.js:21:17:21:28 | message.name | provenance | Config | +| tst.js:21:17:21:28 | message.name | tst.js:21:12:21:28 | '' + message.name | provenance | Config | nodes | example.js:9:37:9:38 | ev | semmle.label | ev | | example.js:10:9:10:37 | message | semmle.label | message | diff --git a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteHtmlAttributeSanitization.expected b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteHtmlAttributeSanitization.expected index 326e6ea7436..7af957d720a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteHtmlAttributeSanitization.expected +++ b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteHtmlAttributeSanitization.expected @@ -16,9 +16,9 @@ nodes | tst.js:303:10:303:34 | s().rep ... /g, '') | semmle.label | s().rep ... /g, '') | | tst.js:309:10:318:3 | s().rep ... ;";\\n\\t}) | semmle.label | s().rep ... ;";\\n\\t}) | edges -| tst.js:274:6:274:94 | arr | tst.js:275:9:275:11 | arr | -| tst.js:274:12:274:94 | s().val ... g , '') | tst.js:274:6:274:94 | arr | -| tst.js:275:9:275:11 | arr | tst.js:275:9:275:21 | arr.join(" ") | +| tst.js:274:6:274:94 | arr | tst.js:275:9:275:11 | arr | provenance | | +| tst.js:274:12:274:94 | s().val ... g , '') | tst.js:274:6:274:94 | arr | provenance | | +| tst.js:275:9:275:11 | arr | tst.js:275:9:275:21 | arr.join(" ") | provenance | | subpaths #select | tst.js:243:9:243:31 | s().rep ... ]/g,'') | tst.js:243:9:243:31 | s().rep ... ]/g,'') | tst.js:243:9:243:31 | s().rep ... ]/g,'') | Cross-site scripting vulnerability as the output of $@ may contain double quotes when it reaches this attribute definition. | tst.js:243:9:243:31 | s().rep ... ]/g,'') | this final HTML sanitizer step | diff --git a/javascript/ql/test/query-tests/Security/CWE-117/LogInjection.expected b/javascript/ql/test/query-tests/Security/CWE-117/LogInjection.expected index 0e4ce448c75..12bbd7feea9 100644 --- a/javascript/ql/test/query-tests/Security/CWE-117/LogInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-117/LogInjection.expected @@ -1,69 +1,69 @@ edges -| logInjectionBad.js:7:25:7:32 | username | logInjectionBad.js:8:38:8:45 | username | -| logInjectionBad.js:19:9:19:36 | q | logInjectionBad.js:20:20:20:20 | q | -| logInjectionBad.js:19:13:19:36 | url.par ... , true) | logInjectionBad.js:19:9:19:36 | q | -| logInjectionBad.js:19:23:19:29 | req.url | logInjectionBad.js:19:13:19:36 | url.par ... , true) | -| logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:22:34:22:41 | username | -| logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:23:37:23:44 | username | -| logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:24:35:24:42 | username | -| logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:25:36:25:43 | username | -| logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:28:24:28:31 | username | -| logInjectionBad.js:20:20:20:20 | q | logInjectionBad.js:20:9:20:35 | username | -| logInjectionBad.js:22:34:22:41 | username | logInjectionBad.js:22:18:22:43 | `[INFO] ... rname}` | -| logInjectionBad.js:28:9:28:32 | exceptional return of check_u ... ername) | logInjectionBad.js:29:14:29:18 | error | -| logInjectionBad.js:28:24:28:31 | username | logInjectionBad.js:7:25:7:32 | username | -| logInjectionBad.js:28:24:28:31 | username | logInjectionBad.js:28:9:28:32 | exceptional return of check_u ... ername) | -| logInjectionBad.js:29:14:29:18 | error | logInjectionBad.js:30:42:30:46 | error | -| logInjectionBad.js:30:42:30:46 | error | logInjectionBad.js:30:23:30:49 | `[ERROR ... rror}"` | -| logInjectionBad.js:46:9:46:36 | q | logInjectionBad.js:47:20:47:20 | q | -| logInjectionBad.js:46:13:46:36 | url.par ... , true) | logInjectionBad.js:46:9:46:36 | q | -| logInjectionBad.js:46:23:46:29 | req.url | logInjectionBad.js:46:13:46:36 | url.par ... , true) | -| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:49:46:49:53 | username | -| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:50:39:50:46 | username | -| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:51:48:51:55 | username | -| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:52:37:52:44 | username | -| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:53:27:53:34 | username | -| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:54:43:54:50 | username | -| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:55:48:55:55 | username | -| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:56:47:56:54 | username | -| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:57:40:57:47 | username | -| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:58:50:58:57 | username | -| logInjectionBad.js:47:20:47:20 | q | logInjectionBad.js:47:9:47:35 | username | -| logInjectionBad.js:49:46:49:53 | username | logInjectionBad.js:49:18:49:54 | ansiCol ... ername) | -| logInjectionBad.js:50:39:50:46 | username | logInjectionBad.js:50:18:50:47 | colors. ... ername) | -| logInjectionBad.js:51:27:51:56 | colors. ... ername) | logInjectionBad.js:51:18:51:61 | wrapAns ... e), 20) | -| logInjectionBad.js:51:48:51:55 | username | logInjectionBad.js:51:27:51:56 | colors. ... ername) | -| logInjectionBad.js:52:27:52:46 | bold(blue(username)) | logInjectionBad.js:52:17:52:47 | underli ... name))) | -| logInjectionBad.js:52:32:52:45 | blue(username) | logInjectionBad.js:52:27:52:46 | bold(blue(username)) | -| logInjectionBad.js:52:37:52:44 | username | logInjectionBad.js:52:32:52:45 | blue(username) | -| logInjectionBad.js:53:27:53:34 | username | logInjectionBad.js:53:17:53:76 | highlig ... true}) | -| logInjectionBad.js:54:43:54:50 | username | logInjectionBad.js:54:17:54:51 | clc.red ... ername) | -| logInjectionBad.js:55:27:55:56 | colors. ... ername) | logInjectionBad.js:55:17:55:65 | sliceAn ... 20, 30) | -| logInjectionBad.js:55:48:55:55 | username | logInjectionBad.js:55:27:55:56 | colors. ... ername) | -| logInjectionBad.js:56:47:56:54 | username | logInjectionBad.js:56:17:56:55 | kleur.b ... ername) | -| logInjectionBad.js:57:40:57:47 | username | logInjectionBad.js:57:17:57:48 | chalk.u ... ername) | -| logInjectionBad.js:58:27:58:58 | chalk.u ... ername) | logInjectionBad.js:58:17:58:59 | stripAn ... rname)) | -| logInjectionBad.js:58:50:58:57 | username | logInjectionBad.js:58:27:58:58 | chalk.u ... ername) | -| logInjectionBad.js:63:9:63:36 | q | logInjectionBad.js:64:20:64:20 | q | -| logInjectionBad.js:63:13:63:36 | url.par ... , true) | logInjectionBad.js:63:9:63:36 | q | -| logInjectionBad.js:63:23:63:29 | req.url | logInjectionBad.js:63:13:63:36 | url.par ... , true) | -| logInjectionBad.js:64:9:64:35 | username | logInjectionBad.js:66:35:66:42 | username | -| logInjectionBad.js:64:20:64:20 | q | logInjectionBad.js:64:9:64:35 | username | -| logInjectionBad.js:66:35:66:42 | username | logInjectionBad.js:66:17:66:43 | prettyj ... ername) | -| logInjectionBad.js:72:9:72:36 | q | logInjectionBad.js:73:20:73:20 | q | -| logInjectionBad.js:72:13:72:36 | url.par ... , true) | logInjectionBad.js:72:9:72:36 | q | -| logInjectionBad.js:72:23:72:29 | req.url | logInjectionBad.js:72:13:72:36 | url.par ... , true) | -| logInjectionBad.js:73:9:73:35 | username | logInjectionBad.js:75:15:75:22 | username | -| logInjectionBad.js:73:9:73:35 | username | logInjectionBad.js:75:15:75:22 | username | -| logInjectionBad.js:73:20:73:20 | q | logInjectionBad.js:73:9:73:35 | username | -| logInjectionBad.js:75:15:75:22 | username | logInjectionBad.js:77:5:85:5 | functio ... ;\\n } [username] | -| logInjectionBad.js:75:15:75:22 | username | logInjectionBad.js:87:5:94:5 | functio ... ;\\n } [username] | -| logInjectionBad.js:75:15:75:22 | username | logInjectionBad.js:96:5:103:5 | functio ... ;\\n } [username] | -| logInjectionBad.js:75:15:75:22 | username | logInjectionBad.js:105:5:118:5 | functio ... ;\\n } [username] | -| logInjectionBad.js:77:5:85:5 | functio ... ;\\n } [username] | logInjectionBad.js:82:30:82:37 | username | -| logInjectionBad.js:87:5:94:5 | functio ... ;\\n } [username] | logInjectionBad.js:91:26:91:33 | username | -| logInjectionBad.js:96:5:103:5 | functio ... ;\\n } [username] | logInjectionBad.js:99:26:99:33 | username | -| logInjectionBad.js:105:5:118:5 | functio ... ;\\n } [username] | logInjectionBad.js:113:37:113:44 | username | +| logInjectionBad.js:7:25:7:32 | username | logInjectionBad.js:8:38:8:45 | username | provenance | | +| logInjectionBad.js:19:9:19:36 | q | logInjectionBad.js:20:20:20:20 | q | provenance | | +| logInjectionBad.js:19:13:19:36 | url.par ... , true) | logInjectionBad.js:19:9:19:36 | q | provenance | | +| logInjectionBad.js:19:23:19:29 | req.url | logInjectionBad.js:19:13:19:36 | url.par ... , true) | provenance | | +| logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:22:34:22:41 | username | provenance | | +| logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:23:37:23:44 | username | provenance | | +| logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:24:35:24:42 | username | provenance | | +| logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:25:36:25:43 | username | provenance | | +| logInjectionBad.js:20:9:20:35 | username | logInjectionBad.js:28:24:28:31 | username | provenance | | +| logInjectionBad.js:20:20:20:20 | q | logInjectionBad.js:20:9:20:35 | username | provenance | | +| logInjectionBad.js:22:34:22:41 | username | logInjectionBad.js:22:18:22:43 | `[INFO] ... rname}` | provenance | | +| logInjectionBad.js:28:9:28:32 | exceptional return of check_u ... ername) | logInjectionBad.js:29:14:29:18 | error | provenance | | +| logInjectionBad.js:28:24:28:31 | username | logInjectionBad.js:7:25:7:32 | username | provenance | | +| logInjectionBad.js:28:24:28:31 | username | logInjectionBad.js:28:9:28:32 | exceptional return of check_u ... ername) | provenance | | +| logInjectionBad.js:29:14:29:18 | error | logInjectionBad.js:30:42:30:46 | error | provenance | | +| logInjectionBad.js:30:42:30:46 | error | logInjectionBad.js:30:23:30:49 | `[ERROR ... rror}"` | provenance | | +| logInjectionBad.js:46:9:46:36 | q | logInjectionBad.js:47:20:47:20 | q | provenance | | +| logInjectionBad.js:46:13:46:36 | url.par ... , true) | logInjectionBad.js:46:9:46:36 | q | provenance | | +| logInjectionBad.js:46:23:46:29 | req.url | logInjectionBad.js:46:13:46:36 | url.par ... , true) | provenance | | +| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:49:46:49:53 | username | provenance | | +| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:50:39:50:46 | username | provenance | | +| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:51:48:51:55 | username | provenance | | +| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:52:37:52:44 | username | provenance | | +| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:53:27:53:34 | username | provenance | | +| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:54:43:54:50 | username | provenance | | +| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:55:48:55:55 | username | provenance | | +| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:56:47:56:54 | username | provenance | | +| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:57:40:57:47 | username | provenance | | +| logInjectionBad.js:47:9:47:35 | username | logInjectionBad.js:58:50:58:57 | username | provenance | | +| logInjectionBad.js:47:20:47:20 | q | logInjectionBad.js:47:9:47:35 | username | provenance | | +| logInjectionBad.js:49:46:49:53 | username | logInjectionBad.js:49:18:49:54 | ansiCol ... ername) | provenance | | +| logInjectionBad.js:50:39:50:46 | username | logInjectionBad.js:50:18:50:47 | colors. ... ername) | provenance | | +| logInjectionBad.js:51:27:51:56 | colors. ... ername) | logInjectionBad.js:51:18:51:61 | wrapAns ... e), 20) | provenance | | +| logInjectionBad.js:51:48:51:55 | username | logInjectionBad.js:51:27:51:56 | colors. ... ername) | provenance | | +| logInjectionBad.js:52:27:52:46 | bold(blue(username)) | logInjectionBad.js:52:17:52:47 | underli ... name))) | provenance | | +| logInjectionBad.js:52:32:52:45 | blue(username) | logInjectionBad.js:52:27:52:46 | bold(blue(username)) | provenance | | +| logInjectionBad.js:52:37:52:44 | username | logInjectionBad.js:52:32:52:45 | blue(username) | provenance | | +| logInjectionBad.js:53:27:53:34 | username | logInjectionBad.js:53:17:53:76 | highlig ... true}) | provenance | | +| logInjectionBad.js:54:43:54:50 | username | logInjectionBad.js:54:17:54:51 | clc.red ... ername) | provenance | | +| logInjectionBad.js:55:27:55:56 | colors. ... ername) | logInjectionBad.js:55:17:55:65 | sliceAn ... 20, 30) | provenance | | +| logInjectionBad.js:55:48:55:55 | username | logInjectionBad.js:55:27:55:56 | colors. ... ername) | provenance | | +| logInjectionBad.js:56:47:56:54 | username | logInjectionBad.js:56:17:56:55 | kleur.b ... ername) | provenance | | +| logInjectionBad.js:57:40:57:47 | username | logInjectionBad.js:57:17:57:48 | chalk.u ... ername) | provenance | | +| logInjectionBad.js:58:27:58:58 | chalk.u ... ername) | logInjectionBad.js:58:17:58:59 | stripAn ... rname)) | provenance | | +| logInjectionBad.js:58:50:58:57 | username | logInjectionBad.js:58:27:58:58 | chalk.u ... ername) | provenance | | +| logInjectionBad.js:63:9:63:36 | q | logInjectionBad.js:64:20:64:20 | q | provenance | | +| logInjectionBad.js:63:13:63:36 | url.par ... , true) | logInjectionBad.js:63:9:63:36 | q | provenance | | +| logInjectionBad.js:63:23:63:29 | req.url | logInjectionBad.js:63:13:63:36 | url.par ... , true) | provenance | | +| logInjectionBad.js:64:9:64:35 | username | logInjectionBad.js:66:35:66:42 | username | provenance | | +| logInjectionBad.js:64:20:64:20 | q | logInjectionBad.js:64:9:64:35 | username | provenance | | +| logInjectionBad.js:66:35:66:42 | username | logInjectionBad.js:66:17:66:43 | prettyj ... ername) | provenance | | +| logInjectionBad.js:72:9:72:36 | q | logInjectionBad.js:73:20:73:20 | q | provenance | | +| logInjectionBad.js:72:13:72:36 | url.par ... , true) | logInjectionBad.js:72:9:72:36 | q | provenance | | +| logInjectionBad.js:72:23:72:29 | req.url | logInjectionBad.js:72:13:72:36 | url.par ... , true) | provenance | | +| logInjectionBad.js:73:9:73:35 | username | logInjectionBad.js:75:15:75:22 | username | provenance | | +| logInjectionBad.js:73:9:73:35 | username | logInjectionBad.js:75:15:75:22 | username | provenance | | +| logInjectionBad.js:73:20:73:20 | q | logInjectionBad.js:73:9:73:35 | username | provenance | | +| logInjectionBad.js:75:15:75:22 | username | logInjectionBad.js:77:5:85:5 | functio ... ;\\n } [username] | provenance | | +| logInjectionBad.js:75:15:75:22 | username | logInjectionBad.js:87:5:94:5 | functio ... ;\\n } [username] | provenance | | +| logInjectionBad.js:75:15:75:22 | username | logInjectionBad.js:96:5:103:5 | functio ... ;\\n } [username] | provenance | | +| logInjectionBad.js:75:15:75:22 | username | logInjectionBad.js:105:5:118:5 | functio ... ;\\n } [username] | provenance | | +| logInjectionBad.js:77:5:85:5 | functio ... ;\\n } [username] | logInjectionBad.js:82:30:82:37 | username | provenance | | +| logInjectionBad.js:87:5:94:5 | functio ... ;\\n } [username] | logInjectionBad.js:91:26:91:33 | username | provenance | | +| logInjectionBad.js:96:5:103:5 | functio ... ;\\n } [username] | logInjectionBad.js:99:26:99:33 | username | provenance | | +| logInjectionBad.js:105:5:118:5 | functio ... ;\\n } [username] | logInjectionBad.js:113:37:113:44 | username | provenance | | nodes | logInjectionBad.js:7:25:7:32 | username | semmle.label | username | | logInjectionBad.js:8:38:8:45 | username | semmle.label | username | diff --git a/javascript/ql/test/query-tests/Security/CWE-200/FileAccessToHttp.expected b/javascript/ql/test/query-tests/Security/CWE-200/FileAccessToHttp.expected index b9c024c5590..c53df2b9abd 100644 --- a/javascript/ql/test/query-tests/Security/CWE-200/FileAccessToHttp.expected +++ b/javascript/ql/test/query-tests/Security/CWE-200/FileAccessToHttp.expected @@ -1,51 +1,51 @@ edges -| FileAccessToHttp.js:4:5:4:47 | content | FileAccessToHttp.js:9:23:9:29 | content | -| FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | FileAccessToHttp.js:4:5:4:47 | content | -| FileAccessToHttp.js:5:11:10:1 | [post update] {\\n hos ... ent }\\n} [headers, Referer] | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | -| FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | FileAccessToHttp.js:5:11:10:1 | [post update] {\\n hos ... ent }\\n} [headers, Referer] | -| FileAccessToHttp.js:9:23:9:29 | content | FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | -| bufferRead.js:12:13:12:43 | buffer | bufferRead.js:13:21:13:26 | buffer | -| bufferRead.js:12:13:12:43 | buffer | bufferRead.js:13:32:13:37 | buffer | -| bufferRead.js:12:22:12:43 | new Buf ... s.size) | bufferRead.js:12:13:12:43 | buffer | -| bufferRead.js:13:21:13:26 | buffer | bufferRead.js:13:32:13:37 | buffer | -| bufferRead.js:13:32:13:37 | buffer | bufferRead.js:15:26:15:31 | buffer | -| bufferRead.js:15:15:15:62 | postData | bufferRead.js:33:21:33:28 | postData | -| bufferRead.js:15:26:15:31 | buffer | bufferRead.js:15:26:15:62 | buffer. ... esRead) | -| bufferRead.js:15:26:15:62 | buffer. ... esRead) | bufferRead.js:15:15:15:62 | postData | -| readFileSync.js:5:5:5:39 | data | readFileSync.js:7:11:7:14 | data | -| readFileSync.js:5:12:5:39 | fs.read ... t.txt") | readFileSync.js:5:5:5:39 | data | -| readFileSync.js:7:7:7:25 | s | readFileSync.js:26:18:26:18 | s | -| readFileSync.js:7:11:7:14 | data | readFileSync.js:7:11:7:25 | data.toString() | -| readFileSync.js:7:11:7:25 | data.toString() | readFileSync.js:7:7:7:25 | s | -| readStreamRead.js:13:13:13:35 | chunk | readStreamRead.js:30:19:30:23 | chunk | -| readStreamRead.js:13:21:13:35 | readable.read() | readStreamRead.js:13:13:13:35 | chunk | -| request.js:6:19:6:26 | jsonData | request.js:8:12:8:19 | jsonData | -| request.js:8:11:8:20 | [post update] {jsonData} [jsonData] | request.js:8:11:8:20 | {jsonData} | -| request.js:8:12:8:19 | jsonData | request.js:8:11:8:20 | [post update] {jsonData} [jsonData] | -| request.js:13:18:13:24 | xmlData | request.js:22:11:22:17 | xmlData | -| request.js:16:11:23:3 | [post update] {\\n u ... ody\\n } [body] | request.js:16:11:23:3 | {\\n u ... ody\\n } | -| request.js:22:11:22:17 | xmlData | request.js:16:11:23:3 | [post update] {\\n u ... ody\\n } [body] | -| request.js:28:52:28:55 | data | request.js:35:14:35:17 | data | -| request.js:35:14:35:17 | data | request.js:6:19:6:26 | jsonData | -| request.js:43:51:43:54 | data | request.js:50:13:50:16 | data | -| request.js:50:13:50:16 | data | request.js:13:18:13:24 | xmlData | -| sentAsHeaders.js:10:79:10:84 | buffer | sentAsHeaders.js:11:23:11:28 | buffer | -| sentAsHeaders.js:11:13:11:59 | content | sentAsHeaders.js:12:19:12:25 | content | -| sentAsHeaders.js:11:23:11:28 | buffer | sentAsHeaders.js:11:23:11:59 | buffer. ... esRead) | -| sentAsHeaders.js:11:23:11:59 | buffer. ... esRead) | sentAsHeaders.js:11:13:11:59 | content | -| sentAsHeaders.js:12:9:12:81 | content | sentAsHeaders.js:18:47:18:53 | content | -| sentAsHeaders.js:12:9:12:81 | content | sentAsHeaders.js:24:47:24:53 | content | -| sentAsHeaders.js:12:19:12:25 | content | sentAsHeaders.js:12:19:12:74 | content ... =", "") | -| sentAsHeaders.js:12:19:12:74 | content ... =", "") | sentAsHeaders.js:12:19:12:81 | content ... .trim() | -| sentAsHeaders.js:12:19:12:81 | content ... .trim() | sentAsHeaders.js:12:9:12:81 | content | -| sentAsHeaders.js:14:20:19:9 | [post update] {\\n ... } [headers, Referer] | sentAsHeaders.js:14:20:19:9 | {\\n ... } | -| sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } [Referer] | sentAsHeaders.js:14:20:19:9 | [post update] {\\n ... } [headers, Referer] | -| sentAsHeaders.js:18:31:18:53 | "http:/ ... content | sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } [Referer] | -| sentAsHeaders.js:18:47:18:53 | content | sentAsHeaders.js:18:31:18:53 | "http:/ ... content | -| sentAsHeaders.js:20:20:25:9 | [post update] {\\n ... } [headers, Referer] | sentAsHeaders.js:20:20:25:9 | {\\n ... } | -| sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } [Referer] | sentAsHeaders.js:20:20:25:9 | [post update] {\\n ... } [headers, Referer] | -| sentAsHeaders.js:24:31:24:53 | "http:/ ... content | sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } [Referer] | -| sentAsHeaders.js:24:47:24:53 | content | sentAsHeaders.js:24:31:24:53 | "http:/ ... content | +| FileAccessToHttp.js:4:5:4:47 | content | FileAccessToHttp.js:9:23:9:29 | content | provenance | | +| FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | FileAccessToHttp.js:4:5:4:47 | content | provenance | | +| FileAccessToHttp.js:5:11:10:1 | [post update] {\\n hos ... ent }\\n} [headers, Referer] | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | provenance | | +| FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | FileAccessToHttp.js:5:11:10:1 | [post update] {\\n hos ... ent }\\n} [headers, Referer] | provenance | | +| FileAccessToHttp.js:9:23:9:29 | content | FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | provenance | | +| bufferRead.js:12:13:12:43 | buffer | bufferRead.js:13:21:13:26 | buffer | provenance | | +| bufferRead.js:12:13:12:43 | buffer | bufferRead.js:13:32:13:37 | buffer | provenance | | +| bufferRead.js:12:22:12:43 | new Buf ... s.size) | bufferRead.js:12:13:12:43 | buffer | provenance | | +| bufferRead.js:13:21:13:26 | buffer | bufferRead.js:13:32:13:37 | buffer | provenance | | +| bufferRead.js:13:32:13:37 | buffer | bufferRead.js:15:26:15:31 | buffer | provenance | | +| bufferRead.js:15:15:15:62 | postData | bufferRead.js:33:21:33:28 | postData | provenance | | +| bufferRead.js:15:26:15:31 | buffer | bufferRead.js:15:26:15:62 | buffer. ... esRead) | provenance | | +| bufferRead.js:15:26:15:62 | buffer. ... esRead) | bufferRead.js:15:15:15:62 | postData | provenance | | +| readFileSync.js:5:5:5:39 | data | readFileSync.js:7:11:7:14 | data | provenance | | +| readFileSync.js:5:12:5:39 | fs.read ... t.txt") | readFileSync.js:5:5:5:39 | data | provenance | | +| readFileSync.js:7:7:7:25 | s | readFileSync.js:26:18:26:18 | s | provenance | | +| readFileSync.js:7:11:7:14 | data | readFileSync.js:7:11:7:25 | data.toString() | provenance | | +| readFileSync.js:7:11:7:25 | data.toString() | readFileSync.js:7:7:7:25 | s | provenance | | +| readStreamRead.js:13:13:13:35 | chunk | readStreamRead.js:30:19:30:23 | chunk | provenance | | +| readStreamRead.js:13:21:13:35 | readable.read() | readStreamRead.js:13:13:13:35 | chunk | provenance | | +| request.js:6:19:6:26 | jsonData | request.js:8:12:8:19 | jsonData | provenance | | +| request.js:8:11:8:20 | [post update] {jsonData} [jsonData] | request.js:8:11:8:20 | {jsonData} | provenance | | +| request.js:8:12:8:19 | jsonData | request.js:8:11:8:20 | [post update] {jsonData} [jsonData] | provenance | | +| request.js:13:18:13:24 | xmlData | request.js:22:11:22:17 | xmlData | provenance | | +| request.js:16:11:23:3 | [post update] {\\n u ... ody\\n } [body] | request.js:16:11:23:3 | {\\n u ... ody\\n } | provenance | | +| request.js:22:11:22:17 | xmlData | request.js:16:11:23:3 | [post update] {\\n u ... ody\\n } [body] | provenance | | +| request.js:28:52:28:55 | data | request.js:35:14:35:17 | data | provenance | | +| request.js:35:14:35:17 | data | request.js:6:19:6:26 | jsonData | provenance | | +| request.js:43:51:43:54 | data | request.js:50:13:50:16 | data | provenance | | +| request.js:50:13:50:16 | data | request.js:13:18:13:24 | xmlData | provenance | | +| sentAsHeaders.js:10:79:10:84 | buffer | sentAsHeaders.js:11:23:11:28 | buffer | provenance | | +| sentAsHeaders.js:11:13:11:59 | content | sentAsHeaders.js:12:19:12:25 | content | provenance | | +| sentAsHeaders.js:11:23:11:28 | buffer | sentAsHeaders.js:11:23:11:59 | buffer. ... esRead) | provenance | | +| sentAsHeaders.js:11:23:11:59 | buffer. ... esRead) | sentAsHeaders.js:11:13:11:59 | content | provenance | | +| sentAsHeaders.js:12:9:12:81 | content | sentAsHeaders.js:18:47:18:53 | content | provenance | | +| sentAsHeaders.js:12:9:12:81 | content | sentAsHeaders.js:24:47:24:53 | content | provenance | | +| sentAsHeaders.js:12:19:12:25 | content | sentAsHeaders.js:12:19:12:74 | content ... =", "") | provenance | | +| sentAsHeaders.js:12:19:12:74 | content ... =", "") | sentAsHeaders.js:12:19:12:81 | content ... .trim() | provenance | | +| sentAsHeaders.js:12:19:12:81 | content ... .trim() | sentAsHeaders.js:12:9:12:81 | content | provenance | | +| sentAsHeaders.js:14:20:19:9 | [post update] {\\n ... } [headers, Referer] | sentAsHeaders.js:14:20:19:9 | {\\n ... } | provenance | | +| sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } [Referer] | sentAsHeaders.js:14:20:19:9 | [post update] {\\n ... } [headers, Referer] | provenance | | +| sentAsHeaders.js:18:31:18:53 | "http:/ ... content | sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } [Referer] | provenance | | +| sentAsHeaders.js:18:47:18:53 | content | sentAsHeaders.js:18:31:18:53 | "http:/ ... content | provenance | | +| sentAsHeaders.js:20:20:25:9 | [post update] {\\n ... } [headers, Referer] | sentAsHeaders.js:20:20:25:9 | {\\n ... } | provenance | | +| sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } [Referer] | sentAsHeaders.js:20:20:25:9 | [post update] {\\n ... } [headers, Referer] | provenance | | +| sentAsHeaders.js:24:31:24:53 | "http:/ ... content | sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } [Referer] | provenance | | +| sentAsHeaders.js:24:47:24:53 | content | sentAsHeaders.js:24:31:24:53 | "http:/ ... content | provenance | | nodes | FileAccessToHttp.js:4:5:4:47 | content | semmle.label | content | | FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | semmle.label | fs.read ... "utf8") | diff --git a/javascript/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected b/javascript/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected index 4a14ef0aaa6..8754a6cbdf0 100644 --- a/javascript/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected +++ b/javascript/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected @@ -1,11 +1,11 @@ edges -| node.js:8:10:8:12 | err | node.js:11:13:11:15 | err | -| node.js:11:13:11:15 | err | node.js:11:13:11:21 | err.stack | -| tst.js:6:12:6:12 | e | tst.js:7:13:7:13 | e | -| tst.js:6:12:6:12 | e | tst.js:8:15:8:15 | e | -| tst.js:8:15:8:15 | e | tst.js:16:20:16:20 | e | -| tst.js:16:20:16:20 | e | tst.js:17:11:17:11 | e | -| tst.js:17:11:17:11 | e | tst.js:17:11:17:17 | e.stack | +| node.js:8:10:8:12 | err | node.js:11:13:11:15 | err | provenance | | +| node.js:11:13:11:15 | err | node.js:11:13:11:21 | err.stack | provenance | | +| tst.js:6:12:6:12 | e | tst.js:7:13:7:13 | e | provenance | | +| tst.js:6:12:6:12 | e | tst.js:8:15:8:15 | e | provenance | | +| tst.js:8:15:8:15 | e | tst.js:16:20:16:20 | e | provenance | | +| tst.js:16:20:16:20 | e | tst.js:17:11:17:11 | e | provenance | | +| tst.js:17:11:17:11 | e | tst.js:17:11:17:17 | e.stack | provenance | | nodes | node.js:8:10:8:12 | err | semmle.label | err | | node.js:11:13:11:15 | err | semmle.label | err | diff --git a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index 181408ccdaa..8e50d05362e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -1,70 +1,70 @@ edges -| passwords.js:7:20:7:20 | x | passwords.js:8:21:8:21 | x | -| passwords.js:10:11:10:18 | password | passwords.js:7:20:7:20 | x | -| passwords.js:14:31:14:38 | password | passwords.js:14:17:14:38 | name + ... assword | -| passwords.js:16:29:16:36 | password | passwords.js:16:17:16:38 | `${name ... sword}` | -| passwords.js:18:9:20:5 | obj1 [password] | passwords.js:21:17:21:20 | obj1 [password] | -| passwords.js:18:16:20:5 | {\\n ... x\\n } [password] | passwords.js:18:9:20:5 | obj1 [password] | -| passwords.js:19:19:19:19 | x | passwords.js:18:16:20:5 | {\\n ... x\\n } [password] | -| passwords.js:21:17:21:20 | obj1 [password] | passwords.js:21:17:21:20 | obj1 | -| passwords.js:23:9:25:5 | obj2 [x] | passwords.js:26:17:26:20 | obj2 [x] | -| passwords.js:23:16:25:5 | {\\n ... d\\n } [x] | passwords.js:23:9:25:5 | obj2 [x] | -| passwords.js:24:12:24:19 | password | passwords.js:23:16:25:5 | {\\n ... d\\n } [x] | -| passwords.js:26:17:26:20 | obj2 [x] | passwords.js:26:17:26:20 | obj2 | -| passwords.js:28:9:28:17 | obj3 [x] | passwords.js:29:17:29:20 | obj3 [x] | -| passwords.js:29:17:29:20 | obj3 [x] | passwords.js:29:17:29:20 | obj3 | -| passwords.js:30:5:30:8 | [post update] obj3 [x] | passwords.js:28:9:28:17 | obj3 [x] | -| passwords.js:30:14:30:21 | password | passwords.js:30:5:30:8 | [post update] obj3 [x] | -| passwords.js:77:9:77:55 | temp [encryptedPassword] | passwords.js:78:17:78:20 | temp [encryptedPassword] | -| passwords.js:77:16:77:55 | { encry ... sword } [encryptedPassword] | passwords.js:77:9:77:55 | temp [encryptedPassword] | -| passwords.js:77:37:77:53 | req.body.password | passwords.js:77:16:77:55 | { encry ... sword } [encryptedPassword] | -| passwords.js:78:17:78:20 | temp [encryptedPassword] | passwords.js:78:17:78:38 | temp.en ... assword | -| passwords.js:80:9:80:25 | secret | passwords.js:81:24:81:29 | secret | -| passwords.js:80:18:80:25 | password | passwords.js:80:9:80:25 | secret | -| passwords.js:81:24:81:29 | secret | passwords.js:81:17:81:31 | `pw: ${secret}` | -| passwords.js:93:39:93:46 | password | passwords.js:93:21:93:46 | "Passwo ... assword | -| passwords.js:98:39:98:46 | password | passwords.js:98:21:98:46 | "Passwo ... assword | -| passwords.js:105:39:105:46 | password | passwords.js:105:21:105:46 | "Passwo ... assword | -| passwords.js:110:39:110:46 | password | passwords.js:110:21:110:46 | "Passwo ... assword | -| passwords.js:114:43:114:50 | password | passwords.js:114:25:114:50 | "Passwo ... assword | -| passwords.js:119:39:119:46 | password | passwords.js:119:21:119:46 | "Passwo ... assword | -| passwords.js:122:31:122:38 | password | passwords.js:122:31:122:49 | password.toString() | -| passwords.js:122:31:122:49 | password.toString() | passwords.js:122:17:122:49 | name + ... tring() | -| passwords.js:123:31:123:38 | password | passwords.js:123:31:123:48 | password.valueOf() | -| passwords.js:123:31:123:48 | password.valueOf() | passwords.js:123:17:123:48 | name + ... lueOf() | -| passwords.js:127:9:132:5 | config [password] | passwords.js:135:17:135:22 | config [password] | -| passwords.js:127:9:132:5 | config [x] | passwords.js:135:17:135:22 | config [x] | -| passwords.js:127:9:132:5 | config [x] | passwords.js:136:17:136:22 | config [x] | -| passwords.js:127:9:132:5 | config [y] | passwords.js:135:17:135:22 | config [y] | -| passwords.js:127:9:132:5 | config [y] | passwords.js:137:17:137:22 | config [y] | -| passwords.js:127:18:132:5 | {\\n ... )\\n } [password] | passwords.js:127:9:132:5 | config [password] | -| passwords.js:127:18:132:5 | {\\n ... )\\n } [x] | passwords.js:127:9:132:5 | config [x] | -| passwords.js:127:18:132:5 | {\\n ... )\\n } [y] | passwords.js:127:9:132:5 | config [y] | -| passwords.js:128:19:128:19 | x | passwords.js:127:18:132:5 | {\\n ... )\\n } [password] | -| passwords.js:130:12:130:19 | password | passwords.js:127:18:132:5 | {\\n ... )\\n } [x] | -| passwords.js:131:12:131:24 | getPassword() | passwords.js:127:18:132:5 | {\\n ... )\\n } [y] | -| passwords.js:135:17:135:22 | config [password] | passwords.js:135:17:135:22 | config | -| passwords.js:135:17:135:22 | config [x] | passwords.js:135:17:135:22 | config | -| passwords.js:135:17:135:22 | config [y] | passwords.js:135:17:135:22 | config | -| passwords.js:136:17:136:22 | config [x] | passwords.js:136:17:136:24 | config.x | -| passwords.js:137:17:137:22 | config [y] | passwords.js:137:17:137:24 | config.y | -| passwords.js:146:9:148:5 | config [x] | passwords.js:149:21:149:26 | config [x] | -| passwords.js:146:18:148:5 | {\\n ... d\\n } [x] | passwords.js:146:9:148:5 | config [x] | -| passwords.js:147:12:147:19 | password | passwords.js:146:18:148:5 | {\\n ... d\\n } [x] | -| passwords.js:149:21:149:26 | config [x] | passwords.js:149:21:149:28 | config.x | -| passwords.js:149:21:149:28 | config.x | passwords.js:142:26:142:34 | arguments | -| passwords.js:150:21:150:31 | process.env | passwords.js:142:26:142:34 | arguments | -| passwords.js:152:9:152:63 | procdesc | passwords.js:154:21:154:28 | procdesc | -| passwords.js:152:20:152:44 | Util.in ... ss.env) | passwords.js:152:20:152:63 | Util.in ... /g, '') | -| passwords.js:152:20:152:63 | Util.in ... /g, '') | passwords.js:152:9:152:63 | procdesc | -| passwords.js:152:33:152:43 | process.env | passwords.js:152:20:152:44 | Util.in ... ss.env) | -| passwords.js:154:21:154:28 | procdesc | passwords.js:142:26:142:34 | arguments | -| passwords.js:163:14:163:21 | password | passwords.js:163:14:163:41 | passwor ... g, "*") | -| passwords.js:164:14:164:21 | password | passwords.js:164:14:164:42 | passwor ... g, "*") | -| passwords.js:169:17:169:24 | password | passwords.js:169:17:169:45 | passwor ... g, "*") | -| passwords.js:170:11:170:18 | password | passwords.js:170:11:170:39 | passwor ... g, "*") | -| passwords_in_server_5.js:4:7:4:24 | req.query.password | passwords_in_server_5.js:7:12:7:12 | x | -| passwords_in_server_5.js:7:12:7:12 | x | passwords_in_server_5.js:8:17:8:17 | x | +| passwords.js:7:20:7:20 | x | passwords.js:8:21:8:21 | x | provenance | | +| passwords.js:10:11:10:18 | password | passwords.js:7:20:7:20 | x | provenance | | +| passwords.js:14:31:14:38 | password | passwords.js:14:17:14:38 | name + ... assword | provenance | | +| passwords.js:16:29:16:36 | password | passwords.js:16:17:16:38 | `${name ... sword}` | provenance | | +| passwords.js:18:9:20:5 | obj1 [password] | passwords.js:21:17:21:20 | obj1 [password] | provenance | | +| passwords.js:18:16:20:5 | {\\n ... x\\n } [password] | passwords.js:18:9:20:5 | obj1 [password] | provenance | | +| passwords.js:19:19:19:19 | x | passwords.js:18:16:20:5 | {\\n ... x\\n } [password] | provenance | | +| passwords.js:21:17:21:20 | obj1 [password] | passwords.js:21:17:21:20 | obj1 | provenance | | +| passwords.js:23:9:25:5 | obj2 [x] | passwords.js:26:17:26:20 | obj2 [x] | provenance | | +| passwords.js:23:16:25:5 | {\\n ... d\\n } [x] | passwords.js:23:9:25:5 | obj2 [x] | provenance | | +| passwords.js:24:12:24:19 | password | passwords.js:23:16:25:5 | {\\n ... d\\n } [x] | provenance | | +| passwords.js:26:17:26:20 | obj2 [x] | passwords.js:26:17:26:20 | obj2 | provenance | | +| passwords.js:28:9:28:17 | obj3 [x] | passwords.js:29:17:29:20 | obj3 [x] | provenance | | +| passwords.js:29:17:29:20 | obj3 [x] | passwords.js:29:17:29:20 | obj3 | provenance | | +| passwords.js:30:5:30:8 | [post update] obj3 [x] | passwords.js:28:9:28:17 | obj3 [x] | provenance | | +| passwords.js:30:14:30:21 | password | passwords.js:30:5:30:8 | [post update] obj3 [x] | provenance | | +| passwords.js:77:9:77:55 | temp [encryptedPassword] | passwords.js:78:17:78:20 | temp [encryptedPassword] | provenance | | +| passwords.js:77:16:77:55 | { encry ... sword } [encryptedPassword] | passwords.js:77:9:77:55 | temp [encryptedPassword] | provenance | | +| passwords.js:77:37:77:53 | req.body.password | passwords.js:77:16:77:55 | { encry ... sword } [encryptedPassword] | provenance | | +| passwords.js:78:17:78:20 | temp [encryptedPassword] | passwords.js:78:17:78:38 | temp.en ... assword | provenance | | +| passwords.js:80:9:80:25 | secret | passwords.js:81:24:81:29 | secret | provenance | | +| passwords.js:80:18:80:25 | password | passwords.js:80:9:80:25 | secret | provenance | | +| passwords.js:81:24:81:29 | secret | passwords.js:81:17:81:31 | `pw: ${secret}` | provenance | | +| passwords.js:93:39:93:46 | password | passwords.js:93:21:93:46 | "Passwo ... assword | provenance | | +| passwords.js:98:39:98:46 | password | passwords.js:98:21:98:46 | "Passwo ... assword | provenance | | +| passwords.js:105:39:105:46 | password | passwords.js:105:21:105:46 | "Passwo ... assword | provenance | | +| passwords.js:110:39:110:46 | password | passwords.js:110:21:110:46 | "Passwo ... assword | provenance | | +| passwords.js:114:43:114:50 | password | passwords.js:114:25:114:50 | "Passwo ... assword | provenance | | +| passwords.js:119:39:119:46 | password | passwords.js:119:21:119:46 | "Passwo ... assword | provenance | | +| passwords.js:122:31:122:38 | password | passwords.js:122:31:122:49 | password.toString() | provenance | | +| passwords.js:122:31:122:49 | password.toString() | passwords.js:122:17:122:49 | name + ... tring() | provenance | | +| passwords.js:123:31:123:38 | password | passwords.js:123:31:123:48 | password.valueOf() | provenance | | +| passwords.js:123:31:123:48 | password.valueOf() | passwords.js:123:17:123:48 | name + ... lueOf() | provenance | | +| passwords.js:127:9:132:5 | config [password] | passwords.js:135:17:135:22 | config [password] | provenance | | +| passwords.js:127:9:132:5 | config [x] | passwords.js:135:17:135:22 | config [x] | provenance | | +| passwords.js:127:9:132:5 | config [x] | passwords.js:136:17:136:22 | config [x] | provenance | | +| passwords.js:127:9:132:5 | config [y] | passwords.js:135:17:135:22 | config [y] | provenance | | +| passwords.js:127:9:132:5 | config [y] | passwords.js:137:17:137:22 | config [y] | provenance | | +| passwords.js:127:18:132:5 | {\\n ... )\\n } [password] | passwords.js:127:9:132:5 | config [password] | provenance | | +| passwords.js:127:18:132:5 | {\\n ... )\\n } [x] | passwords.js:127:9:132:5 | config [x] | provenance | | +| passwords.js:127:18:132:5 | {\\n ... )\\n } [y] | passwords.js:127:9:132:5 | config [y] | provenance | | +| passwords.js:128:19:128:19 | x | passwords.js:127:18:132:5 | {\\n ... )\\n } [password] | provenance | | +| passwords.js:130:12:130:19 | password | passwords.js:127:18:132:5 | {\\n ... )\\n } [x] | provenance | | +| passwords.js:131:12:131:24 | getPassword() | passwords.js:127:18:132:5 | {\\n ... )\\n } [y] | provenance | | +| passwords.js:135:17:135:22 | config [password] | passwords.js:135:17:135:22 | config | provenance | | +| passwords.js:135:17:135:22 | config [x] | passwords.js:135:17:135:22 | config | provenance | | +| passwords.js:135:17:135:22 | config [y] | passwords.js:135:17:135:22 | config | provenance | | +| passwords.js:136:17:136:22 | config [x] | passwords.js:136:17:136:24 | config.x | provenance | | +| passwords.js:137:17:137:22 | config [y] | passwords.js:137:17:137:24 | config.y | provenance | | +| passwords.js:146:9:148:5 | config [x] | passwords.js:149:21:149:26 | config [x] | provenance | | +| passwords.js:146:18:148:5 | {\\n ... d\\n } [x] | passwords.js:146:9:148:5 | config [x] | provenance | | +| passwords.js:147:12:147:19 | password | passwords.js:146:18:148:5 | {\\n ... d\\n } [x] | provenance | | +| passwords.js:149:21:149:26 | config [x] | passwords.js:149:21:149:28 | config.x | provenance | | +| passwords.js:149:21:149:28 | config.x | passwords.js:142:26:142:34 | arguments | provenance | Config | +| passwords.js:150:21:150:31 | process.env | passwords.js:142:26:142:34 | arguments | provenance | Config | +| passwords.js:152:9:152:63 | procdesc | passwords.js:154:21:154:28 | procdesc | provenance | | +| passwords.js:152:20:152:44 | Util.in ... ss.env) | passwords.js:152:20:152:63 | Util.in ... /g, '') | provenance | | +| passwords.js:152:20:152:63 | Util.in ... /g, '') | passwords.js:152:9:152:63 | procdesc | provenance | | +| passwords.js:152:33:152:43 | process.env | passwords.js:152:20:152:44 | Util.in ... ss.env) | provenance | | +| passwords.js:154:21:154:28 | procdesc | passwords.js:142:26:142:34 | arguments | provenance | Config | +| passwords.js:163:14:163:21 | password | passwords.js:163:14:163:41 | passwor ... g, "*") | provenance | | +| passwords.js:164:14:164:21 | password | passwords.js:164:14:164:42 | passwor ... g, "*") | provenance | | +| passwords.js:169:17:169:24 | password | passwords.js:169:17:169:45 | passwor ... g, "*") | provenance | | +| passwords.js:170:11:170:18 | password | passwords.js:170:11:170:39 | passwor ... g, "*") | provenance | | +| passwords_in_server_5.js:4:7:4:24 | req.query.password | passwords_in_server_5.js:7:12:7:12 | x | provenance | | +| passwords_in_server_5.js:7:12:7:12 | x | passwords_in_server_5.js:8:17:8:17 | x | provenance | | nodes | passwords.js:2:17:2:24 | password | semmle.label | password | | passwords.js:3:17:3:26 | o.password | semmle.label | o.password | diff --git a/javascript/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected b/javascript/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected index 5d1885142c9..e6a5f7f551e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected @@ -1,9 +1,9 @@ edges -| CleartextStorage2.js:5:7:5:58 | pw | CleartextStorage2.js:7:33:7:34 | pw | -| CleartextStorage2.js:5:12:5:58 | url.par ... assword | CleartextStorage2.js:5:7:5:58 | pw | -| CleartextStorage2.js:7:33:7:34 | pw | CleartextStorage2.js:7:19:7:34 | 'password=' + pw | -| CleartextStorage.js:5:7:5:40 | pw | CleartextStorage.js:7:26:7:27 | pw | -| CleartextStorage.js:5:12:5:40 | req.par ... sword") | CleartextStorage.js:5:7:5:40 | pw | +| CleartextStorage2.js:5:7:5:58 | pw | CleartextStorage2.js:7:33:7:34 | pw | provenance | | +| CleartextStorage2.js:5:12:5:58 | url.par ... assword | CleartextStorage2.js:5:7:5:58 | pw | provenance | | +| CleartextStorage2.js:7:33:7:34 | pw | CleartextStorage2.js:7:19:7:34 | 'password=' + pw | provenance | | +| CleartextStorage.js:5:7:5:40 | pw | CleartextStorage.js:7:26:7:27 | pw | provenance | | +| CleartextStorage.js:5:12:5:40 | req.par ... sword") | CleartextStorage.js:5:7:5:40 | pw | provenance | | nodes | CleartextStorage2.js:5:7:5:58 | pw | semmle.label | pw | | CleartextStorage2.js:5:12:5:58 | url.par ... assword | semmle.label | url.par ... assword | diff --git a/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected b/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected index 7337287c748..122cb1ac876 100644 --- a/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected +++ b/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected @@ -1,36 +1,36 @@ edges -| tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | provenance | | +| tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | provenance | Config | | tst.js:19:9:19:36 | suffix | tst.js:20:31:20:36 | suffix | provenance | | -| tst.js:19:18:19:30 | Math.random() | tst.js:19:18:19:36 | Math.random() % 255 | provenance | | +| tst.js:19:18:19:30 | Math.random() | tst.js:19:18:19:36 | Math.random() % 255 | provenance | Config | | tst.js:19:18:19:36 | Math.random() % 255 | tst.js:19:9:19:36 | suffix | provenance | | -| tst.js:20:31:20:36 | suffix | tst.js:20:20:20:36 | "prefix" + suffix | provenance | | +| tst.js:20:31:20:36 | suffix | tst.js:20:20:20:36 | "prefix" + suffix | provenance | Config | | tst.js:28:9:28:26 | pw | tst.js:29:20:29:21 | pw | provenance | | | tst.js:28:14:28:26 | Math.random() | tst.js:28:9:28:26 | pw | provenance | | -| tst.js:41:21:41:33 | Math.random() | tst.js:41:20:41:33 | !Math.random() | provenance | | -| tst.js:61:22:61:34 | Math.random() | tst.js:61:17:61:34 | '' + Math.random() | provenance | | -| tst.js:66:29:66:41 | Math.random() | tst.js:66:18:66:42 | Math.fl ... ndom()) | provenance | | +| tst.js:41:21:41:33 | Math.random() | tst.js:41:20:41:33 | !Math.random() | provenance | Config | +| tst.js:61:22:61:34 | Math.random() | tst.js:61:17:61:34 | '' + Math.random() | provenance | Config | +| tst.js:66:29:66:41 | Math.random() | tst.js:66:18:66:42 | Math.fl ... ndom()) | provenance | Config | | tst.js:71:9:71:48 | rand | tst.js:72:34:72:37 | rand | provenance | | | tst.js:71:16:71:48 | Math.fl ... 999999) | tst.js:71:9:71:48 | rand | provenance | | -| tst.js:71:27:71:39 | Math.random() | tst.js:71:27:71:47 | Math.ra ... 9999999 | provenance | | -| tst.js:71:27:71:47 | Math.ra ... 9999999 | tst.js:71:16:71:48 | Math.fl ... 999999) | provenance | | +| tst.js:71:27:71:39 | Math.random() | tst.js:71:27:71:47 | Math.ra ... 9999999 | provenance | Config | +| tst.js:71:27:71:47 | Math.ra ... 9999999 | tst.js:71:16:71:48 | Math.fl ... 999999) | provenance | Config | | tst.js:72:9:72:48 | concat | tst.js:73:23:73:28 | concat | provenance | | | tst.js:72:18:72:48 | ts.toSt ... tring() | tst.js:72:9:72:48 | concat | provenance | | -| tst.js:72:34:72:37 | rand | tst.js:72:34:72:48 | rand.toString() | provenance | | -| tst.js:72:34:72:48 | rand.toString() | tst.js:72:18:72:48 | ts.toSt ... tring() | provenance | | +| tst.js:72:34:72:37 | rand | tst.js:72:34:72:48 | rand.toString() | provenance | Config | +| tst.js:72:34:72:48 | rand.toString() | tst.js:72:18:72:48 | ts.toSt ... tring() | provenance | Config | | tst.js:77:16:77:21 | secret | tst.js:77:16:77:21 | secret | provenance | | | tst.js:80:7:80:19 | Math.random() | tst.js:77:16:77:21 | secret | provenance | | -| tst.js:115:27:115:39 | Math.random() | tst.js:115:27:115:55 | Math.ra ... 000_000 | provenance | | -| tst.js:115:27:115:55 | Math.ra ... 000_000 | tst.js:115:16:115:56 | Math.fl ... 00_000) | provenance | | -| tst.js:116:33:116:45 | Math.random() | tst.js:116:33:116:61 | Math.ra ... 000_000 | provenance | | -| tst.js:116:33:116:61 | Math.ra ... 000_000 | tst.js:116:22:116:62 | Math.fl ... 00_000) | provenance | | -| tst.js:117:26:117:38 | Math.random() | tst.js:117:26:117:54 | Math.ra ... 000_000 | provenance | | -| tst.js:117:26:117:54 | Math.ra ... 000_000 | tst.js:117:15:117:55 | Math.fl ... 00_000) | provenance | | -| tst.js:118:34:118:46 | Math.random() | tst.js:118:34:118:62 | Math.ra ... 000_000 | provenance | | -| tst.js:118:34:118:62 | Math.ra ... 000_000 | tst.js:118:23:118:63 | Math.fl ... 00_000) | provenance | | -| tst.js:136:21:136:67 | chars[M ... ength)] | tst.js:136:9:136:67 | password | provenance | | -| tst.js:136:27:136:66 | Math.fl ... length) | tst.js:136:21:136:67 | chars[M ... ength)] | provenance | | -| tst.js:136:38:136:50 | Math.random() | tst.js:136:38:136:65 | Math.ra ... .length | provenance | | -| tst.js:136:38:136:65 | Math.ra ... .length | tst.js:136:27:136:66 | Math.fl ... length) | provenance | | +| tst.js:115:27:115:39 | Math.random() | tst.js:115:27:115:55 | Math.ra ... 000_000 | provenance | Config | +| tst.js:115:27:115:55 | Math.ra ... 000_000 | tst.js:115:16:115:56 | Math.fl ... 00_000) | provenance | Config | +| tst.js:116:33:116:45 | Math.random() | tst.js:116:33:116:61 | Math.ra ... 000_000 | provenance | Config | +| tst.js:116:33:116:61 | Math.ra ... 000_000 | tst.js:116:22:116:62 | Math.fl ... 00_000) | provenance | Config | +| tst.js:117:26:117:38 | Math.random() | tst.js:117:26:117:54 | Math.ra ... 000_000 | provenance | Config | +| tst.js:117:26:117:54 | Math.ra ... 000_000 | tst.js:117:15:117:55 | Math.fl ... 00_000) | provenance | Config | +| tst.js:118:34:118:46 | Math.random() | tst.js:118:34:118:62 | Math.ra ... 000_000 | provenance | Config | +| tst.js:118:34:118:62 | Math.ra ... 000_000 | tst.js:118:23:118:63 | Math.fl ... 00_000) | provenance | Config | +| tst.js:136:21:136:67 | chars[M ... ength)] | tst.js:136:9:136:67 | password | provenance | Config | +| tst.js:136:27:136:66 | Math.fl ... length) | tst.js:136:21:136:67 | chars[M ... ength)] | provenance | Config | +| tst.js:136:38:136:50 | Math.random() | tst.js:136:38:136:65 | Math.ra ... .length | provenance | Config | +| tst.js:136:38:136:65 | Math.ra ... .length | tst.js:136:27:136:66 | Math.fl ... length) | provenance | Config | nodes | tst.js:2:20:2:32 | Math.random() | semmle.label | Math.random() | | tst.js:6:20:6:43 | "prefix ... andom() | semmle.label | "prefix ... andom() | diff --git a/javascript/ql/test/query-tests/Security/CWE-346/CorsMisconfigurationForCredentials.expected b/javascript/ql/test/query-tests/Security/CWE-346/CorsMisconfigurationForCredentials.expected index fdbf937e0a2..fd0677de03d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-346/CorsMisconfigurationForCredentials.expected +++ b/javascript/ql/test/query-tests/Security/CWE-346/CorsMisconfigurationForCredentials.expected @@ -1,7 +1,7 @@ edges -| tst.js:12:9:12:54 | origin | tst.js:13:50:13:55 | origin | -| tst.js:12:18:12:41 | url.par ... , true) | tst.js:12:9:12:54 | origin | -| tst.js:12:28:12:34 | req.url | tst.js:12:18:12:41 | url.par ... , true) | +| tst.js:12:9:12:54 | origin | tst.js:13:50:13:55 | origin | provenance | | +| tst.js:12:18:12:41 | url.par ... , true) | tst.js:12:9:12:54 | origin | provenance | | +| tst.js:12:28:12:34 | req.url | tst.js:12:18:12:41 | url.par ... , true) | provenance | | nodes | tst.js:12:9:12:54 | origin | semmle.label | origin | | tst.js:12:18:12:41 | url.par ... , true) | semmle.label | url.par ... , true) | diff --git a/javascript/ql/test/query-tests/Security/CWE-377/InsecureTemporaryFile.expected b/javascript/ql/test/query-tests/Security/CWE-377/InsecureTemporaryFile.expected index 113ac3bd205..69dcd04037a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-377/InsecureTemporaryFile.expected +++ b/javascript/ql/test/query-tests/Security/CWE-377/InsecureTemporaryFile.expected @@ -1,16 +1,16 @@ edges -| insecure-temporary-file.js:7:9:11:5 | tmpLocation | insecure-temporary-file.js:13:22:13:32 | tmpLocation | -| insecure-temporary-file.js:7:23:11:5 | path.jo ... )\\n ) | insecure-temporary-file.js:7:9:11:5 | tmpLocation | -| insecure-temporary-file.js:8:21:8:31 | os.tmpdir() | insecure-temporary-file.js:7:23:11:5 | path.jo ... )\\n ) | -| insecure-temporary-file.js:15:9:15:34 | tmpPath | insecure-temporary-file.js:17:32:17:38 | tmpPath | -| insecure-temporary-file.js:15:9:15:34 | tmpPath | insecure-temporary-file.js:23:32:23:38 | tmpPath | -| insecure-temporary-file.js:15:19:15:34 | "/tmp/something" | insecure-temporary-file.js:15:9:15:34 | tmpPath | -| insecure-temporary-file.js:17:32:17:38 | tmpPath | insecure-temporary-file.js:17:22:17:49 | path.jo ... /foo/") | -| insecure-temporary-file.js:23:32:23:38 | tmpPath | insecure-temporary-file.js:23:22:23:49 | path.jo ... /foo/") | -| insecure-temporary-file.js:25:11:25:92 | tmpPath2 | insecure-temporary-file.js:26:22:26:29 | tmpPath2 | -| insecure-temporary-file.js:25:11:25:92 | tmpPath2 | insecure-temporary-file.js:28:17:28:24 | tmpPath2 | -| insecure-temporary-file.js:25:22:25:92 | path.jo ... )}.md`) | insecure-temporary-file.js:25:11:25:92 | tmpPath2 | -| insecure-temporary-file.js:25:32:25:42 | os.tmpdir() | insecure-temporary-file.js:25:22:25:92 | path.jo ... )}.md`) | +| insecure-temporary-file.js:7:9:11:5 | tmpLocation | insecure-temporary-file.js:13:22:13:32 | tmpLocation | provenance | | +| insecure-temporary-file.js:7:23:11:5 | path.jo ... )\\n ) | insecure-temporary-file.js:7:9:11:5 | tmpLocation | provenance | | +| insecure-temporary-file.js:8:21:8:31 | os.tmpdir() | insecure-temporary-file.js:7:23:11:5 | path.jo ... )\\n ) | provenance | | +| insecure-temporary-file.js:15:9:15:34 | tmpPath | insecure-temporary-file.js:17:32:17:38 | tmpPath | provenance | | +| insecure-temporary-file.js:15:9:15:34 | tmpPath | insecure-temporary-file.js:23:32:23:38 | tmpPath | provenance | | +| insecure-temporary-file.js:15:19:15:34 | "/tmp/something" | insecure-temporary-file.js:15:9:15:34 | tmpPath | provenance | | +| insecure-temporary-file.js:17:32:17:38 | tmpPath | insecure-temporary-file.js:17:22:17:49 | path.jo ... /foo/") | provenance | | +| insecure-temporary-file.js:23:32:23:38 | tmpPath | insecure-temporary-file.js:23:22:23:49 | path.jo ... /foo/") | provenance | | +| insecure-temporary-file.js:25:11:25:92 | tmpPath2 | insecure-temporary-file.js:26:22:26:29 | tmpPath2 | provenance | | +| insecure-temporary-file.js:25:11:25:92 | tmpPath2 | insecure-temporary-file.js:28:17:28:24 | tmpPath2 | provenance | | +| insecure-temporary-file.js:25:22:25:92 | path.jo ... )}.md`) | insecure-temporary-file.js:25:11:25:92 | tmpPath2 | provenance | | +| insecure-temporary-file.js:25:32:25:42 | os.tmpdir() | insecure-temporary-file.js:25:22:25:92 | path.jo ... )}.md`) | provenance | | nodes | insecure-temporary-file.js:7:9:11:5 | tmpLocation | semmle.label | tmpLocation | | insecure-temporary-file.js:7:23:11:5 | path.jo ... )\\n ) | semmle.label | path.jo ... )\\n ) | diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected index e8593c903ca..2d21c332482 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected @@ -1,355 +1,355 @@ edges -| lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x | -| lib/indirect.js:1:32:1:32 | x | lib/indirect.js:2:16:2:16 | x | -| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name | -| lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name | -| lib/lib.js:32:32:32:40 | arguments | lib/lib.js:35:1:37:1 | 'arguments' object of function usedWithArguments | -| lib/lib.js:35:1:37:1 | 'arguments' object of function usedWithArguments | lib/lib.js:35:28:35:31 | name | -| lib/lib.js:35:28:35:31 | name | lib/lib.js:36:13:36:16 | name | -| lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | -| lib/lib.js:41:32:41:35 | name | lib/lib.js:44:12:44:15 | name | -| lib/lib.js:44:5:44:25 | name | lib/lib.js:45:17:45:20 | name | -| lib/lib.js:44:12:44:15 | name | lib/lib.js:44:12:44:25 | name.substr(1) | -| lib/lib.js:44:12:44:25 | name.substr(1) | lib/lib.js:44:5:44:25 | name | -| lib/lib.js:52:22:52:25 | name | lib/lib.js:53:16:53:19 | name | -| lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | -| lib/otherLib/js/src/index.js:1:28:1:31 | name | lib/otherLib/js/src/index.js:2:13:2:16 | name | -| lib/snapdragon.js:3:34:3:38 | input | lib/snapdragon.js:9:12:9:16 | input | -| lib/snapdragon.js:9:12:9:16 | input | lib/snapdragon.js:7:15:7:18 | this | -| lib/snapdragon.js:12:34:12:38 | input | lib/snapdragon.js:17:20:17:24 | input | -| lib/snapdragon.js:17:20:17:24 | input | lib/snapdragon.js:15:13:15:16 | this | -| lib/snapdragon.js:20:34:20:38 | input | lib/snapdragon.js:25:22:25:26 | input | -| lib/snapdragon.js:22:44:22:47 | node | lib/snapdragon.js:23:5:23:8 | node | -| lib/snapdragon.js:23:5:23:8 | node | lib/snapdragon.js:23:5:23:12 | node.val | -| lib/snapdragon.js:25:22:25:26 | input | lib/snapdragon.js:22:44:22:47 | node | -| lib/subLib4/factory.js:7:27:7:30 | name | lib/subLib4/factory.js:8:13:8:16 | name | -| lib/subLib5/feature.js:1:28:1:31 | name | lib/subLib5/feature.js:2:13:2:16 | name | -| lib/subLib5/main.js:1:28:1:31 | name | lib/subLib5/main.js:2:13:2:16 | name | -| lib/subLib5/subclass.js:4:10:4:13 | name | lib/subLib5/subclass.js:5:16:5:19 | name | -| lib/subLib6/index.js:1:32:1:35 | name | lib/subLib6/index.js:2:14:2:17 | name | -| lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:7:2:7:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:7:2:7:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:8:2:8:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:8:2:8:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:9:2:9:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:9:2:9:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:10:2:10:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:11:2:11:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:11:2:11:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:12:2:12:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:12:2:12:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:13:2:13:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:14:2:14:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:15:2:15:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:15:2:15:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:16:2:16:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:16:2:16:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:17:23:17:29 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:17:23:17:29 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:18:2:18:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:18:2:18:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:19:2:19:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:19:2:19:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:20:2:20:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:20:2:20:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:21:6:21:12 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:25:2:25:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:25:2:25:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:26:2:26:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:27:77:27:83 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:28:76:28:82 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:30:2:30:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:30:2:30:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:31:2:31:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:32:2:32:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:33:2:33:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:33:2:33:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:34:2:34:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:36:2:36:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:36:2:36:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:37:2:37:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:37:2:37:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:38:2:38:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:38:2:38:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:40:2:40:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:40:2:40:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:41:2:41:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:43:2:43:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:43:2:43:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:44:2:44:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:46:2:46:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:47:2:47:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:48:2:48:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:48:2:48:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:50:14:50:20 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:50:14:50:20 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:51:26:51:32 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:51:26:51:32 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:52:22:52:28 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:52:22:52:28 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:53:21:53:27 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:53:21:53:27 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:54:22:54:28 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:54:22:54:28 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:55:23:55:29 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:55:23:55:29 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:56:22:56:28 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:56:22:56:28 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:57:25:57:31 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:57:25:57:31 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:58:21:58:27 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:58:21:58:27 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:59:23:59:29 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:59:23:59:29 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:60:17:60:23 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:61:18:61:24 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:62:17:62:23 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:62:17:62:23 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:63:21:63:27 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:63:21:63:27 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:64:24:64:30 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:64:24:64:30 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:65:24:65:30 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:65:24:65:30 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:66:19:66:25 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:66:19:66:25 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:67:18:67:24 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:67:18:67:24 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:71:2:71:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:71:2:71:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:73:2:73:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:73:2:73:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:75:2:75:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:75:2:75:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:77:2:77:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:77:2:77:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:80:2:80:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:80:2:80:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:81:2:81:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:81:2:81:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:82:2:82:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:83:2:83:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:84:2:84:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:86:2:86:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:86:2:86:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:88:2:88:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:88:2:88:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:89:2:89:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:89:2:89:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:90:2:90:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:90:2:90:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:91:2:91:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:92:2:92:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:94:2:94:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:94:2:94:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:95:2:95:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:95:2:95:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:96:2:96:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:96:2:96:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:98:2:98:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:98:2:98:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:100:2:100:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:100:2:100:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:101:2:101:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:101:2:101:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:102:2:102:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:102:2:102:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:103:2:103:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:103:2:103:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:104:2:104:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:104:2:104:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:105:2:105:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:107:2:107:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:107:2:107:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:108:2:108:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:108:2:108:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:109:2:109:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:109:2:109:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:111:2:111:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:111:2:111:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:112:2:112:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:112:2:112:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:114:2:114:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:114:2:114:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:116:2:116:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:116:2:116:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:118:2:118:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:118:2:118:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:127:2:127:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:129:17:129:23 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:132:18:132:24 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:135:21:135:27 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:138:5:138:11 | tainted | -| polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:5:6:5:32 | tainted | -| polynomial-redos.js:7:2:7:8 | tainted | polynomial-redos.js:8:2:8:8 | tainted | -| polynomial-redos.js:7:2:7:8 | tainted | polynomial-redos.js:8:2:8:8 | tainted | -| polynomial-redos.js:8:2:8:8 | tainted | polynomial-redos.js:9:2:9:8 | tainted | -| polynomial-redos.js:8:2:8:8 | tainted | polynomial-redos.js:9:2:9:8 | tainted | -| polynomial-redos.js:9:2:9:8 | tainted | polynomial-redos.js:10:2:10:8 | tainted | -| polynomial-redos.js:10:2:10:8 | tainted | polynomial-redos.js:11:2:11:8 | tainted | -| polynomial-redos.js:10:2:10:8 | tainted | polynomial-redos.js:11:2:11:8 | tainted | -| polynomial-redos.js:11:2:11:8 | tainted | polynomial-redos.js:12:2:12:8 | tainted | -| polynomial-redos.js:11:2:11:8 | tainted | polynomial-redos.js:12:2:12:8 | tainted | -| polynomial-redos.js:12:2:12:8 | tainted | polynomial-redos.js:13:2:13:8 | tainted | -| polynomial-redos.js:13:2:13:8 | tainted | polynomial-redos.js:14:2:14:8 | tainted | -| polynomial-redos.js:14:2:14:8 | tainted | polynomial-redos.js:15:2:15:8 | tainted | -| polynomial-redos.js:14:2:14:8 | tainted | polynomial-redos.js:15:2:15:8 | tainted | -| polynomial-redos.js:15:2:15:8 | tainted | polynomial-redos.js:16:2:16:8 | tainted | -| polynomial-redos.js:15:2:15:8 | tainted | polynomial-redos.js:16:2:16:8 | tainted | -| polynomial-redos.js:16:2:16:8 | tainted | polynomial-redos.js:17:23:17:29 | tainted | -| polynomial-redos.js:16:2:16:8 | tainted | polynomial-redos.js:17:23:17:29 | tainted | -| polynomial-redos.js:17:23:17:29 | tainted | polynomial-redos.js:18:2:18:8 | tainted | -| polynomial-redos.js:17:23:17:29 | tainted | polynomial-redos.js:18:2:18:8 | tainted | -| polynomial-redos.js:18:2:18:8 | tainted | polynomial-redos.js:19:2:19:8 | tainted | -| polynomial-redos.js:18:2:18:8 | tainted | polynomial-redos.js:19:2:19:8 | tainted | -| polynomial-redos.js:19:2:19:8 | tainted | polynomial-redos.js:20:2:20:8 | tainted | -| polynomial-redos.js:19:2:19:8 | tainted | polynomial-redos.js:20:2:20:8 | tainted | -| polynomial-redos.js:20:2:20:8 | tainted | polynomial-redos.js:21:6:21:12 | tainted | -| polynomial-redos.js:21:6:21:12 | tainted | polynomial-redos.js:25:2:25:8 | tainted | -| polynomial-redos.js:21:6:21:12 | tainted | polynomial-redos.js:25:2:25:8 | tainted | -| polynomial-redos.js:25:2:25:8 | tainted | polynomial-redos.js:26:2:26:8 | tainted | -| polynomial-redos.js:26:2:26:8 | tainted | polynomial-redos.js:27:77:27:83 | tainted | -| polynomial-redos.js:27:77:27:83 | tainted | polynomial-redos.js:28:76:28:82 | tainted | -| polynomial-redos.js:28:76:28:82 | tainted | polynomial-redos.js:30:2:30:8 | tainted | -| polynomial-redos.js:28:76:28:82 | tainted | polynomial-redos.js:30:2:30:8 | tainted | -| polynomial-redos.js:30:2:30:8 | tainted | polynomial-redos.js:31:2:31:8 | tainted | -| polynomial-redos.js:31:2:31:8 | tainted | polynomial-redos.js:32:2:32:8 | tainted | -| polynomial-redos.js:32:2:32:8 | tainted | polynomial-redos.js:33:2:33:8 | tainted | -| polynomial-redos.js:32:2:32:8 | tainted | polynomial-redos.js:33:2:33:8 | tainted | -| polynomial-redos.js:33:2:33:8 | tainted | polynomial-redos.js:34:2:34:8 | tainted | -| polynomial-redos.js:34:2:34:8 | tainted | polynomial-redos.js:36:2:36:8 | tainted | -| polynomial-redos.js:34:2:34:8 | tainted | polynomial-redos.js:36:2:36:8 | tainted | -| polynomial-redos.js:36:2:36:8 | tainted | polynomial-redos.js:37:2:37:8 | tainted | -| polynomial-redos.js:36:2:36:8 | tainted | polynomial-redos.js:37:2:37:8 | tainted | -| polynomial-redos.js:37:2:37:8 | tainted | polynomial-redos.js:38:2:38:8 | tainted | -| polynomial-redos.js:37:2:37:8 | tainted | polynomial-redos.js:38:2:38:8 | tainted | -| polynomial-redos.js:38:2:38:8 | tainted | polynomial-redos.js:40:2:40:8 | tainted | -| polynomial-redos.js:38:2:38:8 | tainted | polynomial-redos.js:40:2:40:8 | tainted | -| polynomial-redos.js:40:2:40:8 | tainted | polynomial-redos.js:41:2:41:8 | tainted | -| polynomial-redos.js:41:2:41:8 | tainted | polynomial-redos.js:43:2:43:8 | tainted | -| polynomial-redos.js:41:2:41:8 | tainted | polynomial-redos.js:43:2:43:8 | tainted | -| polynomial-redos.js:43:2:43:8 | tainted | polynomial-redos.js:44:2:44:8 | tainted | -| polynomial-redos.js:44:2:44:8 | tainted | polynomial-redos.js:46:2:46:8 | tainted | -| polynomial-redos.js:46:2:46:8 | tainted | polynomial-redos.js:47:2:47:8 | tainted | -| polynomial-redos.js:47:2:47:8 | tainted | polynomial-redos.js:48:2:48:8 | tainted | -| polynomial-redos.js:47:2:47:8 | tainted | polynomial-redos.js:48:2:48:8 | tainted | -| polynomial-redos.js:48:2:48:8 | tainted | polynomial-redos.js:50:14:50:20 | tainted | -| polynomial-redos.js:48:2:48:8 | tainted | polynomial-redos.js:50:14:50:20 | tainted | -| polynomial-redos.js:50:14:50:20 | tainted | polynomial-redos.js:51:26:51:32 | tainted | -| polynomial-redos.js:50:14:50:20 | tainted | polynomial-redos.js:51:26:51:32 | tainted | -| polynomial-redos.js:51:26:51:32 | tainted | polynomial-redos.js:52:22:52:28 | tainted | -| polynomial-redos.js:51:26:51:32 | tainted | polynomial-redos.js:52:22:52:28 | tainted | -| polynomial-redos.js:52:22:52:28 | tainted | polynomial-redos.js:53:21:53:27 | tainted | -| polynomial-redos.js:52:22:52:28 | tainted | polynomial-redos.js:53:21:53:27 | tainted | -| polynomial-redos.js:53:21:53:27 | tainted | polynomial-redos.js:54:22:54:28 | tainted | -| polynomial-redos.js:53:21:53:27 | tainted | polynomial-redos.js:54:22:54:28 | tainted | -| polynomial-redos.js:54:22:54:28 | tainted | polynomial-redos.js:55:23:55:29 | tainted | -| polynomial-redos.js:54:22:54:28 | tainted | polynomial-redos.js:55:23:55:29 | tainted | -| polynomial-redos.js:55:23:55:29 | tainted | polynomial-redos.js:56:22:56:28 | tainted | -| polynomial-redos.js:55:23:55:29 | tainted | polynomial-redos.js:56:22:56:28 | tainted | -| polynomial-redos.js:56:22:56:28 | tainted | polynomial-redos.js:57:25:57:31 | tainted | -| polynomial-redos.js:56:22:56:28 | tainted | polynomial-redos.js:57:25:57:31 | tainted | -| polynomial-redos.js:57:25:57:31 | tainted | polynomial-redos.js:58:21:58:27 | tainted | -| polynomial-redos.js:57:25:57:31 | tainted | polynomial-redos.js:58:21:58:27 | tainted | -| polynomial-redos.js:58:21:58:27 | tainted | polynomial-redos.js:59:23:59:29 | tainted | -| polynomial-redos.js:58:21:58:27 | tainted | polynomial-redos.js:59:23:59:29 | tainted | -| polynomial-redos.js:59:23:59:29 | tainted | polynomial-redos.js:60:17:60:23 | tainted | -| polynomial-redos.js:60:17:60:23 | tainted | polynomial-redos.js:61:18:61:24 | tainted | -| polynomial-redos.js:61:18:61:24 | tainted | polynomial-redos.js:62:17:62:23 | tainted | -| polynomial-redos.js:61:18:61:24 | tainted | polynomial-redos.js:62:17:62:23 | tainted | -| polynomial-redos.js:62:17:62:23 | tainted | polynomial-redos.js:63:21:63:27 | tainted | -| polynomial-redos.js:62:17:62:23 | tainted | polynomial-redos.js:63:21:63:27 | tainted | -| polynomial-redos.js:63:21:63:27 | tainted | polynomial-redos.js:64:24:64:30 | tainted | -| polynomial-redos.js:63:21:63:27 | tainted | polynomial-redos.js:64:24:64:30 | tainted | -| polynomial-redos.js:64:24:64:30 | tainted | polynomial-redos.js:65:24:65:30 | tainted | -| polynomial-redos.js:64:24:64:30 | tainted | polynomial-redos.js:65:24:65:30 | tainted | -| polynomial-redos.js:65:24:65:30 | tainted | polynomial-redos.js:66:19:66:25 | tainted | -| polynomial-redos.js:65:24:65:30 | tainted | polynomial-redos.js:66:19:66:25 | tainted | -| polynomial-redos.js:66:19:66:25 | tainted | polynomial-redos.js:67:18:67:24 | tainted | -| polynomial-redos.js:66:19:66:25 | tainted | polynomial-redos.js:67:18:67:24 | tainted | -| polynomial-redos.js:67:18:67:24 | tainted | polynomial-redos.js:71:2:71:8 | tainted | -| polynomial-redos.js:67:18:67:24 | tainted | polynomial-redos.js:71:2:71:8 | tainted | -| polynomial-redos.js:71:2:71:8 | tainted | polynomial-redos.js:73:2:73:8 | tainted | -| polynomial-redos.js:71:2:71:8 | tainted | polynomial-redos.js:73:2:73:8 | tainted | -| polynomial-redos.js:73:2:73:8 | tainted | polynomial-redos.js:75:2:75:8 | tainted | -| polynomial-redos.js:73:2:73:8 | tainted | polynomial-redos.js:75:2:75:8 | tainted | -| polynomial-redos.js:75:2:75:8 | tainted | polynomial-redos.js:77:2:77:8 | tainted | -| polynomial-redos.js:75:2:75:8 | tainted | polynomial-redos.js:77:2:77:8 | tainted | -| polynomial-redos.js:77:2:77:8 | tainted | polynomial-redos.js:80:2:80:8 | tainted | -| polynomial-redos.js:77:2:77:8 | tainted | polynomial-redos.js:80:2:80:8 | tainted | -| polynomial-redos.js:80:2:80:8 | tainted | polynomial-redos.js:81:2:81:8 | tainted | -| polynomial-redos.js:80:2:80:8 | tainted | polynomial-redos.js:81:2:81:8 | tainted | -| polynomial-redos.js:81:2:81:8 | tainted | polynomial-redos.js:82:2:82:8 | tainted | -| polynomial-redos.js:82:2:82:8 | tainted | polynomial-redos.js:83:2:83:8 | tainted | -| polynomial-redos.js:83:2:83:8 | tainted | polynomial-redos.js:84:2:84:8 | tainted | -| polynomial-redos.js:84:2:84:8 | tainted | polynomial-redos.js:86:2:86:8 | tainted | -| polynomial-redos.js:84:2:84:8 | tainted | polynomial-redos.js:86:2:86:8 | tainted | -| polynomial-redos.js:86:2:86:8 | tainted | polynomial-redos.js:88:2:88:8 | tainted | -| polynomial-redos.js:86:2:86:8 | tainted | polynomial-redos.js:88:2:88:8 | tainted | -| polynomial-redos.js:88:2:88:8 | tainted | polynomial-redos.js:89:2:89:8 | tainted | -| polynomial-redos.js:88:2:88:8 | tainted | polynomial-redos.js:89:2:89:8 | tainted | -| polynomial-redos.js:89:2:89:8 | tainted | polynomial-redos.js:90:2:90:8 | tainted | -| polynomial-redos.js:89:2:89:8 | tainted | polynomial-redos.js:90:2:90:8 | tainted | -| polynomial-redos.js:90:2:90:8 | tainted | polynomial-redos.js:91:2:91:8 | tainted | -| polynomial-redos.js:91:2:91:8 | tainted | polynomial-redos.js:92:2:92:8 | tainted | -| polynomial-redos.js:92:2:92:8 | tainted | polynomial-redos.js:94:2:94:8 | tainted | -| polynomial-redos.js:92:2:92:8 | tainted | polynomial-redos.js:94:2:94:8 | tainted | -| polynomial-redos.js:94:2:94:8 | tainted | polynomial-redos.js:95:2:95:8 | tainted | -| polynomial-redos.js:94:2:94:8 | tainted | polynomial-redos.js:95:2:95:8 | tainted | -| polynomial-redos.js:95:2:95:8 | tainted | polynomial-redos.js:96:2:96:8 | tainted | -| polynomial-redos.js:95:2:95:8 | tainted | polynomial-redos.js:96:2:96:8 | tainted | -| polynomial-redos.js:96:2:96:8 | tainted | polynomial-redos.js:98:2:98:8 | tainted | -| polynomial-redos.js:96:2:96:8 | tainted | polynomial-redos.js:98:2:98:8 | tainted | -| polynomial-redos.js:98:2:98:8 | tainted | polynomial-redos.js:100:2:100:8 | tainted | -| polynomial-redos.js:98:2:98:8 | tainted | polynomial-redos.js:100:2:100:8 | tainted | -| polynomial-redos.js:100:2:100:8 | tainted | polynomial-redos.js:101:2:101:8 | tainted | -| polynomial-redos.js:100:2:100:8 | tainted | polynomial-redos.js:101:2:101:8 | tainted | -| polynomial-redos.js:101:2:101:8 | tainted | polynomial-redos.js:102:2:102:8 | tainted | -| polynomial-redos.js:101:2:101:8 | tainted | polynomial-redos.js:102:2:102:8 | tainted | -| polynomial-redos.js:102:2:102:8 | tainted | polynomial-redos.js:103:2:103:8 | tainted | -| polynomial-redos.js:102:2:102:8 | tainted | polynomial-redos.js:103:2:103:8 | tainted | -| polynomial-redos.js:103:2:103:8 | tainted | polynomial-redos.js:104:2:104:8 | tainted | -| polynomial-redos.js:103:2:103:8 | tainted | polynomial-redos.js:104:2:104:8 | tainted | -| polynomial-redos.js:104:2:104:8 | tainted | polynomial-redos.js:105:2:105:8 | tainted | -| polynomial-redos.js:105:2:105:8 | tainted | polynomial-redos.js:107:2:107:8 | tainted | -| polynomial-redos.js:105:2:105:8 | tainted | polynomial-redos.js:107:2:107:8 | tainted | -| polynomial-redos.js:107:2:107:8 | tainted | polynomial-redos.js:108:2:108:8 | tainted | -| polynomial-redos.js:107:2:107:8 | tainted | polynomial-redos.js:108:2:108:8 | tainted | -| polynomial-redos.js:108:2:108:8 | tainted | polynomial-redos.js:109:2:109:8 | tainted | -| polynomial-redos.js:108:2:108:8 | tainted | polynomial-redos.js:109:2:109:8 | tainted | -| polynomial-redos.js:109:2:109:8 | tainted | polynomial-redos.js:111:2:111:8 | tainted | -| polynomial-redos.js:109:2:109:8 | tainted | polynomial-redos.js:111:2:111:8 | tainted | -| polynomial-redos.js:111:2:111:8 | tainted | polynomial-redos.js:112:2:112:8 | tainted | -| polynomial-redos.js:111:2:111:8 | tainted | polynomial-redos.js:112:2:112:8 | tainted | -| polynomial-redos.js:112:2:112:8 | tainted | polynomial-redos.js:114:2:114:8 | tainted | -| polynomial-redos.js:112:2:112:8 | tainted | polynomial-redos.js:114:2:114:8 | tainted | -| polynomial-redos.js:114:2:114:8 | tainted | polynomial-redos.js:116:2:116:8 | tainted | -| polynomial-redos.js:114:2:114:8 | tainted | polynomial-redos.js:116:2:116:8 | tainted | -| polynomial-redos.js:116:2:116:8 | tainted | polynomial-redos.js:118:2:118:8 | tainted | -| polynomial-redos.js:116:2:116:8 | tainted | polynomial-redos.js:118:2:118:8 | tainted | -| polynomial-redos.js:118:2:118:8 | tainted | polynomial-redos.js:120:2:125:3 | (functi ... OK\\n\\t}) [tainted] | -| polynomial-redos.js:118:2:118:8 | tainted | polynomial-redos.js:121:18:121:24 | tainted | -| polynomial-redos.js:118:2:118:8 | tainted | polynomial-redos.js:127:2:127:8 | tainted | -| polynomial-redos.js:120:2:125:3 | (functi ... OK\\n\\t}) [tainted] | polynomial-redos.js:121:18:121:24 | tainted | -| polynomial-redos.js:121:7:121:55 | replaced | polynomial-redos.js:123:13:123:20 | replaced | -| polynomial-redos.js:121:18:121:24 | tainted | polynomial-redos.js:121:18:121:55 | tainted ... /g, '') | -| polynomial-redos.js:121:18:121:55 | tainted ... /g, '') | polynomial-redos.js:121:7:121:55 | replaced | -| polynomial-redos.js:123:3:123:20 | result | polynomial-redos.js:124:12:124:17 | result | -| polynomial-redos.js:123:13:123:20 | replaced | polynomial-redos.js:123:3:123:20 | result | -| polynomial-redos.js:127:2:127:8 | tainted | polynomial-redos.js:129:17:129:23 | tainted | -| polynomial-redos.js:129:6:129:42 | modified | polynomial-redos.js:130:2:130:9 | modified | -| polynomial-redos.js:129:17:129:23 | tainted | polynomial-redos.js:129:17:129:42 | tainted ... g, "b") | -| polynomial-redos.js:129:17:129:23 | tainted | polynomial-redos.js:132:18:132:24 | tainted | -| polynomial-redos.js:129:17:129:42 | tainted ... g, "b") | polynomial-redos.js:129:6:129:42 | modified | -| polynomial-redos.js:132:6:132:50 | modified2 | polynomial-redos.js:133:2:133:10 | modified2 | -| polynomial-redos.js:132:18:132:24 | tainted | polynomial-redos.js:132:18:132:50 | tainted ... g, "e") | -| polynomial-redos.js:132:18:132:24 | tainted | polynomial-redos.js:135:21:135:27 | tainted | -| polynomial-redos.js:132:18:132:50 | tainted ... g, "e") | polynomial-redos.js:132:6:132:50 | modified2 | -| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:136:5:136:13 | modified3 | -| polynomial-redos.js:135:21:135:27 | tainted | polynomial-redos.js:135:21:135:47 | tainted ... /g, "") | -| polynomial-redos.js:135:21:135:27 | tainted | polynomial-redos.js:138:5:138:11 | tainted | -| polynomial-redos.js:135:21:135:47 | tainted ... /g, "") | polynomial-redos.js:135:9:135:47 | modified3 | +| lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x | provenance | | +| lib/indirect.js:1:32:1:32 | x | lib/indirect.js:2:16:2:16 | x | provenance | | +| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name | provenance | | +| lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name | provenance | | +| lib/lib.js:32:32:32:40 | arguments | lib/lib.js:35:1:37:1 | 'arguments' object of function usedWithArguments | provenance | | +| lib/lib.js:35:1:37:1 | 'arguments' object of function usedWithArguments | lib/lib.js:35:28:35:31 | name | provenance | | +| lib/lib.js:35:28:35:31 | name | lib/lib.js:36:13:36:16 | name | provenance | | +| lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | provenance | | +| lib/lib.js:41:32:41:35 | name | lib/lib.js:44:12:44:15 | name | provenance | | +| lib/lib.js:44:5:44:25 | name | lib/lib.js:45:17:45:20 | name | provenance | | +| lib/lib.js:44:12:44:15 | name | lib/lib.js:44:12:44:25 | name.substr(1) | provenance | | +| lib/lib.js:44:12:44:25 | name.substr(1) | lib/lib.js:44:5:44:25 | name | provenance | | +| lib/lib.js:52:22:52:25 | name | lib/lib.js:53:16:53:19 | name | provenance | | +| lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | provenance | | +| lib/otherLib/js/src/index.js:1:28:1:31 | name | lib/otherLib/js/src/index.js:2:13:2:16 | name | provenance | | +| lib/snapdragon.js:3:34:3:38 | input | lib/snapdragon.js:9:12:9:16 | input | provenance | | +| lib/snapdragon.js:9:12:9:16 | input | lib/snapdragon.js:7:15:7:18 | this | provenance | | +| lib/snapdragon.js:12:34:12:38 | input | lib/snapdragon.js:17:20:17:24 | input | provenance | | +| lib/snapdragon.js:17:20:17:24 | input | lib/snapdragon.js:15:13:15:16 | this | provenance | | +| lib/snapdragon.js:20:34:20:38 | input | lib/snapdragon.js:25:22:25:26 | input | provenance | | +| lib/snapdragon.js:22:44:22:47 | node | lib/snapdragon.js:23:5:23:8 | node | provenance | | +| lib/snapdragon.js:23:5:23:8 | node | lib/snapdragon.js:23:5:23:12 | node.val | provenance | | +| lib/snapdragon.js:25:22:25:26 | input | lib/snapdragon.js:22:44:22:47 | node | provenance | | +| lib/subLib4/factory.js:7:27:7:30 | name | lib/subLib4/factory.js:8:13:8:16 | name | provenance | | +| lib/subLib5/feature.js:1:28:1:31 | name | lib/subLib5/feature.js:2:13:2:16 | name | provenance | | +| lib/subLib5/main.js:1:28:1:31 | name | lib/subLib5/main.js:2:13:2:16 | name | provenance | | +| lib/subLib5/subclass.js:4:10:4:13 | name | lib/subLib5/subclass.js:5:16:5:19 | name | provenance | | +| lib/subLib6/index.js:1:32:1:35 | name | lib/subLib6/index.js:2:14:2:17 | name | provenance | | +| lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:7:2:7:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:7:2:7:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:8:2:8:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:8:2:8:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:9:2:9:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:9:2:9:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:10:2:10:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:11:2:11:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:11:2:11:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:12:2:12:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:12:2:12:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:13:2:13:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:14:2:14:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:15:2:15:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:15:2:15:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:16:2:16:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:16:2:16:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:17:23:17:29 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:17:23:17:29 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:18:2:18:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:18:2:18:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:19:2:19:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:19:2:19:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:20:2:20:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:20:2:20:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:21:6:21:12 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:25:2:25:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:25:2:25:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:26:2:26:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:27:77:27:83 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:28:76:28:82 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:30:2:30:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:30:2:30:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:31:2:31:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:32:2:32:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:33:2:33:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:33:2:33:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:34:2:34:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:36:2:36:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:36:2:36:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:37:2:37:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:37:2:37:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:38:2:38:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:38:2:38:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:40:2:40:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:40:2:40:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:41:2:41:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:43:2:43:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:43:2:43:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:44:2:44:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:46:2:46:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:47:2:47:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:48:2:48:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:48:2:48:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:50:14:50:20 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:50:14:50:20 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:51:26:51:32 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:51:26:51:32 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:52:22:52:28 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:52:22:52:28 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:53:21:53:27 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:53:21:53:27 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:54:22:54:28 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:54:22:54:28 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:55:23:55:29 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:55:23:55:29 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:56:22:56:28 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:56:22:56:28 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:57:25:57:31 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:57:25:57:31 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:58:21:58:27 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:58:21:58:27 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:59:23:59:29 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:59:23:59:29 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:60:17:60:23 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:61:18:61:24 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:62:17:62:23 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:62:17:62:23 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:63:21:63:27 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:63:21:63:27 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:64:24:64:30 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:64:24:64:30 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:65:24:65:30 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:65:24:65:30 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:66:19:66:25 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:66:19:66:25 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:67:18:67:24 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:67:18:67:24 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:71:2:71:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:71:2:71:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:73:2:73:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:73:2:73:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:75:2:75:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:75:2:75:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:77:2:77:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:77:2:77:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:80:2:80:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:80:2:80:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:81:2:81:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:81:2:81:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:82:2:82:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:83:2:83:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:84:2:84:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:86:2:86:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:86:2:86:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:88:2:88:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:88:2:88:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:89:2:89:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:89:2:89:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:90:2:90:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:90:2:90:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:91:2:91:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:92:2:92:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:94:2:94:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:94:2:94:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:95:2:95:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:95:2:95:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:96:2:96:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:96:2:96:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:98:2:98:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:98:2:98:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:100:2:100:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:100:2:100:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:101:2:101:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:101:2:101:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:102:2:102:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:102:2:102:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:103:2:103:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:103:2:103:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:104:2:104:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:104:2:104:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:105:2:105:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:107:2:107:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:107:2:107:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:108:2:108:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:108:2:108:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:109:2:109:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:109:2:109:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:111:2:111:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:111:2:111:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:112:2:112:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:112:2:112:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:114:2:114:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:114:2:114:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:116:2:116:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:116:2:116:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:118:2:118:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:118:2:118:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:127:2:127:8 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:129:17:129:23 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:132:18:132:24 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:135:21:135:27 | tainted | provenance | | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:138:5:138:11 | tainted | provenance | | +| polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:5:6:5:32 | tainted | provenance | | +| polynomial-redos.js:7:2:7:8 | tainted | polynomial-redos.js:8:2:8:8 | tainted | provenance | | +| polynomial-redos.js:7:2:7:8 | tainted | polynomial-redos.js:8:2:8:8 | tainted | provenance | | +| polynomial-redos.js:8:2:8:8 | tainted | polynomial-redos.js:9:2:9:8 | tainted | provenance | | +| polynomial-redos.js:8:2:8:8 | tainted | polynomial-redos.js:9:2:9:8 | tainted | provenance | | +| polynomial-redos.js:9:2:9:8 | tainted | polynomial-redos.js:10:2:10:8 | tainted | provenance | | +| polynomial-redos.js:10:2:10:8 | tainted | polynomial-redos.js:11:2:11:8 | tainted | provenance | | +| polynomial-redos.js:10:2:10:8 | tainted | polynomial-redos.js:11:2:11:8 | tainted | provenance | | +| polynomial-redos.js:11:2:11:8 | tainted | polynomial-redos.js:12:2:12:8 | tainted | provenance | | +| polynomial-redos.js:11:2:11:8 | tainted | polynomial-redos.js:12:2:12:8 | tainted | provenance | | +| polynomial-redos.js:12:2:12:8 | tainted | polynomial-redos.js:13:2:13:8 | tainted | provenance | | +| polynomial-redos.js:13:2:13:8 | tainted | polynomial-redos.js:14:2:14:8 | tainted | provenance | | +| polynomial-redos.js:14:2:14:8 | tainted | polynomial-redos.js:15:2:15:8 | tainted | provenance | | +| polynomial-redos.js:14:2:14:8 | tainted | polynomial-redos.js:15:2:15:8 | tainted | provenance | | +| polynomial-redos.js:15:2:15:8 | tainted | polynomial-redos.js:16:2:16:8 | tainted | provenance | | +| polynomial-redos.js:15:2:15:8 | tainted | polynomial-redos.js:16:2:16:8 | tainted | provenance | | +| polynomial-redos.js:16:2:16:8 | tainted | polynomial-redos.js:17:23:17:29 | tainted | provenance | | +| polynomial-redos.js:16:2:16:8 | tainted | polynomial-redos.js:17:23:17:29 | tainted | provenance | | +| polynomial-redos.js:17:23:17:29 | tainted | polynomial-redos.js:18:2:18:8 | tainted | provenance | | +| polynomial-redos.js:17:23:17:29 | tainted | polynomial-redos.js:18:2:18:8 | tainted | provenance | | +| polynomial-redos.js:18:2:18:8 | tainted | polynomial-redos.js:19:2:19:8 | tainted | provenance | | +| polynomial-redos.js:18:2:18:8 | tainted | polynomial-redos.js:19:2:19:8 | tainted | provenance | | +| polynomial-redos.js:19:2:19:8 | tainted | polynomial-redos.js:20:2:20:8 | tainted | provenance | | +| polynomial-redos.js:19:2:19:8 | tainted | polynomial-redos.js:20:2:20:8 | tainted | provenance | | +| polynomial-redos.js:20:2:20:8 | tainted | polynomial-redos.js:21:6:21:12 | tainted | provenance | | +| polynomial-redos.js:21:6:21:12 | tainted | polynomial-redos.js:25:2:25:8 | tainted | provenance | | +| polynomial-redos.js:21:6:21:12 | tainted | polynomial-redos.js:25:2:25:8 | tainted | provenance | | +| polynomial-redos.js:25:2:25:8 | tainted | polynomial-redos.js:26:2:26:8 | tainted | provenance | | +| polynomial-redos.js:26:2:26:8 | tainted | polynomial-redos.js:27:77:27:83 | tainted | provenance | | +| polynomial-redos.js:27:77:27:83 | tainted | polynomial-redos.js:28:76:28:82 | tainted | provenance | | +| polynomial-redos.js:28:76:28:82 | tainted | polynomial-redos.js:30:2:30:8 | tainted | provenance | | +| polynomial-redos.js:28:76:28:82 | tainted | polynomial-redos.js:30:2:30:8 | tainted | provenance | | +| polynomial-redos.js:30:2:30:8 | tainted | polynomial-redos.js:31:2:31:8 | tainted | provenance | | +| polynomial-redos.js:31:2:31:8 | tainted | polynomial-redos.js:32:2:32:8 | tainted | provenance | | +| polynomial-redos.js:32:2:32:8 | tainted | polynomial-redos.js:33:2:33:8 | tainted | provenance | | +| polynomial-redos.js:32:2:32:8 | tainted | polynomial-redos.js:33:2:33:8 | tainted | provenance | | +| polynomial-redos.js:33:2:33:8 | tainted | polynomial-redos.js:34:2:34:8 | tainted | provenance | | +| polynomial-redos.js:34:2:34:8 | tainted | polynomial-redos.js:36:2:36:8 | tainted | provenance | | +| polynomial-redos.js:34:2:34:8 | tainted | polynomial-redos.js:36:2:36:8 | tainted | provenance | | +| polynomial-redos.js:36:2:36:8 | tainted | polynomial-redos.js:37:2:37:8 | tainted | provenance | | +| polynomial-redos.js:36:2:36:8 | tainted | polynomial-redos.js:37:2:37:8 | tainted | provenance | | +| polynomial-redos.js:37:2:37:8 | tainted | polynomial-redos.js:38:2:38:8 | tainted | provenance | | +| polynomial-redos.js:37:2:37:8 | tainted | polynomial-redos.js:38:2:38:8 | tainted | provenance | | +| polynomial-redos.js:38:2:38:8 | tainted | polynomial-redos.js:40:2:40:8 | tainted | provenance | | +| polynomial-redos.js:38:2:38:8 | tainted | polynomial-redos.js:40:2:40:8 | tainted | provenance | | +| polynomial-redos.js:40:2:40:8 | tainted | polynomial-redos.js:41:2:41:8 | tainted | provenance | | +| polynomial-redos.js:41:2:41:8 | tainted | polynomial-redos.js:43:2:43:8 | tainted | provenance | | +| polynomial-redos.js:41:2:41:8 | tainted | polynomial-redos.js:43:2:43:8 | tainted | provenance | | +| polynomial-redos.js:43:2:43:8 | tainted | polynomial-redos.js:44:2:44:8 | tainted | provenance | | +| polynomial-redos.js:44:2:44:8 | tainted | polynomial-redos.js:46:2:46:8 | tainted | provenance | | +| polynomial-redos.js:46:2:46:8 | tainted | polynomial-redos.js:47:2:47:8 | tainted | provenance | | +| polynomial-redos.js:47:2:47:8 | tainted | polynomial-redos.js:48:2:48:8 | tainted | provenance | | +| polynomial-redos.js:47:2:47:8 | tainted | polynomial-redos.js:48:2:48:8 | tainted | provenance | | +| polynomial-redos.js:48:2:48:8 | tainted | polynomial-redos.js:50:14:50:20 | tainted | provenance | | +| polynomial-redos.js:48:2:48:8 | tainted | polynomial-redos.js:50:14:50:20 | tainted | provenance | | +| polynomial-redos.js:50:14:50:20 | tainted | polynomial-redos.js:51:26:51:32 | tainted | provenance | | +| polynomial-redos.js:50:14:50:20 | tainted | polynomial-redos.js:51:26:51:32 | tainted | provenance | | +| polynomial-redos.js:51:26:51:32 | tainted | polynomial-redos.js:52:22:52:28 | tainted | provenance | | +| polynomial-redos.js:51:26:51:32 | tainted | polynomial-redos.js:52:22:52:28 | tainted | provenance | | +| polynomial-redos.js:52:22:52:28 | tainted | polynomial-redos.js:53:21:53:27 | tainted | provenance | | +| polynomial-redos.js:52:22:52:28 | tainted | polynomial-redos.js:53:21:53:27 | tainted | provenance | | +| polynomial-redos.js:53:21:53:27 | tainted | polynomial-redos.js:54:22:54:28 | tainted | provenance | | +| polynomial-redos.js:53:21:53:27 | tainted | polynomial-redos.js:54:22:54:28 | tainted | provenance | | +| polynomial-redos.js:54:22:54:28 | tainted | polynomial-redos.js:55:23:55:29 | tainted | provenance | | +| polynomial-redos.js:54:22:54:28 | tainted | polynomial-redos.js:55:23:55:29 | tainted | provenance | | +| polynomial-redos.js:55:23:55:29 | tainted | polynomial-redos.js:56:22:56:28 | tainted | provenance | | +| polynomial-redos.js:55:23:55:29 | tainted | polynomial-redos.js:56:22:56:28 | tainted | provenance | | +| polynomial-redos.js:56:22:56:28 | tainted | polynomial-redos.js:57:25:57:31 | tainted | provenance | | +| polynomial-redos.js:56:22:56:28 | tainted | polynomial-redos.js:57:25:57:31 | tainted | provenance | | +| polynomial-redos.js:57:25:57:31 | tainted | polynomial-redos.js:58:21:58:27 | tainted | provenance | | +| polynomial-redos.js:57:25:57:31 | tainted | polynomial-redos.js:58:21:58:27 | tainted | provenance | | +| polynomial-redos.js:58:21:58:27 | tainted | polynomial-redos.js:59:23:59:29 | tainted | provenance | | +| polynomial-redos.js:58:21:58:27 | tainted | polynomial-redos.js:59:23:59:29 | tainted | provenance | | +| polynomial-redos.js:59:23:59:29 | tainted | polynomial-redos.js:60:17:60:23 | tainted | provenance | | +| polynomial-redos.js:60:17:60:23 | tainted | polynomial-redos.js:61:18:61:24 | tainted | provenance | | +| polynomial-redos.js:61:18:61:24 | tainted | polynomial-redos.js:62:17:62:23 | tainted | provenance | | +| polynomial-redos.js:61:18:61:24 | tainted | polynomial-redos.js:62:17:62:23 | tainted | provenance | | +| polynomial-redos.js:62:17:62:23 | tainted | polynomial-redos.js:63:21:63:27 | tainted | provenance | | +| polynomial-redos.js:62:17:62:23 | tainted | polynomial-redos.js:63:21:63:27 | tainted | provenance | | +| polynomial-redos.js:63:21:63:27 | tainted | polynomial-redos.js:64:24:64:30 | tainted | provenance | | +| polynomial-redos.js:63:21:63:27 | tainted | polynomial-redos.js:64:24:64:30 | tainted | provenance | | +| polynomial-redos.js:64:24:64:30 | tainted | polynomial-redos.js:65:24:65:30 | tainted | provenance | | +| polynomial-redos.js:64:24:64:30 | tainted | polynomial-redos.js:65:24:65:30 | tainted | provenance | | +| polynomial-redos.js:65:24:65:30 | tainted | polynomial-redos.js:66:19:66:25 | tainted | provenance | | +| polynomial-redos.js:65:24:65:30 | tainted | polynomial-redos.js:66:19:66:25 | tainted | provenance | | +| polynomial-redos.js:66:19:66:25 | tainted | polynomial-redos.js:67:18:67:24 | tainted | provenance | | +| polynomial-redos.js:66:19:66:25 | tainted | polynomial-redos.js:67:18:67:24 | tainted | provenance | | +| polynomial-redos.js:67:18:67:24 | tainted | polynomial-redos.js:71:2:71:8 | tainted | provenance | | +| polynomial-redos.js:67:18:67:24 | tainted | polynomial-redos.js:71:2:71:8 | tainted | provenance | | +| polynomial-redos.js:71:2:71:8 | tainted | polynomial-redos.js:73:2:73:8 | tainted | provenance | | +| polynomial-redos.js:71:2:71:8 | tainted | polynomial-redos.js:73:2:73:8 | tainted | provenance | | +| polynomial-redos.js:73:2:73:8 | tainted | polynomial-redos.js:75:2:75:8 | tainted | provenance | | +| polynomial-redos.js:73:2:73:8 | tainted | polynomial-redos.js:75:2:75:8 | tainted | provenance | | +| polynomial-redos.js:75:2:75:8 | tainted | polynomial-redos.js:77:2:77:8 | tainted | provenance | | +| polynomial-redos.js:75:2:75:8 | tainted | polynomial-redos.js:77:2:77:8 | tainted | provenance | | +| polynomial-redos.js:77:2:77:8 | tainted | polynomial-redos.js:80:2:80:8 | tainted | provenance | | +| polynomial-redos.js:77:2:77:8 | tainted | polynomial-redos.js:80:2:80:8 | tainted | provenance | | +| polynomial-redos.js:80:2:80:8 | tainted | polynomial-redos.js:81:2:81:8 | tainted | provenance | | +| polynomial-redos.js:80:2:80:8 | tainted | polynomial-redos.js:81:2:81:8 | tainted | provenance | | +| polynomial-redos.js:81:2:81:8 | tainted | polynomial-redos.js:82:2:82:8 | tainted | provenance | | +| polynomial-redos.js:82:2:82:8 | tainted | polynomial-redos.js:83:2:83:8 | tainted | provenance | | +| polynomial-redos.js:83:2:83:8 | tainted | polynomial-redos.js:84:2:84:8 | tainted | provenance | | +| polynomial-redos.js:84:2:84:8 | tainted | polynomial-redos.js:86:2:86:8 | tainted | provenance | | +| polynomial-redos.js:84:2:84:8 | tainted | polynomial-redos.js:86:2:86:8 | tainted | provenance | | +| polynomial-redos.js:86:2:86:8 | tainted | polynomial-redos.js:88:2:88:8 | tainted | provenance | | +| polynomial-redos.js:86:2:86:8 | tainted | polynomial-redos.js:88:2:88:8 | tainted | provenance | | +| polynomial-redos.js:88:2:88:8 | tainted | polynomial-redos.js:89:2:89:8 | tainted | provenance | | +| polynomial-redos.js:88:2:88:8 | tainted | polynomial-redos.js:89:2:89:8 | tainted | provenance | | +| polynomial-redos.js:89:2:89:8 | tainted | polynomial-redos.js:90:2:90:8 | tainted | provenance | | +| polynomial-redos.js:89:2:89:8 | tainted | polynomial-redos.js:90:2:90:8 | tainted | provenance | | +| polynomial-redos.js:90:2:90:8 | tainted | polynomial-redos.js:91:2:91:8 | tainted | provenance | | +| polynomial-redos.js:91:2:91:8 | tainted | polynomial-redos.js:92:2:92:8 | tainted | provenance | | +| polynomial-redos.js:92:2:92:8 | tainted | polynomial-redos.js:94:2:94:8 | tainted | provenance | | +| polynomial-redos.js:92:2:92:8 | tainted | polynomial-redos.js:94:2:94:8 | tainted | provenance | | +| polynomial-redos.js:94:2:94:8 | tainted | polynomial-redos.js:95:2:95:8 | tainted | provenance | | +| polynomial-redos.js:94:2:94:8 | tainted | polynomial-redos.js:95:2:95:8 | tainted | provenance | | +| polynomial-redos.js:95:2:95:8 | tainted | polynomial-redos.js:96:2:96:8 | tainted | provenance | | +| polynomial-redos.js:95:2:95:8 | tainted | polynomial-redos.js:96:2:96:8 | tainted | provenance | | +| polynomial-redos.js:96:2:96:8 | tainted | polynomial-redos.js:98:2:98:8 | tainted | provenance | | +| polynomial-redos.js:96:2:96:8 | tainted | polynomial-redos.js:98:2:98:8 | tainted | provenance | | +| polynomial-redos.js:98:2:98:8 | tainted | polynomial-redos.js:100:2:100:8 | tainted | provenance | | +| polynomial-redos.js:98:2:98:8 | tainted | polynomial-redos.js:100:2:100:8 | tainted | provenance | | +| polynomial-redos.js:100:2:100:8 | tainted | polynomial-redos.js:101:2:101:8 | tainted | provenance | | +| polynomial-redos.js:100:2:100:8 | tainted | polynomial-redos.js:101:2:101:8 | tainted | provenance | | +| polynomial-redos.js:101:2:101:8 | tainted | polynomial-redos.js:102:2:102:8 | tainted | provenance | | +| polynomial-redos.js:101:2:101:8 | tainted | polynomial-redos.js:102:2:102:8 | tainted | provenance | | +| polynomial-redos.js:102:2:102:8 | tainted | polynomial-redos.js:103:2:103:8 | tainted | provenance | | +| polynomial-redos.js:102:2:102:8 | tainted | polynomial-redos.js:103:2:103:8 | tainted | provenance | | +| polynomial-redos.js:103:2:103:8 | tainted | polynomial-redos.js:104:2:104:8 | tainted | provenance | | +| polynomial-redos.js:103:2:103:8 | tainted | polynomial-redos.js:104:2:104:8 | tainted | provenance | | +| polynomial-redos.js:104:2:104:8 | tainted | polynomial-redos.js:105:2:105:8 | tainted | provenance | | +| polynomial-redos.js:105:2:105:8 | tainted | polynomial-redos.js:107:2:107:8 | tainted | provenance | | +| polynomial-redos.js:105:2:105:8 | tainted | polynomial-redos.js:107:2:107:8 | tainted | provenance | | +| polynomial-redos.js:107:2:107:8 | tainted | polynomial-redos.js:108:2:108:8 | tainted | provenance | | +| polynomial-redos.js:107:2:107:8 | tainted | polynomial-redos.js:108:2:108:8 | tainted | provenance | | +| polynomial-redos.js:108:2:108:8 | tainted | polynomial-redos.js:109:2:109:8 | tainted | provenance | | +| polynomial-redos.js:108:2:108:8 | tainted | polynomial-redos.js:109:2:109:8 | tainted | provenance | | +| polynomial-redos.js:109:2:109:8 | tainted | polynomial-redos.js:111:2:111:8 | tainted | provenance | | +| polynomial-redos.js:109:2:109:8 | tainted | polynomial-redos.js:111:2:111:8 | tainted | provenance | | +| polynomial-redos.js:111:2:111:8 | tainted | polynomial-redos.js:112:2:112:8 | tainted | provenance | | +| polynomial-redos.js:111:2:111:8 | tainted | polynomial-redos.js:112:2:112:8 | tainted | provenance | | +| polynomial-redos.js:112:2:112:8 | tainted | polynomial-redos.js:114:2:114:8 | tainted | provenance | | +| polynomial-redos.js:112:2:112:8 | tainted | polynomial-redos.js:114:2:114:8 | tainted | provenance | | +| polynomial-redos.js:114:2:114:8 | tainted | polynomial-redos.js:116:2:116:8 | tainted | provenance | | +| polynomial-redos.js:114:2:114:8 | tainted | polynomial-redos.js:116:2:116:8 | tainted | provenance | | +| polynomial-redos.js:116:2:116:8 | tainted | polynomial-redos.js:118:2:118:8 | tainted | provenance | | +| polynomial-redos.js:116:2:116:8 | tainted | polynomial-redos.js:118:2:118:8 | tainted | provenance | | +| polynomial-redos.js:118:2:118:8 | tainted | polynomial-redos.js:120:2:125:3 | (functi ... OK\\n\\t}) [tainted] | provenance | | +| polynomial-redos.js:118:2:118:8 | tainted | polynomial-redos.js:121:18:121:24 | tainted | provenance | | +| polynomial-redos.js:118:2:118:8 | tainted | polynomial-redos.js:127:2:127:8 | tainted | provenance | | +| polynomial-redos.js:120:2:125:3 | (functi ... OK\\n\\t}) [tainted] | polynomial-redos.js:121:18:121:24 | tainted | provenance | | +| polynomial-redos.js:121:7:121:55 | replaced | polynomial-redos.js:123:13:123:20 | replaced | provenance | | +| polynomial-redos.js:121:18:121:24 | tainted | polynomial-redos.js:121:18:121:55 | tainted ... /g, '') | provenance | | +| polynomial-redos.js:121:18:121:55 | tainted ... /g, '') | polynomial-redos.js:121:7:121:55 | replaced | provenance | | +| polynomial-redos.js:123:3:123:20 | result | polynomial-redos.js:124:12:124:17 | result | provenance | | +| polynomial-redos.js:123:13:123:20 | replaced | polynomial-redos.js:123:3:123:20 | result | provenance | | +| polynomial-redos.js:127:2:127:8 | tainted | polynomial-redos.js:129:17:129:23 | tainted | provenance | | +| polynomial-redos.js:129:6:129:42 | modified | polynomial-redos.js:130:2:130:9 | modified | provenance | | +| polynomial-redos.js:129:17:129:23 | tainted | polynomial-redos.js:129:17:129:42 | tainted ... g, "b") | provenance | | +| polynomial-redos.js:129:17:129:23 | tainted | polynomial-redos.js:132:18:132:24 | tainted | provenance | | +| polynomial-redos.js:129:17:129:42 | tainted ... g, "b") | polynomial-redos.js:129:6:129:42 | modified | provenance | | +| polynomial-redos.js:132:6:132:50 | modified2 | polynomial-redos.js:133:2:133:10 | modified2 | provenance | | +| polynomial-redos.js:132:18:132:24 | tainted | polynomial-redos.js:132:18:132:50 | tainted ... g, "e") | provenance | | +| polynomial-redos.js:132:18:132:24 | tainted | polynomial-redos.js:135:21:135:27 | tainted | provenance | | +| polynomial-redos.js:132:18:132:50 | tainted ... g, "e") | polynomial-redos.js:132:6:132:50 | modified2 | provenance | | +| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:136:5:136:13 | modified3 | provenance | | +| polynomial-redos.js:135:21:135:27 | tainted | polynomial-redos.js:135:21:135:47 | tainted ... /g, "") | provenance | | +| polynomial-redos.js:135:21:135:27 | tainted | polynomial-redos.js:138:5:138:11 | tainted | provenance | | +| polynomial-redos.js:135:21:135:47 | tainted ... /g, "") | polynomial-redos.js:135:9:135:47 | modified3 | provenance | | nodes | lib/closure.js:3:21:3:21 | x | semmle.label | x | | lib/closure.js:4:16:4:16 | x | semmle.label | x | diff --git a/javascript/ql/test/query-tests/Security/CWE-400/RemovePropertyInjection/RemotePropertyInjection.expected b/javascript/ql/test/query-tests/Security/CWE-400/RemovePropertyInjection/RemotePropertyInjection.expected index d6d347c996d..2f21ec2ca3d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/RemovePropertyInjection/RemotePropertyInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/RemovePropertyInjection/RemotePropertyInjection.expected @@ -1,17 +1,17 @@ edges -| tst.js:8:6:8:52 | prop | tst.js:9:8:9:11 | prop | -| tst.js:8:6:8:52 | prop | tst.js:13:15:13:18 | prop | -| tst.js:8:6:8:52 | prop | tst.js:14:31:14:34 | prop | -| tst.js:8:6:8:52 | prop | tst.js:16:10:16:13 | prop | -| tst.js:8:13:8:52 | myCoolL ... rolled) | tst.js:8:6:8:52 | prop | -| tst.js:8:28:8:51 | req.que ... trolled | tst.js:8:13:8:52 | myCoolL ... rolled) | -| tst.js:8:28:8:51 | req.que ... trolled | tst.js:21:25:21:25 | x | -| tst.js:21:25:21:25 | x | tst.js:22:15:22:15 | x | -| tst.js:22:6:22:15 | result | tst.js:23:9:23:14 | result | -| tst.js:22:15:22:15 | x | tst.js:22:6:22:15 | result | -| tst.js:23:9:23:14 | result | tst.js:23:9:23:42 | result. ... length) | -| tstNonExpr.js:5:7:5:23 | userVal | tstNonExpr.js:8:17:8:23 | userVal | -| tstNonExpr.js:5:17:5:23 | req.url | tstNonExpr.js:5:7:5:23 | userVal | +| tst.js:8:6:8:52 | prop | tst.js:9:8:9:11 | prop | provenance | | +| tst.js:8:6:8:52 | prop | tst.js:13:15:13:18 | prop | provenance | | +| tst.js:8:6:8:52 | prop | tst.js:14:31:14:34 | prop | provenance | | +| tst.js:8:6:8:52 | prop | tst.js:16:10:16:13 | prop | provenance | | +| tst.js:8:13:8:52 | myCoolL ... rolled) | tst.js:8:6:8:52 | prop | provenance | | +| tst.js:8:28:8:51 | req.que ... trolled | tst.js:8:13:8:52 | myCoolL ... rolled) | provenance | | +| tst.js:8:28:8:51 | req.que ... trolled | tst.js:21:25:21:25 | x | provenance | | +| tst.js:21:25:21:25 | x | tst.js:22:15:22:15 | x | provenance | | +| tst.js:22:6:22:15 | result | tst.js:23:9:23:14 | result | provenance | | +| tst.js:22:15:22:15 | x | tst.js:22:6:22:15 | result | provenance | | +| tst.js:23:9:23:14 | result | tst.js:23:9:23:42 | result. ... length) | provenance | | +| tstNonExpr.js:5:7:5:23 | userVal | tstNonExpr.js:8:17:8:23 | userVal | provenance | | +| tstNonExpr.js:5:17:5:23 | req.url | tstNonExpr.js:5:7:5:23 | userVal | provenance | | nodes | tst.js:8:6:8:52 | prop | semmle.label | prop | | tst.js:8:13:8:52 | myCoolL ... rolled) | semmle.label | myCoolL ... rolled) | diff --git a/javascript/ql/test/query-tests/Security/CWE-506/HardcodedDataInterpretedAsCode.expected b/javascript/ql/test/query-tests/Security/CWE-506/HardcodedDataInterpretedAsCode.expected index 50fb024e033..bf0f97e28da 100644 --- a/javascript/ql/test/query-tests/Security/CWE-506/HardcodedDataInterpretedAsCode.expected +++ b/javascript/ql/test/query-tests/Security/CWE-506/HardcodedDataInterpretedAsCode.expected @@ -21,23 +21,23 @@ nodes | tst.js:7:8:7:11 | test | semmle.label | test | | tst.js:7:8:7:15 | test+"n" | semmle.label | test+"n" | edges -| event-stream-orig.js:93:16:93:16 | r | event-stream-orig.js:94:26:94:26 | r | -| event-stream-orig.js:94:14:94:34 | Buffer. ... "hex") | event-stream-orig.js:94:14:94:45 | Buffer. ... tring() | -| event-stream-orig.js:94:26:94:26 | r | event-stream-orig.js:94:14:94:34 | Buffer. ... "hex") | -| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:93:16:93:16 | r | -| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | -| event-stream.js:5:12:5:12 | r | event-stream.js:6:22:6:22 | r | -| event-stream.js:6:10:6:30 | Buffer. ... "hex") | event-stream.js:6:10:6:41 | Buffer. ... tring() | -| event-stream.js:6:22:6:22 | r | event-stream.js:6:10:6:30 | Buffer. ... "hex") | -| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:5:12:5:12 | r | -| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | -| tst.js:1:5:1:88 | totallyHarmlessString | tst.js:2:18:2:38 | totally ... sString | -| tst.js:1:29:1:88 | '636f6e ... 6e2729' | tst.js:1:5:1:88 | totallyHarmlessString | -| tst.js:2:6:2:46 | Buffer. ... 'hex') | tst.js:2:6:2:57 | Buffer. ... tring() | -| tst.js:2:18:2:38 | totally ... sString | tst.js:2:6:2:46 | Buffer. ... 'hex') | -| tst.js:5:5:5:23 | test | tst.js:7:8:7:11 | test | -| tst.js:5:12:5:23 | "0123456789" | tst.js:5:5:5:23 | test | -| tst.js:7:8:7:11 | test | tst.js:7:8:7:15 | test+"n" | +| event-stream-orig.js:93:16:93:16 | r | event-stream-orig.js:94:26:94:26 | r | provenance | | +| event-stream-orig.js:94:14:94:34 | Buffer. ... "hex") | event-stream-orig.js:94:14:94:45 | Buffer. ... tring() | provenance | Config | +| event-stream-orig.js:94:26:94:26 | r | event-stream-orig.js:94:14:94:34 | Buffer. ... "hex") | provenance | Config | +| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:93:16:93:16 | r | provenance | | +| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | provenance | Config | +| event-stream.js:5:12:5:12 | r | event-stream.js:6:22:6:22 | r | provenance | | +| event-stream.js:6:10:6:30 | Buffer. ... "hex") | event-stream.js:6:10:6:41 | Buffer. ... tring() | provenance | Config | +| event-stream.js:6:22:6:22 | r | event-stream.js:6:10:6:30 | Buffer. ... "hex") | provenance | Config | +| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:5:12:5:12 | r | provenance | | +| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | provenance | Config | +| tst.js:1:5:1:88 | totallyHarmlessString | tst.js:2:18:2:38 | totally ... sString | provenance | | +| tst.js:1:29:1:88 | '636f6e ... 6e2729' | tst.js:1:5:1:88 | totallyHarmlessString | provenance | | +| tst.js:2:6:2:46 | Buffer. ... 'hex') | tst.js:2:6:2:57 | Buffer. ... tring() | provenance | Config | +| tst.js:2:18:2:38 | totally ... sString | tst.js:2:6:2:46 | Buffer. ... 'hex') | provenance | Config | +| tst.js:5:5:5:23 | test | tst.js:7:8:7:11 | test | provenance | | +| tst.js:5:12:5:23 | "0123456789" | tst.js:5:5:5:23 | test | provenance | | +| tst.js:7:8:7:11 | test | tst.js:7:8:7:15 | test+"n" | provenance | Config | subpaths | event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:93:16:93:16 | r | event-stream-orig.js:94:14:94:45 | Buffer. ... tring() | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | | event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:5:12:5:12 | r | event-stream.js:6:10:6:41 | Buffer. ... tring() | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected index fbac71a1779..c245c3e3a10 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected @@ -120,90 +120,90 @@ nodes | typed.ts:55:25:55:35 | redirectUri | semmle.label | redirectUri | | typed.ts:56:33:56:43 | redirectUri | semmle.label | redirectUri | edges -| electron.js:4:12:4:22 | window.name | electron.js:7:20:7:29 | getTaint() | -| react.js:28:43:28:64 | documen ... on.hash | react.js:28:43:28:74 | documen ... bstr(1) | -| react.js:34:43:34:64 | documen ... on.hash | react.js:34:43:34:74 | documen ... bstr(1) | -| react.js:40:19:40:40 | documen ... on.hash | react.js:40:19:40:50 | documen ... bstr(1) | -| sanitizer.js:2:9:2:25 | url | sanitizer.js:4:27:4:29 | url | -| sanitizer.js:2:9:2:25 | url | sanitizer.js:16:27:16:29 | url | -| sanitizer.js:2:9:2:25 | url | sanitizer.js:19:27:19:29 | url | -| sanitizer.js:2:9:2:25 | url | sanitizer.js:22:27:22:29 | url | -| sanitizer.js:2:9:2:25 | url | sanitizer.js:25:27:25:29 | url | -| sanitizer.js:2:9:2:25 | url | sanitizer.js:28:27:28:29 | url | -| sanitizer.js:2:9:2:25 | url | sanitizer.js:31:27:31:29 | url | -| sanitizer.js:2:9:2:25 | url | sanitizer.js:37:27:37:29 | url | -| sanitizer.js:2:15:2:25 | window.name | sanitizer.js:2:9:2:25 | url | -| tst2.js:2:7:2:33 | href | tst2.js:4:21:4:24 | href | -| tst2.js:2:14:2:33 | window.location.href | tst2.js:2:7:2:33 | href | -| tst2.js:4:21:4:24 | href | tst2.js:4:21:4:55 | href.su ... '?')+1) | -| tst6.js:2:7:2:45 | redirect | tst6.js:4:21:4:28 | redirect | -| tst6.js:2:7:2:45 | redirect | tst6.js:6:17:6:24 | redirect | -| tst6.js:2:18:2:45 | $locati ... irect') | tst6.js:2:7:2:45 | redirect | -| tst6.js:8:21:8:48 | $locati ... irect') | tst6.js:8:21:8:56 | $locati ... + "foo" | -| tst9.js:2:21:2:42 | documen ... on.hash | tst9.js:2:21:2:55 | documen ... ring(1) | -| tst10.js:5:23:5:46 | documen ... .search | tst10.js:5:17:5:46 | '/' + d ... .search | -| tst10.js:8:24:8:47 | documen ... .search | tst10.js:8:17:8:47 | '//' + ... .search | -| tst10.js:11:27:11:50 | documen ... .search | tst10.js:11:17:11:50 | '//foo' ... .search | -| tst10.js:14:33:14:56 | documen ... .search | tst10.js:14:17:14:56 | 'https: ... .search | -| tst12.js:3:9:3:50 | urlParts | tst12.js:4:15:4:22 | urlParts | -| tst12.js:3:20:3:39 | window.location.hash | tst12.js:3:20:3:50 | window. ... it('?') | -| tst12.js:3:20:3:50 | window. ... it('?') | tst12.js:3:9:3:50 | urlParts | -| tst12.js:4:9:4:45 | loc | tst12.js:5:23:5:25 | loc | -| tst12.js:4:15:4:22 | urlParts | tst12.js:4:9:4:45 | loc | -| tst13.js:2:9:2:52 | payload | tst13.js:4:15:4:21 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:8:21:8:27 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:12:14:12:20 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:16:17:16:23 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:20:14:20:20 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:24:14:24:20 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:28:21:28:27 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:32:17:32:23 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:36:21:36:27 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:40:15:40:21 | payload | -| tst13.js:2:9:2:52 | payload | tst13.js:44:14:44:20 | payload | -| tst13.js:2:19:2:42 | documen ... .search | tst13.js:2:19:2:52 | documen ... bstr(1) | -| tst13.js:2:19:2:52 | documen ... bstr(1) | tst13.js:2:9:2:52 | payload | -| tst13.js:49:32:49:32 | e | tst13.js:50:23:50:23 | e | -| tst13.js:52:34:52:34 | e | tst13.js:53:28:53:28 | e | -| tst13.js:59:9:59:52 | payload | tst13.js:61:18:61:24 | payload | -| tst13.js:59:19:59:42 | documen ... .search | tst13.js:59:19:59:52 | documen ... bstr(1) | -| tst13.js:59:19:59:52 | documen ... bstr(1) | tst13.js:59:9:59:52 | payload | -| tst13.js:65:9:65:49 | payload | tst13.js:67:21:67:27 | payload | -| tst13.js:65:19:65:39 | history ... on.hash | tst13.js:65:19:65:49 | history ... bstr(1) | -| tst13.js:65:19:65:49 | history ... bstr(1) | tst13.js:65:9:65:49 | payload | -| tst13.js:72:9:72:49 | payload | tst13.js:74:21:74:27 | payload | -| tst13.js:72:19:72:39 | history ... on.hash | tst13.js:72:19:72:49 | history ... bstr(1) | -| tst13.js:72:19:72:49 | history ... bstr(1) | tst13.js:72:9:72:49 | payload | -| tst13.js:78:9:78:48 | url | tst13.js:80:21:80:23 | url | -| tst13.js:78:9:78:48 | url | tst13.js:81:28:81:30 | url | -| tst13.js:78:9:78:48 | url | tst13.js:82:27:82:29 | url | -| tst13.js:78:9:78:48 | url | tst13.js:83:22:83:24 | url | -| tst13.js:78:15:78:38 | documen ... .search | tst13.js:78:15:78:48 | documen ... bstr(1) | -| tst13.js:78:15:78:48 | documen ... bstr(1) | tst13.js:78:9:78:48 | url | -| tst.js:2:19:2:69 | /.*redi ... n.href) | tst.js:2:19:2:72 | /.*redi ... ref)[1] | -| tst.js:2:47:2:68 | documen ... on.href | tst.js:2:19:2:69 | /.*redi ... n.href) | -| tst.js:6:20:6:56 | indirec ... n.href) | tst.js:6:20:6:59 | indirec ... ref)[1] | -| tst.js:6:34:6:55 | documen ... on.href | tst.js:6:20:6:56 | indirec ... n.href) | -| tst.js:10:19:10:81 | new Reg ... n.href) | tst.js:10:19:10:84 | new Reg ... ref)[1] | -| tst.js:10:59:10:80 | documen ... on.href | tst.js:10:19:10:81 | new Reg ... n.href) | -| tst.js:14:20:14:56 | indirec ... n.href) | tst.js:14:20:14:59 | indirec ... ref)[1] | -| tst.js:14:34:14:55 | documen ... on.href | tst.js:14:20:14:56 | indirec ... n.href) | -| tst.js:18:19:18:81 | new Reg ... n.href) | tst.js:18:19:18:84 | new Reg ... ref)[1] | -| tst.js:18:59:18:80 | documen ... on.href | tst.js:18:19:18:81 | new Reg ... n.href) | -| tst.js:22:20:22:56 | indirec ... n.href) | tst.js:22:20:22:59 | indirec ... ref)[1] | -| tst.js:22:34:22:55 | documen ... on.href | tst.js:22:20:22:56 | indirec ... n.href) | -| tst.js:26:22:26:79 | new Reg ... n.href) | tst.js:26:22:26:82 | new Reg ... ref)[1] | -| tst.js:26:62:26:78 | win.location.href | tst.js:26:22:26:79 | new Reg ... n.href) | -| typed.ts:4:13:4:36 | params | typed.ts:5:25:5:30 | params | -| typed.ts:4:22:4:36 | location.search | typed.ts:4:13:4:36 | params | -| typed.ts:5:25:5:30 | params | typed.ts:7:24:7:34 | redirectUri | -| typed.ts:7:24:7:34 | redirectUri | typed.ts:8:33:8:43 | redirectUri | -| typed.ts:25:25:25:34 | loc.search | typed.ts:28:24:28:34 | redirectUri | -| typed.ts:28:24:28:34 | redirectUri | typed.ts:29:33:29:43 | redirectUri | -| typed.ts:47:25:47:34 | loc.search | typed.ts:51:24:51:34 | redirectUri | -| typed.ts:48:26:48:36 | loc2.search | typed.ts:55:25:55:35 | redirectUri | -| typed.ts:51:24:51:34 | redirectUri | typed.ts:52:33:52:43 | redirectUri | -| typed.ts:55:25:55:35 | redirectUri | typed.ts:56:33:56:43 | redirectUri | +| electron.js:4:12:4:22 | window.name | electron.js:7:20:7:29 | getTaint() | provenance | | +| react.js:28:43:28:64 | documen ... on.hash | react.js:28:43:28:74 | documen ... bstr(1) | provenance | | +| react.js:34:43:34:64 | documen ... on.hash | react.js:34:43:34:74 | documen ... bstr(1) | provenance | | +| react.js:40:19:40:40 | documen ... on.hash | react.js:40:19:40:50 | documen ... bstr(1) | provenance | | +| sanitizer.js:2:9:2:25 | url | sanitizer.js:4:27:4:29 | url | provenance | | +| sanitizer.js:2:9:2:25 | url | sanitizer.js:16:27:16:29 | url | provenance | | +| sanitizer.js:2:9:2:25 | url | sanitizer.js:19:27:19:29 | url | provenance | | +| sanitizer.js:2:9:2:25 | url | sanitizer.js:22:27:22:29 | url | provenance | | +| sanitizer.js:2:9:2:25 | url | sanitizer.js:25:27:25:29 | url | provenance | | +| sanitizer.js:2:9:2:25 | url | sanitizer.js:28:27:28:29 | url | provenance | | +| sanitizer.js:2:9:2:25 | url | sanitizer.js:31:27:31:29 | url | provenance | | +| sanitizer.js:2:9:2:25 | url | sanitizer.js:37:27:37:29 | url | provenance | | +| sanitizer.js:2:15:2:25 | window.name | sanitizer.js:2:9:2:25 | url | provenance | | +| tst2.js:2:7:2:33 | href | tst2.js:4:21:4:24 | href | provenance | | +| tst2.js:2:14:2:33 | window.location.href | tst2.js:2:7:2:33 | href | provenance | | +| tst2.js:4:21:4:24 | href | tst2.js:4:21:4:55 | href.su ... '?')+1) | provenance | Config | +| tst6.js:2:7:2:45 | redirect | tst6.js:4:21:4:28 | redirect | provenance | | +| tst6.js:2:7:2:45 | redirect | tst6.js:6:17:6:24 | redirect | provenance | | +| tst6.js:2:18:2:45 | $locati ... irect') | tst6.js:2:7:2:45 | redirect | provenance | | +| tst6.js:8:21:8:48 | $locati ... irect') | tst6.js:8:21:8:56 | $locati ... + "foo" | provenance | | +| tst9.js:2:21:2:42 | documen ... on.hash | tst9.js:2:21:2:55 | documen ... ring(1) | provenance | | +| tst10.js:5:23:5:46 | documen ... .search | tst10.js:5:17:5:46 | '/' + d ... .search | provenance | | +| tst10.js:8:24:8:47 | documen ... .search | tst10.js:8:17:8:47 | '//' + ... .search | provenance | | +| tst10.js:11:27:11:50 | documen ... .search | tst10.js:11:17:11:50 | '//foo' ... .search | provenance | | +| tst10.js:14:33:14:56 | documen ... .search | tst10.js:14:17:14:56 | 'https: ... .search | provenance | | +| tst12.js:3:9:3:50 | urlParts | tst12.js:4:15:4:22 | urlParts | provenance | | +| tst12.js:3:20:3:39 | window.location.hash | tst12.js:3:20:3:50 | window. ... it('?') | provenance | | +| tst12.js:3:20:3:50 | window. ... it('?') | tst12.js:3:9:3:50 | urlParts | provenance | | +| tst12.js:4:9:4:45 | loc | tst12.js:5:23:5:25 | loc | provenance | | +| tst12.js:4:15:4:22 | urlParts | tst12.js:4:9:4:45 | loc | provenance | | +| tst13.js:2:9:2:52 | payload | tst13.js:4:15:4:21 | payload | provenance | | +| tst13.js:2:9:2:52 | payload | tst13.js:8:21:8:27 | payload | provenance | | +| tst13.js:2:9:2:52 | payload | tst13.js:12:14:12:20 | payload | provenance | | +| tst13.js:2:9:2:52 | payload | tst13.js:16:17:16:23 | payload | provenance | | +| tst13.js:2:9:2:52 | payload | tst13.js:20:14:20:20 | payload | provenance | | +| tst13.js:2:9:2:52 | payload | tst13.js:24:14:24:20 | payload | provenance | | +| tst13.js:2:9:2:52 | payload | tst13.js:28:21:28:27 | payload | provenance | | +| tst13.js:2:9:2:52 | payload | tst13.js:32:17:32:23 | payload | provenance | | +| tst13.js:2:9:2:52 | payload | tst13.js:36:21:36:27 | payload | provenance | | +| tst13.js:2:9:2:52 | payload | tst13.js:40:15:40:21 | payload | provenance | | +| tst13.js:2:9:2:52 | payload | tst13.js:44:14:44:20 | payload | provenance | | +| tst13.js:2:19:2:42 | documen ... .search | tst13.js:2:19:2:52 | documen ... bstr(1) | provenance | | +| tst13.js:2:19:2:52 | documen ... bstr(1) | tst13.js:2:9:2:52 | payload | provenance | | +| tst13.js:49:32:49:32 | e | tst13.js:50:23:50:23 | e | provenance | | +| tst13.js:52:34:52:34 | e | tst13.js:53:28:53:28 | e | provenance | | +| tst13.js:59:9:59:52 | payload | tst13.js:61:18:61:24 | payload | provenance | | +| tst13.js:59:19:59:42 | documen ... .search | tst13.js:59:19:59:52 | documen ... bstr(1) | provenance | | +| tst13.js:59:19:59:52 | documen ... bstr(1) | tst13.js:59:9:59:52 | payload | provenance | | +| tst13.js:65:9:65:49 | payload | tst13.js:67:21:67:27 | payload | provenance | | +| tst13.js:65:19:65:39 | history ... on.hash | tst13.js:65:19:65:49 | history ... bstr(1) | provenance | | +| tst13.js:65:19:65:49 | history ... bstr(1) | tst13.js:65:9:65:49 | payload | provenance | | +| tst13.js:72:9:72:49 | payload | tst13.js:74:21:74:27 | payload | provenance | | +| tst13.js:72:19:72:39 | history ... on.hash | tst13.js:72:19:72:49 | history ... bstr(1) | provenance | | +| tst13.js:72:19:72:49 | history ... bstr(1) | tst13.js:72:9:72:49 | payload | provenance | | +| tst13.js:78:9:78:48 | url | tst13.js:80:21:80:23 | url | provenance | | +| tst13.js:78:9:78:48 | url | tst13.js:81:28:81:30 | url | provenance | | +| tst13.js:78:9:78:48 | url | tst13.js:82:27:82:29 | url | provenance | | +| tst13.js:78:9:78:48 | url | tst13.js:83:22:83:24 | url | provenance | | +| tst13.js:78:15:78:38 | documen ... .search | tst13.js:78:15:78:48 | documen ... bstr(1) | provenance | | +| tst13.js:78:15:78:48 | documen ... bstr(1) | tst13.js:78:9:78:48 | url | provenance | | +| tst.js:2:19:2:69 | /.*redi ... n.href) | tst.js:2:19:2:72 | /.*redi ... ref)[1] | provenance | | +| tst.js:2:47:2:68 | documen ... on.href | tst.js:2:19:2:69 | /.*redi ... n.href) | provenance | Config | +| tst.js:6:20:6:56 | indirec ... n.href) | tst.js:6:20:6:59 | indirec ... ref)[1] | provenance | | +| tst.js:6:34:6:55 | documen ... on.href | tst.js:6:20:6:56 | indirec ... n.href) | provenance | Config | +| tst.js:10:19:10:81 | new Reg ... n.href) | tst.js:10:19:10:84 | new Reg ... ref)[1] | provenance | | +| tst.js:10:59:10:80 | documen ... on.href | tst.js:10:19:10:81 | new Reg ... n.href) | provenance | Config | +| tst.js:14:20:14:56 | indirec ... n.href) | tst.js:14:20:14:59 | indirec ... ref)[1] | provenance | | +| tst.js:14:34:14:55 | documen ... on.href | tst.js:14:20:14:56 | indirec ... n.href) | provenance | Config | +| tst.js:18:19:18:81 | new Reg ... n.href) | tst.js:18:19:18:84 | new Reg ... ref)[1] | provenance | | +| tst.js:18:59:18:80 | documen ... on.href | tst.js:18:19:18:81 | new Reg ... n.href) | provenance | Config | +| tst.js:22:20:22:56 | indirec ... n.href) | tst.js:22:20:22:59 | indirec ... ref)[1] | provenance | | +| tst.js:22:34:22:55 | documen ... on.href | tst.js:22:20:22:56 | indirec ... n.href) | provenance | Config | +| tst.js:26:22:26:79 | new Reg ... n.href) | tst.js:26:22:26:82 | new Reg ... ref)[1] | provenance | | +| tst.js:26:62:26:78 | win.location.href | tst.js:26:22:26:79 | new Reg ... n.href) | provenance | Config | +| typed.ts:4:13:4:36 | params | typed.ts:5:25:5:30 | params | provenance | | +| typed.ts:4:22:4:36 | location.search | typed.ts:4:13:4:36 | params | provenance | | +| typed.ts:5:25:5:30 | params | typed.ts:7:24:7:34 | redirectUri | provenance | | +| typed.ts:7:24:7:34 | redirectUri | typed.ts:8:33:8:43 | redirectUri | provenance | | +| typed.ts:25:25:25:34 | loc.search | typed.ts:28:24:28:34 | redirectUri | provenance | | +| typed.ts:28:24:28:34 | redirectUri | typed.ts:29:33:29:43 | redirectUri | provenance | | +| typed.ts:47:25:47:34 | loc.search | typed.ts:51:24:51:34 | redirectUri | provenance | | +| typed.ts:48:26:48:36 | loc2.search | typed.ts:55:25:55:35 | redirectUri | provenance | | +| typed.ts:51:24:51:34 | redirectUri | typed.ts:52:33:52:43 | redirectUri | provenance | | +| typed.ts:55:25:55:35 | redirectUri | typed.ts:56:33:56:43 | redirectUri | provenance | | subpaths #select | electron.js:7:20:7:29 | getTaint() | electron.js:4:12:4:22 | window.name | electron.js:7:20:7:29 | getTaint() | Untrusted URL redirection depends on a $@. | electron.js:4:12:4:22 | window.name | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected b/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected index 4497676ff2e..ac29a57bf83 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected +++ b/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected @@ -1,47 +1,47 @@ edges -| ServerSideUrlRedirectGood2.js:16:7:16:34 | target | ServerSideUrlRedirectGood2.js:18:18:18:23 | target | -| ServerSideUrlRedirectGood2.js:16:16:16:34 | req.query["target"] | ServerSideUrlRedirectGood2.js:16:7:16:34 | target | -| express.js:27:7:27:34 | target | express.js:30:18:30:23 | target | -| express.js:27:7:27:34 | target | express.js:33:18:33:23 | target | -| express.js:27:7:27:34 | target | express.js:35:16:35:21 | target | -| express.js:27:16:27:34 | req.param("target") | express.js:27:7:27:34 | target | -| express.js:40:69:40:87 | req.param('action') | express.js:40:16:40:108 | (req.pa ... ntacts" | -| express.js:74:19:74:37 | req.param("target") | express.js:74:16:74:43 | `${req. ... )}/foo` | -| express.js:83:7:83:34 | target | express.js:90:18:90:23 | target | -| express.js:83:7:83:34 | target | express.js:97:16:97:21 | target | -| express.js:83:16:83:34 | req.param("target") | express.js:83:7:83:34 | target | -| express.js:118:17:118:30 | req.query.page | express.js:118:16:118:72 | [req.qu ... oin('') | -| express.js:134:22:134:36 | req.params.user | express.js:134:16:134:36 | '/' + r ... ms.user | -| express.js:135:23:135:37 | req.params.user | express.js:135:16:135:37 | '//' + ... ms.user | -| express.js:136:22:136:36 | req.params.user | express.js:136:16:136:36 | 'u' + r ... ms.user | -| express.js:150:7:150:34 | target | express.js:155:18:155:23 | target | -| express.js:150:7:150:34 | target | express.js:160:18:160:23 | target | -| express.js:150:16:150:34 | req.param("target") | express.js:150:7:150:34 | target | -| express.js:164:7:164:54 | myThing | express.js:165:16:165:22 | myThing | -| express.js:164:17:164:41 | JSON.st ... .query) | express.js:164:17:164:54 | JSON.st ... (1, -1) | -| express.js:164:17:164:54 | JSON.st ... (1, -1) | express.js:164:7:164:54 | myThing | -| express.js:164:32:164:40 | req.query | express.js:164:17:164:41 | JSON.st ... .query) | -| koa.js:6:6:6:27 | url | koa.js:7:15:7:17 | url | -| koa.js:6:6:6:27 | url | koa.js:8:18:8:20 | url | -| koa.js:6:6:6:27 | url | koa.js:14:16:14:18 | url | -| koa.js:6:6:6:27 | url | koa.js:20:16:20:18 | url | -| koa.js:6:12:6:27 | ctx.query.target | koa.js:6:6:6:27 | url | -| koa.js:8:18:8:20 | url | koa.js:8:15:8:26 | `${url}${x}` | -| next.ts:11:31:11:38 | req.body | next.ts:11:31:11:50 | req.body.callbackUrl | -| node.js:5:7:5:52 | target | node.js:6:34:6:39 | target | -| node.js:5:16:5:39 | url.par ... , true) | node.js:5:7:5:52 | target | -| node.js:5:26:5:32 | req.url | node.js:5:16:5:39 | url.par ... , true) | -| node.js:10:7:10:52 | target | node.js:14:40:14:45 | target | -| node.js:10:16:10:39 | url.par ... , true) | node.js:10:7:10:52 | target | -| node.js:10:26:10:32 | req.url | node.js:10:16:10:39 | url.par ... , true) | -| node.js:14:40:14:45 | target | node.js:14:34:14:45 | '/' + target | -| node.js:28:7:28:52 | target | node.js:31:34:31:39 | target | -| node.js:28:16:28:39 | url.par ... , true) | node.js:28:7:28:52 | target | -| node.js:28:26:28:32 | req.url | node.js:28:16:28:39 | url.par ... , true) | -| node.js:31:34:31:39 | target | node.js:31:34:31:55 | target ... =" + me | -| react-native.js:7:7:7:33 | tainted | react-native.js:8:17:8:23 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:9:26:9:32 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | +| ServerSideUrlRedirectGood2.js:16:7:16:34 | target | ServerSideUrlRedirectGood2.js:18:18:18:23 | target | provenance | | +| ServerSideUrlRedirectGood2.js:16:16:16:34 | req.query["target"] | ServerSideUrlRedirectGood2.js:16:7:16:34 | target | provenance | | +| express.js:27:7:27:34 | target | express.js:30:18:30:23 | target | provenance | | +| express.js:27:7:27:34 | target | express.js:33:18:33:23 | target | provenance | | +| express.js:27:7:27:34 | target | express.js:35:16:35:21 | target | provenance | | +| express.js:27:16:27:34 | req.param("target") | express.js:27:7:27:34 | target | provenance | | +| express.js:40:69:40:87 | req.param('action') | express.js:40:16:40:108 | (req.pa ... ntacts" | provenance | | +| express.js:74:19:74:37 | req.param("target") | express.js:74:16:74:43 | `${req. ... )}/foo` | provenance | | +| express.js:83:7:83:34 | target | express.js:90:18:90:23 | target | provenance | | +| express.js:83:7:83:34 | target | express.js:97:16:97:21 | target | provenance | | +| express.js:83:16:83:34 | req.param("target") | express.js:83:7:83:34 | target | provenance | | +| express.js:118:17:118:30 | req.query.page | express.js:118:16:118:72 | [req.qu ... oin('') | provenance | | +| express.js:134:22:134:36 | req.params.user | express.js:134:16:134:36 | '/' + r ... ms.user | provenance | | +| express.js:135:23:135:37 | req.params.user | express.js:135:16:135:37 | '//' + ... ms.user | provenance | | +| express.js:136:22:136:36 | req.params.user | express.js:136:16:136:36 | 'u' + r ... ms.user | provenance | | +| express.js:150:7:150:34 | target | express.js:155:18:155:23 | target | provenance | | +| express.js:150:7:150:34 | target | express.js:160:18:160:23 | target | provenance | | +| express.js:150:16:150:34 | req.param("target") | express.js:150:7:150:34 | target | provenance | | +| express.js:164:7:164:54 | myThing | express.js:165:16:165:22 | myThing | provenance | | +| express.js:164:17:164:41 | JSON.st ... .query) | express.js:164:17:164:54 | JSON.st ... (1, -1) | provenance | | +| express.js:164:17:164:54 | JSON.st ... (1, -1) | express.js:164:7:164:54 | myThing | provenance | | +| express.js:164:32:164:40 | req.query | express.js:164:17:164:41 | JSON.st ... .query) | provenance | | +| koa.js:6:6:6:27 | url | koa.js:7:15:7:17 | url | provenance | | +| koa.js:6:6:6:27 | url | koa.js:8:18:8:20 | url | provenance | | +| koa.js:6:6:6:27 | url | koa.js:14:16:14:18 | url | provenance | | +| koa.js:6:6:6:27 | url | koa.js:20:16:20:18 | url | provenance | | +| koa.js:6:12:6:27 | ctx.query.target | koa.js:6:6:6:27 | url | provenance | | +| koa.js:8:18:8:20 | url | koa.js:8:15:8:26 | `${url}${x}` | provenance | | +| next.ts:11:31:11:38 | req.body | next.ts:11:31:11:50 | req.body.callbackUrl | provenance | | +| node.js:5:7:5:52 | target | node.js:6:34:6:39 | target | provenance | | +| node.js:5:16:5:39 | url.par ... , true) | node.js:5:7:5:52 | target | provenance | | +| node.js:5:26:5:32 | req.url | node.js:5:16:5:39 | url.par ... , true) | provenance | | +| node.js:10:7:10:52 | target | node.js:14:40:14:45 | target | provenance | | +| node.js:10:16:10:39 | url.par ... , true) | node.js:10:7:10:52 | target | provenance | | +| node.js:10:26:10:32 | req.url | node.js:10:16:10:39 | url.par ... , true) | provenance | | +| node.js:14:40:14:45 | target | node.js:14:34:14:45 | '/' + target | provenance | | +| node.js:28:7:28:52 | target | node.js:31:34:31:39 | target | provenance | | +| node.js:28:16:28:39 | url.par ... , true) | node.js:28:7:28:52 | target | provenance | | +| node.js:28:26:28:32 | req.url | node.js:28:16:28:39 | url.par ... , true) | provenance | | +| node.js:31:34:31:39 | target | node.js:31:34:31:55 | target ... =" + me | provenance | | +| react-native.js:7:7:7:33 | tainted | react-native.js:8:17:8:23 | tainted | provenance | | +| react-native.js:7:7:7:33 | tainted | react-native.js:9:26:9:32 | tainted | provenance | | +| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | provenance | | nodes | ServerSideUrlRedirect.js:5:16:5:34 | req.query["target"] | semmle.label | req.query["target"] | | ServerSideUrlRedirectGood2.js:16:7:16:34 | target | semmle.label | target | diff --git a/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected b/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected index 8302bf16dd0..7bcfc58847a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected +++ b/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected @@ -1,8 +1,8 @@ edges -| domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src | -| domparser.js:2:7:2:36 | src | domparser.js:14:57:14:59 | src | -| domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src | -| libxml.noent.js:16:27:16:35 | req.files | libxml.noent.js:16:27:16:66 | req.fil ... 'utf8') | +| domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src | provenance | | +| domparser.js:2:7:2:36 | src | domparser.js:14:57:14:59 | src | provenance | | +| domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src | provenance | | +| libxml.noent.js:16:27:16:35 | req.files | libxml.noent.js:16:27:16:66 | req.fil ... 'utf8') | provenance | | nodes | domparser.js:2:7:2:36 | src | semmle.label | src | | domparser.js:2:13:2:36 | documen ... .search | semmle.label | documen ... .search | diff --git a/javascript/ql/test/query-tests/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.expected b/javascript/ql/test/query-tests/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.expected index 12c11f7b2fe..1f3d5bd243d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.expected +++ b/javascript/ql/test/query-tests/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.expected @@ -1,6 +1,6 @@ edges -| tst.js:17:84:17:91 | req.host | tst.js:17:11:17:113 | `Hi, lo ... token}` | -| tst.js:18:78:18:85 | req.host | tst.js:18:11:18:127 | `Hi, lo ... reset.` | +| tst.js:17:84:17:91 | req.host | tst.js:17:11:17:113 | `Hi, lo ... token}` | provenance | | +| tst.js:18:78:18:85 | req.host | tst.js:18:11:18:127 | `Hi, lo ... reset.` | provenance | | nodes | tst.js:17:11:17:113 | `Hi, lo ... token}` | semmle.label | `Hi, lo ... token}` | | tst.js:17:84:17:91 | req.host | semmle.label | req.host | diff --git a/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected b/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected index 5b216204dbe..c28b6cf57cb 100644 --- a/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected @@ -1,15 +1,15 @@ edges -| XpathInjectionBad.js:6:7:6:38 | userName | XpathInjectionBad.js:9:66:9:73 | userName | -| XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | XpathInjectionBad.js:6:7:6:38 | userName | -| XpathInjectionBad.js:9:66:9:73 | userName | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | -| tst2.js:1:13:1:34 | documen ... on.hash | tst2.js:1:13:1:47 | documen ... ring(1) | -| tst2.js:1:13:1:47 | documen ... ring(1) | tst2.js:2:27:2:31 | query | -| tst2.js:1:13:1:47 | documen ... ring(1) | tst2.js:3:19:3:23 | query | -| tst.js:6:7:6:37 | tainted | tst.js:7:15:7:21 | tainted | -| tst.js:6:7:6:37 | tainted | tst.js:8:16:8:22 | tainted | -| tst.js:6:7:6:37 | tainted | tst.js:9:17:9:23 | tainted | -| tst.js:6:7:6:37 | tainted | tst.js:11:8:11:14 | tainted | -| tst.js:6:17:6:37 | req.par ... rName") | tst.js:6:7:6:37 | tainted | +| XpathInjectionBad.js:6:7:6:38 | userName | XpathInjectionBad.js:9:66:9:73 | userName | provenance | | +| XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | XpathInjectionBad.js:6:7:6:38 | userName | provenance | | +| XpathInjectionBad.js:9:66:9:73 | userName | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | provenance | | +| tst2.js:1:13:1:34 | documen ... on.hash | tst2.js:1:13:1:47 | documen ... ring(1) | provenance | | +| tst2.js:1:13:1:47 | documen ... ring(1) | tst2.js:2:27:2:31 | query | provenance | | +| tst2.js:1:13:1:47 | documen ... ring(1) | tst2.js:3:19:3:23 | query | provenance | | +| tst.js:6:7:6:37 | tainted | tst.js:7:15:7:21 | tainted | provenance | | +| tst.js:6:7:6:37 | tainted | tst.js:8:16:8:22 | tainted | provenance | | +| tst.js:6:7:6:37 | tainted | tst.js:9:17:9:23 | tainted | provenance | | +| tst.js:6:7:6:37 | tainted | tst.js:11:8:11:14 | tainted | provenance | | +| tst.js:6:17:6:37 | req.par ... rName") | tst.js:6:7:6:37 | tainted | provenance | | nodes | XpathInjectionBad.js:6:7:6:38 | userName | semmle.label | userName | | XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | semmle.label | req.par ... rName") | diff --git a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected index 936d17028e3..14a51915162 100644 --- a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected @@ -1,48 +1,48 @@ edges -| RegExpInjection.js:5:7:5:28 | key | RegExpInjection.js:8:31:8:33 | key | -| RegExpInjection.js:5:7:5:28 | key | RegExpInjection.js:19:19:19:21 | key | -| RegExpInjection.js:5:7:5:28 | key | RegExpInjection.js:21:19:21:21 | key | -| RegExpInjection.js:5:7:5:28 | key | RegExpInjection.js:33:12:33:14 | key | -| RegExpInjection.js:5:7:5:28 | key | RegExpInjection.js:54:14:54:16 | key | -| RegExpInjection.js:5:13:5:28 | req.param("key") | RegExpInjection.js:5:7:5:28 | key | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:40:23:40:27 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:41:26:41:30 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:42:25:42:29 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:45:24:45:28 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:46:27:46:31 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:47:26:47:30 | input | -| RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:5:31:5:56 | input | -| RegExpInjection.js:8:31:8:33 | key | RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | -| RegExpInjection.js:10:17:10:17 | s | RegExpInjection.js:11:26:11:26 | s | -| RegExpInjection.js:11:20:11:27 | wrap2(s) | RegExpInjection.js:11:12:11:27 | "\\\\b" + wrap2(s) | -| RegExpInjection.js:11:26:11:26 | s | RegExpInjection.js:11:20:11:27 | wrap2(s) | -| RegExpInjection.js:11:26:11:26 | s | RegExpInjection.js:14:18:14:18 | s | -| RegExpInjection.js:14:18:14:18 | s | RegExpInjection.js:15:12:15:12 | s | -| RegExpInjection.js:15:12:15:12 | s | RegExpInjection.js:15:12:15:24 | s + "=(.*)\\n" | -| RegExpInjection.js:19:19:19:21 | key | RegExpInjection.js:10:17:10:17 | s | -| RegExpInjection.js:19:19:19:21 | key | RegExpInjection.js:19:14:19:22 | wrap(key) | -| RegExpInjection.js:21:19:21:21 | key | RegExpInjection.js:10:17:10:17 | s | -| RegExpInjection.js:21:19:21:21 | key | RegExpInjection.js:21:14:21:22 | wrap(key) | -| RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:27:14:27:21 | getKey() | -| RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:34:12:34:19 | getKey() | -| RegExpInjection.js:29:21:29:21 | s | RegExpInjection.js:31:23:31:23 | s | -| RegExpInjection.js:33:12:33:14 | key | RegExpInjection.js:29:21:29:21 | s | -| RegExpInjection.js:34:12:34:19 | getKey() | RegExpInjection.js:29:21:29:21 | s | -| RegExpInjection.js:54:14:54:16 | key | RegExpInjection.js:54:14:54:27 | key.split(".") | -| RegExpInjection.js:54:14:54:27 | key.split(".") | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | -| RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | -| RegExpInjection.js:60:31:60:56 | input | RegExpInjection.js:64:14:64:18 | input | -| RegExpInjection.js:60:39:60:56 | req.param("input") | RegExpInjection.js:60:31:60:56 | input | -| RegExpInjection.js:82:7:82:32 | input | RegExpInjection.js:87:25:87:29 | input | -| RegExpInjection.js:82:15:82:32 | req.param("input") | RegExpInjection.js:82:7:82:32 | input | -| RegExpInjection.js:87:25:87:29 | input | RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") | -| RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") | RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | -| RegExpInjection.js:91:20:91:30 | process.env | RegExpInjection.js:91:16:91:50 | `^${pro ... r.app$` | -| RegExpInjection.js:93:20:93:31 | process.argv | RegExpInjection.js:93:16:93:49 | `^${pro ... r.app$` | -| tst.js:1:46:1:46 | e | tst.js:2:16:2:16 | e | -| tst.js:2:9:2:21 | data | tst.js:3:21:3:24 | data | -| tst.js:2:16:2:16 | e | tst.js:2:9:2:21 | data | -| tst.js:3:21:3:24 | data | tst.js:3:16:3:35 | "^"+ data.name + "$" | +| RegExpInjection.js:5:7:5:28 | key | RegExpInjection.js:8:31:8:33 | key | provenance | | +| RegExpInjection.js:5:7:5:28 | key | RegExpInjection.js:19:19:19:21 | key | provenance | | +| RegExpInjection.js:5:7:5:28 | key | RegExpInjection.js:21:19:21:21 | key | provenance | | +| RegExpInjection.js:5:7:5:28 | key | RegExpInjection.js:33:12:33:14 | key | provenance | | +| RegExpInjection.js:5:7:5:28 | key | RegExpInjection.js:54:14:54:16 | key | provenance | | +| RegExpInjection.js:5:13:5:28 | req.param("key") | RegExpInjection.js:5:7:5:28 | key | provenance | | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:40:23:40:27 | input | provenance | | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:41:26:41:30 | input | provenance | | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:42:25:42:29 | input | provenance | | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:45:24:45:28 | input | provenance | | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:46:27:46:31 | input | provenance | | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:47:26:47:30 | input | provenance | | +| RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:5:31:5:56 | input | provenance | | +| RegExpInjection.js:8:31:8:33 | key | RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | provenance | | +| RegExpInjection.js:10:17:10:17 | s | RegExpInjection.js:11:26:11:26 | s | provenance | | +| RegExpInjection.js:11:20:11:27 | wrap2(s) | RegExpInjection.js:11:12:11:27 | "\\\\b" + wrap2(s) | provenance | | +| RegExpInjection.js:11:26:11:26 | s | RegExpInjection.js:11:20:11:27 | wrap2(s) | provenance | | +| RegExpInjection.js:11:26:11:26 | s | RegExpInjection.js:14:18:14:18 | s | provenance | | +| RegExpInjection.js:14:18:14:18 | s | RegExpInjection.js:15:12:15:12 | s | provenance | | +| RegExpInjection.js:15:12:15:12 | s | RegExpInjection.js:15:12:15:24 | s + "=(.*)\\n" | provenance | | +| RegExpInjection.js:19:19:19:21 | key | RegExpInjection.js:10:17:10:17 | s | provenance | | +| RegExpInjection.js:19:19:19:21 | key | RegExpInjection.js:19:14:19:22 | wrap(key) | provenance | | +| RegExpInjection.js:21:19:21:21 | key | RegExpInjection.js:10:17:10:17 | s | provenance | | +| RegExpInjection.js:21:19:21:21 | key | RegExpInjection.js:21:14:21:22 | wrap(key) | provenance | | +| RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:27:14:27:21 | getKey() | provenance | | +| RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:34:12:34:19 | getKey() | provenance | | +| RegExpInjection.js:29:21:29:21 | s | RegExpInjection.js:31:23:31:23 | s | provenance | | +| RegExpInjection.js:33:12:33:14 | key | RegExpInjection.js:29:21:29:21 | s | provenance | | +| RegExpInjection.js:34:12:34:19 | getKey() | RegExpInjection.js:29:21:29:21 | s | provenance | | +| RegExpInjection.js:54:14:54:16 | key | RegExpInjection.js:54:14:54:27 | key.split(".") | provenance | | +| RegExpInjection.js:54:14:54:27 | key.split(".") | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | provenance | | +| RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | provenance | | +| RegExpInjection.js:60:31:60:56 | input | RegExpInjection.js:64:14:64:18 | input | provenance | | +| RegExpInjection.js:60:39:60:56 | req.param("input") | RegExpInjection.js:60:31:60:56 | input | provenance | | +| RegExpInjection.js:82:7:82:32 | input | RegExpInjection.js:87:25:87:29 | input | provenance | | +| RegExpInjection.js:82:15:82:32 | req.param("input") | RegExpInjection.js:82:7:82:32 | input | provenance | | +| RegExpInjection.js:87:25:87:29 | input | RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") | provenance | | +| RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") | RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | provenance | | +| RegExpInjection.js:91:20:91:30 | process.env | RegExpInjection.js:91:16:91:50 | `^${pro ... r.app$` | provenance | | +| RegExpInjection.js:93:20:93:31 | process.argv | RegExpInjection.js:93:16:93:49 | `^${pro ... r.app$` | provenance | | +| tst.js:1:46:1:46 | e | tst.js:2:16:2:16 | e | provenance | | +| tst.js:2:9:2:21 | data | tst.js:3:21:3:24 | data | provenance | | +| tst.js:2:16:2:16 | e | tst.js:2:9:2:21 | data | provenance | | +| tst.js:3:21:3:24 | data | tst.js:3:16:3:35 | "^"+ data.name + "$" | provenance | | nodes | RegExpInjection.js:5:7:5:28 | key | semmle.label | key | | RegExpInjection.js:5:13:5:28 | req.param("key") | semmle.label | req.param("key") | diff --git a/javascript/ql/test/query-tests/Security/CWE-754/UnvalidatedDynamicMethodCall.expected b/javascript/ql/test/query-tests/Security/CWE-754/UnvalidatedDynamicMethodCall.expected index 55d4ce16510..120f9a82e71 100644 --- a/javascript/ql/test/query-tests/Security/CWE-754/UnvalidatedDynamicMethodCall.expected +++ b/javascript/ql/test/query-tests/Security/CWE-754/UnvalidatedDynamicMethodCall.expected @@ -60,60 +60,60 @@ nodes | 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: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] | -| 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) | -| 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: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: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) | -| 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: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 | -| tst.js:7:9:7:39 | name | tst.js:21:11:21:14 | name | -| tst.js:7:9:7:39 | name | tst.js:26:11:26:14 | name | -| tst.js:7:9:7:39 | name | tst.js:28:11:28:14 | name | -| tst.js:7:9:7:39 | name | tst.js:34:21:34:24 | name | -| tst.js:7:16:7:34 | JSON.parse(ev.data) | tst.js:7:16:7:39 | JSON.pa ... a).name | -| tst.js:7:16:7:39 | JSON.pa ... a).name | tst.js:7:9:7:39 | name | -| tst.js:7:27:7:28 | ev | tst.js:7:27:7:33 | ev.data | -| 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: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:20:7:20:8 | 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: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: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: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: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: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 | -| tst.js:48:16:48:39 | JSON.pa ... a).name | tst.js:48:9:48:39 | name | -| 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: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] | +| UnsafeDynamicMethodAccess.js:5:37:5:38 | ev | UnsafeDynamicMethodAccess.js:6:30:6:31 | ev | provenance | | +| UnsafeDynamicMethodAccess.js:6:9:6:37 | message | UnsafeDynamicMethodAccess.js:15:9:15:15 | message | provenance | | +| UnsafeDynamicMethodAccess.js:6:19:6:37 | JSON.parse(ev.data) | UnsafeDynamicMethodAccess.js:6:9:6:37 | message | provenance | | +| UnsafeDynamicMethodAccess.js:6:30:6:31 | ev | UnsafeDynamicMethodAccess.js:6:30:6:36 | ev.data | provenance | Config | +| UnsafeDynamicMethodAccess.js:6:30:6:36 | ev.data | UnsafeDynamicMethodAccess.js:6:19:6:37 | JSON.parse(ev.data) | provenance | Config | +| UnsafeDynamicMethodAccess.js:15:9:15:15 | message | UnsafeDynamicMethodAccess.js:15:9:15:20 | message.name | provenance | Config | +| UnsafeDynamicMethodAccess.js:15:9:15:20 | message.name | UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] | provenance | Config | +| UnvalidatedDynamicMethodCall2.js:13:9:13:47 | action | UnvalidatedDynamicMethodCall2.js:14:13:14:18 | action | provenance | | +| UnvalidatedDynamicMethodCall2.js:13:18:13:47 | actions ... action) | UnvalidatedDynamicMethodCall2.js:13:9:13:47 | action | provenance | | +| UnvalidatedDynamicMethodCall2.js:13:30:13:46 | req.params.action | UnvalidatedDynamicMethodCall2.js:13:18:13:47 | actions ... action) | provenance | Config | +| UnvalidatedDynamicMethodCall.js:14:7:14:41 | action | UnvalidatedDynamicMethodCall.js:15:11:15:16 | action | provenance | | +| UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] | UnvalidatedDynamicMethodCall.js:14:7:14:41 | action | provenance | | +| UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action | UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] | provenance | Config | +| UnvalidatedDynamicMethodCallGood4.js:14:13:14:51 | action | UnvalidatedDynamicMethodCallGood4.js:15:17:15:22 | action | provenance | | +| UnvalidatedDynamicMethodCallGood4.js:14:22:14:51 | actions ... action) | UnvalidatedDynamicMethodCallGood4.js:14:13:14:51 | action | provenance | | +| UnvalidatedDynamicMethodCallGood4.js:14:34:14:50 | req.params.action | UnvalidatedDynamicMethodCallGood4.js:14:22:14:51 | actions ... action) | provenance | Config | +| tst.js:6:39:6:40 | ev | tst.js:7:27:7:28 | ev | provenance | | +| tst.js:6:39:6:40 | ev | tst.js:9:9:9:10 | ev | provenance | | +| tst.js:7:9:7:39 | name | tst.js:11:9:11:12 | name | provenance | | +| tst.js:7:9:7:39 | name | tst.js:17:18:17:21 | name | provenance | | +| tst.js:7:9:7:39 | name | tst.js:21:11:21:14 | name | provenance | | +| tst.js:7:9:7:39 | name | tst.js:26:11:26:14 | name | provenance | | +| tst.js:7:9:7:39 | name | tst.js:28:11:28:14 | name | provenance | | +| tst.js:7:9:7:39 | name | tst.js:34:21:34:24 | name | provenance | | +| tst.js:7:16:7:34 | JSON.parse(ev.data) | tst.js:7:16:7:39 | JSON.pa ... a).name | provenance | Config | +| tst.js:7:16:7:39 | JSON.pa ... a).name | tst.js:7:9:7:39 | name | provenance | | +| tst.js:7:27:7:28 | ev | tst.js:7:27:7:33 | ev.data | provenance | Config | +| tst.js:7:27:7:33 | ev.data | tst.js:7:16:7:34 | JSON.parse(ev.data) | provenance | Config | +| tst.js:9:9:9:10 | ev | tst.js:9:9:9:15 | ev.data | provenance | Config | +| tst.js:9:9:9:15 | ev.data | tst.js:9:5:9:16 | obj[ev.data] | provenance | Config | +| tst.js:11:9:11:12 | name | tst.js:11:5:11:13 | obj[name] | provenance | Config | +| tst.js:17:9:17:22 | fn | tst.js:18:5:18:6 | fn | provenance | | +| tst.js:17:9:17:22 | fn | tst.js:20:7:20:8 | fn | provenance | | +| tst.js:17:9:17:22 | fn | tst.js:22:11:22:12 | fn | provenance | | +| tst.js:17:14:17:22 | obj[name] | tst.js:17:9:17:22 | fn | provenance | | +| tst.js:17:18:17:21 | name | tst.js:17:14:17:22 | obj[name] | provenance | Config | +| tst.js:21:11:21:14 | name | tst.js:21:7:21:15 | obj[name] | provenance | Config | +| tst.js:26:11:26:14 | name | tst.js:26:7:26:15 | obj[name] | provenance | Config | +| tst.js:28:11:28:14 | name | tst.js:28:7:28:15 | obj[name] | provenance | Config | +| tst.js:34:9:34:24 | key | tst.js:35:9:35:11 | key | provenance | | +| tst.js:34:9:34:24 | key | tst.js:37:11:37:13 | key | provenance | | +| tst.js:34:15:34:24 | "$" + name | tst.js:34:9:34:24 | key | provenance | | +| tst.js:34:21:34:24 | name | tst.js:34:15:34:24 | "$" + name | provenance | Config | +| tst.js:35:9:35:11 | key | tst.js:35:5:35:12 | obj[key] | provenance | Config | +| tst.js:37:11:37:13 | key | tst.js:37:7:37:14 | obj[key] | provenance | Config | +| tst.js:47:39:47:40 | ev | tst.js:48:27:48:28 | ev | provenance | | +| tst.js:48:9:48:39 | name | tst.js:49:19:49:22 | name | provenance | | +| tst.js:48:16:48:34 | JSON.parse(ev.data) | tst.js:48:16:48:39 | JSON.pa ... a).name | provenance | Config | +| tst.js:48:16:48:39 | JSON.pa ... a).name | tst.js:48:9:48:39 | name | provenance | | +| tst.js:48:27:48:28 | ev | tst.js:48:27:48:33 | ev.data | provenance | Config | +| tst.js:48:27:48:33 | ev.data | tst.js:48:16:48:34 | JSON.parse(ev.data) | provenance | Config | +| tst.js:49:9:49:23 | fn | tst.js:50:5:50:6 | fn | provenance | | +| tst.js:49:14:49:23 | obj2[name] | tst.js:49:9:49:23 | fn | provenance | | +| tst.js:49:19:49:22 | name | tst.js:49:14:49:23 | obj2[name] | provenance | Config | 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 | diff --git a/javascript/ql/test/query-tests/Security/CWE-770/ResourceExhaustion/ResourceExhaustion.expected b/javascript/ql/test/query-tests/Security/CWE-770/ResourceExhaustion/ResourceExhaustion.expected index f3b767c64b4..7ca54548996 100644 --- a/javascript/ql/test/query-tests/Security/CWE-770/ResourceExhaustion/ResourceExhaustion.expected +++ b/javascript/ql/test/query-tests/Security/CWE-770/ResourceExhaustion/ResourceExhaustion.expected @@ -1,33 +1,33 @@ edges -| documentaion-examples/ResourceExhaustion_timeout.js:5:6:5:59 | delay | documentaion-examples/ResourceExhaustion_timeout.js:7:16:7:20 | delay | -| documentaion-examples/ResourceExhaustion_timeout.js:5:14:5:59 | parseIn ... .delay) | documentaion-examples/ResourceExhaustion_timeout.js:5:6:5:59 | delay | -| documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:46 | url.par ... , true) | documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:58 | url.par ... y.delay | -| documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:58 | url.par ... y.delay | documentaion-examples/ResourceExhaustion_timeout.js:5:14:5:59 | parseIn ... .delay) | -| documentaion-examples/ResourceExhaustion_timeout.js:5:33:5:39 | req.url | documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:46 | url.par ... , true) | -| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:6:20:6:20 | s | -| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:35:12:35:12 | s | -| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:82:17:82:17 | s | -| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:84:18:84:18 | s | -| resource-exhaustion.js:5:11:5:34 | url.par ... , true) | resource-exhaustion.js:5:7:5:42 | s | -| resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:5:11:5:34 | url.par ... , true) | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:14:16:14:16 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:15:22:15:22 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:16:26:16:26 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:20:20:20:20 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:22:18:22:18 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:27:9:27:9 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:28:13:28:13 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:29:9:29:9 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:30:9:30:9 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:31:9:31:9 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:32:9:32:9 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:34:12:34:12 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:81:17:81:17 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:83:18:83:18 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:88:16:88:16 | n | -| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:92:18:92:18 | n | -| resource-exhaustion.js:6:11:6:21 | parseInt(s) | resource-exhaustion.js:6:7:6:21 | n | -| resource-exhaustion.js:6:20:6:20 | s | resource-exhaustion.js:6:11:6:21 | parseInt(s) | +| documentaion-examples/ResourceExhaustion_timeout.js:5:6:5:59 | delay | documentaion-examples/ResourceExhaustion_timeout.js:7:16:7:20 | delay | provenance | | +| documentaion-examples/ResourceExhaustion_timeout.js:5:14:5:59 | parseIn ... .delay) | documentaion-examples/ResourceExhaustion_timeout.js:5:6:5:59 | delay | provenance | | +| documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:46 | url.par ... , true) | documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:58 | url.par ... y.delay | provenance | | +| documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:58 | url.par ... y.delay | documentaion-examples/ResourceExhaustion_timeout.js:5:14:5:59 | parseIn ... .delay) | provenance | Config | +| documentaion-examples/ResourceExhaustion_timeout.js:5:33:5:39 | req.url | documentaion-examples/ResourceExhaustion_timeout.js:5:23:5:46 | url.par ... , true) | provenance | | +| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:6:20:6:20 | s | provenance | | +| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:35:12:35:12 | s | provenance | | +| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:82:17:82:17 | s | provenance | | +| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:84:18:84:18 | s | provenance | | +| resource-exhaustion.js:5:11:5:34 | url.par ... , true) | resource-exhaustion.js:5:7:5:42 | s | provenance | | +| resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:5:11:5:34 | url.par ... , true) | provenance | | +| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:14:16:14:16 | n | provenance | | +| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:15:22:15:22 | n | provenance | | +| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:16:26:16:26 | n | provenance | | +| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:20:20:20:20 | n | provenance | | +| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:22:18:22:18 | n | provenance | | +| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:27:9:27:9 | n | provenance | | +| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:28:13:28:13 | n | provenance | | +| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:29:9:29:9 | n | provenance | | +| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:30:9:30:9 | n | provenance | | +| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:31:9:31:9 | n | provenance | | +| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:32:9:32:9 | n | provenance | | +| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:34:12:34:12 | n | provenance | | +| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:81:17:81:17 | n | provenance | | +| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:83:18:83:18 | n | provenance | | +| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:88:16:88:16 | n | provenance | | +| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:92:18:92:18 | n | provenance | | +| resource-exhaustion.js:6:11:6:21 | parseInt(s) | resource-exhaustion.js:6:7:6:21 | n | provenance | | +| resource-exhaustion.js:6:20:6:20 | s | resource-exhaustion.js:6:11:6:21 | parseInt(s) | provenance | Config | nodes | documentaion-examples/ResourceExhaustion_timeout.js:5:6:5:59 | delay | semmle.label | delay | | documentaion-examples/ResourceExhaustion_timeout.js:5:14:5:59 | parseIn ... .delay) | semmle.label | parseIn ... .delay) | diff --git a/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected b/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected index be99aaf7513..bcdb2c57680 100644 --- a/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected +++ b/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected @@ -1,12 +1,12 @@ edges -| closure.js:2:7:2:36 | src | closure.js:4:24:4:26 | src | -| closure.js:2:13:2:36 | documen ... .search | closure.js:2:7:2:36 | src | -| domparser.js:2:7:2:36 | src | domparser.js:6:37:6:39 | src | -| domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src | -| domparser.js:2:7:2:36 | src | domparser.js:14:57:14:59 | src | -| domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src | -| jquery.js:2:7:2:36 | src | jquery.js:5:14:5:16 | src | -| jquery.js:2:13:2:36 | documen ... .search | jquery.js:2:7:2:36 | src | +| closure.js:2:7:2:36 | src | closure.js:4:24:4:26 | src | provenance | | +| closure.js:2:13:2:36 | documen ... .search | closure.js:2:7:2:36 | src | provenance | | +| domparser.js:2:7:2:36 | src | domparser.js:6:37:6:39 | src | provenance | | +| domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src | provenance | | +| domparser.js:2:7:2:36 | src | domparser.js:14:57:14:59 | src | provenance | | +| domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src | provenance | | +| jquery.js:2:7:2:36 | src | jquery.js:5:14:5:16 | src | provenance | | +| jquery.js:2:13:2:36 | documen ... .search | jquery.js:2:7:2:36 | src | provenance | | nodes | closure.js:2:7:2:36 | src | semmle.label | src | | closure.js:2:13:2:36 | documen ... .search | semmle.label | documen ... .search | diff --git a/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected b/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected index f78e2428b90..834ad02c1f2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected +++ b/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected @@ -1,19 +1,19 @@ edges -| example_bypass.js:6:9:6:19 | req.cookies | example_bypass.js:6:9:6:34 | req.coo ... nUserId | -| tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing | -| tst.js:24:17:24:17 | v | tst.js:25:16:25:16 | v | -| tst.js:27:9:27:37 | v3 | tst.js:28:9:28:10 | v3 | -| tst.js:27:14:27:37 | id(req. ... okieId) | tst.js:27:9:27:37 | v3 | -| tst.js:27:17:27:27 | req.cookies | tst.js:27:17:27:36 | req.cookies.cookieId | -| tst.js:27:17:27:36 | req.cookies.cookieId | tst.js:24:17:24:17 | v | -| tst.js:27:17:27:36 | req.cookies.cookieId | tst.js:27:14:27:37 | id(req. ... okieId) | -| tst.js:33:13:33:23 | req.cookies | tst.js:33:13:33:32 | req.cookies.cookieId | -| tst.js:38:9:38:19 | req.cookies | tst.js:38:9:38:28 | req.cookies.cookieId | -| tst.js:61:9:61:19 | req.cookies | tst.js:61:9:61:28 | req.cookies.cookieId | -| tst.js:65:14:65:24 | req.cookies | tst.js:65:14:65:33 | req.cookies.cookieId | -| tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:28 | req.cookies.cookieId | -| tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:28 | req.cookies.cookieId | -| tst.js:78:9:78:28 | req.cookies.cookieId | tst.js:78:9:78:41 | req.coo ... secret" | +| example_bypass.js:6:9:6:19 | req.cookies | example_bypass.js:6:9:6:34 | req.coo ... nUserId | provenance | | +| tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing | provenance | | +| tst.js:24:17:24:17 | v | tst.js:25:16:25:16 | v | provenance | | +| tst.js:27:9:27:37 | v3 | tst.js:28:9:28:10 | v3 | provenance | | +| tst.js:27:14:27:37 | id(req. ... okieId) | tst.js:27:9:27:37 | v3 | provenance | | +| tst.js:27:17:27:27 | req.cookies | tst.js:27:17:27:36 | req.cookies.cookieId | provenance | | +| tst.js:27:17:27:36 | req.cookies.cookieId | tst.js:24:17:24:17 | v | provenance | | +| tst.js:27:17:27:36 | req.cookies.cookieId | tst.js:27:14:27:37 | id(req. ... okieId) | provenance | | +| tst.js:33:13:33:23 | req.cookies | tst.js:33:13:33:32 | req.cookies.cookieId | provenance | | +| tst.js:38:9:38:19 | req.cookies | tst.js:38:9:38:28 | req.cookies.cookieId | provenance | | +| tst.js:61:9:61:19 | req.cookies | tst.js:61:9:61:28 | req.cookies.cookieId | provenance | | +| tst.js:65:14:65:24 | req.cookies | tst.js:65:14:65:33 | req.cookies.cookieId | provenance | | +| tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:28 | req.cookies.cookieId | provenance | | +| tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:28 | req.cookies.cookieId | provenance | | +| tst.js:78:9:78:28 | req.cookies.cookieId | tst.js:78:9:78:41 | req.coo ... secret" | provenance | Config | nodes | example_bypass.js:6:9:6:19 | req.cookies | semmle.label | req.cookies | | example_bypass.js:6:9:6:34 | req.coo ... nUserId | semmle.label | req.coo ... nUserId | diff --git a/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjection.expected b/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjection.expected index 464b21ca14e..511e776ed3c 100644 --- a/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjection.expected @@ -1,22 +1,22 @@ edges -| LoopBoundInjectionBad.js:8:13:8:20 | req.body | LoopBoundInjectionBad.js:17:18:17:20 | val | -| LoopBoundInjectionBad.js:10:15:10:22 | req.body | LoopBoundInjectionBad.js:25:20:25:22 | val | -| LoopBoundInjectionBad.js:12:25:12:32 | req.body | LoopBoundInjectionBad.js:35:30:35:32 | val | -| LoopBoundInjectionBad.js:14:19:14:26 | req.body | LoopBoundInjectionBad.js:46:24:46:26 | val | -| LoopBoundInjectionBad.js:17:18:17:20 | val | LoopBoundInjectionBad.js:20:25:20:27 | val | -| LoopBoundInjectionBad.js:25:20:25:22 | val | LoopBoundInjectionBad.js:29:16:29:18 | val | -| LoopBoundInjectionBad.js:35:30:35:32 | val | LoopBoundInjectionBad.js:38:15:38:17 | val | -| LoopBoundInjectionBad.js:46:24:46:26 | val | LoopBoundInjectionBad.js:51:25:51:27 | val | -| LoopBoundInjectionExitBad.js:8:9:8:16 | req.body | LoopBoundInjectionExitBad.js:17:17:17:19 | val | -| LoopBoundInjectionExitBad.js:10:9:10:16 | req.body | LoopBoundInjectionExitBad.js:31:17:31:19 | val | -| LoopBoundInjectionExitBad.js:12:10:12:17 | req.body | LoopBoundInjectionExitBad.js:46:18:46:20 | val | -| LoopBoundInjectionExitBad.js:14:14:14:21 | req.body | LoopBoundInjectionExitBad.js:59:22:59:24 | val | -| LoopBoundInjectionExitBad.js:17:17:17:19 | val | LoopBoundInjectionExitBad.js:20:22:20:24 | val | -| LoopBoundInjectionExitBad.js:31:17:31:19 | val | LoopBoundInjectionExitBad.js:34:22:34:24 | val | -| LoopBoundInjectionExitBad.js:46:18:46:20 | val | LoopBoundInjectionExitBad.js:49:22:49:24 | val | -| LoopBoundInjectionExitBad.js:59:22:59:24 | val | LoopBoundInjectionExitBad.js:60:8:60:10 | val | -| LoopBoundInjectionLodash.js:9:13:9:20 | req.body | LoopBoundInjectionLodash.js:12:18:12:20 | val | -| LoopBoundInjectionLodash.js:12:18:12:20 | val | LoopBoundInjectionLodash.js:13:13:13:15 | val | +| LoopBoundInjectionBad.js:8:13:8:20 | req.body | LoopBoundInjectionBad.js:17:18:17:20 | val | provenance | | +| LoopBoundInjectionBad.js:10:15:10:22 | req.body | LoopBoundInjectionBad.js:25:20:25:22 | val | provenance | | +| LoopBoundInjectionBad.js:12:25:12:32 | req.body | LoopBoundInjectionBad.js:35:30:35:32 | val | provenance | | +| LoopBoundInjectionBad.js:14:19:14:26 | req.body | LoopBoundInjectionBad.js:46:24:46:26 | val | provenance | | +| LoopBoundInjectionBad.js:17:18:17:20 | val | LoopBoundInjectionBad.js:20:25:20:27 | val | provenance | | +| LoopBoundInjectionBad.js:25:20:25:22 | val | LoopBoundInjectionBad.js:29:16:29:18 | val | provenance | | +| LoopBoundInjectionBad.js:35:30:35:32 | val | LoopBoundInjectionBad.js:38:15:38:17 | val | provenance | | +| LoopBoundInjectionBad.js:46:24:46:26 | val | LoopBoundInjectionBad.js:51:25:51:27 | val | provenance | | +| LoopBoundInjectionExitBad.js:8:9:8:16 | req.body | LoopBoundInjectionExitBad.js:17:17:17:19 | val | provenance | | +| LoopBoundInjectionExitBad.js:10:9:10:16 | req.body | LoopBoundInjectionExitBad.js:31:17:31:19 | val | provenance | | +| LoopBoundInjectionExitBad.js:12:10:12:17 | req.body | LoopBoundInjectionExitBad.js:46:18:46:20 | val | provenance | | +| LoopBoundInjectionExitBad.js:14:14:14:21 | req.body | LoopBoundInjectionExitBad.js:59:22:59:24 | val | provenance | | +| LoopBoundInjectionExitBad.js:17:17:17:19 | val | LoopBoundInjectionExitBad.js:20:22:20:24 | val | provenance | | +| LoopBoundInjectionExitBad.js:31:17:31:19 | val | LoopBoundInjectionExitBad.js:34:22:34:24 | val | provenance | | +| LoopBoundInjectionExitBad.js:46:18:46:20 | val | LoopBoundInjectionExitBad.js:49:22:49:24 | val | provenance | | +| LoopBoundInjectionExitBad.js:59:22:59:24 | val | LoopBoundInjectionExitBad.js:60:8:60:10 | val | provenance | | +| LoopBoundInjectionLodash.js:9:13:9:20 | req.body | LoopBoundInjectionLodash.js:12:18:12:20 | val | provenance | | +| LoopBoundInjectionLodash.js:12:18:12:20 | val | LoopBoundInjectionLodash.js:13:13:13:15 | val | provenance | | nodes | LoopBoundInjectionBad.js:8:13:8:20 | req.body | semmle.label | req.body | | LoopBoundInjectionBad.js:10:15:10:22 | req.body | semmle.label | req.body | diff --git a/javascript/ql/test/query-tests/Security/CWE-843/TypeConfusionThroughParameterTampering.expected b/javascript/ql/test/query-tests/Security/CWE-843/TypeConfusionThroughParameterTampering.expected index d0234ead079..27de08dc846 100644 --- a/javascript/ql/test/query-tests/Security/CWE-843/TypeConfusionThroughParameterTampering.expected +++ b/javascript/ql/test/query-tests/Security/CWE-843/TypeConfusionThroughParameterTampering.expected @@ -1,41 +1,41 @@ edges -| tst.js:5:9:5:27 | foo | tst.js:6:5:6:7 | foo | -| tst.js:5:9:5:27 | foo | tst.js:6:5:6:7 | foo | -| tst.js:5:9:5:27 | foo | tst.js:8:5:8:7 | foo | -| tst.js:5:9:5:27 | foo | tst.js:8:5:8:7 | foo | -| tst.js:5:9:5:27 | foo | tst.js:17:7:17:9 | foo | -| tst.js:5:9:5:27 | foo | tst.js:21:5:21:7 | foo | -| tst.js:5:9:5:27 | foo | tst.js:22:5:22:7 | foo | -| tst.js:5:9:5:27 | foo | tst.js:23:5:23:7 | foo | -| tst.js:5:9:5:27 | foo | tst.js:25:5:25:7 | foo | -| tst.js:5:9:5:27 | foo | tst.js:27:5:27:7 | foo | -| tst.js:5:9:5:27 | foo | tst.js:27:5:27:7 | foo | -| tst.js:5:9:5:27 | foo | tst.js:28:5:28:7 | foo | -| tst.js:5:15:5:27 | req.query.foo | tst.js:5:9:5:27 | foo | -| tst.js:6:5:6:7 | foo | tst.js:8:5:8:7 | foo | -| tst.js:6:5:6:7 | foo | tst.js:8:5:8:7 | foo | -| tst.js:8:5:8:7 | foo | tst.js:10:5:12:5 | functio ... K\\n } [foo] | -| tst.js:8:5:8:7 | foo | tst.js:17:7:17:9 | foo | -| tst.js:10:5:12:5 | functio ... K\\n } [foo] | tst.js:10:14:10:14 | f [foo] | -| tst.js:10:5:12:5 | functio ... K\\n } [foo] | tst.js:11:9:11:11 | foo | -| tst.js:10:14:10:14 | f [foo] | tst.js:39:12:39:12 | f [foo] | -| tst.js:14:16:14:18 | bar | tst.js:15:9:15:11 | bar | -| tst.js:17:7:17:9 | foo | tst.js:14:16:14:18 | bar | -| tst.js:17:7:17:9 | foo | tst.js:21:5:21:7 | foo | -| tst.js:21:5:21:7 | foo | tst.js:22:5:22:7 | foo | -| tst.js:22:5:22:7 | foo | tst.js:23:5:23:7 | foo | -| tst.js:23:5:23:7 | foo | tst.js:25:5:25:7 | foo | -| tst.js:25:5:25:7 | foo | tst.js:27:5:27:7 | foo | -| tst.js:25:5:25:7 | foo | tst.js:27:5:27:7 | foo | -| tst.js:27:5:27:7 | foo | tst.js:28:5:28:7 | foo | -| tst.js:39:12:39:12 | f [foo] | tst.js:11:9:11:11 | foo | -| tst.js:45:9:45:35 | foo | tst.js:46:5:46:7 | foo | -| tst.js:45:15:45:35 | ctx.req ... ery.foo | tst.js:45:9:45:35 | foo | -| tst.js:77:25:77:38 | req.query.path | tst.js:80:23:80:23 | p | -| tst.js:80:23:80:23 | p | tst.js:81:9:81:9 | p | -| tst.js:80:23:80:23 | p | tst.js:82:9:82:9 | p | -| tst.js:103:9:103:29 | data | tst.js:104:5:104:8 | data | -| tst.js:103:16:103:29 | req.query.data | tst.js:103:9:103:29 | data | +| tst.js:5:9:5:27 | foo | tst.js:6:5:6:7 | foo | provenance | | +| tst.js:5:9:5:27 | foo | tst.js:6:5:6:7 | foo | provenance | | +| tst.js:5:9:5:27 | foo | tst.js:8:5:8:7 | foo | provenance | | +| tst.js:5:9:5:27 | foo | tst.js:8:5:8:7 | foo | provenance | | +| tst.js:5:9:5:27 | foo | tst.js:17:7:17:9 | foo | provenance | | +| tst.js:5:9:5:27 | foo | tst.js:21:5:21:7 | foo | provenance | | +| tst.js:5:9:5:27 | foo | tst.js:22:5:22:7 | foo | provenance | | +| tst.js:5:9:5:27 | foo | tst.js:23:5:23:7 | foo | provenance | | +| tst.js:5:9:5:27 | foo | tst.js:25:5:25:7 | foo | provenance | | +| tst.js:5:9:5:27 | foo | tst.js:27:5:27:7 | foo | provenance | | +| tst.js:5:9:5:27 | foo | tst.js:27:5:27:7 | foo | provenance | | +| tst.js:5:9:5:27 | foo | tst.js:28:5:28:7 | foo | provenance | | +| tst.js:5:15:5:27 | req.query.foo | tst.js:5:9:5:27 | foo | provenance | | +| tst.js:6:5:6:7 | foo | tst.js:8:5:8:7 | foo | provenance | | +| tst.js:6:5:6:7 | foo | tst.js:8:5:8:7 | foo | provenance | | +| tst.js:8:5:8:7 | foo | tst.js:10:5:12:5 | functio ... K\\n } [foo] | provenance | | +| tst.js:8:5:8:7 | foo | tst.js:17:7:17:9 | foo | provenance | | +| tst.js:10:5:12:5 | functio ... K\\n } [foo] | tst.js:10:14:10:14 | f [foo] | provenance | | +| tst.js:10:5:12:5 | functio ... K\\n } [foo] | tst.js:11:9:11:11 | foo | provenance | | +| tst.js:10:14:10:14 | f [foo] | tst.js:39:12:39:12 | f [foo] | provenance | | +| tst.js:14:16:14:18 | bar | tst.js:15:9:15:11 | bar | provenance | | +| tst.js:17:7:17:9 | foo | tst.js:14:16:14:18 | bar | provenance | | +| tst.js:17:7:17:9 | foo | tst.js:21:5:21:7 | foo | provenance | | +| tst.js:21:5:21:7 | foo | tst.js:22:5:22:7 | foo | provenance | | +| tst.js:22:5:22:7 | foo | tst.js:23:5:23:7 | foo | provenance | | +| tst.js:23:5:23:7 | foo | tst.js:25:5:25:7 | foo | provenance | | +| tst.js:25:5:25:7 | foo | tst.js:27:5:27:7 | foo | provenance | | +| tst.js:25:5:25:7 | foo | tst.js:27:5:27:7 | foo | provenance | | +| tst.js:27:5:27:7 | foo | tst.js:28:5:28:7 | foo | provenance | | +| tst.js:39:12:39:12 | f [foo] | tst.js:11:9:11:11 | foo | provenance | | +| tst.js:45:9:45:35 | foo | tst.js:46:5:46:7 | foo | provenance | | +| tst.js:45:15:45:35 | ctx.req ... ery.foo | tst.js:45:9:45:35 | foo | provenance | | +| tst.js:77:25:77:38 | req.query.path | tst.js:80:23:80:23 | p | provenance | | +| tst.js:80:23:80:23 | p | tst.js:81:9:81:9 | p | provenance | | +| tst.js:80:23:80:23 | p | tst.js:82:9:82:9 | p | provenance | | +| tst.js:103:9:103:29 | data | tst.js:104:5:104:8 | data | provenance | | +| tst.js:103:16:103:29 | req.query.data | tst.js:103:9:103:29 | data | provenance | | nodes | tst.js:5:9:5:27 | foo | semmle.label | foo | | tst.js:5:15:5:27 | req.query.foo | semmle.label | req.query.foo | diff --git a/javascript/ql/test/query-tests/Security/CWE-912/HttpToFileAccess.expected b/javascript/ql/test/query-tests/Security/CWE-912/HttpToFileAccess.expected index a9973f75465..0928df48ef9 100644 --- a/javascript/ql/test/query-tests/Security/CWE-912/HttpToFileAccess.expected +++ b/javascript/ql/test/query-tests/Security/CWE-912/HttpToFileAccess.expected @@ -1,12 +1,12 @@ edges -| HttpToFileAccess.js:5:18:5:18 | d | HttpToFileAccess.js:6:37:6:37 | d | -| tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | -| tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | -| tst.js:15:26:15:26 | c | tst.js:19:25:19:25 | c | -| tst.js:15:26:15:26 | c | tst.js:19:25:19:25 | c | -| tst.js:16:33:16:33 | c | tst.js:19:25:19:25 | c | -| tst.js:16:33:16:33 | c | tst.js:19:25:19:25 | c | -| tst.js:19:25:19:25 | c | tst.js:24:22:24:22 | c | +| HttpToFileAccess.js:5:18:5:18 | d | HttpToFileAccess.js:6:37:6:37 | d | provenance | | +| tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | provenance | | +| tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | provenance | | +| tst.js:15:26:15:26 | c | tst.js:19:25:19:25 | c | provenance | | +| tst.js:15:26:15:26 | c | tst.js:19:25:19:25 | c | provenance | | +| tst.js:16:33:16:33 | c | tst.js:19:25:19:25 | c | provenance | | +| tst.js:16:33:16:33 | c | tst.js:19:25:19:25 | c | provenance | | +| tst.js:19:25:19:25 | c | tst.js:24:22:24:22 | c | provenance | | nodes | HttpToFileAccess.js:5:18:5:18 | d | semmle.label | d | | HttpToFileAccess.js:6:37:6:37 | d | semmle.label | d | diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected index e3e20255490..46afcf5a14f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected @@ -1,106 +1,106 @@ edges -| 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: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: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:21:11:31 | currentPath | lib.js:11:17:11:32 | obj[currentPath] | -| 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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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]] | -| 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]] | -| 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/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]] | -| 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: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: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: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:45:9:45: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: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: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: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: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: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:105:12:105:16 | taint | tst.js:105:5:105:17 | object[taint] | +| lib.js:1:38:1:40 | obj | lib.js:6:7:6:9 | obj | provenance | | +| lib.js:1:43:1:46 | path | lib.js:2:21:2:24 | path | provenance | | +| lib.js:2:7:2:27 | currentPath | lib.js:11:21:11:31 | currentPath | provenance | | +| lib.js:2:21:2:24 | path | lib.js:2:21:2:27 | path[0] | provenance | Config | +| lib.js:2:21:2:27 | path[0] | lib.js:2:7:2:27 | currentPath | provenance | | +| lib.js:11:17:11:32 | obj[currentPath] | lib.js:1:38:1:40 | obj | provenance | | +| lib.js:11:21:11:31 | currentPath | lib.js:11:17:11:32 | obj[currentPath] | provenance | Config | +| lib.js:14:38:14:41 | path | lib.js:15:7:15:10 | path | provenance | | +| lib.js:15:7:15:10 | path | lib.js:15:7:15:13 | path[0] | provenance | Config | +| lib.js:15:7:15:13 | path[0] | lib.js:15:3:15:14 | obj[path[0]] | provenance | Config | +| lib.js:20:7:20:25 | path | lib.js:22:7:22:10 | path | provenance | | +| lib.js:20:14:20:22 | arguments | lib.js:20:14:20:25 | arguments[1] | provenance | Config | +| lib.js:20:14:20:25 | arguments[1] | lib.js:20:7:20:25 | path | provenance | | +| lib.js:22:7:22:10 | path | lib.js:22:7:22:13 | path[0] | provenance | Config | +| lib.js:22:7:22:13 | path[0] | lib.js:22:3:22:14 | obj[path[0]] | provenance | Config | +| lib.js:25:44:25:47 | path | lib.js:26:14:26:17 | path | provenance | | +| lib.js:26:14:26:17 | path | lib.js:26:14:26:20 | path[0] | provenance | Config | +| lib.js:26:14:26:20 | path[0] | lib.js:26:10:26:21 | obj[path[0]] | provenance | Config | +| lib.js:30:9:30:52 | args | lib.js:32:14:32:17 | args | provenance | | +| lib.js:30:16:30:52 | Array.p ... uments) | lib.js:30:9:30:52 | args | provenance | | +| lib.js:30:16:30:52 | reflective call | lib.js:30:16:30:52 | Array.p ... uments) | provenance | | +| lib.js:30:43:30:51 | arguments | lib.js:30:16:30:52 | reflective call | provenance | Config | +| lib.js:32:7:32:20 | path | lib.js:34:7:34:10 | path | provenance | | +| lib.js:32:14:32:17 | args | lib.js:32:14:32:20 | args[1] | provenance | Config | +| lib.js:32:14:32:20 | args[1] | lib.js:32:7:32:20 | path | provenance | | +| lib.js:34:7:34:10 | path | lib.js:34:7:34:13 | path[0] | provenance | Config | +| lib.js:34:7:34:13 | path[0] | lib.js:34:3:34:14 | obj[path[0]] | provenance | Config | +| lib.js:38:9:38:36 | args | lib.js:40:14:40:17 | args | provenance | | +| lib.js:38:16:38:36 | Array.f ... uments) | lib.js:38:9:38:36 | args | provenance | | +| lib.js:38:27:38:35 | arguments | lib.js:38:16:38:36 | Array.f ... uments) | provenance | Config | +| lib.js:40:7:40:20 | path | lib.js:42:7:42:10 | path | provenance | | +| lib.js:40:14:40:17 | args | lib.js:40:14:40:20 | args[1] | provenance | Config | +| lib.js:40:14:40:20 | args[1] | lib.js:40:7:40:20 | path | provenance | | +| lib.js:42:7:42:10 | path | lib.js:42:7:42:13 | path[0] | provenance | Config | +| lib.js:42:7:42:13 | path[0] | lib.js:42:3:42:14 | obj[path[0]] | provenance | Config | +| lib.js:83:7:83:25 | path | lib.js:86:19:86:22 | path | provenance | | +| lib.js:83:14:83:22 | arguments | lib.js:83:14:83:25 | arguments[1] | provenance | Config | +| lib.js:83:14:83:25 | arguments[1] | lib.js:83:7:83:25 | path | provenance | | +| lib.js:86:7:86:26 | proto | lib.js:87:10:87:14 | proto | provenance | | +| lib.js:86:15:86:26 | obj[path[0]] | lib.js:86:7:86:26 | proto | provenance | | +| lib.js:86:19:86:22 | path | lib.js:86:19:86:25 | path[0] | provenance | Config | +| lib.js:86:19:86:25 | path[0] | lib.js:86:15:86:26 | obj[path[0]] | provenance | Config | +| lib.js:90:43:90:46 | path | lib.js:91:24:91:27 | path | provenance | | +| lib.js:91:7:91:28 | maybeProto | lib.js:92:3:92:12 | maybeProto | provenance | | +| lib.js:91:7:91:28 | maybeProto | lib.js:95:3:95:12 | maybeProto | provenance | | +| lib.js:91:20:91:28 | obj[path] | lib.js:91:7:91:28 | maybeProto | provenance | | +| lib.js:91:24:91:27 | path | lib.js:91:20:91:28 | obj[path] | provenance | Config | +| lib.js:104:7:104:24 | one | lib.js:108:7:108:9 | one | provenance | | +| lib.js:104:13:104:21 | arguments | lib.js:104:13:104:24 | arguments[1] | provenance | Config | +| lib.js:104:13:104:24 | arguments[1] | lib.js:104:7:104:24 | one | provenance | | +| lib.js:108:7:108:9 | one | lib.js:108:3:108:10 | obj[one] | provenance | Config | +| lib.js:118:29:118:32 | path | lib.js:119:17:119:20 | path | provenance | | +| lib.js:119:17:119:20 | path | lib.js:119:17:119:23 | path[0] | provenance | Config | +| lib.js:119:17:119:23 | path[0] | lib.js:119:13:119:24 | obj[path[0]] | provenance | Config | +| lib.js:127:14:127:17 | path | lib.js:128:13:128:16 | path | provenance | | +| lib.js:128:13:128:16 | path | lib.js:128:13:128:19 | path[0] | provenance | Config | +| lib.js:128:13:128:19 | path[0] | lib.js:128:9:128:20 | obj[path[0]] | provenance | Config | +| otherlib/src/otherlibimpl.js:1:37:1:40 | path | otherlib/src/otherlibimpl.js:2:7:2:10 | path | provenance | | +| otherlib/src/otherlibimpl.js:2:7:2:10 | path | otherlib/src/otherlibimpl.js:2:7:2:13 | path[0] | provenance | Config | +| otherlib/src/otherlibimpl.js:2:7:2:13 | path[0] | otherlib/src/otherlibimpl.js:2:3:2:14 | obj[path[0]] | provenance | Config | +| sublib/other.js:5:28:5:31 | path | sublib/other.js:6:11:6:14 | path | provenance | | +| sublib/other.js:6:11:6:14 | path | sublib/other.js:6:11:6:17 | path[0] | provenance | Config | +| sublib/other.js:6:11:6:17 | path[0] | sublib/other.js:6:7:6:18 | obj[path[0]] | provenance | Config | +| sublib/sub.js:1:37:1:40 | path | sublib/sub.js:2:7:2:10 | path | provenance | | +| sublib/sub.js:2:7:2:10 | path | sublib/sub.js:2:7:2:13 | path[0] | provenance | Config | +| sublib/sub.js:2:7:2:13 | path[0] | sublib/sub.js:2:3:2:14 | obj[path[0]] | provenance | Config | +| tst.js:5:9:5:38 | taint | tst.js:8:12:8:16 | taint | provenance | | +| tst.js:5:9:5:38 | taint | tst.js:9:12:9:16 | taint | provenance | | +| tst.js:5:9:5:38 | taint | tst.js:12:25:12:29 | taint | provenance | | +| tst.js:5:9:5:38 | taint | tst.js:14:27:14:31 | taint | provenance | | +| tst.js:5:17:5:38 | String( ... y.data) | tst.js:5:9:5:38 | taint | provenance | | +| tst.js:5:24:5:37 | req.query.data | tst.js:5:17:5:38 | String( ... y.data) | provenance | Config | +| tst.js:8:12:8:16 | taint | tst.js:8:5:8:17 | object[taint] | provenance | Config | +| tst.js:9:12:9:16 | taint | tst.js:9:5:9:17 | object[taint] | provenance | Config | +| tst.js:12:18:12:30 | object[taint] | tst.js:33:23:33:25 | obj | provenance | | +| tst.js:12:25:12:29 | taint | tst.js:12:18:12:30 | object[taint] | provenance | Config | +| tst.js:14:27:14:31 | taint | tst.js:14:5:14:32 | unsafeG ... taint) | provenance | Config | +| tst.js:14:27:14:31 | taint | tst.js:55:29:55:32 | prop | provenance | | +| tst.js:33:23:33:25 | obj | tst.js:34:5:34:7 | obj | provenance | | +| tst.js:33:23:33:25 | obj | tst.js:39:9:39:11 | obj | provenance | | +| tst.js:33:23:33:25 | obj | tst.js:45:9:45:11 | obj | provenance | | +| tst.js:33:23:33:25 | obj | tst.js:48:9:48:11 | obj | provenance | | +| tst.js:55:29:55:32 | prop | tst.js:56:22:56:25 | prop | provenance | | +| tst.js:56:18:56:26 | obj[prop] | tst.js:56:12:56:33 | obj ? o ... : null | provenance | | +| tst.js:56:22:56:25 | prop | tst.js:56:18:56:26 | obj[prop] | provenance | Config | +| tst.js:77:9:77:38 | taint | tst.js:80:12:80:16 | taint | provenance | | +| tst.js:77:9:77:38 | taint | tst.js:82:17:82:21 | taint | provenance | | +| tst.js:77:9:77:38 | taint | tst.js:87:16:87:20 | taint | provenance | | +| tst.js:77:17:77:38 | String( ... y.data) | tst.js:77:9:77:38 | taint | provenance | | +| tst.js:77:24:77:37 | req.query.data | tst.js:77:17:77:38 | String( ... y.data) | provenance | Config | +| tst.js:80:12:80:16 | taint | tst.js:80:5:80:17 | object[taint] | provenance | Config | +| tst.js:82:12:82:21 | "" + taint | tst.js:82:5:82:22 | object["" + taint] | provenance | Config | +| tst.js:82:17:82:21 | taint | tst.js:82:12:82:21 | "" + taint | provenance | Config | +| tst.js:87:16:87:20 | taint | tst.js:87:9:87:21 | object[taint] | provenance | Config | +| tst.js:94:9:94:19 | req.query.x | tst.js:94:9:94:36 | req.que ... _', '') | provenance | Config | +| tst.js:94:9:94:36 | req.que ... _', '') | tst.js:94:5:94:37 | obj[req ... ', '')] | provenance | Config | +| tst.js:97:9:97:19 | req.query.x | tst.js:97:9:97:45 | req.que ... /g, '') | provenance | Config | +| tst.js:97:9:97:45 | req.que ... /g, '') | tst.js:97:5:97:46 | obj[req ... g, '')] | provenance | Config | +| tst.js:102:9:102:38 | taint | tst.js:105:12:105:16 | taint | provenance | | +| tst.js:102:17:102:38 | String( ... y.data) | tst.js:102:9:102:38 | taint | provenance | | +| tst.js:102:24:102:37 | req.query.data | tst.js:102:17:102:38 | String( ... y.data) | provenance | Config | +| tst.js:105:12:105:16 | taint | tst.js:105:5:105:17 | object[taint] | provenance | Config | nodes | lib.js:1:38:1:40 | obj | semmle.label | obj | | lib.js:1:43:1:46 | path | semmle.label | path | diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/PrototypePollutingFunction.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/PrototypePollutingFunction.expected index 185775d7dac..1c21a699533 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/PrototypePollutingFunction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/PrototypePollutingFunction.expected @@ -642,65 +642,65 @@ edges | examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:5:33:5:35 | key | provenance | | | examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:17:7:19 | key | provenance | | | examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:28:7:30 | key | provenance | | -| examples/PrototypePollutingFunction.js:5:19:5:21 | dst | examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | provenance | | +| examples/PrototypePollutingFunction.js:5:19:5:21 | dst | examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | provenance | Config | | examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | examples/PrototypePollutingFunction.js:1:16:1:18 | dst | provenance | | -| examples/PrototypePollutingFunction.js:5:23:5:25 | key | examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | provenance | | -| examples/PrototypePollutingFunction.js:5:29:5:31 | src | examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | provenance | | +| examples/PrototypePollutingFunction.js:5:23:5:25 | key | examples/PrototypePollutingFunction.js:5:19:5:26 | dst[key] | provenance | Config | +| examples/PrototypePollutingFunction.js:5:29:5:31 | src | examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | provenance | Config | | examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction.js:1:21:1:23 | src | provenance | | -| examples/PrototypePollutingFunction.js:5:33:5:35 | key | examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | provenance | | -| examples/PrototypePollutingFunction.js:7:24:7:26 | src | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | provenance | | -| examples/PrototypePollutingFunction.js:7:28:7:30 | key | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | provenance | | +| examples/PrototypePollutingFunction.js:5:33:5:35 | key | examples/PrototypePollutingFunction.js:5:29:5:36 | src[key] | provenance | Config | +| examples/PrototypePollutingFunction.js:7:24:7:26 | src | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | provenance | Config | +| examples/PrototypePollutingFunction.js:7:28:7:30 | key | examples/PrototypePollutingFunction.js:7:24:7:31 | src[key] | provenance | Config | | examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed2.js:6:29:6:31 | src | provenance | | | examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed2.js:8:24:8:26 | src | provenance | | -| examples/PrototypePollutingFunction_fixed2.js:6:29:6:31 | src | examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | provenance | | +| examples/PrototypePollutingFunction_fixed2.js:6:29:6:31 | src | examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | provenance | Config | | examples/PrototypePollutingFunction_fixed2.js:6:29:6:36 | src[key] | examples/PrototypePollutingFunction_fixed2.js:1:21:1:23 | src | provenance | | -| examples/PrototypePollutingFunction_fixed2.js:8:24:8:26 | src | examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | provenance | | +| examples/PrototypePollutingFunction_fixed2.js:8:24:8:26 | src | examples/PrototypePollutingFunction_fixed2.js:8:24:8:31 | src[key] | provenance | Config | | examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed.js:5:29:5:31 | src | provenance | | | examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | examples/PrototypePollutingFunction_fixed.js:7:24:7:26 | src | provenance | | | examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:17:7:19 | key | provenance | | | examples/PrototypePollutingFunction_fixed.js:2:14:2:16 | key | examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | provenance | | -| examples/PrototypePollutingFunction_fixed.js:5:29:5:31 | src | examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | provenance | | +| examples/PrototypePollutingFunction_fixed.js:5:29:5:31 | src | examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | provenance | Config | | examples/PrototypePollutingFunction_fixed.js:5:29:5:36 | src[key] | examples/PrototypePollutingFunction_fixed.js:1:21:1:23 | src | provenance | | -| examples/PrototypePollutingFunction_fixed.js:7:24:7:26 | src | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | provenance | | -| examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | provenance | | +| examples/PrototypePollutingFunction_fixed.js:7:24:7:26 | src | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | provenance | Config | +| examples/PrototypePollutingFunction_fixed.js:7:28:7:30 | key | examples/PrototypePollutingFunction_fixed.js:7:24:7:31 | src[key] | provenance | Config | | path-assignment.js:8:13:8:25 | key | path-assignment.js:13:29:13:31 | key | provenance | | | path-assignment.js:8:13:8:25 | key | path-assignment.js:15:20:15:22 | key | provenance | | | path-assignment.js:8:19:8:25 | keys[i] | path-assignment.js:8:13:8:25 | key | provenance | | | path-assignment.js:13:13:13:32 | target | path-assignment.js:13:22:13:27 | target | provenance | | | path-assignment.js:13:13:13:32 | target | path-assignment.js:15:13:15:18 | target | provenance | | -| path-assignment.js:13:22:13:27 | target | path-assignment.js:13:22:13:32 | target[key] | provenance | | +| path-assignment.js:13:22:13:27 | target | path-assignment.js:13:22:13:32 | target[key] | provenance | Config | | path-assignment.js:13:22:13:32 | target[key] | path-assignment.js:13:13:13:32 | target | provenance | | -| path-assignment.js:13:29:13:31 | key | path-assignment.js:13:22:13:32 | target[key] | provenance | | +| path-assignment.js:13:29:13:31 | key | path-assignment.js:13:22:13:32 | target[key] | provenance | Config | | path-assignment.js:41:13:41:25 | key | path-assignment.js:42:25:42:27 | key | provenance | | | path-assignment.js:41:13:41:25 | key | path-assignment.js:42:39:42:41 | key | provenance | | | path-assignment.js:41:19:41:25 | keys[i] | path-assignment.js:41:13:41:25 | key | provenance | | | path-assignment.js:42:9:42:48 | target | path-assignment.js:42:18:42:23 | target | provenance | | | path-assignment.js:42:9:42:48 | target | path-assignment.js:42:32:42:37 | target | provenance | | | path-assignment.js:42:9:42:48 | target | path-assignment.js:44:5:44:10 | target | provenance | | -| path-assignment.js:42:32:42:37 | target | path-assignment.js:42:32:42:42 | target[key] | provenance | | +| path-assignment.js:42:32:42:37 | target | path-assignment.js:42:32:42:42 | target[key] | provenance | Config | | path-assignment.js:42:32:42:42 | target[key] | path-assignment.js:42:9:42:48 | target | provenance | | | path-assignment.js:42:32:42:42 | target[key] | path-assignment.js:42:32:42:48 | target[key] \|\| {} | provenance | | -| path-assignment.js:42:39:42:41 | key | path-assignment.js:42:32:42:42 | target[key] | provenance | | +| path-assignment.js:42:39:42:41 | key | path-assignment.js:42:32:42:42 | target[key] | provenance | Config | | path-assignment.js:58:13:58:25 | key | path-assignment.js:59:25:59:27 | key | provenance | | | path-assignment.js:58:13:58:25 | key | path-assignment.js:59:39:59:41 | key | provenance | | | path-assignment.js:58:19:58:25 | keys[i] | path-assignment.js:58:13:58:25 | key | provenance | | | path-assignment.js:59:9:59:48 | target | path-assignment.js:59:18:59:23 | target | provenance | | | path-assignment.js:59:9:59:48 | target | path-assignment.js:59:32:59:37 | target | provenance | | | path-assignment.js:59:9:59:48 | target | path-assignment.js:61:5:61:10 | target | provenance | | -| path-assignment.js:59:32:59:37 | target | path-assignment.js:59:32:59:42 | target[key] | provenance | | +| path-assignment.js:59:32:59:37 | target | path-assignment.js:59:32:59:42 | target[key] | provenance | Config | | path-assignment.js:59:32:59:42 | target[key] | path-assignment.js:59:9:59:48 | target | provenance | | | path-assignment.js:59:32:59:42 | target[key] | path-assignment.js:59:32:59:48 | target[key] \|\| {} | provenance | | -| path-assignment.js:59:39:59:41 | key | path-assignment.js:59:32:59:42 | target[key] | provenance | | +| path-assignment.js:59:39:59:41 | key | path-assignment.js:59:32:59:42 | target[key] | provenance | Config | | path-assignment.js:68:13:68:25 | key | path-assignment.js:69:25:69:27 | key | provenance | | | path-assignment.js:68:13:68:25 | key | path-assignment.js:69:39:69:41 | key | provenance | | | path-assignment.js:68:19:68:25 | keys[i] | path-assignment.js:68:13:68:25 | key | provenance | | | path-assignment.js:69:9:69:48 | target | path-assignment.js:69:18:69:23 | target | provenance | | | path-assignment.js:69:9:69:48 | target | path-assignment.js:69:32:69:37 | target | provenance | | | path-assignment.js:69:9:69:48 | target | path-assignment.js:71:5:71:10 | target | provenance | | -| path-assignment.js:69:32:69:37 | target | path-assignment.js:69:32:69:42 | target[key] | provenance | | +| path-assignment.js:69:32:69:37 | target | path-assignment.js:69:32:69:42 | target[key] | provenance | Config | | path-assignment.js:69:32:69:42 | target[key] | path-assignment.js:69:9:69:48 | target | provenance | | | path-assignment.js:69:32:69:42 | target[key] | path-assignment.js:69:32:69:48 | target[key] \|\| {} | provenance | | -| path-assignment.js:69:39:69:41 | key | path-assignment.js:69:32:69:42 | target[key] | provenance | | +| path-assignment.js:69:39:69:41 | key | path-assignment.js:69:32:69:42 | target[key] | provenance | Config | | tests.js:3:25:3:27 | dst | tests.js:6:28:6:30 | dst | provenance | | | tests.js:3:25:3:27 | dst | tests.js:8:13:8:15 | dst | provenance | | | tests.js:3:30:3:32 | src | tests.js:6:38:6:40 | src | provenance | | @@ -709,14 +709,14 @@ edges | tests.js:4:14:4:16 | key | tests.js:6:42:6:44 | key | provenance | | | tests.js:4:14:4:16 | key | tests.js:8:17:8:19 | key | provenance | | | tests.js:4:14:4:16 | key | tests.js:8:28:8:30 | key | provenance | | -| tests.js:6:28:6:30 | dst | tests.js:6:28:6:35 | dst[key] | provenance | | +| tests.js:6:28:6:30 | dst | tests.js:6:28:6:35 | dst[key] | provenance | Config | | tests.js:6:28:6:35 | dst[key] | tests.js:3:25:3:27 | dst | provenance | | -| tests.js:6:32:6:34 | key | tests.js:6:28:6:35 | dst[key] | provenance | | -| tests.js:6:38:6:40 | src | tests.js:6:38:6:45 | src[key] | provenance | | +| tests.js:6:32:6:34 | key | tests.js:6:28:6:35 | dst[key] | provenance | Config | +| tests.js:6:38:6:40 | src | tests.js:6:38:6:45 | src[key] | provenance | Config | | tests.js:6:38:6:45 | src[key] | tests.js:3:30:3:32 | src | provenance | | -| tests.js:6:42:6:44 | key | tests.js:6:38:6:45 | src[key] | provenance | | -| tests.js:8:24:8:26 | src | tests.js:8:24:8:31 | src[key] | provenance | | -| tests.js:8:28:8:30 | key | tests.js:8:24:8:31 | src[key] | provenance | | +| tests.js:6:42:6:44 | key | tests.js:6:38:6:45 | src[key] | provenance | Config | +| tests.js:8:24:8:26 | src | tests.js:8:24:8:31 | src[key] | provenance | Config | +| tests.js:8:28:8:30 | key | tests.js:8:24:8:31 | src[key] | provenance | Config | | tests.js:13:24:13:26 | dst | tests.js:16:27:16:29 | dst | provenance | | | tests.js:13:24:13:26 | dst | tests.js:18:13:18:15 | dst | provenance | | | tests.js:13:29:13:31 | src | tests.js:14:17:14:19 | src | provenance | | @@ -726,20 +726,20 @@ edges | tests.js:14:30:14:32 | key | tests.js:16:41:16:43 | key | provenance | | | tests.js:14:30:14:32 | key | tests.js:18:17:18:19 | key | provenance | | | tests.js:14:30:14:32 | key | tests.js:18:28:18:30 | key | provenance | | -| tests.js:16:27:16:29 | dst | tests.js:16:27:16:34 | dst[key] | provenance | | +| tests.js:16:27:16:29 | dst | tests.js:16:27:16:34 | dst[key] | provenance | Config | | tests.js:16:27:16:34 | dst[key] | tests.js:13:24:13:26 | dst | provenance | | -| tests.js:16:31:16:33 | key | tests.js:16:27:16:34 | dst[key] | provenance | | -| tests.js:16:37:16:39 | src | tests.js:16:37:16:44 | src[key] | provenance | | +| tests.js:16:31:16:33 | key | tests.js:16:27:16:34 | dst[key] | provenance | Config | +| tests.js:16:37:16:39 | src | tests.js:16:37:16:44 | src[key] | provenance | Config | | tests.js:16:37:16:44 | src[key] | tests.js:13:29:13:31 | src | provenance | | -| tests.js:16:41:16:43 | key | tests.js:16:37:16:44 | src[key] | provenance | | -| tests.js:18:24:18:26 | src | tests.js:18:24:18:31 | src[key] | provenance | | -| tests.js:18:28:18:30 | key | tests.js:18:24:18:31 | src[key] | provenance | | +| tests.js:16:41:16:43 | key | tests.js:16:37:16:44 | src[key] | provenance | Config | +| tests.js:18:24:18:26 | src | tests.js:18:24:18:31 | src[key] | provenance | Config | +| tests.js:18:28:18:30 | key | tests.js:18:24:18:31 | src[key] | provenance | Config | | tests.js:23:19:23:21 | dst | tests.js:26:25:26:27 | dst | provenance | | | tests.js:25:18:25:20 | key | tests.js:26:37:26:39 | key | provenance | | | tests.js:25:18:25:20 | key | tests.js:26:43:26:45 | key | provenance | | | tests.js:26:25:26:27 | dst | tests.js:31:22:31:24 | dst | provenance | | | tests.js:26:30:26:40 | source[key] | tests.js:31:27:31:31 | value | provenance | | -| tests.js:26:37:26:39 | key | tests.js:26:30:26:40 | source[key] | provenance | | +| tests.js:26:37:26:39 | key | tests.js:26:30:26:40 | source[key] | provenance | Config | | tests.js:26:43:26:45 | key | tests.js:31:34:31:36 | key | provenance | | | tests.js:31:22:31:24 | dst | tests.js:32:20:32:22 | dst | provenance | | | tests.js:31:22:31:24 | dst | tests.js:36:9:36:11 | dst | provenance | | @@ -747,9 +747,9 @@ edges | tests.js:31:34:31:36 | key | tests.js:32:24:32:26 | key | provenance | | | tests.js:31:34:31:36 | key | tests.js:36:13:36:15 | key | provenance | | | tests.js:32:9:32:27 | dstValue | tests.js:34:18:34:25 | dstValue | provenance | | -| tests.js:32:20:32:22 | dst | tests.js:32:20:32:27 | dst[key] | provenance | | +| tests.js:32:20:32:22 | dst | tests.js:32:20:32:27 | dst[key] | provenance | Config | | tests.js:32:20:32:27 | dst[key] | tests.js:32:9:32:27 | dstValue | provenance | | -| tests.js:32:24:32:26 | key | tests.js:32:20:32:27 | dst[key] | provenance | | +| tests.js:32:24:32:26 | key | tests.js:32:20:32:27 | dst[key] | provenance | Config | | tests.js:34:18:34:25 | dstValue | tests.js:23:19:23:21 | dst | provenance | | | tests.js:40:27:40:29 | dst | tests.js:44:30:44:32 | dst | provenance | | | tests.js:40:27:40:29 | dst | tests.js:46:13:46:15 | dst | provenance | | @@ -759,14 +759,14 @@ edges | tests.js:41:14:41:16 | key | tests.js:44:44:44:46 | key | provenance | | | tests.js:41:14:41:16 | key | tests.js:46:17:46:19 | key | provenance | | | tests.js:41:14:41:16 | key | tests.js:46:28:46:30 | key | provenance | | -| tests.js:44:30:44:32 | dst | tests.js:44:30:44:37 | dst[key] | provenance | | +| tests.js:44:30:44:32 | dst | tests.js:44:30:44:37 | dst[key] | provenance | Config | | tests.js:44:30:44:37 | dst[key] | tests.js:40:27:40:29 | dst | provenance | | -| tests.js:44:34:44:36 | key | tests.js:44:30:44:37 | dst[key] | provenance | | -| tests.js:44:40:44:42 | src | tests.js:44:40:44:47 | src[key] | provenance | | +| tests.js:44:34:44:36 | key | tests.js:44:30:44:37 | dst[key] | provenance | Config | +| tests.js:44:40:44:42 | src | tests.js:44:40:44:47 | src[key] | provenance | Config | | tests.js:44:40:44:47 | src[key] | tests.js:40:32:40:34 | src | provenance | | -| tests.js:44:44:44:46 | key | tests.js:44:40:44:47 | src[key] | provenance | | -| tests.js:46:24:46:26 | src | tests.js:46:24:46:31 | src[key] | provenance | | -| tests.js:46:28:46:30 | key | tests.js:46:24:46:31 | src[key] | provenance | | +| tests.js:44:44:44:46 | key | tests.js:44:40:44:47 | src[key] | provenance | Config | +| tests.js:46:24:46:26 | src | tests.js:46:24:46:31 | src[key] | provenance | Config | +| tests.js:46:28:46:30 | key | tests.js:46:24:46:31 | src[key] | provenance | Config | | tests.js:51:26:51:28 | dst | tests.js:55:29:55:31 | dst | provenance | | | tests.js:51:26:51:28 | dst | tests.js:57:13:57:15 | dst | provenance | | | tests.js:51:31:51:33 | src | tests.js:55:39:55:41 | src | provenance | | @@ -775,32 +775,32 @@ edges | tests.js:52:14:52:16 | key | tests.js:55:43:55:45 | key | provenance | | | tests.js:52:14:52:16 | key | tests.js:57:17:57:19 | key | provenance | | | tests.js:52:14:52:16 | key | tests.js:57:28:57:30 | key | provenance | | -| tests.js:55:29:55:31 | dst | tests.js:55:29:55:36 | dst[key] | provenance | | +| tests.js:55:29:55:31 | dst | tests.js:55:29:55:36 | dst[key] | provenance | Config | | tests.js:55:29:55:36 | dst[key] | tests.js:51:26:51:28 | dst | provenance | | -| tests.js:55:33:55:35 | key | tests.js:55:29:55:36 | dst[key] | provenance | | -| tests.js:55:39:55:41 | src | tests.js:55:39:55:46 | src[key] | provenance | | +| tests.js:55:33:55:35 | key | tests.js:55:29:55:36 | dst[key] | provenance | Config | +| tests.js:55:39:55:41 | src | tests.js:55:39:55:46 | src[key] | provenance | Config | | tests.js:55:39:55:46 | src[key] | tests.js:51:31:51:33 | src | provenance | | -| tests.js:55:43:55:45 | key | tests.js:55:39:55:46 | src[key] | provenance | | -| tests.js:57:24:57:26 | src | tests.js:57:24:57:31 | src[key] | provenance | | -| tests.js:57:28:57:30 | key | tests.js:57:24:57:31 | src[key] | provenance | | +| tests.js:55:43:55:45 | key | tests.js:55:39:55:46 | src[key] | provenance | Config | +| tests.js:57:24:57:26 | src | tests.js:57:24:57:31 | src[key] | provenance | Config | +| tests.js:57:28:57:30 | key | tests.js:57:24:57:31 | src[key] | provenance | Config | | tests.js:62:33:62:35 | src | tests.js:66:41:66:43 | src | provenance | | | tests.js:62:33:62:35 | src | tests.js:68:24:68:26 | src | provenance | | -| tests.js:66:41:66:43 | src | tests.js:66:41:66:48 | src[key] | provenance | | +| tests.js:66:41:66:43 | src | tests.js:66:41:66:48 | src[key] | provenance | Config | | tests.js:66:41:66:48 | src[key] | tests.js:62:33:62:35 | src | provenance | | -| tests.js:68:24:68:26 | src | tests.js:68:24:68:31 | src[key] | provenance | | +| tests.js:68:24:68:26 | src | tests.js:68:24:68:31 | src[key] | provenance | Config | | tests.js:77:27:77:29 | src | tests.js:81:39:81:41 | src | provenance | | | tests.js:77:27:77:29 | src | tests.js:83:28:83:30 | src | provenance | | -| tests.js:81:39:81:41 | src | tests.js:81:39:81:46 | src[key] | provenance | | +| tests.js:81:39:81:41 | src | tests.js:81:39:81:46 | src[key] | provenance | Config | | tests.js:81:39:81:46 | src[key] | tests.js:77:27:77:29 | src | provenance | | -| tests.js:83:28:83:30 | src | tests.js:83:28:83:35 | src[key] | provenance | | +| tests.js:83:28:83:30 | src | tests.js:83:28:83:35 | src[key] | provenance | Config | | tests.js:89:34:89:36 | src | tests.js:94:42:94:44 | src | provenance | | | tests.js:89:34:89:36 | src | tests.js:96:24:96:26 | src | provenance | | | tests.js:90:14:90:16 | key | tests.js:96:17:96:19 | key | provenance | | | tests.js:90:14:90:16 | key | tests.js:96:28:96:30 | key | provenance | | -| tests.js:94:42:94:44 | src | tests.js:94:42:94:49 | src[key] | provenance | | +| tests.js:94:42:94:44 | src | tests.js:94:42:94:49 | src[key] | provenance | Config | | tests.js:94:42:94:49 | src[key] | tests.js:89:34:89:36 | src | provenance | | -| tests.js:96:24:96:26 | src | tests.js:96:24:96:31 | src[key] | provenance | | -| tests.js:96:28:96:30 | key | tests.js:96:24:96:31 | src[key] | provenance | | +| tests.js:96:24:96:26 | src | tests.js:96:24:96:31 | src[key] | provenance | Config | +| tests.js:96:28:96:30 | key | tests.js:96:24:96:31 | src[key] | provenance | Config | | tests.js:101:32:101:34 | dst | tests.js:107:35:107:37 | dst | provenance | | | tests.js:101:32:101:34 | dst | tests.js:109:13:109:15 | dst | provenance | | | tests.js:101:37:101:39 | src | tests.js:107:45:107:47 | src | provenance | | @@ -809,22 +809,22 @@ edges | tests.js:102:14:102:16 | key | tests.js:107:49:107:51 | key | provenance | | | tests.js:102:14:102:16 | key | tests.js:109:17:109:19 | key | provenance | | | tests.js:102:14:102:16 | key | tests.js:109:28:109:30 | key | provenance | | -| tests.js:107:35:107:37 | dst | tests.js:107:35:107:42 | dst[key] | provenance | | +| tests.js:107:35:107:37 | dst | tests.js:107:35:107:42 | dst[key] | provenance | Config | | tests.js:107:35:107:42 | dst[key] | tests.js:101:32:101:34 | dst | provenance | | -| tests.js:107:39:107:41 | key | tests.js:107:35:107:42 | dst[key] | provenance | | -| tests.js:107:45:107:47 | src | tests.js:107:45:107:52 | src[key] | provenance | | +| tests.js:107:39:107:41 | key | tests.js:107:35:107:42 | dst[key] | provenance | Config | +| tests.js:107:45:107:47 | src | tests.js:107:45:107:52 | src[key] | provenance | Config | | tests.js:107:45:107:52 | src[key] | tests.js:101:37:101:39 | src | provenance | | -| tests.js:107:49:107:51 | key | tests.js:107:45:107:52 | src[key] | provenance | | -| tests.js:109:24:109:26 | src | tests.js:109:24:109:31 | src[key] | provenance | | -| tests.js:109:28:109:30 | key | tests.js:109:24:109:31 | src[key] | provenance | | +| tests.js:107:49:107:51 | key | tests.js:107:45:107:52 | src[key] | provenance | Config | +| tests.js:109:24:109:26 | src | tests.js:109:24:109:31 | src[key] | provenance | Config | +| tests.js:109:28:109:30 | key | tests.js:109:24:109:31 | src[key] | provenance | Config | | tests.js:116:41:116:43 | src | tests.js:119:49:119:51 | src | provenance | | | tests.js:116:41:116:43 | src | tests.js:121:24:121:26 | src | provenance | | | tests.js:117:14:117:16 | key | tests.js:121:17:121:19 | key | provenance | | | tests.js:117:14:117:16 | key | tests.js:121:28:121:30 | key | provenance | | -| tests.js:119:49:119:51 | src | tests.js:119:49:119:56 | src[key] | provenance | | +| tests.js:119:49:119:51 | src | tests.js:119:49:119:56 | src[key] | provenance | Config | | tests.js:119:49:119:56 | src[key] | tests.js:116:41:116:43 | src | provenance | | -| tests.js:121:24:121:26 | src | tests.js:121:24:121:31 | src[key] | provenance | | -| tests.js:121:28:121:30 | key | tests.js:121:24:121:31 | src[key] | provenance | | +| tests.js:121:24:121:26 | src | tests.js:121:24:121:31 | src[key] | provenance | Config | +| tests.js:121:28:121:30 | key | tests.js:121:24:121:31 | src[key] | provenance | Config | | tests.js:149:31:149:33 | dst | tests.js:152:22:152:24 | dst | provenance | | | tests.js:149:31:149:33 | dst | tests.js:154:13:154:15 | dst | provenance | | | tests.js:149:36:149:38 | src | tests.js:152:27:152:29 | src | provenance | | @@ -835,8 +835,8 @@ edges | tests.js:152:22:152:24 | dst | tests.js:160:37:160:39 | dst | provenance | | | tests.js:152:27:152:29 | src | tests.js:160:42:160:44 | src | provenance | | | tests.js:152:32:152:34 | key | tests.js:160:47:160:49 | key | provenance | | -| tests.js:154:24:154:26 | src | tests.js:154:24:154:31 | src[key] | provenance | | -| tests.js:154:28:154:30 | key | tests.js:154:24:154:31 | src[key] | provenance | | +| tests.js:154:24:154:26 | src | tests.js:154:24:154:31 | src[key] | provenance | Config | +| tests.js:154:28:154:30 | key | tests.js:154:24:154:31 | src[key] | provenance | Config | | tests.js:159:36:159:38 | dst | tests.js:160:26:160:28 | dst | provenance | | | tests.js:159:41:159:43 | src | tests.js:160:31:160:33 | src | provenance | | | tests.js:160:26:160:28 | dst | tests.js:149:31:149:33 | dst | provenance | | @@ -845,27 +845,27 @@ edges | tests.js:160:42:160:44 | src | tests.js:161:45:161:47 | src | provenance | | | tests.js:160:47:160:49 | key | tests.js:161:39:161:41 | key | provenance | | | tests.js:160:47:160:49 | key | tests.js:161:49:161:51 | key | provenance | | -| tests.js:161:35:161:37 | dst | tests.js:161:35:161:42 | dst[key] | provenance | | +| tests.js:161:35:161:37 | dst | tests.js:161:35:161:42 | dst[key] | provenance | Config | | tests.js:161:35:161:42 | dst[key] | tests.js:159:36:159:38 | dst | provenance | | -| tests.js:161:39:161:41 | key | tests.js:161:35:161:42 | dst[key] | provenance | | -| tests.js:161:45:161:47 | src | tests.js:161:45:161:52 | src[key] | provenance | | +| tests.js:161:39:161:41 | key | tests.js:161:35:161:42 | dst[key] | provenance | Config | +| tests.js:161:45:161:47 | src | tests.js:161:45:161:52 | src[key] | provenance | Config | | tests.js:161:45:161:52 | src[key] | tests.js:159:41:159:43 | src | provenance | | -| tests.js:161:49:161:51 | key | tests.js:161:45:161:52 | src[key] | provenance | | +| tests.js:161:49:161:51 | key | tests.js:161:45:161:52 | src[key] | provenance | Config | | tests.js:165:37:165:39 | src | tests.js:169:45:169:47 | src | provenance | | | tests.js:165:37:165:39 | src | tests.js:171:24:171:26 | src | provenance | | | tests.js:166:14:166:16 | key | tests.js:169:49:169:51 | key | provenance | | | tests.js:166:14:166:16 | key | tests.js:171:17:171:19 | key | provenance | | | tests.js:166:14:166:16 | key | tests.js:171:28:171:30 | key | provenance | | -| tests.js:169:45:169:47 | src | tests.js:169:45:169:52 | src[key] | provenance | | +| tests.js:169:45:169:47 | src | tests.js:169:45:169:52 | src[key] | provenance | Config | | tests.js:169:45:169:52 | src[key] | tests.js:165:37:165:39 | src | provenance | | -| tests.js:169:49:169:51 | key | tests.js:169:45:169:52 | src[key] | provenance | | -| tests.js:171:24:171:26 | src | tests.js:171:24:171:31 | src[key] | provenance | | -| tests.js:171:28:171:30 | key | tests.js:171:24:171:31 | src[key] | provenance | | +| tests.js:169:49:169:51 | key | tests.js:169:45:169:52 | src[key] | provenance | Config | +| tests.js:171:24:171:26 | src | tests.js:171:24:171:31 | src[key] | provenance | Config | +| tests.js:171:28:171:30 | key | tests.js:171:24:171:31 | src[key] | provenance | Config | | tests.js:178:33:178:35 | src | tests.js:182:41:182:43 | src | provenance | | | tests.js:178:33:178:35 | src | tests.js:184:24:184:26 | src | provenance | | -| tests.js:182:41:182:43 | src | tests.js:182:41:182:48 | src[key] | provenance | | +| tests.js:182:41:182:43 | src | tests.js:182:41:182:48 | src[key] | provenance | Config | | tests.js:182:41:182:48 | src[key] | tests.js:178:33:178:35 | src | provenance | | -| tests.js:184:24:184:26 | src | tests.js:184:24:184:31 | src[key] | provenance | | +| tests.js:184:24:184:26 | src | tests.js:184:24:184:31 | src[key] | provenance | Config | | tests.js:189:32:189:34 | dst | tests.js:194:35:194:37 | dst | provenance | | | tests.js:189:32:189:34 | dst | tests.js:196:13:196:15 | dst | provenance | | | tests.js:189:37:189:39 | src | tests.js:194:45:194:47 | src | provenance | | @@ -875,54 +875,54 @@ edges | tests.js:192:13:192:25 | key | tests.js:196:17:196:19 | key | provenance | | | tests.js:192:13:192:25 | key | tests.js:196:28:196:30 | key | provenance | | | tests.js:192:19:192:25 | keys[i] | tests.js:192:13:192:25 | key | provenance | | -| tests.js:194:35:194:37 | dst | tests.js:194:35:194:42 | dst[key] | provenance | | +| tests.js:194:35:194:37 | dst | tests.js:194:35:194:42 | dst[key] | provenance | Config | | tests.js:194:35:194:42 | dst[key] | tests.js:189:32:189:34 | dst | provenance | | -| tests.js:194:39:194:41 | key | tests.js:194:35:194:42 | dst[key] | provenance | | -| tests.js:194:45:194:47 | src | tests.js:194:45:194:52 | src[key] | provenance | | +| tests.js:194:39:194:41 | key | tests.js:194:35:194:42 | dst[key] | provenance | Config | +| tests.js:194:45:194:47 | src | tests.js:194:45:194:52 | src[key] | provenance | Config | | tests.js:194:45:194:52 | src[key] | tests.js:189:37:189:39 | src | provenance | | -| tests.js:194:49:194:51 | key | tests.js:194:45:194:52 | src[key] | provenance | | -| tests.js:196:24:196:26 | src | tests.js:196:24:196:31 | src[key] | provenance | | -| tests.js:196:28:196:30 | key | tests.js:196:24:196:31 | src[key] | provenance | | +| tests.js:194:49:194:51 | key | tests.js:194:45:194:52 | src[key] | provenance | Config | +| tests.js:196:24:196:26 | src | tests.js:196:24:196:31 | src[key] | provenance | Config | +| tests.js:196:28:196:30 | key | tests.js:196:24:196:31 | src[key] | provenance | Config | | tests.js:201:39:201:41 | dst | tests.js:206:42:206:44 | dst | provenance | | | tests.js:201:39:201:41 | dst | tests.js:208:13:208:15 | dst | provenance | | | tests.js:201:44:201:46 | src | tests.js:206:56:206:58 | src | provenance | | | tests.js:201:44:201:46 | src | tests.js:208:28:208:30 | src | provenance | | -| tests.js:206:42:206:44 | dst | tests.js:206:42:206:53 | dst[keys[i]] | provenance | | +| tests.js:206:42:206:44 | dst | tests.js:206:42:206:53 | dst[keys[i]] | provenance | Config | | tests.js:206:42:206:53 | dst[keys[i]] | tests.js:201:39:201:41 | dst | provenance | | -| tests.js:206:46:206:52 | keys[i] | tests.js:206:42:206:53 | dst[keys[i]] | provenance | | -| tests.js:206:56:206:58 | src | tests.js:206:56:206:67 | src[keys[i]] | provenance | | +| tests.js:206:46:206:52 | keys[i] | tests.js:206:42:206:53 | dst[keys[i]] | provenance | Config | +| tests.js:206:56:206:58 | src | tests.js:206:56:206:67 | src[keys[i]] | provenance | Config | | tests.js:206:56:206:67 | src[keys[i]] | tests.js:201:44:201:46 | src | provenance | | -| tests.js:206:60:206:66 | keys[i] | tests.js:206:56:206:67 | src[keys[i]] | provenance | | -| tests.js:208:28:208:30 | src | tests.js:208:28:208:39 | src[keys[i]] | provenance | | -| tests.js:208:32:208:38 | keys[i] | tests.js:208:28:208:39 | src[keys[i]] | provenance | | +| tests.js:206:60:206:66 | keys[i] | tests.js:206:56:206:67 | src[keys[i]] | provenance | Config | +| tests.js:208:28:208:30 | src | tests.js:208:28:208:39 | src[keys[i]] | provenance | Config | +| tests.js:208:32:208:38 | keys[i] | tests.js:208:28:208:39 | src[keys[i]] | provenance | Config | | tests.js:213:23:213:26 | key1 | tests.js:217:9:217:12 | key1 | provenance | | | tests.js:213:29:213:32 | key2 | tests.js:217:15:217:18 | key2 | provenance | | | tests.js:213:35:213:39 | value | tests.js:217:23:217:27 | value | provenance | | -| tests.js:217:9:217:12 | key1 | tests.js:217:5:217:13 | map[key1] | provenance | | +| tests.js:217:9:217:12 | key1 | tests.js:217:5:217:13 | map[key1] | provenance | Config | | tests.js:223:14:223:16 | key | tests.js:224:23:224:25 | key | provenance | | | tests.js:223:14:223:16 | key | tests.js:224:38:224:40 | key | provenance | | | tests.js:223:14:223:16 | key | tests.js:225:28:225:30 | key | provenance | | | tests.js:223:14:223:16 | key | tests.js:225:38:225:40 | key | provenance | | | tests.js:224:23:224:25 | key | tests.js:213:23:213:26 | key1 | provenance | | | tests.js:224:33:224:41 | data[key] | tests.js:213:35:213:39 | value | provenance | | -| tests.js:224:38:224:40 | key | tests.js:224:33:224:41 | data[key] | provenance | | +| tests.js:224:38:224:40 | key | tests.js:224:33:224:41 | data[key] | provenance | Config | | tests.js:225:28:225:30 | key | tests.js:213:29:213:32 | key2 | provenance | | | tests.js:225:33:225:41 | data[key] | tests.js:213:35:213:39 | value | provenance | | -| tests.js:225:38:225:40 | key | tests.js:225:33:225:41 | data[key] | provenance | | +| tests.js:225:38:225:40 | key | tests.js:225:33:225:41 | data[key] | provenance | Config | | tests.js:229:26:229:29 | key1 | tests.js:233:9:233:12 | key1 | provenance | | | tests.js:229:32:229:35 | key2 | tests.js:233:15:233:18 | key2 | provenance | | | tests.js:229:38:229:42 | value | tests.js:233:23:233:27 | value | provenance | | -| tests.js:233:9:233:12 | key1 | tests.js:233:5:233:13 | map[key1] | provenance | | +| tests.js:233:9:233:12 | key1 | tests.js:233:5:233:13 | map[key1] | provenance | Config | | tests.js:238:14:238:16 | key | tests.js:239:24:239:26 | key | provenance | | | tests.js:238:14:238:16 | key | tests.js:239:39:239:41 | key | provenance | | | tests.js:238:14:238:16 | key | tests.js:240:31:240:33 | key | provenance | | | tests.js:238:14:238:16 | key | tests.js:240:41:240:43 | key | provenance | | | tests.js:239:24:239:26 | key | tests.js:229:26:229:29 | key1 | provenance | | | tests.js:239:34:239:42 | data[key] | tests.js:229:38:229:42 | value | provenance | | -| tests.js:239:39:239:41 | key | tests.js:239:34:239:42 | data[key] | provenance | | +| tests.js:239:39:239:41 | key | tests.js:239:34:239:42 | data[key] | provenance | Config | | tests.js:240:31:240:33 | key | tests.js:229:32:229:35 | key2 | provenance | | | tests.js:240:36:240:44 | data[key] | tests.js:229:38:229:42 | value | provenance | | -| tests.js:240:41:240:43 | key | tests.js:240:36:240:44 | data[key] | provenance | | +| tests.js:240:41:240:43 | key | tests.js:240:36:240:44 | data[key] | provenance | Config | | tests.js:263:27:263:29 | dst | tests.js:268:30:268:32 | dst | provenance | | | tests.js:263:27:263:29 | dst | tests.js:270:13:270:15 | dst | provenance | | | tests.js:265:13:265:26 | key | tests.js:268:34:268:36 | key | provenance | | @@ -930,9 +930,9 @@ edges | tests.js:265:19:265:26 | entry[0] | tests.js:265:13:265:26 | key | provenance | | | tests.js:266:13:266:28 | value | tests.js:270:24:270:28 | value | provenance | | | tests.js:266:21:266:28 | entry[1] | tests.js:266:13:266:28 | value | provenance | | -| tests.js:268:30:268:32 | dst | tests.js:268:30:268:37 | dst[key] | provenance | | +| tests.js:268:30:268:32 | dst | tests.js:268:30:268:37 | dst[key] | provenance | Config | | tests.js:268:30:268:37 | dst[key] | tests.js:263:27:263:29 | dst | provenance | | -| tests.js:268:34:268:36 | key | tests.js:268:30:268:37 | dst[key] | provenance | | +| tests.js:268:34:268:36 | key | tests.js:268:30:268:37 | dst[key] | provenance | Config | | tests.js:275:27:275:29 | dst | tests.js:278:30:278:32 | dst | provenance | | | tests.js:275:27:275:29 | dst | tests.js:280:13:280:15 | dst | provenance | | | tests.js:275:32:275:34 | src | tests.js:276:21:276:23 | src | provenance | | @@ -942,14 +942,14 @@ edges | tests.js:276:34:276:36 | key | tests.js:278:44:278:46 | key | provenance | | | tests.js:276:34:276:36 | key | tests.js:280:17:280:19 | key | provenance | | | tests.js:276:34:276:36 | key | tests.js:280:28:280:30 | key | provenance | | -| tests.js:278:30:278:32 | dst | tests.js:278:30:278:37 | dst[key] | provenance | | +| tests.js:278:30:278:32 | dst | tests.js:278:30:278:37 | dst[key] | provenance | Config | | tests.js:278:30:278:37 | dst[key] | tests.js:275:27:275:29 | dst | provenance | | -| tests.js:278:34:278:36 | key | tests.js:278:30:278:37 | dst[key] | provenance | | -| tests.js:278:40:278:42 | src | tests.js:278:40:278:47 | src[key] | provenance | | +| tests.js:278:34:278:36 | key | tests.js:278:30:278:37 | dst[key] | provenance | Config | +| tests.js:278:40:278:42 | src | tests.js:278:40:278:47 | src[key] | provenance | Config | | tests.js:278:40:278:47 | src[key] | tests.js:275:32:275:34 | src | provenance | | -| tests.js:278:44:278:46 | key | tests.js:278:40:278:47 | src[key] | provenance | | -| tests.js:280:24:280:26 | src | tests.js:280:24:280:31 | src[key] | provenance | | -| tests.js:280:28:280:30 | key | tests.js:280:24:280:31 | src[key] | provenance | | +| tests.js:278:44:278:46 | key | tests.js:278:40:278:47 | src[key] | provenance | Config | +| tests.js:280:24:280:26 | src | tests.js:280:24:280:31 | src[key] | provenance | Config | +| tests.js:280:28:280:30 | key | tests.js:280:24:280:31 | src[key] | provenance | Config | | tests.js:301:27:301:29 | dst | tests.js:306:34:306:36 | dst | provenance | | | tests.js:301:27:301:29 | dst | tests.js:308:17:308:19 | dst | provenance | | | tests.js:301:32:301:34 | src | tests.js:304:25:304:27 | src | provenance | | @@ -961,15 +961,15 @@ edges | tests.js:304:17:304:32 | value | tests.js:308:28:308:32 | value | provenance | | | tests.js:304:17:304:32 | value | tests.js:308:28:308:32 | value | provenance | | | tests.js:304:17:304:32 | value | tests.js:308:28:308:32 | value | provenance | | -| tests.js:304:25:304:27 | src | tests.js:304:25:304:32 | src[key] | provenance | | +| tests.js:304:25:304:27 | src | tests.js:304:25:304:32 | src[key] | provenance | Config | | tests.js:304:25:304:32 | src[key] | tests.js:304:17:304:32 | value | provenance | | | tests.js:304:25:304:32 | src[key] | tests.js:304:17:304:32 | value | provenance | | | tests.js:304:25:304:32 | src[key] | tests.js:304:17:304:32 | value | provenance | | -| tests.js:304:29:304:31 | key | tests.js:304:25:304:32 | src[key] | provenance | | -| tests.js:304:29:304:31 | key | tests.js:304:25:304:32 | src[key] | provenance | | -| tests.js:306:34:306:36 | dst | tests.js:306:34:306:41 | dst[key] | provenance | | +| tests.js:304:29:304:31 | key | tests.js:304:25:304:32 | src[key] | provenance | Config | +| tests.js:304:29:304:31 | key | tests.js:304:25:304:32 | src[key] | provenance | Config | +| tests.js:306:34:306:36 | dst | tests.js:306:34:306:41 | dst[key] | provenance | Config | | tests.js:306:34:306:41 | dst[key] | tests.js:301:27:301:29 | dst | provenance | | -| tests.js:306:38:306:40 | key | tests.js:306:34:306:41 | dst[key] | provenance | | +| tests.js:306:38:306:40 | key | tests.js:306:34:306:41 | dst[key] | provenance | Config | | tests.js:306:44:306:48 | value | tests.js:301:32:301:34 | src | provenance | | | tests.js:306:44:306:48 | value | tests.js:301:32:301:34 | src | provenance | | | tests.js:314:31:314:33 | dst | tests.js:320:38:320:40 | dst | provenance | | @@ -983,15 +983,15 @@ edges | tests.js:318:17:318:32 | value | tests.js:322:28:322:32 | value | provenance | | | tests.js:318:17:318:32 | value | tests.js:322:28:322:32 | value | provenance | | | tests.js:318:17:318:32 | value | tests.js:322:28:322:32 | value | provenance | | -| tests.js:318:25:318:27 | src | tests.js:318:25:318:32 | src[key] | provenance | | +| tests.js:318:25:318:27 | src | tests.js:318:25:318:32 | src[key] | provenance | Config | | tests.js:318:25:318:32 | src[key] | tests.js:318:17:318:32 | value | provenance | | | tests.js:318:25:318:32 | src[key] | tests.js:318:17:318:32 | value | provenance | | | tests.js:318:25:318:32 | src[key] | tests.js:318:17:318:32 | value | provenance | | -| tests.js:318:29:318:31 | key | tests.js:318:25:318:32 | src[key] | provenance | | -| tests.js:318:29:318:31 | key | tests.js:318:25:318:32 | src[key] | provenance | | -| tests.js:320:38:320:40 | dst | tests.js:320:38:320:45 | dst[key] | provenance | | +| tests.js:318:29:318:31 | key | tests.js:318:25:318:32 | src[key] | provenance | Config | +| tests.js:318:29:318:31 | key | tests.js:318:25:318:32 | src[key] | provenance | Config | +| tests.js:320:38:320:40 | dst | tests.js:320:38:320:45 | dst[key] | provenance | Config | | tests.js:320:38:320:45 | dst[key] | tests.js:314:31:314:33 | dst | provenance | | -| tests.js:320:42:320:44 | key | tests.js:320:38:320:45 | dst[key] | provenance | | +| tests.js:320:42:320:44 | key | tests.js:320:38:320:45 | dst[key] | provenance | Config | | tests.js:320:48:320:52 | value | tests.js:314:36:314:38 | src | provenance | | | tests.js:320:48:320:52 | value | tests.js:314:36:314:38 | src | provenance | | | tests.js:328:25:328:27 | dst | tests.js:336:32:336:34 | dst | provenance | | @@ -1002,14 +1002,14 @@ edges | tests.js:329:14:329:16 | key | tests.js:336:46:336:48 | key | provenance | | | tests.js:329:14:329:16 | key | tests.js:338:21:338:23 | key | provenance | | | tests.js:329:14:329:16 | key | tests.js:338:32:338:34 | key | provenance | | -| tests.js:336:32:336:34 | dst | tests.js:336:32:336:39 | dst[key] | provenance | | +| tests.js:336:32:336:34 | dst | tests.js:336:32:336:39 | dst[key] | provenance | Config | | tests.js:336:32:336:39 | dst[key] | tests.js:328:25:328:27 | dst | provenance | | -| tests.js:336:36:336:38 | key | tests.js:336:32:336:39 | dst[key] | provenance | | -| tests.js:336:42:336:44 | src | tests.js:336:42:336:49 | src[key] | provenance | | +| tests.js:336:36:336:38 | key | tests.js:336:32:336:39 | dst[key] | provenance | Config | +| tests.js:336:42:336:44 | src | tests.js:336:42:336:49 | src[key] | provenance | Config | | tests.js:336:42:336:49 | src[key] | tests.js:328:30:328:32 | src | provenance | | -| tests.js:336:46:336:48 | key | tests.js:336:42:336:49 | src[key] | provenance | | -| tests.js:338:28:338:30 | src | tests.js:338:28:338:35 | src[key] | provenance | | -| tests.js:338:32:338:34 | key | tests.js:338:28:338:35 | src[key] | provenance | | +| tests.js:336:46:336:48 | key | tests.js:336:42:336:49 | src[key] | provenance | Config | +| tests.js:338:28:338:30 | src | tests.js:338:28:338:35 | src[key] | provenance | Config | +| tests.js:338:32:338:34 | key | tests.js:338:28:338:35 | src[key] | provenance | Config | | tests.js:348:32:348:37 | target | tests.js:349:26:349:31 | target | provenance | | | tests.js:348:32:348:37 | target | tests.js:361:12:361:17 | target | provenance | | | tests.js:348:40:348:45 | source | tests.js:349:54:349:59 | source | provenance | | @@ -1025,14 +1025,14 @@ edges | tests.js:350:37:350:39 | key | tests.js:355:60:355:62 | key | provenance | | | tests.js:350:37:350:39 | key | tests.js:357:24:357:26 | key | provenance | | | tests.js:350:37:350:39 | key | tests.js:357:38:357:40 | key | provenance | | -| tests.js:355:53:355:58 | target | tests.js:355:53:355:63 | target[key] | provenance | | +| tests.js:355:53:355:58 | target | tests.js:355:53:355:63 | target[key] | provenance | Config | | tests.js:355:53:355:63 | target[key] | tests.js:348:32:348:37 | target | provenance | | | tests.js:355:53:355:63 | target[key] | tests.js:355:31:355:86 | mergePl ... ptions) | provenance | | -| tests.js:355:60:355:62 | key | tests.js:355:53:355:63 | target[key] | provenance | | -| tests.js:355:66:355:71 | source | tests.js:355:66:355:76 | source[key] | provenance | | +| tests.js:355:60:355:62 | key | tests.js:355:53:355:63 | target[key] | provenance | Config | +| tests.js:355:66:355:71 | source | tests.js:355:66:355:76 | source[key] | provenance | Config | | tests.js:355:66:355:76 | source[key] | tests.js:348:40:348:45 | source | provenance | | -| tests.js:357:31:357:36 | source | tests.js:357:31:357:41 | source[key] | provenance | | -| tests.js:357:38:357:40 | key | tests.js:357:31:357:41 | source[key] | provenance | | +| tests.js:357:31:357:36 | source | tests.js:357:31:357:41 | source[key] | provenance | Config | +| tests.js:357:38:357:40 | key | tests.js:357:31:357:41 | source[key] | provenance | Config | | tests.js:364:41:364:46 | target | tests.js:377:12:377:17 | target | provenance | | | tests.js:364:49:364:54 | source | tests.js:371:75:371:80 | source | provenance | | | tests.js:364:49:364:54 | source | tests.js:373:31:373:36 | source | provenance | | @@ -1042,11 +1042,11 @@ edges | tests.js:366:18:366:20 | key | tests.js:373:38:373:40 | key | provenance | | | tests.js:371:62:371:72 | target[key] | tests.js:364:41:364:46 | target | provenance | | | tests.js:371:62:371:72 | target[key] | tests.js:371:31:371:95 | mergePl ... ptions) | provenance | | -| tests.js:371:69:371:71 | key | tests.js:371:62:371:72 | target[key] | provenance | | -| tests.js:371:75:371:80 | source | tests.js:371:75:371:85 | source[key] | provenance | | +| tests.js:371:69:371:71 | key | tests.js:371:62:371:72 | target[key] | provenance | Config | +| tests.js:371:75:371:80 | source | tests.js:371:75:371:85 | source[key] | provenance | Config | | tests.js:371:75:371:85 | source[key] | tests.js:364:49:364:54 | source | provenance | | -| tests.js:373:31:373:36 | source | tests.js:373:31:373:41 | source[key] | provenance | | -| tests.js:373:38:373:40 | key | tests.js:373:31:373:41 | source[key] | provenance | | +| tests.js:373:31:373:36 | source | tests.js:373:31:373:41 | source[key] | provenance | Config | +| tests.js:373:38:373:40 | key | tests.js:373:31:373:41 | source[key] | provenance | Config | | tests.js:380:22:380:24 | obj | tests.js:383:27:383:29 | obj | provenance | | | tests.js:380:27:380:34 | callback [dst] | tests.js:383:13:383:20 | callback [dst] | provenance | | | tests.js:380:27:380:34 | callback [dst] | tests.js:383:13:383:20 | callback [dst] | provenance | | @@ -1067,9 +1067,9 @@ edges | tests.js:383:13:383:20 | callback [src] | tests.js:393:24:393:26 | src | provenance | | | tests.js:383:22:383:24 | key | tests.js:389:22:389:24 | key | provenance | | | tests.js:383:22:383:24 | key | tests.js:399:23:399:25 | key | provenance | | -| tests.js:383:27:383:29 | obj | tests.js:383:27:383:34 | obj[key] | provenance | | +| tests.js:383:27:383:29 | obj | tests.js:383:27:383:34 | obj[key] | provenance | Config | | tests.js:383:27:383:34 | obj[key] | tests.js:399:28:399:32 | value | provenance | | -| tests.js:383:31:383:33 | key | tests.js:383:27:383:34 | obj[key] | provenance | | +| tests.js:383:31:383:33 | key | tests.js:383:27:383:34 | obj[key] | provenance | Config | | tests.js:388:29:388:31 | dst | tests.js:380:27:380:34 | callback [dst] | provenance | | | tests.js:388:29:388:31 | dst | tests.js:380:27:380:34 | callback [dst] | provenance | | | tests.js:388:29:388:31 | dst | tests.js:391:32:391:34 | dst | provenance | | @@ -1084,17 +1084,17 @@ edges | tests.js:389:22:389:24 | key | tests.js:391:46:391:48 | key | provenance | | | tests.js:389:22:389:24 | key | tests.js:393:17:393:19 | key | provenance | | | tests.js:389:22:389:24 | key | tests.js:393:28:393:30 | key | provenance | | -| tests.js:391:32:391:34 | dst | tests.js:391:32:391:39 | dst[key] | provenance | | -| tests.js:391:32:391:34 | dst | tests.js:391:32:391:39 | dst[key] | provenance | | +| tests.js:391:32:391:34 | dst | tests.js:391:32:391:39 | dst[key] | provenance | Config | +| tests.js:391:32:391:34 | dst | tests.js:391:32:391:39 | dst[key] | provenance | Config | | tests.js:391:32:391:39 | dst[key] | tests.js:388:29:388:31 | dst | provenance | | | tests.js:391:32:391:39 | dst[key] | tests.js:388:29:388:31 | dst | provenance | | -| tests.js:391:36:391:38 | key | tests.js:391:32:391:39 | dst[key] | provenance | | -| tests.js:391:36:391:38 | key | tests.js:391:32:391:39 | dst[key] | provenance | | -| tests.js:391:42:391:44 | src | tests.js:391:42:391:49 | src[key] | provenance | | +| tests.js:391:36:391:38 | key | tests.js:391:32:391:39 | dst[key] | provenance | Config | +| tests.js:391:36:391:38 | key | tests.js:391:32:391:39 | dst[key] | provenance | Config | +| tests.js:391:42:391:44 | src | tests.js:391:42:391:49 | src[key] | provenance | Config | | tests.js:391:42:391:49 | src[key] | tests.js:388:34:388:36 | src | provenance | | -| tests.js:391:46:391:48 | key | tests.js:391:42:391:49 | src[key] | provenance | | -| tests.js:393:24:393:26 | src | tests.js:393:24:393:31 | src[key] | provenance | | -| tests.js:393:28:393:30 | key | tests.js:393:24:393:31 | src[key] | provenance | | +| tests.js:391:46:391:48 | key | tests.js:391:42:391:49 | src[key] | provenance | Config | +| tests.js:393:24:393:26 | src | tests.js:393:24:393:31 | src[key] | provenance | Config | +| tests.js:393:28:393:30 | key | tests.js:393:24:393:31 | src[key] | provenance | Config | | tests.js:398:30:398:32 | dst | tests.js:380:27:380:34 | callback [dst] | provenance | | | tests.js:398:30:398:32 | dst | tests.js:380:27:380:34 | callback [dst] | provenance | | | tests.js:398:30:398:32 | dst | tests.js:401:33:401:35 | dst | provenance | | @@ -1107,17 +1107,17 @@ edges | tests.js:399:23:399:25 | key | tests.js:403:17:403:19 | key | provenance | | | tests.js:399:28:399:32 | value | tests.js:401:43:401:47 | value | provenance | | | tests.js:399:28:399:32 | value | tests.js:403:24:403:28 | value | provenance | | -| tests.js:401:33:401:35 | dst | tests.js:401:33:401:40 | dst[key] | provenance | | -| tests.js:401:33:401:35 | dst | tests.js:401:33:401:40 | dst[key] | provenance | | +| tests.js:401:33:401:35 | dst | tests.js:401:33:401:40 | dst[key] | provenance | Config | +| tests.js:401:33:401:35 | dst | tests.js:401:33:401:40 | dst[key] | provenance | Config | | tests.js:401:33:401:40 | dst[key] | tests.js:398:30:398:32 | dst | provenance | | | tests.js:401:33:401:40 | dst[key] | tests.js:398:30:398:32 | dst | provenance | | -| tests.js:401:37:401:39 | key | tests.js:401:33:401:40 | dst[key] | provenance | | -| tests.js:401:37:401:39 | key | tests.js:401:33:401:40 | dst[key] | provenance | | +| tests.js:401:37:401:39 | key | tests.js:401:33:401:40 | dst[key] | provenance | Config | +| tests.js:401:37:401:39 | key | tests.js:401:33:401:40 | dst[key] | provenance | Config | | tests.js:401:43:401:47 | value | tests.js:398:35:398:37 | src | provenance | | | tests.js:408:22:408:24 | obj | tests.js:409:12:409:14 | obj | provenance | | | tests.js:408:27:408:29 | key | tests.js:409:16:409:18 | key | provenance | | -| tests.js:409:12:409:14 | obj | tests.js:409:12:409:19 | obj[key] | provenance | | -| tests.js:409:16:409:18 | key | tests.js:409:12:409:19 | obj[key] | provenance | | +| tests.js:409:12:409:14 | obj | tests.js:409:12:409:19 | obj[key] | provenance | Config | +| tests.js:409:16:409:18 | key | tests.js:409:12:409:19 | obj[key] | provenance | Config | | tests.js:412:31:412:33 | dst | tests.js:415:34:415:36 | dst | provenance | | | tests.js:412:31:412:33 | dst | tests.js:419:13:419:15 | dst | provenance | | | tests.js:412:36:412:38 | src | tests.js:414:33:414:35 | src | provenance | | @@ -1128,21 +1128,21 @@ edges | tests.js:414:13:414:41 | value | tests.js:419:24:419:28 | value | provenance | | | tests.js:414:21:414:41 | wrapped ... c, key) | tests.js:414:13:414:41 | value | provenance | | | tests.js:414:33:414:35 | src | tests.js:408:22:408:24 | obj | provenance | | -| tests.js:414:33:414:35 | src | tests.js:414:21:414:41 | wrapped ... c, key) | provenance | | +| tests.js:414:33:414:35 | src | tests.js:414:21:414:41 | wrapped ... c, key) | provenance | Config | | tests.js:414:38:414:40 | key | tests.js:408:27:408:29 | key | provenance | | -| tests.js:414:38:414:40 | key | tests.js:414:21:414:41 | wrapped ... c, key) | provenance | | +| tests.js:414:38:414:40 | key | tests.js:414:21:414:41 | wrapped ... c, key) | provenance | Config | | tests.js:415:13:415:42 | target | tests.js:417:34:417:39 | target | provenance | | | tests.js:415:22:415:42 | wrapped ... t, key) | tests.js:415:13:415:42 | target | provenance | | | tests.js:415:34:415:36 | dst | tests.js:408:22:408:24 | obj | provenance | | -| tests.js:415:34:415:36 | dst | tests.js:415:22:415:42 | wrapped ... t, key) | provenance | | +| tests.js:415:34:415:36 | dst | tests.js:415:22:415:42 | wrapped ... t, key) | provenance | Config | | tests.js:415:39:415:41 | key | tests.js:408:27:408:29 | key | provenance | | -| tests.js:415:39:415:41 | key | tests.js:415:22:415:42 | wrapped ... t, key) | provenance | | +| tests.js:415:39:415:41 | key | tests.js:415:22:415:42 | wrapped ... t, key) | provenance | Config | | tests.js:417:34:417:39 | target | tests.js:412:31:412:33 | dst | provenance | | | tests.js:417:42:417:46 | value | tests.js:412:36:412:38 | src | provenance | | | tests.js:424:25:424:27 | obj | tests.js:426:12:426:14 | obj | provenance | | | tests.js:424:30:424:32 | key | tests.js:426:16:426:18 | key | provenance | | -| tests.js:426:12:426:14 | obj | tests.js:426:12:426:19 | obj[key] | provenance | | -| tests.js:426:16:426:18 | key | tests.js:426:12:426:19 | obj[key] | provenance | | +| tests.js:426:12:426:14 | obj | tests.js:426:12:426:19 | obj[key] | provenance | Config | +| tests.js:426:16:426:18 | key | tests.js:426:12:426:19 | obj[key] | provenance | Config | | tests.js:429:34:429:36 | dst | tests.js:432:37:432:39 | dst | provenance | | | tests.js:429:34:429:36 | dst | tests.js:436:13:436:15 | dst | provenance | | | tests.js:429:39:429:41 | src | tests.js:431:36:431:38 | src | provenance | | @@ -1153,26 +1153,26 @@ edges | tests.js:431:13:431:44 | value | tests.js:436:24:436:28 | value | provenance | | | tests.js:431:21:431:44 | almostS ... c, key) | tests.js:431:13:431:44 | value | provenance | | | tests.js:431:36:431:38 | src | tests.js:424:25:424:27 | obj | provenance | | -| tests.js:431:36:431:38 | src | tests.js:431:21:431:44 | almostS ... c, key) | provenance | | +| tests.js:431:36:431:38 | src | tests.js:431:21:431:44 | almostS ... c, key) | provenance | Config | | tests.js:431:41:431:43 | key | tests.js:424:30:424:32 | key | provenance | | -| tests.js:431:41:431:43 | key | tests.js:431:21:431:44 | almostS ... c, key) | provenance | | +| tests.js:431:41:431:43 | key | tests.js:431:21:431:44 | almostS ... c, key) | provenance | Config | | tests.js:432:13:432:45 | target | tests.js:434:37:434:42 | target | provenance | | | tests.js:432:22:432:45 | almostS ... t, key) | tests.js:432:13:432:45 | target | provenance | | | tests.js:432:37:432:39 | dst | tests.js:424:25:424:27 | obj | provenance | | -| tests.js:432:37:432:39 | dst | tests.js:432:22:432:45 | almostS ... t, key) | provenance | | +| tests.js:432:37:432:39 | dst | tests.js:432:22:432:45 | almostS ... t, key) | provenance | Config | | tests.js:432:42:432:44 | key | tests.js:424:30:424:32 | key | provenance | | -| tests.js:432:42:432:44 | key | tests.js:432:22:432:45 | almostS ... t, key) | provenance | | +| tests.js:432:42:432:44 | key | tests.js:432:22:432:45 | almostS ... t, key) | provenance | Config | | tests.js:434:37:434:42 | target | tests.js:429:34:429:36 | dst | provenance | | | tests.js:434:45:434:49 | value | tests.js:429:39:429:41 | src | provenance | | | tests.js:441:19:441:21 | obj | tests.js:443:12:443:14 | obj | provenance | | -| tests.js:443:12:443:14 | obj | tests.js:443:12:443:19 | obj[key] | provenance | | +| tests.js:443:12:443:14 | obj | tests.js:443:12:443:19 | obj[key] | provenance | Config | | tests.js:446:33:446:35 | src | tests.js:448:30:448:32 | src | provenance | | | tests.js:447:14:447:16 | key | tests.js:453:17:453:19 | key | provenance | | | tests.js:448:13:448:38 | value | tests.js:451:39:451:43 | value | provenance | | | tests.js:448:13:448:38 | value | tests.js:453:24:453:28 | value | provenance | | | tests.js:448:21:448:38 | safeRead(src, key) | tests.js:448:13:448:38 | value | provenance | | | tests.js:448:30:448:32 | src | tests.js:441:19:441:21 | obj | provenance | | -| tests.js:448:30:448:32 | src | tests.js:448:21:448:38 | safeRead(src, key) | provenance | | +| tests.js:448:30:448:32 | src | tests.js:448:21:448:38 | safeRead(src, key) | provenance | Config | | tests.js:451:39:451:43 | value | tests.js:446:33:446:35 | src | provenance | | | tests.js:458:26:458:28 | dst | tests.js:462:29:462:31 | dst | provenance | | | tests.js:458:26:458:28 | dst | tests.js:465:30:465:32 | dst | provenance | | @@ -1189,23 +1189,23 @@ edges | tests.js:460:25:460:27 | key | tests.js:466:34:466:36 | key | provenance | | | tests.js:460:25:460:27 | key | tests.js:466:43:466:45 | key | provenance | | | tests.js:460:25:460:27 | key | tests.js:467:34:467:36 | key | provenance | | -| tests.js:462:29:462:31 | dst | tests.js:462:29:462:36 | dst[key] | provenance | | +| tests.js:462:29:462:31 | dst | tests.js:462:29:462:36 | dst[key] | provenance | Config | | tests.js:462:29:462:36 | dst[key] | tests.js:458:26:458:28 | dst | provenance | | -| tests.js:462:33:462:35 | key | tests.js:462:29:462:36 | dst[key] | provenance | | -| tests.js:462:39:462:41 | src | tests.js:462:39:462:46 | src[key] | provenance | | +| tests.js:462:33:462:35 | key | tests.js:462:29:462:36 | dst[key] | provenance | Config | +| tests.js:462:39:462:41 | src | tests.js:462:39:462:46 | src[key] | provenance | Config | | tests.js:462:39:462:46 | src[key] | tests.js:458:31:458:33 | src | provenance | | -| tests.js:462:43:462:45 | key | tests.js:462:39:462:46 | src[key] | provenance | | -| tests.js:465:41:465:43 | src | tests.js:465:41:465:48 | src[key] | provenance | | -| tests.js:465:45:465:47 | key | tests.js:465:41:465:48 | src[key] | provenance | | -| tests.js:466:43:466:45 | key | tests.js:466:41:466:46 | o[key] | provenance | | +| tests.js:462:43:462:45 | key | tests.js:462:39:462:46 | src[key] | provenance | Config | +| tests.js:465:41:465:43 | src | tests.js:465:41:465:48 | src[key] | provenance | Config | +| tests.js:465:45:465:47 | key | tests.js:465:41:465:48 | src[key] | provenance | Config | +| tests.js:466:43:466:45 | key | tests.js:466:41:466:46 | o[key] | provenance | Config | | tests.js:472:38:472:40 | dst | tests.js:475:41:475:43 | dst | provenance | | | tests.js:472:38:472:40 | dst | tests.js:477:13:477:15 | dst | provenance | | | tests.js:473:18:473:22 | value | tests.js:477:24:477:28 | value | provenance | | | tests.js:473:25:473:27 | key | tests.js:475:45:475:47 | key | provenance | | | tests.js:473:25:473:27 | key | tests.js:477:17:477:19 | key | provenance | | -| tests.js:475:41:475:43 | dst | tests.js:475:41:475:48 | dst[key] | provenance | | +| tests.js:475:41:475:43 | dst | tests.js:475:41:475:48 | dst[key] | provenance | Config | | tests.js:475:41:475:48 | dst[key] | tests.js:472:38:472:40 | dst | provenance | | -| tests.js:475:45:475:47 | key | tests.js:475:41:475:48 | dst[key] | provenance | | +| tests.js:475:45:475:47 | key | tests.js:475:41:475:48 | dst[key] | provenance | Config | | tests.js:483:26:483:28 | dst | tests.js:487:29:487:31 | dst | provenance | | | tests.js:483:26:483:28 | dst | tests.js:489:13:489:15 | dst | provenance | | | tests.js:483:31:483:33 | src | tests.js:487:39:487:41 | src | provenance | | @@ -1215,16 +1215,16 @@ edges | tests.js:484:14:484:16 | key | tests.js:487:43:487:45 | key | provenance | | | tests.js:484:14:484:16 | key | tests.js:489:17:489:19 | key | provenance | | | tests.js:484:14:484:16 | key | tests.js:489:28:489:30 | key | provenance | | -| tests.js:487:29:487:31 | dst | tests.js:487:29:487:36 | dst[key] | provenance | | +| tests.js:487:29:487:31 | dst | tests.js:487:29:487:36 | dst[key] | provenance | Config | | tests.js:487:29:487:36 | dst[key] | tests.js:483:26:483:28 | dst | provenance | | -| tests.js:487:33:487:35 | key | tests.js:487:29:487:36 | dst[key] | provenance | | -| tests.js:487:39:487:41 | src | tests.js:487:39:487:46 | src[key] | provenance | | +| tests.js:487:33:487:35 | key | tests.js:487:29:487:36 | dst[key] | provenance | Config | +| tests.js:487:39:487:41 | src | tests.js:487:39:487:46 | src[key] | provenance | Config | | tests.js:487:39:487:46 | src[key] | tests.js:483:31:483:33 | src | provenance | | | tests.js:487:39:487:46 | src[key] | tests.js:483:31:483:33 | src | provenance | | | tests.js:487:39:487:46 | src[key] | tests.js:483:31:483:33 | src | provenance | | -| tests.js:487:43:487:45 | key | tests.js:487:39:487:46 | src[key] | provenance | | -| tests.js:489:24:489:26 | src | tests.js:489:24:489:31 | src[key] | provenance | | -| tests.js:489:28:489:30 | key | tests.js:489:24:489:31 | src[key] | provenance | | +| tests.js:487:43:487:45 | key | tests.js:487:39:487:46 | src[key] | provenance | Config | +| tests.js:489:24:489:26 | src | tests.js:489:24:489:31 | src[key] | provenance | Config | +| tests.js:489:28:489:30 | key | tests.js:489:24:489:31 | src[key] | provenance | Config | | tests.js:494:32:494:34 | src | tests.js:498:21:498:23 | src | provenance | | | tests.js:495:14:495:16 | key | tests.js:498:25:498:27 | key | provenance | | | tests.js:495:14:495:16 | key | tests.js:502:17:502:19 | key | provenance | | @@ -1233,11 +1233,11 @@ edges | tests.js:498:13:498:28 | value | tests.js:502:24:502:28 | value | provenance | | | tests.js:498:13:498:28 | value | tests.js:502:24:502:28 | value | provenance | | | tests.js:498:13:498:28 | value | tests.js:502:24:502:28 | value | provenance | | -| tests.js:498:21:498:23 | src | tests.js:498:21:498:28 | src[key] | provenance | | +| tests.js:498:21:498:23 | src | tests.js:498:21:498:28 | src[key] | provenance | Config | | tests.js:498:21:498:28 | src[key] | tests.js:498:13:498:28 | value | provenance | | | tests.js:498:21:498:28 | src[key] | tests.js:498:13:498:28 | value | provenance | | | tests.js:498:21:498:28 | src[key] | tests.js:498:13:498:28 | value | provenance | | -| tests.js:498:25:498:27 | key | tests.js:498:21:498:28 | src[key] | provenance | | +| tests.js:498:25:498:27 | key | tests.js:498:21:498:28 | src[key] | provenance | Config | | tests.js:500:38:500:42 | value | tests.js:494:32:494:34 | src | provenance | | | tests.js:500:38:500:42 | value | tests.js:494:32:494:34 | src | provenance | | | tests.js:508:30:508:32 | dst | tests.js:513:33:513:35 | dst | provenance | | @@ -1249,25 +1249,25 @@ edges | tests.js:511:13:511:25 | key | tests.js:516:36:516:38 | key | provenance | | | tests.js:511:13:511:25 | key | tests.js:517:40:517:42 | key | provenance | | | tests.js:511:19:511:25 | keys[i] | tests.js:511:13:511:25 | key | provenance | | -| tests.js:513:33:513:35 | dst | tests.js:513:33:513:40 | dst[key] | provenance | | +| tests.js:513:33:513:35 | dst | tests.js:513:33:513:40 | dst[key] | provenance | Config | | tests.js:513:33:513:40 | dst[key] | tests.js:508:30:508:32 | dst | provenance | | -| tests.js:513:37:513:39 | key | tests.js:513:33:513:40 | dst[key] | provenance | | -| tests.js:513:43:513:45 | src | tests.js:513:43:513:50 | src[key] | provenance | | +| tests.js:513:37:513:39 | key | tests.js:513:33:513:40 | dst[key] | provenance | Config | +| tests.js:513:43:513:45 | src | tests.js:513:43:513:50 | src[key] | provenance | Config | | tests.js:513:43:513:50 | src[key] | tests.js:508:35:508:37 | src | provenance | | -| tests.js:513:47:513:49 | key | tests.js:513:43:513:50 | src[key] | provenance | | -| tests.js:516:32:516:34 | src | tests.js:516:32:516:39 | src[key] | provenance | | -| tests.js:516:36:516:38 | key | tests.js:516:32:516:39 | src[key] | provenance | | +| tests.js:513:47:513:49 | key | tests.js:513:43:513:50 | src[key] | provenance | Config | +| tests.js:516:32:516:34 | src | tests.js:516:32:516:39 | src[key] | provenance | Config | +| tests.js:516:36:516:38 | key | tests.js:516:32:516:39 | src[key] | provenance | Config | | tests.js:525:14:525:16 | key | tests.js:529:17:529:19 | key | provenance | | | tests.js:525:14:525:16 | key | tests.js:529:28:529:30 | key | provenance | | -| tests.js:529:28:529:30 | key | tests.js:529:24:529:31 | src[key] | provenance | | +| tests.js:529:28:529:30 | key | tests.js:529:24:529:31 | src[key] | provenance | Config | | tests.js:534:31:534:33 | obj | tests.js:538:27:538:29 | obj | provenance | | | tests.js:534:36:534:43 | callback [dst] | tests.js:538:9:538:16 | callback [dst] | provenance | | | tests.js:538:9:538:16 | callback [dst] | tests.js:545:33:545:35 | dst | provenance | | | tests.js:538:9:538:16 | callback [dst] | tests.js:547:13:547:15 | dst | provenance | | | tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key | provenance | | -| tests.js:538:27:538:29 | obj | tests.js:538:27:538:38 | obj[keys[i]] | provenance | | +| tests.js:538:27:538:29 | obj | tests.js:538:27:538:38 | obj[keys[i]] | provenance | Config | | tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value | provenance | | -| tests.js:538:31:538:37 | keys[i] | tests.js:538:27:538:38 | obj[keys[i]] | provenance | | +| tests.js:538:31:538:37 | keys[i] | tests.js:538:27:538:38 | obj[keys[i]] | provenance | Config | | tests.js:542:30:542:32 | dst | tests.js:534:36:534:43 | callback [dst] | provenance | | | tests.js:542:30:542:32 | dst | tests.js:545:33:545:35 | dst | provenance | | | tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst | provenance | | @@ -1277,34 +1277,34 @@ edges | tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key | provenance | | | tests.js:543:37:543:41 | value | tests.js:545:43:545:47 | value | provenance | | | tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value | provenance | | -| tests.js:545:33:545:35 | dst | tests.js:545:33:545:40 | dst[key] | provenance | | +| tests.js:545:33:545:35 | dst | tests.js:545:33:545:40 | dst[key] | provenance | Config | | tests.js:545:33:545:40 | dst[key] | tests.js:542:30:542:32 | dst | provenance | | -| tests.js:545:37:545:39 | key | tests.js:545:33:545:40 | dst[key] | provenance | | +| tests.js:545:37:545:39 | key | tests.js:545:33:545:40 | dst[key] | provenance | Config | | tests.js:545:43:545:47 | value | tests.js:542:35:542:37 | src | provenance | | | tests.js:552:35:552:37 | src | tests.js:557:43:557:45 | src | provenance | | | tests.js:552:35:552:37 | src | tests.js:559:24:559:26 | src | provenance | | | tests.js:553:14:553:16 | key | tests.js:559:17:559:19 | key | provenance | | | tests.js:553:14:553:16 | key | tests.js:559:28:559:30 | key | provenance | | -| tests.js:557:43:557:45 | src | tests.js:557:43:557:50 | src[key] | provenance | | +| tests.js:557:43:557:45 | src | tests.js:557:43:557:50 | src[key] | provenance | Config | | tests.js:557:43:557:50 | src[key] | tests.js:552:35:552:37 | src | provenance | | -| tests.js:559:24:559:26 | src | tests.js:559:24:559:31 | src[key] | provenance | | -| tests.js:559:28:559:30 | key | tests.js:559:24:559:31 | src[key] | provenance | | +| tests.js:559:24:559:26 | src | tests.js:559:24:559:31 | src[key] | provenance | Config | +| tests.js:559:28:559:30 | key | tests.js:559:24:559:31 | src[key] | provenance | Config | | tests.js:564:35:564:37 | src | tests.js:569:43:569:45 | src | provenance | | | tests.js:564:35:564:37 | src | tests.js:571:24:571:26 | src | provenance | | | tests.js:565:14:565:16 | key | tests.js:571:17:571:19 | key | provenance | | | tests.js:565:14:565:16 | key | tests.js:571:28:571:30 | key | provenance | | -| tests.js:569:43:569:45 | src | tests.js:569:43:569:50 | src[key] | provenance | | +| tests.js:569:43:569:45 | src | tests.js:569:43:569:50 | src[key] | provenance | Config | | tests.js:569:43:569:50 | src[key] | tests.js:564:35:564:37 | src | provenance | | -| tests.js:571:24:571:26 | src | tests.js:571:24:571:31 | src[key] | provenance | | -| tests.js:571:28:571:30 | key | tests.js:571:24:571:31 | src[key] | provenance | | +| tests.js:571:24:571:26 | src | tests.js:571:24:571:31 | src[key] | provenance | Config | +| tests.js:571:28:571:30 | key | tests.js:571:24:571:31 | src[key] | provenance | Config | | tests.js:576:30:576:32 | src | tests.js:580:38:580:40 | src | provenance | | | tests.js:576:30:576:32 | src | tests.js:582:24:582:26 | src | provenance | | | tests.js:577:14:577:16 | key | tests.js:582:17:582:19 | key | provenance | | | tests.js:577:14:577:16 | key | tests.js:582:28:582:30 | key | provenance | | -| tests.js:580:38:580:40 | src | tests.js:580:38:580:45 | src[key] | provenance | | +| tests.js:580:38:580:40 | src | tests.js:580:38:580:45 | src[key] | provenance | Config | | tests.js:580:38:580:45 | src[key] | tests.js:576:30:576:32 | src | provenance | | -| tests.js:582:24:582:26 | src | tests.js:582:24:582:31 | src[key] | provenance | | -| tests.js:582:28:582:30 | key | tests.js:582:24:582:31 | src[key] | provenance | | +| tests.js:582:24:582:26 | src | tests.js:582:24:582:31 | src[key] | provenance | Config | +| tests.js:582:28:582:30 | key | tests.js:582:24:582:31 | src[key] | provenance | Config | | tests.js:591:25:591:27 | obj | tests.js:592:7:592:9 | obj | provenance | | | tests.js:591:25:591:27 | obj | tests.js:592:21:592:23 | obj | provenance | | | tests.js:592:7:592:9 | obj | tests.js:592:21:592:23 | obj | provenance | | @@ -1318,16 +1318,16 @@ edges | tests.js:601:16:601:18 | key | tests.js:603:52:603:54 | key | provenance | | | tests.js:601:16:601:18 | key | tests.js:605:18:605:20 | key | provenance | | | tests.js:601:16:601:18 | key | tests.js:605:47:605:49 | key | provenance | | -| tests.js:603:34:603:37 | dest | tests.js:603:34:603:42 | dest[key] | provenance | | +| tests.js:603:34:603:37 | dest | tests.js:603:34:603:42 | dest[key] | provenance | Config | | tests.js:603:34:603:42 | dest[key] | tests.js:600:31:600:34 | dest | provenance | | -| tests.js:603:39:603:41 | key | tests.js:603:34:603:42 | dest[key] | provenance | | -| tests.js:603:45:603:50 | source | tests.js:603:45:603:55 | source[key] | provenance | | +| tests.js:603:39:603:41 | key | tests.js:603:34:603:42 | dest[key] | provenance | Config | +| tests.js:603:45:603:50 | source | tests.js:603:45:603:55 | source[key] | provenance | Config | | tests.js:603:45:603:55 | source[key] | tests.js:600:37:600:42 | source | provenance | | -| tests.js:603:52:603:54 | key | tests.js:603:45:603:55 | source[key] | provenance | | -| tests.js:605:40:605:45 | source | tests.js:605:40:605:50 | source[key] | provenance | | +| tests.js:603:52:603:54 | key | tests.js:603:45:603:55 | source[key] | provenance | Config | +| tests.js:605:40:605:45 | source | tests.js:605:40:605:50 | source[key] | provenance | Config | | tests.js:605:40:605:50 | source[key] | tests.js:591:25:591:27 | obj | provenance | | | tests.js:605:40:605:50 | source[key] | tests.js:605:25:605:51 | capture ... e[key]) | provenance | | -| tests.js:605:47:605:49 | key | tests.js:605:40:605:50 | source[key] | provenance | | +| tests.js:605:47:605:49 | key | tests.js:605:40:605:50 | source[key] | provenance | Config | subpaths | tests.js:355:53:355:63 | target[key] | tests.js:348:32:348:37 | target | tests.js:361:12:361:17 | target | tests.js:355:31:355:86 | mergePl ... ptions) | | tests.js:371:62:371:72 | target[key] | tests.js:364:41:364:46 | target | tests.js:377:12:377:17 | target | tests.js:371:31:371:95 | mergePl ... ptions) | diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected index 29d49ed71a4..b773f9b2dee 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected @@ -31,31 +31,31 @@ nodes | 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: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) | -| 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: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: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.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: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: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) | +| angularmerge.js:1:30:1:34 | event | angularmerge.js:2:32:2:36 | event | provenance | | +| angularmerge.js:2:32:2:36 | event | angularmerge.js:2:32:2:41 | event.data | provenance | | +| angularmerge.js:2:32:2:41 | event.data | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | provenance | Config | +| 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] | provenance | | +| 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 } | provenance | | +| 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] | provenance | | +| src-vulnerable-lodash/tst.js:14:9:16:5 | opts [thing] | src-vulnerable-lodash/tst.js:18:16:18:19 | opts [thing] | provenance | | +| src-vulnerable-lodash/tst.js:14:16:16:5 | {\\n ... e\\n } [thing] | src-vulnerable-lodash/tst.js:14:9:16:5 | opts [thing] | provenance | | +| 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] | provenance | | +| 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] | provenance | | +| 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 } | provenance | | +| src-vulnerable-lodash/tst.js:18:16:18:19 | opts [thing] | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | provenance | | +| 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] | provenance | | +| webix/webix.html:3:34:3:38 | event | webix/webix.html:4:37:4:41 | event | provenance | | +| webix/webix.html:3:34:3:38 | event | webix/webix.html:5:35:5:39 | event | provenance | | +| webix/webix.html:4:37:4:41 | event | webix/webix.html:4:37:4:46 | event.data | provenance | | +| webix/webix.html:4:37:4:46 | event.data | webix/webix.html:4:26:4:47 | JSON.pa ... t.data) | provenance | Config | +| webix/webix.html:5:35:5:39 | event | webix/webix.html:5:35:5:44 | event.data | provenance | | +| webix/webix.html:5:35:5:44 | event.data | webix/webix.html:5:24:5:45 | JSON.pa ... t.data) | provenance | Config | +| webix/webix.js:3:30:3:34 | event | webix/webix.js:4:33:4:37 | event | provenance | | +| webix/webix.js:3:30:3:34 | event | webix/webix.js:5:31:5:35 | event | provenance | | +| webix/webix.js:4:33:4:37 | event | webix/webix.js:4:33:4:42 | event.data | provenance | | +| webix/webix.js:4:33:4:42 | event.data | webix/webix.js:4:22:4:43 | JSON.pa ... t.data) | provenance | Config | +| webix/webix.js:5:31:5:35 | event | webix/webix.js:5:31:5:40 | event.data | provenance | | +| webix/webix.js:5:31:5:40 | event.data | webix/webix.js:5:20:5:41 | JSON.pa ... t.data) | provenance | Config | 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 | diff --git a/javascript/ql/test/query-tests/Security/CWE-918/ClientSideRequestForgery.expected b/javascript/ql/test/query-tests/Security/CWE-918/ClientSideRequestForgery.expected index b11a9d20a64..5a267ea5689 100644 --- a/javascript/ql/test/query-tests/Security/CWE-918/ClientSideRequestForgery.expected +++ b/javascript/ql/test/query-tests/Security/CWE-918/ClientSideRequestForgery.expected @@ -1,16 +1,16 @@ edges -| clientSide.js:11:11:11:53 | query | clientSide.js:12:42:12:46 | query | -| clientSide.js:11:19:11:40 | window. ... .search | clientSide.js:11:19:11:53 | window. ... ring(1) | -| clientSide.js:11:19:11:53 | window. ... ring(1) | clientSide.js:11:11:11:53 | query | -| clientSide.js:12:42:12:46 | query | clientSide.js:12:13:12:54 | 'https: ... + '/id' | -| clientSide.js:14:42:14:63 | window. ... .search | clientSide.js:14:13:14:63 | 'https: ... .search | -| clientSide.js:16:11:16:54 | fragment | clientSide.js:17:42:17:49 | fragment | -| clientSide.js:16:22:16:41 | window.location.hash | clientSide.js:16:22:16:54 | window. ... ring(1) | -| clientSide.js:16:22:16:54 | window. ... ring(1) | clientSide.js:16:11:16:54 | fragment | -| clientSide.js:17:42:17:49 | fragment | clientSide.js:17:13:17:57 | 'https: ... + '/id' | -| clientSide.js:20:11:20:28 | name | clientSide.js:21:42:21:45 | name | -| clientSide.js:20:18:20:28 | window.name | clientSide.js:20:11:20:28 | name | -| clientSide.js:21:42:21:45 | name | clientSide.js:21:13:21:53 | 'https: ... + '/id' | +| clientSide.js:11:11:11:53 | query | clientSide.js:12:42:12:46 | query | provenance | | +| clientSide.js:11:19:11:40 | window. ... .search | clientSide.js:11:19:11:53 | window. ... ring(1) | provenance | | +| clientSide.js:11:19:11:53 | window. ... ring(1) | clientSide.js:11:11:11:53 | query | provenance | | +| clientSide.js:12:42:12:46 | query | clientSide.js:12:13:12:54 | 'https: ... + '/id' | provenance | | +| clientSide.js:14:42:14:63 | window. ... .search | clientSide.js:14:13:14:63 | 'https: ... .search | provenance | | +| clientSide.js:16:11:16:54 | fragment | clientSide.js:17:42:17:49 | fragment | provenance | | +| clientSide.js:16:22:16:41 | window.location.hash | clientSide.js:16:22:16:54 | window. ... ring(1) | provenance | | +| clientSide.js:16:22:16:54 | window. ... ring(1) | clientSide.js:16:11:16:54 | fragment | provenance | | +| clientSide.js:17:42:17:49 | fragment | clientSide.js:17:13:17:57 | 'https: ... + '/id' | provenance | | +| clientSide.js:20:11:20:28 | name | clientSide.js:21:42:21:45 | name | provenance | | +| clientSide.js:20:18:20:28 | window.name | clientSide.js:20:11:20:28 | name | provenance | | +| clientSide.js:21:42:21:45 | name | clientSide.js:21:13:21:53 | 'https: ... + '/id' | provenance | | nodes | clientSide.js:11:11:11:53 | query | semmle.label | query | | clientSide.js:11:19:11:40 | window. ... .search | semmle.label | window. ... .search | diff --git a/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected b/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected index 4d97d522e54..edeab8f1d94 100644 --- a/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected +++ b/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected @@ -1,52 +1,52 @@ edges -| serverSide.js:14:9:14:52 | tainted | serverSide.js:18:13:18:19 | tainted | -| serverSide.js:14:9:14:52 | tainted | serverSide.js:20:17:20:23 | tainted | -| serverSide.js:14:9:14:52 | tainted | serverSide.js:23:19:23:25 | tainted | -| serverSide.js:14:9:14:52 | tainted | serverSide.js:26:25:26:31 | tainted | -| serverSide.js:14:9:14:52 | tainted | serverSide.js:28:36:28:42 | tainted | -| serverSide.js:14:9:14:52 | tainted | serverSide.js:30:37:30:43 | tainted | -| serverSide.js:14:9:14:52 | tainted | serverSide.js:34:34:34:40 | tainted | -| serverSide.js:14:9:14:52 | tainted | serverSide.js:36:24:36:30 | tainted | -| serverSide.js:14:9:14:52 | tainted | serverSide.js:37:30:37:36 | tainted | -| serverSide.js:14:9:14:52 | tainted | serverSide.js:41:43:41:49 | tainted | -| serverSide.js:14:9:14:52 | tainted | serverSide.js:43:46:43:52 | tainted | -| serverSide.js:14:9:14:52 | tainted | serverSide.js:45:50:45:56 | tainted | -| serverSide.js:14:19:14:42 | url.par ... , true) | serverSide.js:14:9:14:52 | tainted | -| serverSide.js:14:29:14:35 | req.url | serverSide.js:14:19:14:42 | url.par ... , true) | -| serverSide.js:26:25:26:31 | tainted | serverSide.js:26:13:26:31 | "http://" + tainted | -| serverSide.js:28:36:28:42 | tainted | serverSide.js:28:13:28:42 | "http:/ ... tainted | -| serverSide.js:30:37:30:43 | tainted | serverSide.js:30:13:30:43 | "http:/ ... tainted | -| serverSide.js:36:24:36:30 | tainted | serverSide.js:36:16:36:31 | new Uri(tainted) | -| serverSide.js:37:30:37:36 | tainted | serverSide.js:37:22:37:37 | new Uri(tainted) | -| serverSide.js:41:43:41:49 | tainted | serverSide.js:41:13:41:51 | `http:/ ... inted}` | -| serverSide.js:43:46:43:52 | tainted | serverSide.js:43:13:43:54 | `http:/ ... inted}` | -| serverSide.js:45:50:45:56 | tainted | serverSide.js:45:13:45:56 | 'http:/ ... tainted | -| serverSide.js:58:9:58:52 | tainted | serverSide.js:61:29:61:35 | tainted | -| serverSide.js:58:9:58:52 | tainted | serverSide.js:61:29:61:35 | tainted | -| serverSide.js:58:19:58:42 | url.par ... , true) | serverSide.js:58:9:58:52 | tainted | -| serverSide.js:58:29:58:35 | req.url | serverSide.js:58:19:58:42 | url.par ... , true) | -| serverSide.js:61:29:61:35 | tainted | serverSide.js:64:30:64:36 | tainted | -| serverSide.js:61:29:61:35 | tainted | serverSide.js:68:30:68:36 | tainted | -| serverSide.js:74:9:74:52 | tainted | serverSide.js:76:19:76:25 | tainted | -| serverSide.js:74:19:74:42 | url.par ... , true) | serverSide.js:74:9:74:52 | tainted | -| serverSide.js:74:29:74:35 | req.url | serverSide.js:74:19:74:42 | url.par ... , true) | -| serverSide.js:83:38:83:43 | param1 | serverSide.js:84:19:84:24 | param1 | -| serverSide.js:90:19:90:28 | ctx.params | serverSide.js:90:19:90:32 | ctx.params.foo | -| serverSide.js:92:19:92:28 | ctx.params | serverSide.js:92:19:92:32 | ctx.params.foo | -| serverSide.js:98:9:98:52 | tainted | serverSide.js:100:19:100:25 | tainted | -| serverSide.js:98:19:98:42 | url.par ... , true) | serverSide.js:98:9:98:52 | tainted | -| serverSide.js:98:29:98:35 | req.url | serverSide.js:98:19:98:42 | url.par ... , true) | -| serverSide.js:108:11:108:27 | url | serverSide.js:109:27:109:29 | url | -| serverSide.js:108:17:108:27 | request.url | serverSide.js:108:11:108:27 | url | -| serverSide.js:115:11:115:42 | url | serverSide.js:117:27:117:29 | url | -| serverSide.js:115:17:115:42 | new URL ... , base) | serverSide.js:115:11:115:42 | url | -| serverSide.js:115:25:115:35 | request.url | serverSide.js:115:17:115:42 | new URL ... , base) | -| serverSide.js:123:9:123:52 | tainted | serverSide.js:127:14:127:20 | tainted | -| serverSide.js:123:9:123:52 | tainted | serverSide.js:130:37:130:43 | tainted | -| serverSide.js:123:19:123:42 | url.par ... , true) | serverSide.js:123:9:123:52 | tainted | -| serverSide.js:123:29:123:35 | req.url | serverSide.js:123:19:123:42 | url.par ... , true) | -| serverSide.js:130:9:130:45 | myUrl | serverSide.js:131:15:131:19 | myUrl | -| serverSide.js:130:37:130:43 | tainted | serverSide.js:130:9:130:45 | myUrl | +| serverSide.js:14:9:14:52 | tainted | serverSide.js:18:13:18:19 | tainted | provenance | | +| serverSide.js:14:9:14:52 | tainted | serverSide.js:20:17:20:23 | tainted | provenance | | +| serverSide.js:14:9:14:52 | tainted | serverSide.js:23:19:23:25 | tainted | provenance | | +| serverSide.js:14:9:14:52 | tainted | serverSide.js:26:25:26:31 | tainted | provenance | | +| serverSide.js:14:9:14:52 | tainted | serverSide.js:28:36:28:42 | tainted | provenance | | +| serverSide.js:14:9:14:52 | tainted | serverSide.js:30:37:30:43 | tainted | provenance | | +| serverSide.js:14:9:14:52 | tainted | serverSide.js:34:34:34:40 | tainted | provenance | | +| serverSide.js:14:9:14:52 | tainted | serverSide.js:36:24:36:30 | tainted | provenance | | +| serverSide.js:14:9:14:52 | tainted | serverSide.js:37:30:37:36 | tainted | provenance | | +| serverSide.js:14:9:14:52 | tainted | serverSide.js:41:43:41:49 | tainted | provenance | | +| serverSide.js:14:9:14:52 | tainted | serverSide.js:43:46:43:52 | tainted | provenance | | +| serverSide.js:14:9:14:52 | tainted | serverSide.js:45:50:45:56 | tainted | provenance | | +| serverSide.js:14:19:14:42 | url.par ... , true) | serverSide.js:14:9:14:52 | tainted | provenance | | +| serverSide.js:14:29:14:35 | req.url | serverSide.js:14:19:14:42 | url.par ... , true) | provenance | | +| serverSide.js:26:25:26:31 | tainted | serverSide.js:26:13:26:31 | "http://" + tainted | provenance | | +| serverSide.js:28:36:28:42 | tainted | serverSide.js:28:13:28:42 | "http:/ ... tainted | provenance | | +| serverSide.js:30:37:30:43 | tainted | serverSide.js:30:13:30:43 | "http:/ ... tainted | provenance | | +| serverSide.js:36:24:36:30 | tainted | serverSide.js:36:16:36:31 | new Uri(tainted) | provenance | | +| serverSide.js:37:30:37:36 | tainted | serverSide.js:37:22:37:37 | new Uri(tainted) | provenance | | +| serverSide.js:41:43:41:49 | tainted | serverSide.js:41:13:41:51 | `http:/ ... inted}` | provenance | | +| serverSide.js:43:46:43:52 | tainted | serverSide.js:43:13:43:54 | `http:/ ... inted}` | provenance | | +| serverSide.js:45:50:45:56 | tainted | serverSide.js:45:13:45:56 | 'http:/ ... tainted | provenance | | +| serverSide.js:58:9:58:52 | tainted | serverSide.js:61:29:61:35 | tainted | provenance | | +| serverSide.js:58:9:58:52 | tainted | serverSide.js:61:29:61:35 | tainted | provenance | | +| serverSide.js:58:19:58:42 | url.par ... , true) | serverSide.js:58:9:58:52 | tainted | provenance | | +| serverSide.js:58:29:58:35 | req.url | serverSide.js:58:19:58:42 | url.par ... , true) | provenance | | +| serverSide.js:61:29:61:35 | tainted | serverSide.js:64:30:64:36 | tainted | provenance | | +| serverSide.js:61:29:61:35 | tainted | serverSide.js:68:30:68:36 | tainted | provenance | | +| serverSide.js:74:9:74:52 | tainted | serverSide.js:76:19:76:25 | tainted | provenance | | +| serverSide.js:74:19:74:42 | url.par ... , true) | serverSide.js:74:9:74:52 | tainted | provenance | | +| serverSide.js:74:29:74:35 | req.url | serverSide.js:74:19:74:42 | url.par ... , true) | provenance | | +| serverSide.js:83:38:83:43 | param1 | serverSide.js:84:19:84:24 | param1 | provenance | | +| serverSide.js:90:19:90:28 | ctx.params | serverSide.js:90:19:90:32 | ctx.params.foo | provenance | | +| serverSide.js:92:19:92:28 | ctx.params | serverSide.js:92:19:92:32 | ctx.params.foo | provenance | | +| serverSide.js:98:9:98:52 | tainted | serverSide.js:100:19:100:25 | tainted | provenance | | +| serverSide.js:98:19:98:42 | url.par ... , true) | serverSide.js:98:9:98:52 | tainted | provenance | | +| serverSide.js:98:29:98:35 | req.url | serverSide.js:98:19:98:42 | url.par ... , true) | provenance | | +| serverSide.js:108:11:108:27 | url | serverSide.js:109:27:109:29 | url | provenance | | +| serverSide.js:108:17:108:27 | request.url | serverSide.js:108:11:108:27 | url | provenance | | +| serverSide.js:115:11:115:42 | url | serverSide.js:117:27:117:29 | url | provenance | | +| serverSide.js:115:17:115:42 | new URL ... , base) | serverSide.js:115:11:115:42 | url | provenance | | +| serverSide.js:115:25:115:35 | request.url | serverSide.js:115:17:115:42 | new URL ... , base) | provenance | Config | +| serverSide.js:123:9:123:52 | tainted | serverSide.js:127:14:127:20 | tainted | provenance | | +| serverSide.js:123:9:123:52 | tainted | serverSide.js:130:37:130:43 | tainted | provenance | | +| serverSide.js:123:19:123:42 | url.par ... , true) | serverSide.js:123:9:123:52 | tainted | provenance | | +| serverSide.js:123:29:123:35 | req.url | serverSide.js:123:19:123:42 | url.par ... , true) | provenance | | +| serverSide.js:130:9:130:45 | myUrl | serverSide.js:131:15:131:19 | myUrl | provenance | | +| serverSide.js:130:37:130:43 | tainted | serverSide.js:130:9:130:45 | myUrl | provenance | | nodes | serverSide.js:14:9:14:52 | tainted | semmle.label | tainted | | serverSide.js:14:19:14:42 | url.par ... , true) | semmle.label | url.par ... , true) | From af7b4e30633dd69bc9081b08b10df48ec3575816 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 26 Jun 2024 13:45:09 +0200 Subject: [PATCH 212/514] Accept flow difference due to added test cases New library gets FN for spread arguments in a call to splice(), which was added to the old version in this PR: https://github.com/github/codeql/pull/16739 --- javascript/ql/test/library-tests/Arrays/DataFlow.expected | 2 +- javascript/ql/test/library-tests/Arrays/TaintFlow.expected | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/test/library-tests/Arrays/DataFlow.expected b/javascript/ql/test/library-tests/Arrays/DataFlow.expected index 3c9cd4147f1..340f5dbe230 100644 --- a/javascript/ql/test/library-tests/Arrays/DataFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/DataFlow.expected @@ -1,11 +1,11 @@ legacyDataFlowDifference +| arrays.js:2:16:2:23 | "source" | arrays.js:39:8:39:24 | arr4_spread.pop() | only flow with OLD data flow library | flow | arrays.js:2:16:2:23 | "source" | arrays.js:5:8:5:14 | obj.foo | | arrays.js:2:16:2:23 | "source" | arrays.js:11:10:11:15 | arr[i] | | arrays.js:2:16:2:23 | "source" | arrays.js:15:27:15:27 | e | | arrays.js:2:16:2:23 | "source" | arrays.js:16:23:16:23 | e | | arrays.js:2:16:2:23 | "source" | arrays.js:20:8:20:16 | arr.pop() | -| arrays.js:2:16:2:23 | "source" | arrays.js:39:8:39:24 | arr4_spread.pop() | | arrays.js:2:16:2:23 | "source" | arrays.js:61:10:61:10 | x | | arrays.js:2:16:2:23 | "source" | arrays.js:65:10:65:10 | x | | arrays.js:2:16:2:23 | "source" | arrays.js:69:10:69:10 | x | diff --git a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected index 12d926e8eb6..0f246a750bc 100644 --- a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected @@ -1,11 +1,11 @@ legacyDataFlowDifference +| arrays.js:2:16:2:23 | "source" | arrays.js:39:8:39:24 | arr4_spread.pop() | only flow with OLD data flow library | flow | arrays.js:2:16:2:23 | "source" | arrays.js:5:8:5:14 | obj.foo | | arrays.js:2:16:2:23 | "source" | arrays.js:11:10:11:15 | arr[i] | | arrays.js:2:16:2:23 | "source" | arrays.js:15:27:15:27 | e | | arrays.js:2:16:2:23 | "source" | arrays.js:16:23:16:23 | e | | arrays.js:2:16:2:23 | "source" | arrays.js:20:8:20:16 | arr.pop() | -| arrays.js:2:16:2:23 | "source" | arrays.js:39:8:39:24 | arr4_spread.pop() | | arrays.js:2:16:2:23 | "source" | arrays.js:58:8:58:13 | arr[0] | | arrays.js:2:16:2:23 | "source" | arrays.js:61:10:61:10 | x | | arrays.js:2:16:2:23 | "source" | arrays.js:65:10:65:10 | x | From 24732746813a0877c7c7639a38384cb5997294ef Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 27 Jun 2024 09:06:45 +0200 Subject: [PATCH 213/514] JS: Benign test output changes --- .../InterProceduralFlow/tests.expected | 6 +++ .../frameworks/Templating/XssDiff.expected | 1 + .../IndirectCommandInjection.expected | 8 ++-- .../ImproperCodeSanitization.expected | 18 ++++---- .../CWE-798/HardcodedCredentials.expected | 45 ++++++++++--------- 5 files changed, 45 insertions(+), 33 deletions(-) diff --git a/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected b/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected index 81321780859..94fe390a046 100644 --- a/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected +++ b/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected @@ -48,6 +48,7 @@ dataFlow | partial.js:6:15:6:24 | "tainted2" | partial.js:42:15:42:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:48:15:48:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:54:15:54:15 | y | +| promises.js:32:24:32:37 | "also tainted" | promises.js:38:32:38:32 | v | | properties2.js:7:14:7:21 | "source" | properties2.js:8:12:8:24 | foo(source).p | | properties2.js:7:14:7:21 | "source" | properties2.js:17:13:17:15 | o.p | | properties2.js:7:14:7:21 | "source" | properties2.js:33:13:33:20 | getP(o3) | @@ -61,6 +62,7 @@ dataFlow | tst2.js:6:24:6:37 | "also tainted" | tst2.js:11:15:11:24 | g(source2) | | tst6.mjs:12:14:12:21 | "source" | tst6.mjs:14:12:14:16 | a.m() | | tst6.mjs:16:15:16:23 | "source2" | tst6.mjs:18:13:18:24 | a.m.call(a2) | +| tst.js:2:17:2:22 | "src1" | tst.js:28:20:28:22 | elt | | tst.js:2:17:2:22 | "src1" | tst.js:39:17:39:17 | x | | tst.js:2:17:2:22 | "src1" | tst.js:41:19:41:19 | x | | tst.js:2:17:2:22 | "src1" | tst.js:45:17:45:17 | x | @@ -126,6 +128,7 @@ taintTracking | partial.js:6:15:6:24 | "tainted2" | partial.js:42:15:42:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:48:15:48:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:54:15:54:15 | y | +| promises.js:32:24:32:37 | "also tainted" | promises.js:38:32:38:32 | v | | properties2.js:7:14:7:21 | "source" | properties2.js:8:12:8:24 | foo(source).p | | properties2.js:7:14:7:21 | "source" | properties2.js:17:13:17:15 | o.p | | properties2.js:7:14:7:21 | "source" | properties2.js:33:13:33:20 | getP(o3) | @@ -154,6 +157,7 @@ taintTracking | tst.js:2:17:2:22 | "src1" | tst.js:19:16:19:34 | JSON.parse(source1) | | tst.js:2:17:2:22 | "src1" | tst.js:20:16:20:37 | JSON.st ... sink10) | | tst.js:2:17:2:22 | "src1" | tst.js:24:16:24:18 | foo | +| tst.js:2:17:2:22 | "src1" | tst.js:28:20:28:22 | elt | | tst.js:2:17:2:22 | "src1" | tst.js:30:20:30:22 | ary | | tst.js:2:17:2:22 | "src1" | tst.js:36:16:36:24 | dict[key] | | tst.js:2:17:2:22 | "src1" | tst.js:39:17:39:17 | x | @@ -223,6 +227,7 @@ germanFlow | partial.js:6:15:6:24 | "tainted2" | partial.js:42:15:42:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:48:15:48:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:54:15:54:15 | y | +| promises.js:32:24:32:37 | "also tainted" | promises.js:38:32:38:32 | v | | properties2.js:7:14:7:21 | "source" | properties2.js:8:12:8:24 | foo(source).p | | properties2.js:7:14:7:21 | "source" | properties2.js:17:13:17:15 | o.p | | properties2.js:7:14:7:21 | "source" | properties2.js:33:13:33:20 | getP(o3) | @@ -236,6 +241,7 @@ germanFlow | tst2.js:6:24:6:37 | "also tainted" | tst2.js:11:15:11:24 | g(source2) | | tst6.mjs:12:14:12:21 | "source" | tst6.mjs:14:12:14:16 | a.m() | | tst6.mjs:16:15:16:23 | "source2" | tst6.mjs:18:13:18:24 | a.m.call(a2) | +| tst.js:2:17:2:22 | "src1" | tst.js:28:20:28:22 | elt | | tst.js:2:17:2:22 | "src1" | tst.js:39:17:39:17 | x | | tst.js:2:17:2:22 | "src1" | tst.js:41:19:41:19 | x | | tst.js:2:17:2:22 | "src1" | tst.js:45:17:45:17 | x | diff --git a/javascript/ql/test/library-tests/frameworks/Templating/XssDiff.expected b/javascript/ql/test/library-tests/frameworks/Templating/XssDiff.expected index 168b17e2a1b..1bed23967d2 100644 --- a/javascript/ql/test/library-tests/frameworks/Templating/XssDiff.expected +++ b/javascript/ql/test/library-tests/frameworks/Templating/XssDiff.expected @@ -25,6 +25,7 @@ flow | app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | | app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | | app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | +| app.js:73:18:73:30 | req.query.foo | views/dot_sinks.html.dot:3:9:3:22 | {{! tainted }} | | projectA/src/index.js:6:38:6:53 | req.query.taintA | projectA/views/main.ejs:5:1:5:26 | <%- taintedInMiddleware %> | | projectA/src/index.js:12:16:12:30 | req.query.sinkA | projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | | projectA/src/index.js:17:16:17:30 | req.query.sinkA | projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected index 1dd1715cdcc..26416731806 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected @@ -74,16 +74,16 @@ edges | command-line-parameter-command-injection.js:76:15:76:26 | process.argv | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | provenance | | | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | command-line-parameter-command-injection.js:76:8:76:35 | argv | provenance | | | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | command-line-parameter-command-injection.js:79:10:79:39 | "cmd.sh ... gv).foo | provenance | | -| command-line-parameter-command-injection.js:79:31:79:34 | argv | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | provenance | | +| command-line-parameter-command-injection.js:79:31:79:34 | argv | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | provenance | Config | | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | command-line-parameter-command-injection.js:82:10:82:54 | "cmd.sh ... 2)).foo | provenance | | | command-line-parameter-command-injection.js:82:29:82:40 | process.argv | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | provenance | | -| command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | provenance | | +| command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | provenance | Config | | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | command-line-parameter-command-injection.js:85:10:85:59 | "cmd.sh ... 2)).foo | provenance | | | command-line-parameter-command-injection.js:85:34:85:45 | process.argv | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | provenance | | -| command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | provenance | | +| command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | provenance | Config | | command-line-parameter-command-injection.js:88:6:88:37 | flags | command-line-parameter-command-injection.js:89:22:89:26 | flags | provenance | | | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | command-line-parameter-command-injection.js:88:6:88:37 | flags | provenance | | -| command-line-parameter-command-injection.js:88:25:88:36 | process.argv | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | provenance | | +| command-line-parameter-command-injection.js:88:25:88:36 | process.argv | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | provenance | Config | | command-line-parameter-command-injection.js:89:22:89:26 | flags | command-line-parameter-command-injection.js:89:10:89:30 | "cmd.sh ... ags.foo | provenance | | | command-line-parameter-command-injection.js:91:6:91:38 | flags | command-line-parameter-command-injection.js:92:22:92:26 | flags | provenance | | | command-line-parameter-command-injection.js:91:14:91:38 | require ... .spec}) | command-line-parameter-command-injection.js:91:6:91:38 | flags | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/ImproperCodeSanitization.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/ImproperCodeSanitization.expected index ee2425775bb..6e8db046097 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/ImproperCodeSanitization.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/ImproperCodeSanitization.expected @@ -1,13 +1,13 @@ edges -| bad-code-sanitization.js:2:12:2:90 | /^[_$a- ... key)}]` | bad-code-sanitization.js:7:31:7:43 | safeProp(key) | -| bad-code-sanitization.js:2:69:2:87 | JSON.stringify(key) | bad-code-sanitization.js:2:12:2:90 | /^[_$a- ... key)}]` | -| bad-code-sanitization.js:6:11:6:25 | statements | bad-code-sanitization.js:8:27:8:36 | statements | -| bad-code-sanitization.js:7:5:7:14 | [post update] statements | bad-code-sanitization.js:6:11:6:25 | statements | -| bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | bad-code-sanitization.js:7:5:7:14 | [post update] statements | -| bad-code-sanitization.js:7:31:7:43 | safeProp(key) | bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | -| bad-code-sanitization.js:8:27:8:36 | statements | bad-code-sanitization.js:8:27:8:46 | statements.join(';') | -| bad-code-sanitization.js:63:11:63:55 | assignment | bad-code-sanitization.js:64:27:64:36 | assignment | -| bad-code-sanitization.js:63:31:63:49 | JSON.stringify(key) | bad-code-sanitization.js:63:11:63:55 | assignment | +| bad-code-sanitization.js:2:12:2:90 | /^[_$a- ... key)}]` | bad-code-sanitization.js:7:31:7:43 | safeProp(key) | provenance | | +| bad-code-sanitization.js:2:69:2:87 | JSON.stringify(key) | bad-code-sanitization.js:2:12:2:90 | /^[_$a- ... key)}]` | provenance | | +| bad-code-sanitization.js:6:11:6:25 | statements | bad-code-sanitization.js:8:27:8:36 | statements | provenance | | +| bad-code-sanitization.js:7:5:7:14 | [post update] statements | bad-code-sanitization.js:6:11:6:25 | statements | provenance | | +| bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | bad-code-sanitization.js:7:5:7:14 | [post update] statements | provenance | | +| bad-code-sanitization.js:7:31:7:43 | safeProp(key) | bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | provenance | | +| bad-code-sanitization.js:8:27:8:36 | statements | bad-code-sanitization.js:8:27:8:46 | statements.join(';') | provenance | | +| bad-code-sanitization.js:63:11:63:55 | assignment | bad-code-sanitization.js:64:27:64:36 | assignment | provenance | | +| bad-code-sanitization.js:63:31:63:49 | JSON.stringify(key) | bad-code-sanitization.js:63:11:63:55 | assignment | provenance | | nodes | bad-code-sanitization.js:2:12:2:90 | /^[_$a- ... key)}]` | semmle.label | /^[_$a- ... key)}]` | | bad-code-sanitization.js:2:69:2:87 | JSON.stringify(key) | semmle.label | JSON.stringify(key) | diff --git a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected index 12f0b7bb5a7..086af0f7bdf 100644 --- a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected +++ b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected @@ -9,32 +9,32 @@ edges | HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:195:46:195:49 | AUTH | provenance | | | HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:204:44:204:47 | AUTH | provenance | | | HardcodedCredentials.js:173:18:173:49 | base64. ... PASS}`) | HardcodedCredentials.js:173:11:173:49 | AUTH | provenance | | -| HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | HardcodedCredentials.js:173:18:173:49 | base64. ... PASS}`) | provenance | | -| HardcodedCredentials.js:173:35:173:38 | USER | HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | provenance | | -| HardcodedCredentials.js:173:43:173:46 | PASS | HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | provenance | | -| HardcodedCredentials.js:178:39:178:42 | AUTH | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | provenance | | -| HardcodedCredentials.js:188:39:188:42 | AUTH | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | provenance | | -| HardcodedCredentials.js:195:46:195:49 | AUTH | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | provenance | | -| HardcodedCredentials.js:204:44:204:47 | AUTH | HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` | provenance | | +| HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | HardcodedCredentials.js:173:18:173:49 | base64. ... PASS}`) | provenance | Config | +| HardcodedCredentials.js:173:35:173:38 | USER | HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | provenance | Config | +| HardcodedCredentials.js:173:43:173:46 | PASS | HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | provenance | Config | +| HardcodedCredentials.js:178:39:178:42 | AUTH | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | provenance | Config | +| HardcodedCredentials.js:188:39:188:42 | AUTH | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | provenance | Config | +| HardcodedCredentials.js:195:46:195:49 | AUTH | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | provenance | Config | +| HardcodedCredentials.js:204:44:204:47 | AUTH | HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` | provenance | Config | | HardcodedCredentials.js:214:11:214:25 | USER | HardcodedCredentials.js:216:35:216:38 | USER | provenance | | | HardcodedCredentials.js:214:18:214:25 | 'sdsdag' | HardcodedCredentials.js:214:11:214:25 | USER | provenance | | | HardcodedCredentials.js:215:11:215:25 | PASS | HardcodedCredentials.js:216:43:216:46 | PASS | provenance | | | HardcodedCredentials.js:215:18:215:25 | 'sdsdag' | HardcodedCredentials.js:215:11:215:25 | PASS | provenance | | | HardcodedCredentials.js:216:11:216:49 | AUTH | HardcodedCredentials.js:221:46:221:49 | AUTH | provenance | | | HardcodedCredentials.js:216:18:216:49 | base64. ... PASS}`) | HardcodedCredentials.js:216:11:216:49 | AUTH | provenance | | -| HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | HardcodedCredentials.js:216:18:216:49 | base64. ... PASS}`) | provenance | | -| HardcodedCredentials.js:216:35:216:38 | USER | HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | provenance | | -| HardcodedCredentials.js:216:43:216:46 | PASS | HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | provenance | | -| HardcodedCredentials.js:221:46:221:49 | AUTH | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | provenance | | +| HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | HardcodedCredentials.js:216:18:216:49 | base64. ... PASS}`) | provenance | Config | +| HardcodedCredentials.js:216:35:216:38 | USER | HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | provenance | Config | +| HardcodedCredentials.js:216:43:216:46 | PASS | HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | provenance | Config | +| HardcodedCredentials.js:221:46:221:49 | AUTH | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | provenance | Config | | HardcodedCredentials.js:231:11:231:29 | username | HardcodedCredentials.js:237:47:237:54 | username | provenance | | | HardcodedCredentials.js:231:22:231:29 | 'sdsdag' | HardcodedCredentials.js:231:11:231:29 | username | provenance | | -| HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) | HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | provenance | | -| HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') | provenance | | -| HardcodedCredentials.js:237:47:237:54 | username | HardcodedCredentials.js:237:47:237:71 | usernam ... assword | provenance | | -| HardcodedCredentials.js:237:47:237:71 | usernam ... assword | HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) | provenance | | +| HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) | HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | provenance | Config | +| HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') | provenance | Config | +| HardcodedCredentials.js:237:47:237:54 | username | HardcodedCredentials.js:237:47:237:71 | usernam ... assword | provenance | Config | +| HardcodedCredentials.js:237:47:237:71 | usernam ... assword | HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) | provenance | Config | | HardcodedCredentials.js:245:9:245:44 | privateKey | HardcodedCredentials.js:246:42:246:51 | privateKey | provenance | | | HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:245:9:245:44 | privateKey | provenance | | -| HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | HardcodedCredentials.js:268:30:268:73 | `${foo ... Token}` | provenance | | +| HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | HardcodedCredentials.js:268:30:268:73 | `${foo ... Token}` | provenance | Config | | HardcodedCredentials.js:268:39:268:46 | 'Bearer' | HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | provenance | | | HardcodedCredentials.js:268:50:268:56 | 'OAuth' | HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | provenance | | nodes @@ -90,8 +90,8 @@ nodes | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | semmle.label | 'hgfedcba' | | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | semmle.label | 'hgfedcba' | | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | semmle.label | "hgfedcba" | -| HardcodedCredentials.js:160:38:160:48 | "change_me" | semmle.label | "change_me" | -| HardcodedCredentials.js:161:41:161:51 | 'change_me' | semmle.label | 'change_me' | +| HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | semmle.label | "oiuneawrgiyubaegr" | +| HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | semmle.label | 'oiuneawrgiyubaegr' | | HardcodedCredentials.js:164:35:164:45 | 'change_me' | semmle.label | 'change_me' | | HardcodedCredentials.js:171:11:171:25 | USER | semmle.label | USER | | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | semmle.label | 'sdsdag' | @@ -152,6 +152,10 @@ nodes | HardcodedCredentials.js:293:37:293:65 | `Basic ... xxxxxx` | semmle.label | `Basic ... xxxxxx` | | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | semmle.label | `Basic ... gbbbbb` | | HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | semmle.label | `Basic ... 000001` | +| HardcodedCredentials.js:299:44:299:52 | 'mytoken' | semmle.label | 'mytoken' | +| HardcodedCredentials.js:300:44:300:56 | 'SampleToken' | semmle.label | 'SampleToken' | +| HardcodedCredentials.js:301:44:301:55 | 'MyPassword' | semmle.label | 'MyPassword' | +| HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | semmle.label | 'iubfew ... ybgera' | subpaths #select | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | The hard-coded value "dbuser" is used as $@. | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | user name | @@ -202,8 +206,8 @@ subpaths | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | The hard-coded value "hgfedcba" is used as $@. | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | key | | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | The hard-coded value "hgfedcba" is used as $@. | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | key | | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | The hard-coded value "hgfedcba" is used as $@. | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | key | -| HardcodedCredentials.js:160:38:160:48 | "change_me" | HardcodedCredentials.js:160:38:160:48 | "change_me" | HardcodedCredentials.js:160:38:160:48 | "change_me" | The hard-coded value "change_me" is used as $@. | HardcodedCredentials.js:160:38:160:48 | "change_me" | key | -| HardcodedCredentials.js:161:41:161:51 | 'change_me' | HardcodedCredentials.js:161:41:161:51 | 'change_me' | HardcodedCredentials.js:161:41:161:51 | 'change_me' | The hard-coded value "change_me" is used as $@. | HardcodedCredentials.js:161:41:161:51 | 'change_me' | key | +| HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | The hard-coded value "oiuneawrgiyubaegr" is used as $@. | HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | key | +| HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | The hard-coded value "oiuneawrgiyubaegr" is used as $@. | HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | key | | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | authorization header | | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | authorization header | | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | authorization header | @@ -218,3 +222,4 @@ subpaths | HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:246:42:246:51 | privateKey | The hard-coded value "myHardCodedPrivateKey" is used as $@. | HardcodedCredentials.js:246:42:246:51 | privateKey | key | | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | The hard-coded value "Basic sdsdag:sdsdag" is used as $@. | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | authorization header | | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | The hard-coded value "Basic sdsdag:aaaiuogrweuibgbbbbb" is used as $@. | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | authorization header | +| HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | The hard-coded value "iubfewiaaweiybgaeuybgera" is used as $@. | HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | key | From e53c0cdce71ae60d5e198cad96f2a0e32517c9be Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 27 Jun 2024 09:39:06 +0200 Subject: [PATCH 214/514] Fix unknown Parameter/Argument decoding --- .../javascript/dataflow/internal/FlowSummaryPrivate.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index 1186c713e9a..ddf7d450d11 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -180,7 +180,7 @@ string encodeWithContent(ContentSet c, string arg) { result = "With" + encodeCon */ bindingset[token] ParameterPosition decodeUnknownParameterPosition(AccessPathSyntax::AccessPathTokenBase token) { - token.getName() = "Parameter" and + token.getName() = "Argument" and desugaredPositionName(result, token.getAnArgument()) } @@ -194,7 +194,7 @@ ParameterPosition decodeUnknownParameterPosition(AccessPathSyntax::AccessPathTok */ bindingset[token] ArgumentPosition decodeUnknownArgumentPosition(AccessPathSyntax::AccessPathTokenBase token) { - token.getName() = "Argument" and + token.getName() = "Parameter" and desugaredPositionName(result, token.getAnArgument()) } From c52a4b0621898639672240ef4cbefb628c743e46 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 27 Jun 2024 09:44:45 +0200 Subject: [PATCH 215/514] JS: Provide RenderSummarizedCallable --- .../semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index ddf7d450d11..24b1081d932 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -139,6 +139,8 @@ private module FlowSummaryStepInput implements Private::StepsInputSig { module Steps = Private::Steps; +module RenderSummarizedCallable = Private::RenderSummarizedCallable; + /** * Gets the textual representation of return kind `rk` used in MaD. * From df0488a4700919689169b6a8f19733dcd54dcb89 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 27 Jun 2024 10:22:14 +0200 Subject: [PATCH 216/514] Ensure Member tokens from flow summaries are seen in PropertyName --- .../javascript/dataflow/internal/Contents.qll | 20 ++++++++++++------- .../dataflow/internal/FlowSummaryPrivate.qll | 4 ++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll index 6c6272e6e32..a359ee0d1d5 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll @@ -1,5 +1,7 @@ private import javascript private import semmle.javascript.frameworks.data.internal.ApiGraphModels as ApiGraphModels +private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate +private import codeql.dataflow.internal.AccessPathSyntax as AccessPathSyntax module Private { import Public @@ -15,6 +17,15 @@ module Private { /** Gets the largest array index should be propagated precisely through flow summaries. */ int getAPreciseArrayIndex() { result = [0 .. getMaxPreciseArrayIndex()] } + /** + * Holds if a MaD access path token of form `name[arg]` exists. + */ + predicate isAccessPathTokenPresent(string name, string arg) { + arg = any(FlowSummaryPrivate::AccessPathToken tok).getAnArgument(name) + or + arg = any(ApiGraphModels::AccessPathToken tok).getAnArgument(name) + } + /** * Holds if values associated with `key` should be tracked as a individual contents of a `Map` object. */ @@ -25,10 +36,7 @@ module Private { call.getArgument(0).getStringValue() = key ) or - exists(ApiGraphModels::AccessPathToken token | - token.getName() = "MapValue" and - token.getAnArgument() = key - ) + isAccessPathTokenPresent("MapValue", key) } /** @@ -47,9 +55,7 @@ module Private { or this = getAPreciseArrayIndex().toString() or - exists(ApiGraphModels::AccessPathToken tok | - tok.getName() = "Member" and this = tok.getAnArgument() - ) + isAccessPathTokenPresent("Member", this) } /** Gets the array index corresponding to this property name. */ diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index 24b1081d932..d978f81fb8a 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -141,6 +141,10 @@ module Steps = Private::Steps; module RenderSummarizedCallable = Private::RenderSummarizedCallable; +class AccessPath = Private::AccessPath; + +class AccessPathToken = Private::AccessPathToken; + /** * Gets the textual representation of return kind `rk` used in MaD. * From ee10702e7346478c875fff12d2269bb82fd3a115 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 27 Jun 2024 11:56:01 +0200 Subject: [PATCH 217/514] JS: Another provanance test output update --- .../CommandInjection.expected | 206 +++++++++--------- 1 file changed, 103 insertions(+), 103 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected index 6126cef4888..82521f20efa 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected @@ -1,107 +1,107 @@ edges -| actions.js:8:9:8:57 | title | actions.js:9:16:9:20 | title | -| actions.js:8:17:8:57 | github. ... t.title | actions.js:8:9:8:57 | title | -| actions.js:9:16:9:20 | title | actions.js:9:8:9:22 | `echo ${title}` | -| actions.js:18:9:18:63 | head_ref | actions.js:19:22:19:29 | head_ref | -| actions.js:18:20:18:63 | github. ... ead.ref | actions.js:18:9:18:63 | head_ref | -| actions.js:19:22:19:29 | head_ref | actions.js:19:14:19:31 | `echo ${head_ref}` | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:17:13:17:15 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:18:17:18:19 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:19:17:19:19 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:20:21:20:23 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:21:14:21:16 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:22:18:22:20 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:23:13:23:15 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:25:21:25:23 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:39:26:39:28 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:43:15:43:17 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:48:15:48:17 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:53:15:53:17 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:56:54:56:56 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:56:54:56:56 | cmd | -| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:57:46:57:48 | cmd | -| child_process-test.js:6:15:6:38 | url.par ... , true) | child_process-test.js:6:9:6:49 | cmd | -| child_process-test.js:6:15:6:38 | url.par ... , true) | child_process-test.js:6:15:6:49 | url.par ... ry.path | -| child_process-test.js:6:15:6:38 | url.par ... , true) | child_process-test.js:6:15:6:49 | url.par ... ry.path | -| child_process-test.js:6:15:6:49 | url.par ... ry.path | child_process-test.js:6:9:6:49 | cmd | -| child_process-test.js:6:25:6:31 | req.url | child_process-test.js:6:15:6:38 | url.par ... , true) | -| child_process-test.js:25:21:25:23 | cmd | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | -| child_process-test.js:56:46:56:57 | ["bar", cmd] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | -| child_process-test.js:56:46:56:57 | ["bar", cmd] [1] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | -| child_process-test.js:56:54:56:56 | cmd | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | -| child_process-test.js:56:54:56:56 | cmd | child_process-test.js:56:46:56:57 | ["bar", cmd] | -| child_process-test.js:56:54:56:56 | cmd | child_process-test.js:56:46:56:57 | ["bar", cmd] [1] | -| child_process-test.js:57:46:57:48 | cmd | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) | -| child_process-test.js:73:9:73:49 | cmd | child_process-test.js:75:29:75:31 | cmd | -| child_process-test.js:73:15:73:38 | url.par ... , true) | child_process-test.js:73:9:73:49 | cmd | -| child_process-test.js:73:25:73:31 | req.url | child_process-test.js:73:15:73:38 | url.par ... , true) | -| child_process-test.js:94:21:94:30 | ctx.params | child_process-test.js:94:11:94:35 | "ping " ... ms.host | -| exec-sh2.js:9:17:9:23 | command | exec-sh2.js:10:40:10:46 | command | -| exec-sh2.js:14:9:14:49 | cmd | exec-sh2.js:15:12:15:14 | cmd | -| exec-sh2.js:14:15:14:38 | url.par ... , true) | exec-sh2.js:14:9:14:49 | cmd | -| exec-sh2.js:14:25:14:31 | req.url | exec-sh2.js:14:15:14:38 | url.par ... , true) | -| exec-sh2.js:15:12:15:14 | cmd | exec-sh2.js:9:17:9:23 | command | -| exec-sh.js:13:17:13:23 | command | exec-sh.js:15:44:15:50 | command | -| exec-sh.js:19:9:19:49 | cmd | exec-sh.js:20:12:20:14 | cmd | -| exec-sh.js:19:15:19:38 | url.par ... , true) | exec-sh.js:19:9:19:49 | cmd | -| exec-sh.js:19:25:19:31 | req.url | exec-sh.js:19:15:19:38 | url.par ... , true) | -| exec-sh.js:20:12:20:14 | cmd | exec-sh.js:13:17:13:23 | command | -| execSeries.js:3:20:3:22 | arr | execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr] | -| execSeries.js:3:20:3:22 | arr | execSeries.js:6:14:6:16 | arr | -| execSeries.js:3:20:3:22 | arr [0] | execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr, 0] | -| execSeries.js:3:20:3:22 | arr [0] | execSeries.js:6:14:6:16 | arr [0] | -| execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr, 0] | execSeries.js:6:14:6:16 | arr [0] | -| execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr] | execSeries.js:6:14:6:16 | arr | -| execSeries.js:6:14:6:16 | arr | execSeries.js:6:14:6:21 | arr[i++] | -| execSeries.js:6:14:6:16 | arr [0] | execSeries.js:6:14:6:21 | arr[i++] | -| execSeries.js:6:14:6:21 | arr[i++] | execSeries.js:14:24:14:30 | command | -| execSeries.js:13:19:13:26 | commands | execSeries.js:14:13:14:20 | commands | -| execSeries.js:13:19:13:26 | commands [0] | execSeries.js:14:13:14:20 | commands [0] | -| execSeries.js:14:13:14:20 | commands | execSeries.js:3:20:3:22 | arr | -| execSeries.js:14:13:14:20 | commands [0] | execSeries.js:3:20:3:22 | arr [0] | -| execSeries.js:14:24:14:30 | command | execSeries.js:14:41:14:47 | command | -| execSeries.js:18:7:18:58 | cmd | execSeries.js:19:13:19:15 | cmd | -| execSeries.js:18:13:18:47 | require ... , true) | execSeries.js:18:7:18:58 | cmd | -| execSeries.js:18:34:18:40 | req.url | execSeries.js:18:13:18:47 | require ... , true) | -| execSeries.js:19:12:19:16 | [cmd] | execSeries.js:13:19:13:26 | commands | -| execSeries.js:19:12:19:16 | [cmd] [0] | execSeries.js:13:19:13:26 | commands [0] | -| execSeries.js:19:13:19:15 | cmd | execSeries.js:19:12:19:16 | [cmd] | -| execSeries.js:19:13:19:15 | cmd | execSeries.js:19:12:19:16 | [cmd] [0] | -| form-parsers.js:9:19:9:26 | req.file | form-parsers.js:9:8:9:39 | "touch ... nalname | -| form-parsers.js:13:3:13:11 | req.files | form-parsers.js:13:21:13:24 | file | -| form-parsers.js:13:21:13:24 | file | form-parsers.js:14:21:14:24 | file | -| form-parsers.js:14:21:14:24 | file | form-parsers.js:14:10:14:37 | "touch ... nalname | -| form-parsers.js:24:48:24:55 | filename | form-parsers.js:25:21:25:28 | filename | -| form-parsers.js:25:21:25:28 | filename | form-parsers.js:25:10:25:28 | "touch " + filename | -| form-parsers.js:35:25:35:30 | fields | form-parsers.js:36:21:36:26 | fields | -| form-parsers.js:36:21:36:26 | fields | form-parsers.js:36:10:36:31 | "touch ... ds.name | -| form-parsers.js:40:26:40:31 | fields | form-parsers.js:41:21:41:26 | fields | -| form-parsers.js:41:21:41:26 | fields | form-parsers.js:41:10:41:31 | "touch ... ds.name | -| form-parsers.js:52:34:52:39 | fields | form-parsers.js:53:21:53:26 | fields | -| form-parsers.js:53:21:53:26 | fields | form-parsers.js:53:10:53:31 | "touch ... ds.name | -| form-parsers.js:58:30:58:33 | part | form-parsers.js:59:21:59:24 | part | -| form-parsers.js:59:21:59:24 | part | form-parsers.js:59:10:59:33 | "touch ... ilename | -| other.js:5:9:5:49 | cmd | other.js:7:33:7:35 | cmd | -| other.js:5:9:5:49 | cmd | other.js:8:28:8:30 | cmd | -| other.js:5:9:5:49 | cmd | other.js:9:32:9:34 | cmd | -| other.js:5:9:5:49 | cmd | other.js:10:29:10:31 | cmd | -| other.js:5:9:5:49 | cmd | other.js:11:29:11:31 | cmd | -| other.js:5:9:5:49 | cmd | other.js:12:27:12:29 | cmd | -| other.js:5:9:5:49 | cmd | other.js:14:28:14:30 | cmd | -| other.js:5:9:5:49 | cmd | other.js:15:34:15:36 | cmd | -| other.js:5:9:5:49 | cmd | other.js:16:21:16:23 | cmd | -| other.js:5:9:5:49 | cmd | other.js:17:27:17:29 | cmd | -| other.js:5:9:5:49 | cmd | other.js:18:22:18:24 | cmd | -| other.js:5:9:5:49 | cmd | other.js:19:36:19:38 | cmd | -| other.js:5:9:5:49 | cmd | other.js:22:21:22:23 | cmd | -| other.js:5:9:5:49 | cmd | other.js:23:28:23:30 | cmd | -| other.js:5:9:5:49 | cmd | other.js:26:34:26:36 | cmd | -| other.js:5:9:5:49 | cmd | other.js:28:27:28:29 | cmd | -| other.js:5:9:5:49 | cmd | other.js:30:33:30:35 | cmd | -| other.js:5:9:5:49 | cmd | other.js:34:44:34:46 | cmd | -| other.js:5:15:5:38 | url.par ... , true) | other.js:5:9:5:49 | cmd | -| other.js:5:25:5:31 | req.url | other.js:5:15:5:38 | url.par ... , true) | -| third-party-command-injection.js:5:20:5:26 | command | third-party-command-injection.js:6:21:6:27 | command | +| actions.js:8:9:8:57 | title | actions.js:9:16:9:20 | title | provenance | | +| actions.js:8:17:8:57 | github. ... t.title | actions.js:8:9:8:57 | title | provenance | | +| actions.js:9:16:9:20 | title | actions.js:9:8:9:22 | `echo ${title}` | provenance | | +| actions.js:18:9:18:63 | head_ref | actions.js:19:22:19:29 | head_ref | provenance | | +| actions.js:18:20:18:63 | github. ... ead.ref | actions.js:18:9:18:63 | head_ref | provenance | | +| actions.js:19:22:19:29 | head_ref | actions.js:19:14:19:31 | `echo ${head_ref}` | provenance | | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:17:13:17:15 | cmd | provenance | | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:18:17:18:19 | cmd | provenance | | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:19:17:19:19 | cmd | provenance | | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:20:21:20:23 | cmd | provenance | | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:21:14:21:16 | cmd | provenance | | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:22:18:22:20 | cmd | provenance | | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:23:13:23:15 | cmd | provenance | | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:25:21:25:23 | cmd | provenance | | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:39:26:39:28 | cmd | provenance | | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:43:15:43:17 | cmd | provenance | | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:48:15:48:17 | cmd | provenance | | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:53:15:53:17 | cmd | provenance | | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:56:54:56:56 | cmd | provenance | | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:56:54:56:56 | cmd | provenance | | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:57:46:57:48 | cmd | provenance | | +| child_process-test.js:6:15:6:38 | url.par ... , true) | child_process-test.js:6:9:6:49 | cmd | provenance | | +| child_process-test.js:6:15:6:38 | url.par ... , true) | child_process-test.js:6:15:6:49 | url.par ... ry.path | provenance | | +| child_process-test.js:6:15:6:38 | url.par ... , true) | child_process-test.js:6:15:6:49 | url.par ... ry.path | provenance | | +| child_process-test.js:6:15:6:49 | url.par ... ry.path | child_process-test.js:6:9:6:49 | cmd | provenance | | +| child_process-test.js:6:25:6:31 | req.url | child_process-test.js:6:15:6:38 | url.par ... , true) | provenance | | +| child_process-test.js:25:21:25:23 | cmd | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | provenance | | +| child_process-test.js:56:46:56:57 | ["bar", cmd] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | provenance | | +| child_process-test.js:56:46:56:57 | ["bar", cmd] [1] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | provenance | | +| child_process-test.js:56:54:56:56 | cmd | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | provenance | | +| child_process-test.js:56:54:56:56 | cmd | child_process-test.js:56:46:56:57 | ["bar", cmd] | provenance | | +| child_process-test.js:56:54:56:56 | cmd | child_process-test.js:56:46:56:57 | ["bar", cmd] [1] | provenance | | +| child_process-test.js:57:46:57:48 | cmd | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) | provenance | | +| child_process-test.js:73:9:73:49 | cmd | child_process-test.js:75:29:75:31 | cmd | provenance | | +| child_process-test.js:73:15:73:38 | url.par ... , true) | child_process-test.js:73:9:73:49 | cmd | provenance | | +| child_process-test.js:73:25:73:31 | req.url | child_process-test.js:73:15:73:38 | url.par ... , true) | provenance | | +| child_process-test.js:94:21:94:30 | ctx.params | child_process-test.js:94:11:94:35 | "ping " ... ms.host | provenance | | +| exec-sh2.js:9:17:9:23 | command | exec-sh2.js:10:40:10:46 | command | provenance | | +| exec-sh2.js:14:9:14:49 | cmd | exec-sh2.js:15:12:15:14 | cmd | provenance | | +| exec-sh2.js:14:15:14:38 | url.par ... , true) | exec-sh2.js:14:9:14:49 | cmd | provenance | | +| exec-sh2.js:14:25:14:31 | req.url | exec-sh2.js:14:15:14:38 | url.par ... , true) | provenance | | +| exec-sh2.js:15:12:15:14 | cmd | exec-sh2.js:9:17:9:23 | command | provenance | | +| exec-sh.js:13:17:13:23 | command | exec-sh.js:15:44:15:50 | command | provenance | | +| exec-sh.js:19:9:19:49 | cmd | exec-sh.js:20:12:20:14 | cmd | provenance | | +| exec-sh.js:19:15:19:38 | url.par ... , true) | exec-sh.js:19:9:19:49 | cmd | provenance | | +| exec-sh.js:19:25:19:31 | req.url | exec-sh.js:19:15:19:38 | url.par ... , true) | provenance | | +| exec-sh.js:20:12:20:14 | cmd | exec-sh.js:13:17:13:23 | command | provenance | | +| execSeries.js:3:20:3:22 | arr | execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr] | provenance | | +| execSeries.js:3:20:3:22 | arr | execSeries.js:6:14:6:16 | arr | provenance | | +| execSeries.js:3:20:3:22 | arr [0] | execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr, 0] | provenance | | +| execSeries.js:3:20:3:22 | arr [0] | execSeries.js:6:14:6:16 | arr [0] | provenance | | +| execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr, 0] | execSeries.js:6:14:6:16 | arr [0] | provenance | | +| execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr] | execSeries.js:6:14:6:16 | arr | provenance | | +| execSeries.js:6:14:6:16 | arr | execSeries.js:6:14:6:21 | arr[i++] | provenance | | +| execSeries.js:6:14:6:16 | arr [0] | execSeries.js:6:14:6:21 | arr[i++] | provenance | | +| execSeries.js:6:14:6:21 | arr[i++] | execSeries.js:14:24:14:30 | command | provenance | | +| execSeries.js:13:19:13:26 | commands | execSeries.js:14:13:14:20 | commands | provenance | | +| execSeries.js:13:19:13:26 | commands [0] | execSeries.js:14:13:14:20 | commands [0] | provenance | | +| execSeries.js:14:13:14:20 | commands | execSeries.js:3:20:3:22 | arr | provenance | | +| execSeries.js:14:13:14:20 | commands [0] | execSeries.js:3:20:3:22 | arr [0] | provenance | | +| execSeries.js:14:24:14:30 | command | execSeries.js:14:41:14:47 | command | provenance | | +| execSeries.js:18:7:18:58 | cmd | execSeries.js:19:13:19:15 | cmd | provenance | | +| execSeries.js:18:13:18:47 | require ... , true) | execSeries.js:18:7:18:58 | cmd | provenance | | +| execSeries.js:18:34:18:40 | req.url | execSeries.js:18:13:18:47 | require ... , true) | provenance | | +| execSeries.js:19:12:19:16 | [cmd] | execSeries.js:13:19:13:26 | commands | provenance | | +| execSeries.js:19:12:19:16 | [cmd] [0] | execSeries.js:13:19:13:26 | commands [0] | provenance | | +| execSeries.js:19:13:19:15 | cmd | execSeries.js:19:12:19:16 | [cmd] | provenance | | +| execSeries.js:19:13:19:15 | cmd | execSeries.js:19:12:19:16 | [cmd] [0] | provenance | | +| form-parsers.js:9:19:9:26 | req.file | form-parsers.js:9:8:9:39 | "touch ... nalname | provenance | | +| form-parsers.js:13:3:13:11 | req.files | form-parsers.js:13:21:13:24 | file | provenance | | +| form-parsers.js:13:21:13:24 | file | form-parsers.js:14:21:14:24 | file | provenance | | +| form-parsers.js:14:21:14:24 | file | form-parsers.js:14:10:14:37 | "touch ... nalname | provenance | | +| form-parsers.js:24:48:24:55 | filename | form-parsers.js:25:21:25:28 | filename | provenance | | +| form-parsers.js:25:21:25:28 | filename | form-parsers.js:25:10:25:28 | "touch " + filename | provenance | | +| form-parsers.js:35:25:35:30 | fields | form-parsers.js:36:21:36:26 | fields | provenance | | +| form-parsers.js:36:21:36:26 | fields | form-parsers.js:36:10:36:31 | "touch ... ds.name | provenance | | +| form-parsers.js:40:26:40:31 | fields | form-parsers.js:41:21:41:26 | fields | provenance | | +| form-parsers.js:41:21:41:26 | fields | form-parsers.js:41:10:41:31 | "touch ... ds.name | provenance | | +| form-parsers.js:52:34:52:39 | fields | form-parsers.js:53:21:53:26 | fields | provenance | | +| form-parsers.js:53:21:53:26 | fields | form-parsers.js:53:10:53:31 | "touch ... ds.name | provenance | | +| form-parsers.js:58:30:58:33 | part | form-parsers.js:59:21:59:24 | part | provenance | | +| form-parsers.js:59:21:59:24 | part | form-parsers.js:59:10:59:33 | "touch ... ilename | provenance | | +| other.js:5:9:5:49 | cmd | other.js:7:33:7:35 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:8:28:8:30 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:9:32:9:34 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:10:29:10:31 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:11:29:11:31 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:12:27:12:29 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:14:28:14:30 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:15:34:15:36 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:16:21:16:23 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:17:27:17:29 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:18:22:18:24 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:19:36:19:38 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:22:21:22:23 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:23:28:23:30 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:26:34:26:36 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:28:27:28:29 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:30:33:30:35 | cmd | provenance | | +| other.js:5:9:5:49 | cmd | other.js:34:44:34:46 | cmd | provenance | | +| other.js:5:15:5:38 | url.par ... , true) | other.js:5:9:5:49 | cmd | provenance | | +| other.js:5:25:5:31 | req.url | other.js:5:15:5:38 | url.par ... , true) | provenance | | +| third-party-command-injection.js:5:20:5:26 | command | third-party-command-injection.js:6:21:6:27 | command | provenance | | nodes | actions.js:8:9:8:57 | title | semmle.label | title | | actions.js:8:17:8:57 | github. ... t.title | semmle.label | github. ... t.title | From 90f0e07e49421797b23ed244b93ad69c87ecb54b Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 27 Jun 2024 11:56:22 +0200 Subject: [PATCH 218/514] JS: Benign update after fixing PropertyName charpred --- .../InterProceduralFlow/tests.expected | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected b/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected index 94fe390a046..aab7951f480 100644 --- a/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected +++ b/javascript/ql/test/library-tests/InterProceduralFlow/tests.expected @@ -48,6 +48,11 @@ dataFlow | partial.js:6:15:6:24 | "tainted2" | partial.js:42:15:42:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:48:15:48:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:54:15:54:15 | y | +| promises.js:2:16:2:24 | "tainted" | promises.js:7:16:7:18 | val | +| promises.js:2:16:2:24 | "tainted" | promises.js:38:32:38:32 | v | +| promises.js:11:22:11:31 | "resolved" | promises.js:19:20:19:20 | v | +| promises.js:12:22:12:31 | "rejected" | promises.js:21:20:21:20 | v | +| promises.js:12:22:12:31 | "rejected" | promises.js:24:20:24:20 | v | | promises.js:32:24:32:37 | "also tainted" | promises.js:38:32:38:32 | v | | properties2.js:7:14:7:21 | "source" | properties2.js:8:12:8:24 | foo(source).p | | properties2.js:7:14:7:21 | "source" | properties2.js:17:13:17:15 | o.p | @@ -128,6 +133,11 @@ taintTracking | partial.js:6:15:6:24 | "tainted2" | partial.js:42:15:42:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:48:15:48:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:54:15:54:15 | y | +| promises.js:2:16:2:24 | "tainted" | promises.js:7:16:7:18 | val | +| promises.js:2:16:2:24 | "tainted" | promises.js:38:32:38:32 | v | +| promises.js:11:22:11:31 | "resolved" | promises.js:19:20:19:20 | v | +| promises.js:12:22:12:31 | "rejected" | promises.js:21:20:21:20 | v | +| promises.js:12:22:12:31 | "rejected" | promises.js:24:20:24:20 | v | | promises.js:32:24:32:37 | "also tainted" | promises.js:38:32:38:32 | v | | properties2.js:7:14:7:21 | "source" | properties2.js:8:12:8:24 | foo(source).p | | properties2.js:7:14:7:21 | "source" | properties2.js:17:13:17:15 | o.p | @@ -227,6 +237,11 @@ germanFlow | partial.js:6:15:6:24 | "tainted2" | partial.js:42:15:42:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:48:15:48:15 | y | | partial.js:6:15:6:24 | "tainted2" | partial.js:54:15:54:15 | y | +| promises.js:2:16:2:24 | "tainted" | promises.js:7:16:7:18 | val | +| promises.js:2:16:2:24 | "tainted" | promises.js:38:32:38:32 | v | +| promises.js:11:22:11:31 | "resolved" | promises.js:19:20:19:20 | v | +| promises.js:12:22:12:31 | "rejected" | promises.js:21:20:21:20 | v | +| promises.js:12:22:12:31 | "rejected" | promises.js:24:20:24:20 | v | | promises.js:32:24:32:37 | "also tainted" | promises.js:38:32:38:32 | v | | properties2.js:7:14:7:21 | "source" | properties2.js:8:12:8:24 | foo(source).p | | properties2.js:7:14:7:21 | "source" | properties2.js:17:13:17:15 | o.p | From c3806a2210a9f4ce8c21f36c7cf3ba63f3114d5e Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 27 Jun 2024 11:59:56 +0200 Subject: [PATCH 219/514] JS: Messy test output updates These initially got messed up by a merge conflict where I couldn't rerun the tests due to breaking changes in the data flow library. I wanted the breaking-change updates to live in their own commits, not just eaten by a merge resolution commit, so the test output became broken for a while. The '#select' result set is unchanged in all of these, so they should be safe to accept. --- .../CWE-022/TaintedPath/TaintedPath.expected | 5324 ++--------------- .../Security/CWE-079/DomBasedXss/Xss.expected | 2311 ++----- .../XssWithAdditionalSources.expected | 2395 ++------ .../ExceptionXss/ExceptionXss.expected | 148 +- .../ReflectedXss/ReflectedXss.expected | 810 +-- .../CWE-079/StoredXss/StoredXss.expected | 82 +- .../UnsafeHtmlConstruction.expected | 81 +- .../CWE-089/untyped/SqlInjection.expected | 704 +-- .../CWE-312/BuildArtifactLeak.expected | 83 +- 9 files changed, 2540 insertions(+), 9398 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected index f226bc69840..fcc9e4dd3b2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected @@ -1,5 +1,4 @@ nodes -<<<<<<< HEAD | TaintedPath-es6.js:7:7:7:44 | path | semmle.label | path | | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | semmle.label | parse(req.url, true) | | TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | semmle.label | parse(r ... ).query | @@ -139,6 +138,13 @@ nodes | TaintedPath.js:212:31:212:34 | path | semmle.label | path | | TaintedPath.js:213:45:213:48 | path | semmle.label | path | | TaintedPath.js:214:35:214:38 | path | semmle.label | path | +| examples/TaintedPath.js:8:7:8:52 | filePath | semmle.label | filePath | +| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | semmle.label | url.par ... , true) | +| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | semmle.label | url.par ... ).query | +| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| examples/TaintedPath.js:8:28:8:34 | req.url | semmle.label | req.url | +| examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | semmle.label | ROOT + filePath | +| examples/TaintedPath.js:11:36:11:43 | filePath | semmle.label | filePath | | express.js:8:20:8:32 | req.query.bar | semmle.label | req.query.bar | | handlebars.js:10:51:10:58 | filePath | semmle.label | filePath | | handlebars.js:11:32:11:39 | filePath | semmle.label | filePath | @@ -486,4898 +492,432 @@ nodes | typescript.ts:30:15:30:18 | path | semmle.label | path | | typescript.ts:32:29:32:33 | path6 | semmle.label | path6 | | views.js:1:43:1:55 | req.params[0] | semmle.label | req.params[0] | -======= -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:20:7:26 | req.url | -| TaintedPath-es6.js:7:20:7:26 | req.url | -| TaintedPath-es6.js:7:20:7:26 | req.url | -| TaintedPath-es6.js:7:20:7:26 | req.url | -| TaintedPath-es6.js:7:20:7:26 | req.url | -| TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:24:9:30 | req.url | -| TaintedPath.js:9:24:9:30 | req.url | -| TaintedPath.js:9:24:9:30 | req.url | -| TaintedPath.js:9:24:9:30 | req.url | -| TaintedPath.js:9:24:9:30 | req.url | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:20:38:26 | req.url | -| TaintedPath.js:38:20:38:26 | req.url | -| TaintedPath.js:38:20:38:26 | req.url | -| TaintedPath.js:38:20:38:26 | req.url | -| TaintedPath.js:38:20:38:26 | req.url | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:63:77:69 | req.url | -| TaintedPath.js:77:63:77:69 | req.url | -| TaintedPath.js:77:63:77:69 | req.url | -| TaintedPath.js:77:63:77:69 | req.url | -| TaintedPath.js:77:63:77:69 | req.url | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:61:78:67 | req.url | -| TaintedPath.js:78:61:78:67 | req.url | -| TaintedPath.js:78:61:78:67 | req.url | -| TaintedPath.js:78:61:78:67 | req.url | -| TaintedPath.js:78:61:78:67 | req.url | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:60:79:66 | req.url | -| TaintedPath.js:79:60:79:66 | req.url | -| TaintedPath.js:79:60:79:66 | req.url | -| TaintedPath.js:79:60:79:66 | req.url | -| TaintedPath.js:79:60:79:66 | req.url | -| TaintedPath.js:87:48:87:60 | req.params[0] | -| TaintedPath.js:87:48:87:60 | req.params[0] | -| TaintedPath.js:87:48:87:60 | req.params[0] | -| TaintedPath.js:87:48:87:60 | req.params[0] | -| TaintedPath.js:87:48:87:60 | req.params[0] | -| TaintedPath.js:87:48:87:60 | req.params[0] | -| TaintedPath.js:95:30:95:31 | ev | -| TaintedPath.js:95:30:95:31 | ev | -| TaintedPath.js:95:30:95:31 | ev | -| TaintedPath.js:95:30:95:31 | ev | -| TaintedPath.js:95:30:95:31 | ev | -| TaintedPath.js:96:24:96:25 | ev | -| TaintedPath.js:96:24:96:25 | ev | -| TaintedPath.js:96:24:96:25 | ev | -| TaintedPath.js:96:24:96:25 | ev | -| TaintedPath.js:96:24:96:30 | ev.data | -| TaintedPath.js:96:24:96:30 | ev.data | -| TaintedPath.js:96:24:96:30 | ev.data | -| TaintedPath.js:96:24:96:30 | ev.data | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:23:100:29 | req.url | -| TaintedPath.js:100:23:100:29 | req.url | -| TaintedPath.js:100:23:100:29 | req.url | -| TaintedPath.js:100:23:100:29 | req.url | -| TaintedPath.js:100:23:100:29 | req.url | -| TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:23:136:29 | req.url | -| TaintedPath.js:136:23:136:29 | req.url | -| TaintedPath.js:136:23:136:29 | req.url | -| TaintedPath.js:136:23:136:29 | req.url | -| TaintedPath.js:136:23:136:29 | req.url | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:24:142:30 | req.url | -| TaintedPath.js:142:24:142:30 | req.url | -| TaintedPath.js:142:24:142:30 | req.url | -| TaintedPath.js:142:24:142:30 | req.url | -| TaintedPath.js:142:24:142:30 | req.url | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:146:7:146:29 | split | -| TaintedPath.js:146:7:146:29 | split | -| TaintedPath.js:146:7:146:29 | split | -| TaintedPath.js:146:7:146:29 | split | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:148:19:148:23 | split | -| TaintedPath.js:148:19:148:23 | split | -| TaintedPath.js:148:19:148:23 | split | -| TaintedPath.js:148:19:148:23 | split | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:152:19:152:23 | split | -| TaintedPath.js:152:19:152:23 | split | -| TaintedPath.js:152:19:152:23 | split | -| TaintedPath.js:152:19:152:23 | split | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:153:28:153:32 | split | -| TaintedPath.js:153:28:153:32 | split | -| TaintedPath.js:153:28:153:32 | split | -| TaintedPath.js:153:28:153:32 | split | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:155:7:155:38 | concatted | -| TaintedPath.js:155:7:155:38 | concatted | -| TaintedPath.js:155:7:155:38 | concatted | -| TaintedPath.js:155:7:155:38 | concatted | -| TaintedPath.js:155:19:155:38 | prefix.concat(split) | -| TaintedPath.js:155:19:155:38 | prefix.concat(split) | -| TaintedPath.js:155:19:155:38 | prefix.concat(split) | -| TaintedPath.js:155:19:155:38 | prefix.concat(split) | -| TaintedPath.js:155:33:155:37 | split | -| TaintedPath.js:155:33:155:37 | split | -| TaintedPath.js:155:33:155:37 | split | -| TaintedPath.js:155:33:155:37 | split | -| TaintedPath.js:156:19:156:27 | concatted | -| TaintedPath.js:156:19:156:27 | concatted | -| TaintedPath.js:156:19:156:27 | concatted | -| TaintedPath.js:156:19:156:27 | concatted | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:158:7:158:39 | concatted2 | -| TaintedPath.js:158:7:158:39 | concatted2 | -| TaintedPath.js:158:7:158:39 | concatted2 | -| TaintedPath.js:158:7:158:39 | concatted2 | -| TaintedPath.js:158:20:158:24 | split | -| TaintedPath.js:158:20:158:24 | split | -| TaintedPath.js:158:20:158:24 | split | -| TaintedPath.js:158:20:158:24 | split | -| TaintedPath.js:158:20:158:39 | split.concat(prefix) | -| TaintedPath.js:158:20:158:39 | split.concat(prefix) | -| TaintedPath.js:158:20:158:39 | split.concat(prefix) | -| TaintedPath.js:158:20:158:39 | split.concat(prefix) | -| TaintedPath.js:159:19:159:28 | concatted2 | -| TaintedPath.js:159:19:159:28 | concatted2 | -| TaintedPath.js:159:19:159:28 | concatted2 | -| TaintedPath.js:159:19:159:28 | concatted2 | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:161:19:161:23 | split | -| TaintedPath.js:161:19:161:23 | split | -| TaintedPath.js:161:19:161:23 | split | -| TaintedPath.js:161:19:161:23 | split | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:24:166:30 | req.url | -| TaintedPath.js:166:24:166:30 | req.url | -| TaintedPath.js:166:24:166:30 | req.url | -| TaintedPath.js:166:24:166:30 | req.url | -| TaintedPath.js:166:24:166:30 | req.url | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | -| TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:38:203:44 | req.url | -| TaintedPath.js:203:38:203:44 | req.url | -| TaintedPath.js:203:38:203:44 | req.url | -| TaintedPath.js:203:38:203:44 | req.url | -| TaintedPath.js:203:38:203:44 | req.url | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | -| TaintedPath.js:204:51:204:57 | req.url | -| TaintedPath.js:204:51:204:57 | req.url | -| TaintedPath.js:204:51:204:57 | req.url | -| TaintedPath.js:204:51:204:57 | req.url | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:44:206:50 | req.url | -| TaintedPath.js:206:44:206:50 | req.url | -| TaintedPath.js:206:44:206:50 | req.url | -| TaintedPath.js:206:44:206:50 | req.url | -| TaintedPath.js:206:44:206:50 | req.url | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:24:211:30 | req.url | -| TaintedPath.js:211:24:211:30 | req.url | -| TaintedPath.js:211:24:211:30 | req.url | -| TaintedPath.js:211:24:211:30 | req.url | -| TaintedPath.js:211:24:211:30 | req.url | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:214:35:214:38 | path | -| examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:28:8:34 | req.url | -| examples/TaintedPath.js:8:28:8:34 | req.url | -| examples/TaintedPath.js:8:28:8:34 | req.url | -| examples/TaintedPath.js:8:28:8:34 | req.url | -| examples/TaintedPath.js:8:28:8:34 | req.url | -| examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | -| express.js:8:20:8:32 | req.query.bar | -| express.js:8:20:8:32 | req.query.bar | -| express.js:8:20:8:32 | req.query.bar | -| express.js:8:20:8:32 | req.query.bar | -| express.js:8:20:8:32 | req.query.bar | -| express.js:8:20:8:32 | req.query.bar | -| handlebars.js:10:51:10:58 | filePath | -| handlebars.js:10:51:10:58 | filePath | -| handlebars.js:10:51:10:58 | filePath | -| handlebars.js:10:51:10:58 | filePath | -| handlebars.js:11:32:11:39 | filePath | -| handlebars.js:11:32:11:39 | filePath | -| handlebars.js:11:32:11:39 | filePath | -| handlebars.js:11:32:11:39 | filePath | -| handlebars.js:11:32:11:39 | filePath | -| handlebars.js:13:73:13:80 | filePath | -| handlebars.js:13:73:13:80 | filePath | -| handlebars.js:13:73:13:80 | filePath | -| handlebars.js:13:73:13:80 | filePath | -| handlebars.js:15:25:15:32 | filePath | -| handlebars.js:15:25:15:32 | filePath | -| handlebars.js:15:25:15:32 | filePath | -| handlebars.js:15:25:15:32 | filePath | -| handlebars.js:15:25:15:32 | filePath | -| handlebars.js:29:46:29:60 | req.params.path | -| handlebars.js:29:46:29:60 | req.params.path | -| handlebars.js:29:46:29:60 | req.params.path | -| handlebars.js:29:46:29:60 | req.params.path | -| handlebars.js:29:46:29:60 | req.params.path | -| handlebars.js:43:15:43:29 | req.params.path | -| handlebars.js:43:15:43:29 | req.params.path | -| handlebars.js:43:15:43:29 | req.params.path | -| handlebars.js:43:15:43:29 | req.params.path | -| handlebars.js:43:15:43:29 | req.params.path | -| normalizedPaths.js:11:7:11:27 | path | -| normalizedPaths.js:11:7:11:27 | path | -| normalizedPaths.js:11:7:11:27 | path | -| normalizedPaths.js:11:7:11:27 | path | -| normalizedPaths.js:11:14:11:27 | req.query.path | -| normalizedPaths.js:11:14:11:27 | req.query.path | -| normalizedPaths.js:11:14:11:27 | req.query.path | -| normalizedPaths.js:11:14:11:27 | req.query.path | -| normalizedPaths.js:11:14:11:27 | req.query.path | -| normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:14:19:14:29 | './' + path | -| normalizedPaths.js:14:19:14:29 | './' + path | -| normalizedPaths.js:14:19:14:29 | './' + path | -| normalizedPaths.js:14:19:14:29 | './' + path | -| normalizedPaths.js:14:26:14:29 | path | -| normalizedPaths.js:14:26:14:29 | path | -| normalizedPaths.js:14:26:14:29 | path | -| normalizedPaths.js:15:19:15:22 | path | -| normalizedPaths.js:15:19:15:22 | path | -| normalizedPaths.js:15:19:15:22 | path | -| normalizedPaths.js:15:19:15:22 | path | -| normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:16:35:16:38 | path | -| normalizedPaths.js:16:35:16:38 | path | -| normalizedPaths.js:16:35:16:38 | path | -| normalizedPaths.js:16:35:16:38 | path | -| normalizedPaths.js:17:19:17:57 | pathMod ... , path) | -| normalizedPaths.js:17:19:17:57 | pathMod ... , path) | -| normalizedPaths.js:17:19:17:57 | pathMod ... , path) | -| normalizedPaths.js:17:19:17:57 | pathMod ... , path) | -| normalizedPaths.js:17:53:17:56 | path | -| normalizedPaths.js:17:53:17:56 | path | -| normalizedPaths.js:17:53:17:56 | path | -| normalizedPaths.js:21:7:21:49 | path | -| normalizedPaths.js:21:7:21:49 | path | -| normalizedPaths.js:21:7:21:49 | path | -| normalizedPaths.js:21:7:21:49 | path | -| normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:21:35:21:48 | req.query.path | -| normalizedPaths.js:21:35:21:48 | req.query.path | -| normalizedPaths.js:21:35:21:48 | req.query.path | -| normalizedPaths.js:21:35:21:48 | req.query.path | -| normalizedPaths.js:21:35:21:48 | req.query.path | -| normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:24:19:24:29 | './' + path | -| normalizedPaths.js:24:19:24:29 | './' + path | -| normalizedPaths.js:24:19:24:29 | './' + path | -| normalizedPaths.js:24:26:24:29 | path | -| normalizedPaths.js:24:26:24:29 | path | -| normalizedPaths.js:25:19:25:22 | path | -| normalizedPaths.js:25:19:25:22 | path | -| normalizedPaths.js:25:19:25:22 | path | -| normalizedPaths.js:25:19:25:22 | path | -| normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:26:35:26:38 | path | -| normalizedPaths.js:26:35:26:38 | path | -| normalizedPaths.js:26:35:26:38 | path | -| normalizedPaths.js:26:35:26:38 | path | -| normalizedPaths.js:27:19:27:57 | pathMod ... , path) | -| normalizedPaths.js:27:19:27:57 | pathMod ... , path) | -| normalizedPaths.js:27:19:27:57 | pathMod ... , path) | -| normalizedPaths.js:27:53:27:56 | path | -| normalizedPaths.js:27:53:27:56 | path | -| normalizedPaths.js:31:7:31:49 | path | -| normalizedPaths.js:31:7:31:49 | path | -| normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | -| normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | -| normalizedPaths.js:31:35:31:48 | req.query.path | -| normalizedPaths.js:31:35:31:48 | req.query.path | -| normalizedPaths.js:31:35:31:48 | req.query.path | -| normalizedPaths.js:36:19:36:22 | path | -| normalizedPaths.js:36:19:36:22 | path | -| normalizedPaths.js:36:19:36:22 | path | -| normalizedPaths.js:41:21:41:24 | path | -| normalizedPaths.js:41:21:41:24 | path | -| normalizedPaths.js:41:21:41:24 | path | -| normalizedPaths.js:54:7:54:49 | path | -| normalizedPaths.js:54:7:54:49 | path | -| normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | -| normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | -| normalizedPaths.js:54:35:54:48 | req.query.path | -| normalizedPaths.js:54:35:54:48 | req.query.path | -| normalizedPaths.js:54:35:54:48 | req.query.path | -| normalizedPaths.js:59:19:59:22 | path | -| normalizedPaths.js:59:19:59:22 | path | -| normalizedPaths.js:59:19:59:22 | path | -| normalizedPaths.js:63:19:63:22 | path | -| normalizedPaths.js:63:19:63:22 | path | -| normalizedPaths.js:63:19:63:38 | path + "/index.html" | -| normalizedPaths.js:63:19:63:38 | path + "/index.html" | -| normalizedPaths.js:63:19:63:38 | path + "/index.html" | -| normalizedPaths.js:68:21:68:24 | path | -| normalizedPaths.js:68:21:68:24 | path | -| normalizedPaths.js:68:21:68:24 | path | -| normalizedPaths.js:73:7:73:56 | path | -| normalizedPaths.js:73:7:73:56 | path | -| normalizedPaths.js:73:7:73:56 | path | -| normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | -| normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | -| normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | -| normalizedPaths.js:73:35:73:55 | './' + ... ry.path | -| normalizedPaths.js:73:35:73:55 | './' + ... ry.path | -| normalizedPaths.js:73:35:73:55 | './' + ... ry.path | -| normalizedPaths.js:73:42:73:55 | req.query.path | -| normalizedPaths.js:73:42:73:55 | req.query.path | -| normalizedPaths.js:73:42:73:55 | req.query.path | -| normalizedPaths.js:73:42:73:55 | req.query.path | -| normalizedPaths.js:78:22:78:25 | path | -| normalizedPaths.js:78:22:78:25 | path | -| normalizedPaths.js:78:22:78:25 | path | -| normalizedPaths.js:78:22:78:25 | path | -| normalizedPaths.js:82:7:82:27 | path | -| normalizedPaths.js:82:7:82:27 | path | -| normalizedPaths.js:82:14:82:27 | req.query.path | -| normalizedPaths.js:82:14:82:27 | req.query.path | -| normalizedPaths.js:82:14:82:27 | req.query.path | -| normalizedPaths.js:87:29:87:32 | path | -| normalizedPaths.js:87:29:87:32 | path | -| normalizedPaths.js:87:29:87:32 | path | -| normalizedPaths.js:90:31:90:34 | path | -| normalizedPaths.js:90:31:90:34 | path | -| normalizedPaths.js:94:7:94:49 | path | -| normalizedPaths.js:94:7:94:49 | path | -| normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | -| normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | -| normalizedPaths.js:94:35:94:48 | req.query.path | -| normalizedPaths.js:94:35:94:48 | req.query.path | -| normalizedPaths.js:94:35:94:48 | req.query.path | -| normalizedPaths.js:99:29:99:32 | path | -| normalizedPaths.js:99:29:99:32 | path | -| normalizedPaths.js:99:29:99:32 | path | -| normalizedPaths.js:117:7:117:44 | path | -| normalizedPaths.js:117:7:117:44 | path | -| normalizedPaths.js:117:7:117:44 | path | -| normalizedPaths.js:117:7:117:44 | path | -| normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | -| normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | -| normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | -| normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | -| normalizedPaths.js:117:30:117:43 | req.query.path | -| normalizedPaths.js:117:30:117:43 | req.query.path | -| normalizedPaths.js:117:30:117:43 | req.query.path | -| normalizedPaths.js:117:30:117:43 | req.query.path | -| normalizedPaths.js:117:30:117:43 | req.query.path | -| normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:120:35:120:38 | path | -| normalizedPaths.js:120:35:120:38 | path | -| normalizedPaths.js:120:35:120:38 | path | -| normalizedPaths.js:120:35:120:38 | path | -| normalizedPaths.js:130:7:130:49 | path | -| normalizedPaths.js:130:7:130:49 | path | -| normalizedPaths.js:130:7:130:49 | path | -| normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | -| normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | -| normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | -| normalizedPaths.js:130:35:130:48 | req.query.path | -| normalizedPaths.js:130:35:130:48 | req.query.path | -| normalizedPaths.js:130:35:130:48 | req.query.path | -| normalizedPaths.js:130:35:130:48 | req.query.path | -| normalizedPaths.js:135:21:135:24 | path | -| normalizedPaths.js:135:21:135:24 | path | -| normalizedPaths.js:135:21:135:24 | path | -| normalizedPaths.js:135:21:135:24 | path | -| normalizedPaths.js:139:7:139:62 | path | -| normalizedPaths.js:139:7:139:62 | path | -| normalizedPaths.js:139:7:139:62 | path | -| normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | -| normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | -| normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | -| normalizedPaths.js:139:48:139:61 | req.query.path | -| normalizedPaths.js:139:48:139:61 | req.query.path | -| normalizedPaths.js:139:48:139:61 | req.query.path | -| normalizedPaths.js:139:48:139:61 | req.query.path | -| normalizedPaths.js:144:21:144:24 | path | -| normalizedPaths.js:144:21:144:24 | path | -| normalizedPaths.js:144:21:144:24 | path | -| normalizedPaths.js:144:21:144:24 | path | -| normalizedPaths.js:148:7:148:58 | path | -| normalizedPaths.js:148:7:148:58 | path | -| normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | -| normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | -| normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | -| normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | -| normalizedPaths.js:148:44:148:57 | req.query.path | -| normalizedPaths.js:148:44:148:57 | req.query.path | -| normalizedPaths.js:148:44:148:57 | req.query.path | -| normalizedPaths.js:151:21:151:24 | path | -| normalizedPaths.js:151:21:151:24 | path | -| normalizedPaths.js:151:21:151:24 | path | -| normalizedPaths.js:153:21:153:24 | path | -| normalizedPaths.js:153:21:153:24 | path | -| normalizedPaths.js:153:21:153:24 | path | -| normalizedPaths.js:160:7:160:49 | path | -| normalizedPaths.js:160:7:160:49 | path | -| normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | -| normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | -| normalizedPaths.js:160:35:160:48 | req.query.path | -| normalizedPaths.js:160:35:160:48 | req.query.path | -| normalizedPaths.js:160:35:160:48 | req.query.path | -| normalizedPaths.js:165:19:165:22 | path | -| normalizedPaths.js:165:19:165:22 | path | -| normalizedPaths.js:165:19:165:22 | path | -| normalizedPaths.js:170:21:170:24 | path | -| normalizedPaths.js:170:21:170:24 | path | -| normalizedPaths.js:170:21:170:24 | path | -| normalizedPaths.js:174:7:174:27 | path | -| normalizedPaths.js:174:7:174:27 | path | -| normalizedPaths.js:174:7:174:27 | path | -| normalizedPaths.js:174:7:174:27 | path | -| normalizedPaths.js:174:14:174:27 | req.query.path | -| normalizedPaths.js:174:14:174:27 | req.query.path | -| normalizedPaths.js:174:14:174:27 | req.query.path | -| normalizedPaths.js:174:14:174:27 | req.query.path | -| normalizedPaths.js:174:14:174:27 | req.query.path | -| normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:187:21:187:24 | path | -| normalizedPaths.js:187:21:187:24 | path | -| normalizedPaths.js:187:21:187:24 | path | -| normalizedPaths.js:189:21:189:24 | path | -| normalizedPaths.js:189:21:189:24 | path | -| normalizedPaths.js:189:21:189:24 | path | -| normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:194:21:194:24 | path | -| normalizedPaths.js:194:21:194:24 | path | -| normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:201:7:201:49 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | -| normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | -| normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | -| normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | -| normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | -| normalizedPaths.js:201:45:201:48 | path | -| normalizedPaths.js:201:45:201:48 | path | -| normalizedPaths.js:201:45:201:48 | path | -| normalizedPaths.js:201:45:201:48 | path | -| normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:214:7:214:49 | path | -| normalizedPaths.js:214:7:214:49 | path | -| normalizedPaths.js:214:7:214:49 | path | -| normalizedPaths.js:214:7:214:49 | path | -| normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:214:35:214:48 | req.query.path | -| normalizedPaths.js:214:35:214:48 | req.query.path | -| normalizedPaths.js:214:35:214:48 | req.query.path | -| normalizedPaths.js:214:35:214:48 | req.query.path | -| normalizedPaths.js:214:35:214:48 | req.query.path | -| normalizedPaths.js:219:3:219:33 | path | -| normalizedPaths.js:219:3:219:33 | path | -| normalizedPaths.js:219:3:219:33 | path | -| normalizedPaths.js:219:3:219:33 | path | -| normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | -| normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | -| normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | -| normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | -| normalizedPaths.js:219:29:219:32 | path | -| normalizedPaths.js:219:29:219:32 | path | -| normalizedPaths.js:219:29:219:32 | path | -| normalizedPaths.js:219:29:219:32 | path | -| normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:226:7:226:70 | path | -| normalizedPaths.js:226:7:226:70 | path | -| normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | -| normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | -| normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | -| normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | -| normalizedPaths.js:226:35:226:48 | req.query.path | -| normalizedPaths.js:226:35:226:48 | req.query.path | -| normalizedPaths.js:226:35:226:48 | req.query.path | -| normalizedPaths.js:228:21:228:24 | path | -| normalizedPaths.js:228:21:228:24 | path | -| normalizedPaths.js:228:21:228:24 | path | -| normalizedPaths.js:236:7:236:47 | path | -| normalizedPaths.js:236:7:236:47 | path | -| normalizedPaths.js:236:7:236:47 | path | -| normalizedPaths.js:236:7:236:47 | path | -| normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | -| normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | -| normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | -| normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | -| normalizedPaths.js:236:33:236:46 | req.query.path | -| normalizedPaths.js:236:33:236:46 | req.query.path | -| normalizedPaths.js:236:33:236:46 | req.query.path | -| normalizedPaths.js:236:33:236:46 | req.query.path | -| normalizedPaths.js:236:33:236:46 | req.query.path | -| normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:254:7:254:47 | path | -| normalizedPaths.js:254:7:254:47 | path | -| normalizedPaths.js:254:7:254:47 | path | -| normalizedPaths.js:254:7:254:47 | path | -| normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:254:33:254:46 | req.query.path | -| normalizedPaths.js:254:33:254:46 | req.query.path | -| normalizedPaths.js:254:33:254:46 | req.query.path | -| normalizedPaths.js:254:33:254:46 | req.query.path | -| normalizedPaths.js:254:33:254:46 | req.query.path | -| normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:267:7:267:42 | newpath | -| normalizedPaths.js:267:7:267:42 | newpath | -| normalizedPaths.js:267:7:267:42 | newpath | -| normalizedPaths.js:267:7:267:42 | newpath | -| normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | -| normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | -| normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | -| normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | -| normalizedPaths.js:267:38:267:41 | path | -| normalizedPaths.js:267:38:267:41 | path | -| normalizedPaths.js:267:38:267:41 | path | -| normalizedPaths.js:267:38:267:41 | path | -| normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:275:7:275:42 | newpath | -| normalizedPaths.js:275:7:275:42 | newpath | -| normalizedPaths.js:275:7:275:42 | newpath | -| normalizedPaths.js:275:7:275:42 | newpath | -| normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | -| normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | -| normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | -| normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | -| normalizedPaths.js:275:38:275:41 | path | -| normalizedPaths.js:275:38:275:41 | path | -| normalizedPaths.js:275:38:275:41 | path | -| normalizedPaths.js:275:38:275:41 | path | -| normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:283:7:283:42 | newpath | -| normalizedPaths.js:283:7:283:42 | newpath | -| normalizedPaths.js:283:7:283:42 | newpath | -| normalizedPaths.js:283:7:283:42 | newpath | -| normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | -| normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | -| normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | -| normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | -| normalizedPaths.js:283:38:283:41 | path | -| normalizedPaths.js:283:38:283:41 | path | -| normalizedPaths.js:283:38:283:41 | path | -| normalizedPaths.js:283:38:283:41 | path | -| normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:291:7:291:42 | newpath | -| normalizedPaths.js:291:7:291:42 | newpath | -| normalizedPaths.js:291:7:291:42 | newpath | -| normalizedPaths.js:291:7:291:42 | newpath | -| normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | -| normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | -| normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | -| normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | -| normalizedPaths.js:291:38:291:41 | path | -| normalizedPaths.js:291:38:291:41 | path | -| normalizedPaths.js:291:38:291:41 | path | -| normalizedPaths.js:291:38:291:41 | path | -| normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:303:6:303:26 | path | -| normalizedPaths.js:303:6:303:26 | path | -| normalizedPaths.js:303:6:303:26 | path | -| normalizedPaths.js:303:6:303:26 | path | -| normalizedPaths.js:303:13:303:26 | req.query.path | -| normalizedPaths.js:303:13:303:26 | req.query.path | -| normalizedPaths.js:303:13:303:26 | req.query.path | -| normalizedPaths.js:303:13:303:26 | req.query.path | -| normalizedPaths.js:303:13:303:26 | req.query.path | -| normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:313:19:313:22 | path | -| normalizedPaths.js:313:19:313:22 | path | -| normalizedPaths.js:313:19:313:22 | path | -| normalizedPaths.js:313:19:313:22 | path | -| normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:320:6:320:49 | normalizedPath | -| normalizedPaths.js:320:6:320:49 | normalizedPath | -| normalizedPaths.js:320:6:320:49 | normalizedPath | -| normalizedPaths.js:320:23:320:49 | pathMod ... , path) | -| normalizedPaths.js:320:23:320:49 | pathMod ... , path) | -| normalizedPaths.js:320:23:320:49 | pathMod ... , path) | -| normalizedPaths.js:320:45:320:48 | path | -| normalizedPaths.js:320:45:320:48 | path | -| normalizedPaths.js:320:45:320:48 | path | -| normalizedPaths.js:325:19:325:32 | normalizedPath | -| normalizedPaths.js:325:19:325:32 | normalizedPath | -| normalizedPaths.js:325:19:325:32 | normalizedPath | -| normalizedPaths.js:325:19:325:32 | normalizedPath | -| normalizedPaths.js:332:19:332:32 | normalizedPath | -| normalizedPaths.js:332:19:332:32 | normalizedPath | -| normalizedPaths.js:332:19:332:32 | normalizedPath | -| normalizedPaths.js:332:19:332:32 | normalizedPath | -| normalizedPaths.js:339:6:339:46 | path | -| normalizedPaths.js:339:6:339:46 | path | -| normalizedPaths.js:339:6:339:46 | path | -| normalizedPaths.js:339:6:339:46 | path | -| normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:339:32:339:45 | req.query.path | -| normalizedPaths.js:339:32:339:45 | req.query.path | -| normalizedPaths.js:339:32:339:45 | req.query.path | -| normalizedPaths.js:339:32:339:45 | req.query.path | -| normalizedPaths.js:339:32:339:45 | req.query.path | -| normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:354:14:354:27 | req.query.path | -| normalizedPaths.js:354:14:354:27 | req.query.path | -| normalizedPaths.js:354:14:354:27 | req.query.path | -| normalizedPaths.js:354:14:354:27 | req.query.path | -| normalizedPaths.js:354:14:354:27 | req.query.path | -| normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:358:7:358:51 | requestPath | -| normalizedPaths.js:358:7:358:51 | requestPath | -| normalizedPaths.js:358:7:358:51 | requestPath | -| normalizedPaths.js:358:21:358:51 | pathMod ... , path) | -| normalizedPaths.js:358:21:358:51 | pathMod ... , path) | -| normalizedPaths.js:358:21:358:51 | pathMod ... , path) | -| normalizedPaths.js:358:47:358:50 | path | -| normalizedPaths.js:358:47:358:50 | path | -| normalizedPaths.js:358:47:358:50 | path | -| normalizedPaths.js:363:21:363:31 | requestPath | -| normalizedPaths.js:363:21:363:31 | requestPath | -| normalizedPaths.js:363:21:363:31 | requestPath | -| normalizedPaths.js:363:21:363:31 | requestPath | -| normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:377:14:377:27 | req.query.path | -| normalizedPaths.js:377:14:377:27 | req.query.path | -| normalizedPaths.js:377:14:377:27 | req.query.path | -| normalizedPaths.js:377:14:377:27 | req.query.path | -| normalizedPaths.js:377:14:377:27 | req.query.path | -| normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:381:25:381:28 | path | -| normalizedPaths.js:381:25:381:28 | path | -| normalizedPaths.js:381:25:381:28 | path | -| normalizedPaths.js:381:25:381:28 | path | -| normalizedPaths.js:385:7:385:46 | path | -| normalizedPaths.js:385:7:385:46 | path | -| normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | -| normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | -| normalizedPaths.js:385:35:385:45 | req.query.x | -| normalizedPaths.js:385:35:385:45 | req.query.x | -| normalizedPaths.js:385:35:385:45 | req.query.x | -| normalizedPaths.js:388:19:388:22 | path | -| normalizedPaths.js:388:19:388:22 | path | -| normalizedPaths.js:388:19:388:22 | path | -| normalizedPaths.js:399:21:399:24 | path | -| normalizedPaths.js:399:21:399:24 | path | -| normalizedPaths.js:399:21:399:24 | path | -| normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | -| normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | -| normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | -| normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | -| normalizedPaths.js:407:45:407:55 | req.query.x | -| normalizedPaths.js:407:45:407:55 | req.query.x | -| normalizedPaths.js:407:45:407:55 | req.query.x | -| normalizedPaths.js:407:45:407:55 | req.query.x | -| normalizedPaths.js:407:45:407:66 | req.que ... it('/') | -| normalizedPaths.js:407:45:407:66 | req.que ... it('/') | -| normalizedPaths.js:407:45:407:66 | req.que ... it('/') | -| normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | -| normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | -| normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | -| normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | -| normalizedPaths.js:408:38:408:48 | req.query.x | -| normalizedPaths.js:408:38:408:48 | req.query.x | -| normalizedPaths.js:408:38:408:48 | req.query.x | -| normalizedPaths.js:408:38:408:48 | req.query.x | -| normalizedPaths.js:408:38:408:59 | req.que ... it('/') | -| normalizedPaths.js:408:38:408:59 | req.que ... it('/') | -| normalizedPaths.js:408:38:408:59 | req.que ... it('/') | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:24:9:30 | req.url | -| other-fs-libraries.js:9:24:9:30 | req.url | -| other-fs-libraries.js:9:24:9:30 | req.url | -| other-fs-libraries.js:9:24:9:30 | req.url | -| other-fs-libraries.js:9:24:9:30 | req.url | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:24:38:30 | req.url | -| other-fs-libraries.js:38:24:38:30 | req.url | -| other-fs-libraries.js:38:24:38:30 | req.url | -| other-fs-libraries.js:38:24:38:30 | req.url | -| other-fs-libraries.js:38:24:38:30 | req.url | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:24:49:30 | req.url | -| other-fs-libraries.js:49:24:49:30 | req.url | -| other-fs-libraries.js:49:24:49:30 | req.url | -| other-fs-libraries.js:49:24:49:30 | req.url | -| other-fs-libraries.js:49:24:49:30 | req.url | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:24:68:30 | req.url | -| other-fs-libraries.js:68:24:68:30 | req.url | -| other-fs-libraries.js:68:24:68:30 | req.url | -| other-fs-libraries.js:68:24:68:30 | req.url | -| other-fs-libraries.js:68:24:68:30 | req.url | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:7:77:48 | path | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:37 | url.par ... , true) | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:43 | url.par ... ).query | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:14:77:48 | url.par ... ry.path | -| other-fs-libraries.js:77:24:77:30 | req.url | -| other-fs-libraries.js:77:24:77:30 | req.url | -| other-fs-libraries.js:77:24:77:30 | req.url | -| other-fs-libraries.js:77:24:77:30 | req.url | -| other-fs-libraries.js:77:24:77:30 | req.url | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| other-fs-libraries.js:79:16:79:19 | path | -| prettier.js:6:11:6:28 | p | -| prettier.js:6:11:6:28 | p | -| prettier.js:6:11:6:28 | p | -| prettier.js:6:11:6:28 | p | -| prettier.js:6:13:6:13 | p | -| prettier.js:6:13:6:13 | p | -| prettier.js:6:13:6:13 | p | -| prettier.js:6:13:6:13 | p | -| prettier.js:6:13:6:13 | p | -| prettier.js:7:28:7:28 | p | -| prettier.js:7:28:7:28 | p | -| prettier.js:7:28:7:28 | p | -| prettier.js:7:28:7:28 | p | -| prettier.js:7:28:7:28 | p | -| prettier.js:11:44:11:44 | p | -| prettier.js:11:44:11:44 | p | -| prettier.js:11:44:11:44 | p | -| prettier.js:11:44:11:44 | p | -| prettier.js:11:44:11:44 | p | -| pupeteer.js:5:9:5:71 | tainted | -| pupeteer.js:5:9:5:71 | tainted | -| pupeteer.js:5:9:5:71 | tainted | -| pupeteer.js:5:19:5:71 | "dir/" ... t.data" | -| pupeteer.js:5:19:5:71 | "dir/" ... t.data" | -| pupeteer.js:5:19:5:71 | "dir/" ... t.data" | -| pupeteer.js:5:28:5:53 | parseTo ... t).name | -| pupeteer.js:5:28:5:53 | parseTo ... t).name | -| pupeteer.js:5:28:5:53 | parseTo ... t).name | -| pupeteer.js:5:28:5:53 | parseTo ... t).name | -| pupeteer.js:9:28:9:34 | tainted | -| pupeteer.js:9:28:9:34 | tainted | -| pupeteer.js:9:28:9:34 | tainted | -| pupeteer.js:9:28:9:34 | tainted | -| pupeteer.js:13:37:13:43 | tainted | -| pupeteer.js:13:37:13:43 | tainted | -| pupeteer.js:13:37:13:43 | tainted | -| pupeteer.js:13:37:13:43 | tainted | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:24:6:30 | req.url | -| tainted-access-paths.js:6:24:6:30 | req.url | -| tainted-access-paths.js:6:24:6:30 | req.url | -| tainted-access-paths.js:6:24:6:30 | req.url | -| tainted-access-paths.js:6:24:6:30 | req.url | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:13:10:36 | bla ? s ... : path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:24:39:30 | req.url | -| tainted-access-paths.js:39:24:39:30 | req.url | -| tainted-access-paths.js:39:24:39:30 | req.url | -| tainted-access-paths.js:39:24:39:30 | req.url | -| tainted-access-paths.js:39:24:39:30 | req.url | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:24:48:30 | req.url | -| tainted-access-paths.js:48:24:48:30 | req.url | -| tainted-access-paths.js:48:24:48:30 | req.url | -| tainted-access-paths.js:48:24:48:30 | req.url | -| tainted-access-paths.js:48:24:48:30 | req.url | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:49:10:49:13 | path | -| tainted-require.js:7:19:7:37 | req.param("module") | -| tainted-require.js:7:19:7:37 | req.param("module") | -| tainted-require.js:7:19:7:37 | req.param("module") | -| tainted-require.js:7:19:7:37 | req.param("module") | -| tainted-require.js:7:19:7:37 | req.param("module") | -| tainted-require.js:7:19:7:37 | req.param("module") | -| tainted-require.js:12:29:12:47 | req.param("module") | -| tainted-require.js:12:29:12:47 | req.param("module") | -| tainted-require.js:12:29:12:47 | req.param("module") | -| tainted-require.js:12:29:12:47 | req.param("module") | -| tainted-require.js:12:29:12:47 | req.param("module") | -| tainted-require.js:12:29:12:47 | req.param("module") | -| tainted-require.js:14:11:14:29 | req.param("module") | -| tainted-require.js:14:11:14:29 | req.param("module") | -| tainted-require.js:14:11:14:29 | req.param("module") | -| tainted-require.js:14:11:14:29 | req.param("module") | -| tainted-require.js:14:11:14:29 | req.param("module") | -| tainted-require.js:14:11:14:29 | req.param("module") | -| tainted-sendFile.js:8:16:8:33 | req.param("gimme") | -| tainted-sendFile.js:8:16:8:33 | req.param("gimme") | -| tainted-sendFile.js:8:16:8:33 | req.param("gimme") | -| tainted-sendFile.js:8:16:8:33 | req.param("gimme") | -| tainted-sendFile.js:10:16:10:33 | req.param("gimme") | -| tainted-sendFile.js:10:16:10:33 | req.param("gimme") | -| tainted-sendFile.js:10:16:10:33 | req.param("gimme") | -| tainted-sendFile.js:10:16:10:33 | req.param("gimme") | -| tainted-sendFile.js:18:43:18:58 | req.param("dir") | -| tainted-sendFile.js:18:43:18:58 | req.param("dir") | -| tainted-sendFile.js:18:43:18:58 | req.param("dir") | -| tainted-sendFile.js:18:43:18:58 | req.param("dir") | -| tainted-sendFile.js:18:43:18:58 | req.param("dir") | -| tainted-sendFile.js:18:43:18:58 | req.param("dir") | -| tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:24:37:24:48 | req.params.x | -| tainted-sendFile.js:24:37:24:48 | req.params.x | -| tainted-sendFile.js:24:37:24:48 | req.params.x | -| tainted-sendFile.js:24:37:24:48 | req.params.x | -| tainted-sendFile.js:24:37:24:48 | req.params.x | -| tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-sendFile.js:25:34:25:45 | req.params.x | -| tainted-sendFile.js:25:34:25:45 | req.params.x | -| tainted-sendFile.js:25:34:25:45 | req.params.x | -| tainted-sendFile.js:25:34:25:45 | req.params.x | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:24:6:30 | req.url | -| tainted-string-steps.js:6:24:6:30 | req.url | -| tainted-string-steps.js:6:24:6:30 | req.url | -| tainted-string-steps.js:6:24:6:30 | req.url | -| tainted-string-steps.js:6:24:6:30 | req.url | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| torrents.js:5:6:5:38 | name | -| torrents.js:5:6:5:38 | name | -| torrents.js:5:6:5:38 | name | -| torrents.js:5:13:5:38 | parseTo ... t).name | -| torrents.js:5:13:5:38 | parseTo ... t).name | -| torrents.js:5:13:5:38 | parseTo ... t).name | -| torrents.js:5:13:5:38 | parseTo ... t).name | -| torrents.js:6:6:6:45 | loc | -| torrents.js:6:6:6:45 | loc | -| torrents.js:6:6:6:45 | loc | -| torrents.js:6:12:6:45 | dir + " ... t.data" | -| torrents.js:6:12:6:45 | dir + " ... t.data" | -| torrents.js:6:12:6:45 | dir + " ... t.data" | -| torrents.js:6:24:6:27 | name | -| torrents.js:6:24:6:27 | name | -| torrents.js:6:24:6:27 | name | -| torrents.js:7:25:7:27 | loc | -| torrents.js:7:25:7:27 | loc | -| torrents.js:7:25:7:27 | loc | -| torrents.js:7:25:7:27 | loc | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:7:9:48 | path | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:24:9:30 | req.url | -| typescript.ts:9:24:9:30 | req.url | -| typescript.ts:9:24:9:30 | req.url | -| typescript.ts:9:24:9:30 | req.url | -| typescript.ts:9:24:9:30 | req.url | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:12:29:12:32 | path | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:7:20:18 | path3 | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:20:15:20:18 | path | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:21:39:21:43 | path3 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:7:23:18 | path4 | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:23:15:23:18 | path | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:24:39:24:43 | path4 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:7:30:18 | path6 | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:30:15:30:18 | path | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| typescript.ts:32:29:32:33 | path6 | -| views.js:1:43:1:55 | req.params[0] | -| views.js:1:43:1:55 | req.params[0] | -| views.js:1:43:1:55 | req.params[0] | -| views.js:1:43:1:55 | req.params[0] | -| views.js:1:43:1:55 | req.params[0] | -| views.js:1:43:1:55 | req.params[0] | ->>>>>>> main edges -| TaintedPath-es6.js:7:7:7:44 | path | TaintedPath-es6.js:10:41:10:44 | path | -| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | -| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | -| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | TaintedPath-es6.js:7:7:7:44 | path | -| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | -| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:15:45:15:48 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:18:33:18:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | -| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | -| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | -| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | -| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | -| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:48:51:48:54 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | -| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | -| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | -| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | -| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | -| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | -| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | -| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | -| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | -| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | -| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | -| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | -| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | -| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | -| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | -| TaintedPath.js:95:30:95:31 | ev | TaintedPath.js:96:24:96:25 | ev | -| TaintedPath.js:96:24:96:25 | ev | TaintedPath.js:96:24:96:30 | ev.data | -| TaintedPath.js:96:24:96:30 | ev.data | TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | -| TaintedPath.js:104:32:104:39 | realpath | TaintedPath.js:105:45:105:52 | realpath | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:146:15:146:18 | path | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:148:19:148:23 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:152:19:152:23 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:153:28:153:32 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:155:33:155:37 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:158:20:158:24 | split | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:161:19:161:23 | split | -| TaintedPath.js:146:15:146:18 | path | TaintedPath.js:146:15:146:29 | path.split("/") | -| TaintedPath.js:146:15:146:29 | path.split("/") | TaintedPath.js:146:7:146:29 | split | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | -| TaintedPath.js:153:28:153:32 | split | TaintedPath.js:153:28:153:35 | split[x] | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | -| TaintedPath.js:155:7:155:38 | concatted | TaintedPath.js:156:19:156:27 | concatted | -| TaintedPath.js:155:19:155:38 | prefix.concat(split) | TaintedPath.js:155:7:155:38 | concatted | -| TaintedPath.js:155:33:155:37 | split | TaintedPath.js:155:19:155:38 | prefix.concat(split) | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | -| TaintedPath.js:158:7:158:39 | concatted2 | TaintedPath.js:159:19:159:28 | concatted2 | -| TaintedPath.js:158:20:158:24 | split | TaintedPath.js:158:20:158:39 | split.concat(prefix) | -| TaintedPath.js:158:20:158:39 | split.concat(prefix) | TaintedPath.js:158:7:158:39 | concatted2 | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:176:29:176:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:177:29:177:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:178:29:178:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:179:29:179:32 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:194:40:194:43 | path | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:195:50:195:53 | path | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | -| TaintedPath.js:195:50:195:53 | path | TaintedPath.js:195:29:195:54 | pathMod ... e(path) | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -<<<<<<< HEAD -======= -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | -| examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | examples/TaintedPath.js:8:7:8:52 | filePath | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | -| express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | -| handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | -| handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | -| handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | -| handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | -| handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | -| handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | -| handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | ->>>>>>> main -| handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | -| handlebars.js:13:73:13:80 | filePath | handlebars.js:15:25:15:32 | filePath | -| handlebars.js:29:46:29:60 | req.params.path | handlebars.js:10:51:10:58 | filePath | -| handlebars.js:43:15:43:29 | req.params.path | handlebars.js:13:73:13:80 | filePath | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:14:26:14:29 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:15:19:15:22 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:16:35:16:38 | path | -| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:17:53:17:56 | path | -| normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | -| normalizedPaths.js:14:26:14:29 | path | normalizedPaths.js:14:19:14:29 | './' + path | -| normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | -| normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | -| normalizedPaths.js:17:53:17:56 | path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:24:26:24:29 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:25:19:25:22 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:26:35:26:38 | path | -| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:27:53:27:56 | path | -| normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | normalizedPaths.js:21:7:21:49 | path | -| normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | -| normalizedPaths.js:24:26:24:29 | path | normalizedPaths.js:24:19:24:29 | './' + path | -| normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | -| normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | -| normalizedPaths.js:27:53:27:56 | path | normalizedPaths.js:27:19:27:57 | pathMod ... , path) | -| normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:36:19:36:22 | path | -| normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:41:21:41:24 | path | -| normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | normalizedPaths.js:31:7:31:49 | path | -| normalizedPaths.js:31:35:31:48 | req.query.path | normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | -| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:59:19:59:22 | path | -| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:63:19:63:22 | path | -| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:68:21:68:24 | path | -| normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | normalizedPaths.js:54:7:54:49 | path | -| normalizedPaths.js:54:35:54:48 | req.query.path | normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | -| normalizedPaths.js:63:19:63:22 | path | normalizedPaths.js:63:19:63:38 | path + "/index.html" | -| normalizedPaths.js:73:7:73:56 | path | normalizedPaths.js:78:22:78:25 | path | -| normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | normalizedPaths.js:73:7:73:56 | path | -| normalizedPaths.js:73:35:73:55 | './' + ... ry.path | normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | -| normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:73:35:73:55 | './' + ... ry.path | -| normalizedPaths.js:82:7:82:27 | path | normalizedPaths.js:87:29:87:32 | path | -| normalizedPaths.js:82:7:82:27 | path | normalizedPaths.js:90:31:90:34 | path | -| normalizedPaths.js:82:14:82:27 | req.query.path | normalizedPaths.js:82:7:82:27 | path | -| normalizedPaths.js:94:7:94:49 | path | normalizedPaths.js:99:29:99:32 | path | -| normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | normalizedPaths.js:94:7:94:49 | path | -| normalizedPaths.js:94:35:94:48 | req.query.path | normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | -| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | -| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:120:35:120:38 | path | -| normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | normalizedPaths.js:117:7:117:44 | path | -| normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | -| normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | -| normalizedPaths.js:130:7:130:49 | path | normalizedPaths.js:135:21:135:24 | path | -| normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | normalizedPaths.js:130:7:130:49 | path | -| normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | -| normalizedPaths.js:139:7:139:62 | path | normalizedPaths.js:144:21:144:24 | path | -| normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | normalizedPaths.js:139:7:139:62 | path | -| normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | -| normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:151:21:151:24 | path | -| normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:153:21:153:24 | path | -| normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | normalizedPaths.js:148:7:148:58 | path | -| normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | -| normalizedPaths.js:148:44:148:57 | req.query.path | normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | -| normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:165:19:165:22 | path | -| normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:170:21:170:24 | path | -| normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | normalizedPaths.js:160:7:160:49 | path | -| normalizedPaths.js:160:35:160:48 | req.query.path | normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:187:21:187:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:189:21:189:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:194:21:194:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | -| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:201:45:201:48 | path | -| normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | -| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | -| normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | normalizedPaths.js:201:7:201:49 | normalizedPath | -| normalizedPaths.js:201:45:201:48 | path | normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | -| normalizedPaths.js:214:7:214:49 | path | normalizedPaths.js:219:29:219:32 | path | -| normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | normalizedPaths.js:214:7:214:49 | path | -| normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | -| normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | -| normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | normalizedPaths.js:219:3:219:33 | path | -| normalizedPaths.js:219:29:219:32 | path | normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | -| normalizedPaths.js:226:7:226:70 | path | normalizedPaths.js:228:21:228:24 | path | -| normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | -| normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | normalizedPaths.js:226:7:226:70 | path | -| normalizedPaths.js:226:35:226:48 | req.query.path | normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:238:19:238:22 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:245:21:245:24 | path | -| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:250:21:250:24 | path | -| normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | normalizedPaths.js:236:7:236:47 | path | -| normalizedPaths.js:236:33:236:46 | req.query.path | normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:256:19:256:22 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:262:21:262:24 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:267:38:267:41 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:275:38:275:41 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:283:38:283:41 | path | -| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:291:38:291:41 | path | -| normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | normalizedPaths.js:254:7:254:47 | path | -| normalizedPaths.js:254:33:254:46 | req.query.path | normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | -| normalizedPaths.js:267:7:267:42 | newpath | normalizedPaths.js:270:21:270:27 | newpath | -| normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | normalizedPaths.js:267:7:267:42 | newpath | -| normalizedPaths.js:267:38:267:41 | path | normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | -| normalizedPaths.js:275:7:275:42 | newpath | normalizedPaths.js:278:21:278:27 | newpath | -| normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | normalizedPaths.js:275:7:275:42 | newpath | -| normalizedPaths.js:275:38:275:41 | path | normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | -| normalizedPaths.js:283:7:283:42 | newpath | normalizedPaths.js:286:21:286:27 | newpath | -| normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | normalizedPaths.js:283:7:283:42 | newpath | -| normalizedPaths.js:283:38:283:41 | path | normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | -| normalizedPaths.js:291:7:291:42 | newpath | normalizedPaths.js:296:21:296:27 | newpath | -| normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | normalizedPaths.js:291:7:291:42 | newpath | -| normalizedPaths.js:291:38:291:41 | path | normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:304:18:304:21 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:309:19:309:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:313:19:313:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:316:19:316:22 | path | -| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:320:45:320:48 | path | -| normalizedPaths.js:303:13:303:26 | req.query.path | normalizedPaths.js:303:6:303:26 | path | -| normalizedPaths.js:320:6:320:49 | normalizedPath | normalizedPaths.js:325:19:325:32 | normalizedPath | -| normalizedPaths.js:320:6:320:49 | normalizedPath | normalizedPaths.js:332:19:332:32 | normalizedPath | -| normalizedPaths.js:320:23:320:49 | pathMod ... , path) | normalizedPaths.js:320:6:320:49 | normalizedPath | -| normalizedPaths.js:320:45:320:48 | path | normalizedPaths.js:320:23:320:49 | pathMod ... , path) | -| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:341:18:341:21 | path | -| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:346:19:346:22 | path | -| normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | normalizedPaths.js:339:6:339:46 | path | -| normalizedPaths.js:339:32:339:45 | req.query.path | normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | -| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path | -| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:358:47:358:50 | path | -| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path | -| normalizedPaths.js:358:7:358:51 | requestPath | normalizedPaths.js:363:21:363:31 | requestPath | -| normalizedPaths.js:358:21:358:51 | pathMod ... , path) | normalizedPaths.js:358:7:358:51 | requestPath | -| normalizedPaths.js:358:47:358:50 | path | normalizedPaths.js:358:21:358:51 | pathMod ... , path) | -| normalizedPaths.js:377:7:377:27 | path | normalizedPaths.js:379:19:379:22 | path | -| normalizedPaths.js:377:7:377:27 | path | normalizedPaths.js:381:25:381:28 | path | -| normalizedPaths.js:377:14:377:27 | req.query.path | normalizedPaths.js:377:7:377:27 | path | -| normalizedPaths.js:381:25:381:28 | path | normalizedPaths.js:381:19:381:29 | slash(path) | -| normalizedPaths.js:385:7:385:46 | path | normalizedPaths.js:388:19:388:22 | path | -| normalizedPaths.js:385:7:385:46 | path | normalizedPaths.js:399:21:399:24 | path | -| normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | normalizedPaths.js:385:7:385:46 | path | -| normalizedPaths.js:385:35:385:45 | req.query.x | normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | -| normalizedPaths.js:407:45:407:55 | req.query.x | normalizedPaths.js:407:45:407:66 | req.que ... it('/') | -| normalizedPaths.js:407:45:407:66 | req.que ... it('/') | normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | -| normalizedPaths.js:408:38:408:48 | req.query.x | normalizedPaths.js:408:38:408:59 | req.que ... it('/') | -| normalizedPaths.js:408:38:408:59 | req.que ... it('/') | normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | -| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | -| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | -| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | -| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | -| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | -| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | -| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | -| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | -| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | -| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | -| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | -| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | -| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | -| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | -| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | -| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:73:8:73:11 | path | -| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | -| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | -| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | -| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | -| other-fs-libraries.js:73:8:73:11 | path | other-fs-libraries.js:75:15:75:15 | x | -| other-fs-libraries.js:75:15:75:15 | x | other-fs-libraries.js:76:19:76:19 | x | -| other-fs-libraries.js:81:7:81:48 | path | other-fs-libraries.js:83:16:83:19 | path | -| other-fs-libraries.js:81:14:81:37 | url.par ... , true) | other-fs-libraries.js:81:14:81:43 | url.par ... ).query | -| other-fs-libraries.js:81:14:81:43 | url.par ... ).query | other-fs-libraries.js:81:14:81:48 | url.par ... ry.path | -| other-fs-libraries.js:81:14:81:48 | url.par ... ry.path | other-fs-libraries.js:81:7:81:48 | path | -| other-fs-libraries.js:81:24:81:30 | req.url | other-fs-libraries.js:81:14:81:37 | url.par ... , true) | -| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | -| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | -| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | -| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted | -| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:13:37:13:43 | tainted | -| pupeteer.js:5:19:5:71 | "dir/" ... t.data" | pupeteer.js:5:9:5:71 | tainted | -| pupeteer.js:5:28:5:53 | parseTo ... t).name | pupeteer.js:5:19:5:71 | "dir/" ... t.data" | -| sharedlib-repro.js:13:22:13:43 | req.par ... spaceId | sharedlib-repro.js:21:27:21:34 | filepath | -| sharedlib-repro.js:21:27:21:34 | filepath | sharedlib-repro.js:22:18:22:25 | filepath | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | -| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | -| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | -| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | -| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | -| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | -| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | -| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:7:10:36 | obj | -| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | -| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | -| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | -| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | -| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | -| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | -| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | -| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | -| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | -| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | -| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | -| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | -| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | -| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | -| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | -| tainted-promise-steps.js:6:7:6:48 | path | tainted-promise-steps.js:7:26:7:29 | path | -| tainted-promise-steps.js:6:14:6:37 | url.par ... , true) | tainted-promise-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-promise-steps.js:6:14:6:43 | url.par ... ).query | tainted-promise-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-promise-steps.js:6:14:6:48 | url.par ... ry.path | tainted-promise-steps.js:6:7:6:48 | path | -| tainted-promise-steps.js:6:24:6:30 | req.url | tainted-promise-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-promise-steps.js:7:10:7:30 | Promise ... e(path) [PromiseValue] | tainted-promise-steps.js:10:23:10:33 | pathPromise [PromiseValue] | -| tainted-promise-steps.js:7:26:7:29 | path | tainted-promise-steps.js:7:10:7:30 | Promise ... e(path) [PromiseValue] | -| tainted-promise-steps.js:10:23:10:33 | pathPromise [PromiseValue] | tainted-promise-steps.js:11:25:11:35 | pathPromise [PromiseValue] | -| tainted-promise-steps.js:10:23:10:33 | pathPromise [PromiseValue] | tainted-promise-steps.js:12:3:12:13 | pathPromise [PromiseValue] | -| tainted-promise-steps.js:11:25:11:35 | pathPromise [PromiseValue] | tainted-promise-steps.js:11:19:11:35 | await pathPromise | -| tainted-promise-steps.js:12:3:12:13 | pathPromise [PromiseValue] | tainted-promise-steps.js:12:20:12:23 | path | -| tainted-promise-steps.js:12:20:12:23 | path | tainted-promise-steps.js:12:44:12:47 | path | -| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | -| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:14:33:14:36 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:15:42:15:45 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:22:18:22:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:23:18:23:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | -| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | -| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | -| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | -| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | -| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | -| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | -| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | -| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | -| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | -| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | -| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | -| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | -| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | -| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | -| tainted-string-steps.js:22:18:22:21 | path | tainted-string-steps.js:22:18:22:32 | path.split('/') | -| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | -| tainted-string-steps.js:23:18:23:21 | path | tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | -| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | -| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | -| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | -| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | -| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | -| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | -| torrents.js:5:6:5:38 | name | torrents.js:6:24:6:27 | name | -| torrents.js:5:13:5:38 | parseTo ... t).name | torrents.js:5:6:5:38 | name | -| torrents.js:6:6:6:45 | loc | torrents.js:7:25:7:27 | loc | -| torrents.js:6:12:6:45 | dir + " ... t.data" | torrents.js:6:6:6:45 | loc | -| torrents.js:6:24:6:27 | name | torrents.js:6:12:6:45 | dir + " ... t.data" | -| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | -| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | -| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | -| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | -| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | -| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | -| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | -| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | -| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | -| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | -| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | -| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | +| TaintedPath-es6.js:7:7:7:44 | path | TaintedPath-es6.js:10:41:10:44 | path | provenance | | +| TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | provenance | Config | +| TaintedPath-es6.js:7:14:7:39 | parse(r ... ).query | TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | provenance | Config | +| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path | TaintedPath-es6.js:7:7:7:44 | path | provenance | | +| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | provenance | Config | +| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | provenance | Config | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | provenance | | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:15:45:15:48 | path | provenance | | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:18:33:18:36 | path | provenance | | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:21:33:21:36 | path | provenance | | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:24:33:24:36 | path | provenance | | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:33:31:33:34 | path | provenance | | +| TaintedPath.js:9:14:9:37 | url.par ... , true) | TaintedPath.js:9:14:9:43 | url.par ... ).query | provenance | Config | +| TaintedPath.js:9:14:9:43 | url.par ... ).query | TaintedPath.js:9:14:9:48 | url.par ... ry.path | provenance | Config | +| TaintedPath.js:9:14:9:48 | url.par ... ry.path | TaintedPath.js:9:7:9:48 | path | provenance | | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | provenance | Config | +| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | provenance | Config | +| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:42:48:42:51 | path | provenance | | +| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:46:45:46:48 | path | provenance | | +| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:48:51:48:54 | path | provenance | | +| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:50:50:50:53 | path | provenance | | +| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:52:52:52:55 | path | provenance | | +| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:54:49:54:52 | path | provenance | | +| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:56:48:56:51 | path | provenance | | +| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:58:54:58:57 | path | provenance | | +| TaintedPath.js:38:3:38:44 | path | TaintedPath.js:60:57:60:60 | path | provenance | | +| TaintedPath.js:38:10:38:33 | url.par ... , true) | TaintedPath.js:38:10:38:39 | url.par ... ).query | provenance | Config | +| TaintedPath.js:38:10:38:39 | url.par ... ).query | TaintedPath.js:38:10:38:44 | url.par ... ry.path | provenance | Config | +| TaintedPath.js:38:10:38:44 | url.par ... ry.path | TaintedPath.js:38:3:38:44 | path | provenance | | +| TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:38:10:38:33 | url.par ... , true) | provenance | Config | +| TaintedPath.js:42:48:42:51 | path | TaintedPath.js:42:29:42:52 | pathMod ... e(path) | provenance | Config | +| TaintedPath.js:46:45:46:48 | path | TaintedPath.js:46:29:46:49 | pathMod ... n(path) | provenance | Config | +| TaintedPath.js:48:51:48:54 | path | TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | provenance | Config | +| TaintedPath.js:50:50:50:53 | path | TaintedPath.js:50:29:50:54 | pathMod ... e(path) | provenance | Config | +| TaintedPath.js:52:52:52:55 | path | TaintedPath.js:52:29:52:56 | pathMod ... , path) | provenance | Config | +| TaintedPath.js:54:49:54:52 | path | TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | provenance | Config | +| TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | provenance | Config | +| TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | provenance | Config | +| TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | provenance | Config | +| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | provenance | Config | +| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | provenance | Config | +| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | provenance | Config | +| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | provenance | Config | +| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | provenance | Config | +| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | provenance | Config | +| TaintedPath.js:95:30:95:31 | ev | TaintedPath.js:96:24:96:25 | ev | provenance | | +| TaintedPath.js:96:24:96:25 | ev | TaintedPath.js:96:24:96:30 | ev.data | provenance | Config | +| TaintedPath.js:96:24:96:30 | ev.data | TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | provenance | Config | +| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | provenance | | +| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | provenance | | +| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | provenance | Config | +| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | provenance | Config | +| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | provenance | | +| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | provenance | Config | +| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | provenance | Config | +| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | provenance | Config | +| TaintedPath.js:104:32:104:39 | realpath | TaintedPath.js:105:45:105:52 | realpath | provenance | | +| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | provenance | | +| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | provenance | Config | +| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | provenance | Config | +| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | provenance | | +| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | provenance | Config | +| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | provenance | | +| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:146:15:146:18 | path | provenance | | +| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | provenance | Config | +| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | provenance | Config | +| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | provenance | | +| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | provenance | Config | +| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:148:19:148:23 | split | provenance | | +| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:152:19:152:23 | split | provenance | | +| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:153:28:153:32 | split | provenance | | +| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:155:33:155:37 | split | provenance | | +| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:158:20:158:24 | split | provenance | | +| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:161:19:161:23 | split | provenance | | +| TaintedPath.js:146:15:146:18 | path | TaintedPath.js:146:15:146:29 | path.split("/") | provenance | Config | +| TaintedPath.js:146:15:146:29 | path.split("/") | TaintedPath.js:146:7:146:29 | split | provenance | | +| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | provenance | Config | +| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | provenance | Config | +| TaintedPath.js:153:28:153:32 | split | TaintedPath.js:153:28:153:35 | split[x] | provenance | Config | +| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | provenance | Config | +| TaintedPath.js:155:7:155:38 | concatted | TaintedPath.js:156:19:156:27 | concatted | provenance | | +| TaintedPath.js:155:19:155:38 | prefix.concat(split) | TaintedPath.js:155:7:155:38 | concatted | provenance | | +| TaintedPath.js:155:33:155:37 | split | TaintedPath.js:155:19:155:38 | prefix.concat(split) | provenance | Config | +| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | provenance | Config | +| TaintedPath.js:158:7:158:39 | concatted2 | TaintedPath.js:159:19:159:28 | concatted2 | provenance | | +| TaintedPath.js:158:20:158:24 | split | TaintedPath.js:158:20:158:39 | split.concat(prefix) | provenance | Config | +| TaintedPath.js:158:20:158:39 | split.concat(prefix) | TaintedPath.js:158:7:158:39 | concatted2 | provenance | | +| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | provenance | Config | +| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | provenance | Config | +| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | provenance | | +| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:176:29:176:32 | path | provenance | | +| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:177:29:177:32 | path | provenance | | +| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:178:29:178:32 | path | provenance | | +| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:179:29:179:32 | path | provenance | | +| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:194:40:194:43 | path | provenance | | +| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:195:50:195:53 | path | provenance | | +| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | provenance | Config | +| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | provenance | Config | +| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | provenance | | +| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | provenance | Config | +| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | provenance | Config | +| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | provenance | Config | +| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | provenance | Config | +| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | provenance | Config | +| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | provenance | Config | +| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | provenance | Config | +| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | provenance | Config | +| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | provenance | Config | +| TaintedPath.js:195:50:195:53 | path | TaintedPath.js:195:29:195:54 | pathMod ... e(path) | provenance | Config | +| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | provenance | Config | +| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | provenance | Config | +| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | provenance | Config | +| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | provenance | Config | +| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | provenance | Config | +| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | provenance | Config | +| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | provenance | Config | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | provenance | | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | provenance | | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | provenance | | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | provenance | Config | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | provenance | Config | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | provenance | | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | provenance | Config | +| examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | provenance | | +| examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | provenance | Config | +| examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | provenance | Config | +| examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | examples/TaintedPath.js:8:7:8:52 | filePath | provenance | | +| examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | provenance | Config | +| examples/TaintedPath.js:11:36:11:43 | filePath | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | provenance | Config | +| handlebars.js:10:51:10:58 | filePath | handlebars.js:11:32:11:39 | filePath | provenance | | +| handlebars.js:13:73:13:80 | filePath | handlebars.js:15:25:15:32 | filePath | provenance | | +| handlebars.js:29:46:29:60 | req.params.path | handlebars.js:10:51:10:58 | filePath | provenance | | +| handlebars.js:43:15:43:29 | req.params.path | handlebars.js:13:73:13:80 | filePath | provenance | | +| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | provenance | | +| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:14:26:14:29 | path | provenance | | +| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:15:19:15:22 | path | provenance | | +| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:16:35:16:38 | path | provenance | | +| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:17:53:17:56 | path | provenance | | +| normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | provenance | | +| normalizedPaths.js:14:26:14:29 | path | normalizedPaths.js:14:19:14:29 | './' + path | provenance | Config | +| normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | provenance | Config | +| normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | provenance | Config | +| normalizedPaths.js:17:53:17:56 | path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | provenance | Config | +| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | provenance | | +| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:24:26:24:29 | path | provenance | | +| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:25:19:25:22 | path | provenance | | +| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:26:35:26:38 | path | provenance | | +| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:27:53:27:56 | path | provenance | | +| normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | normalizedPaths.js:21:7:21:49 | path | provenance | | +| normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | provenance | Config | +| normalizedPaths.js:24:26:24:29 | path | normalizedPaths.js:24:19:24:29 | './' + path | provenance | Config | +| normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | provenance | Config | +| normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | provenance | Config | +| normalizedPaths.js:27:53:27:56 | path | normalizedPaths.js:27:19:27:57 | pathMod ... , path) | provenance | Config | +| normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:36:19:36:22 | path | provenance | | +| normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:41:21:41:24 | path | provenance | | +| normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | normalizedPaths.js:31:7:31:49 | path | provenance | | +| normalizedPaths.js:31:35:31:48 | req.query.path | normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | provenance | Config | +| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:59:19:59:22 | path | provenance | | +| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:63:19:63:22 | path | provenance | | +| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:68:21:68:24 | path | provenance | | +| normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | normalizedPaths.js:54:7:54:49 | path | provenance | | +| normalizedPaths.js:54:35:54:48 | req.query.path | normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | provenance | Config | +| normalizedPaths.js:63:19:63:22 | path | normalizedPaths.js:63:19:63:38 | path + "/index.html" | provenance | Config | +| normalizedPaths.js:73:7:73:56 | path | normalizedPaths.js:78:22:78:25 | path | provenance | | +| normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | normalizedPaths.js:73:7:73:56 | path | provenance | | +| normalizedPaths.js:73:35:73:55 | './' + ... ry.path | normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | provenance | Config | +| normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:73:35:73:55 | './' + ... ry.path | provenance | Config | +| normalizedPaths.js:82:7:82:27 | path | normalizedPaths.js:87:29:87:32 | path | provenance | | +| normalizedPaths.js:82:7:82:27 | path | normalizedPaths.js:90:31:90:34 | path | provenance | | +| normalizedPaths.js:82:14:82:27 | req.query.path | normalizedPaths.js:82:7:82:27 | path | provenance | | +| normalizedPaths.js:94:7:94:49 | path | normalizedPaths.js:99:29:99:32 | path | provenance | | +| normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | normalizedPaths.js:94:7:94:49 | path | provenance | | +| normalizedPaths.js:94:35:94:48 | req.query.path | normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | provenance | Config | +| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | provenance | | +| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:120:35:120:38 | path | provenance | | +| normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | normalizedPaths.js:117:7:117:44 | path | provenance | | +| normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | provenance | Config | +| normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | provenance | Config | +| normalizedPaths.js:130:7:130:49 | path | normalizedPaths.js:135:21:135:24 | path | provenance | | +| normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | normalizedPaths.js:130:7:130:49 | path | provenance | | +| normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | provenance | Config | +| normalizedPaths.js:139:7:139:62 | path | normalizedPaths.js:144:21:144:24 | path | provenance | | +| normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | normalizedPaths.js:139:7:139:62 | path | provenance | | +| normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | provenance | Config | +| normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:151:21:151:24 | path | provenance | | +| normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:153:21:153:24 | path | provenance | | +| normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | normalizedPaths.js:148:7:148:58 | path | provenance | | +| normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | provenance | Config | +| normalizedPaths.js:148:44:148:57 | req.query.path | normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | provenance | Config | +| normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:165:19:165:22 | path | provenance | | +| normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:170:21:170:24 | path | provenance | | +| normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | normalizedPaths.js:160:7:160:49 | path | provenance | | +| normalizedPaths.js:160:35:160:48 | req.query.path | normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | provenance | Config | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | provenance | | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:187:21:187:24 | path | provenance | | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:189:21:189:24 | path | provenance | | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | provenance | | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:194:21:194:24 | path | provenance | | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | provenance | | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:201:45:201:48 | path | provenance | | +| normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | provenance | | +| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | provenance | | +| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | provenance | | +| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | provenance | | +| normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | normalizedPaths.js:201:7:201:49 | normalizedPath | provenance | | +| normalizedPaths.js:201:45:201:48 | path | normalizedPaths.js:201:24:201:49 | pathMod ... e(path) | provenance | Config | +| normalizedPaths.js:214:7:214:49 | path | normalizedPaths.js:219:29:219:32 | path | provenance | | +| normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | normalizedPaths.js:214:7:214:49 | path | provenance | | +| normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | provenance | Config | +| normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | provenance | | +| normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | normalizedPaths.js:219:3:219:33 | path | provenance | | +| normalizedPaths.js:219:29:219:32 | path | normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | provenance | Config | +| normalizedPaths.js:226:7:226:70 | path | normalizedPaths.js:228:21:228:24 | path | provenance | | +| normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | provenance | Config | +| normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | normalizedPaths.js:226:7:226:70 | path | provenance | | +| normalizedPaths.js:226:35:226:48 | req.query.path | normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | provenance | Config | +| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:238:19:238:22 | path | provenance | | +| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:245:21:245:24 | path | provenance | | +| normalizedPaths.js:236:7:236:47 | path | normalizedPaths.js:250:21:250:24 | path | provenance | | +| normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | normalizedPaths.js:236:7:236:47 | path | provenance | | +| normalizedPaths.js:236:33:236:46 | req.query.path | normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | provenance | Config | +| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:256:19:256:22 | path | provenance | | +| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:262:21:262:24 | path | provenance | | +| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:267:38:267:41 | path | provenance | | +| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:275:38:275:41 | path | provenance | | +| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:283:38:283:41 | path | provenance | | +| normalizedPaths.js:254:7:254:47 | path | normalizedPaths.js:291:38:291:41 | path | provenance | | +| normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | normalizedPaths.js:254:7:254:47 | path | provenance | | +| normalizedPaths.js:254:33:254:46 | req.query.path | normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | provenance | Config | +| normalizedPaths.js:267:7:267:42 | newpath | normalizedPaths.js:270:21:270:27 | newpath | provenance | | +| normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | normalizedPaths.js:267:7:267:42 | newpath | provenance | | +| normalizedPaths.js:267:38:267:41 | path | normalizedPaths.js:267:17:267:42 | pathMod ... e(path) | provenance | Config | +| normalizedPaths.js:275:7:275:42 | newpath | normalizedPaths.js:278:21:278:27 | newpath | provenance | | +| normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | normalizedPaths.js:275:7:275:42 | newpath | provenance | | +| normalizedPaths.js:275:38:275:41 | path | normalizedPaths.js:275:17:275:42 | pathMod ... e(path) | provenance | Config | +| normalizedPaths.js:283:7:283:42 | newpath | normalizedPaths.js:286:21:286:27 | newpath | provenance | | +| normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | normalizedPaths.js:283:7:283:42 | newpath | provenance | | +| normalizedPaths.js:283:38:283:41 | path | normalizedPaths.js:283:17:283:42 | pathMod ... e(path) | provenance | Config | +| normalizedPaths.js:291:7:291:42 | newpath | normalizedPaths.js:296:21:296:27 | newpath | provenance | | +| normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | normalizedPaths.js:291:7:291:42 | newpath | provenance | | +| normalizedPaths.js:291:38:291:41 | path | normalizedPaths.js:291:17:291:42 | pathMod ... e(path) | provenance | Config | +| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:304:18:304:21 | path | provenance | | +| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:309:19:309:22 | path | provenance | | +| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:313:19:313:22 | path | provenance | | +| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:316:19:316:22 | path | provenance | | +| normalizedPaths.js:303:6:303:26 | path | normalizedPaths.js:320:45:320:48 | path | provenance | | +| normalizedPaths.js:303:13:303:26 | req.query.path | normalizedPaths.js:303:6:303:26 | path | provenance | | +| normalizedPaths.js:320:6:320:49 | normalizedPath | normalizedPaths.js:325:19:325:32 | normalizedPath | provenance | | +| normalizedPaths.js:320:6:320:49 | normalizedPath | normalizedPaths.js:332:19:332:32 | normalizedPath | provenance | | +| normalizedPaths.js:320:23:320:49 | pathMod ... , path) | normalizedPaths.js:320:6:320:49 | normalizedPath | provenance | | +| normalizedPaths.js:320:45:320:48 | path | normalizedPaths.js:320:23:320:49 | pathMod ... , path) | provenance | Config | +| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:341:18:341:21 | path | provenance | | +| normalizedPaths.js:339:6:339:46 | path | normalizedPaths.js:346:19:346:22 | path | provenance | | +| normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | normalizedPaths.js:339:6:339:46 | path | provenance | | +| normalizedPaths.js:339:32:339:45 | req.query.path | normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | provenance | Config | +| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path | provenance | | +| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:358:47:358:50 | path | provenance | | +| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path | provenance | | +| normalizedPaths.js:358:7:358:51 | requestPath | normalizedPaths.js:363:21:363:31 | requestPath | provenance | | +| normalizedPaths.js:358:21:358:51 | pathMod ... , path) | normalizedPaths.js:358:7:358:51 | requestPath | provenance | | +| normalizedPaths.js:358:47:358:50 | path | normalizedPaths.js:358:21:358:51 | pathMod ... , path) | provenance | Config | +| normalizedPaths.js:377:7:377:27 | path | normalizedPaths.js:379:19:379:22 | path | provenance | | +| normalizedPaths.js:377:7:377:27 | path | normalizedPaths.js:381:25:381:28 | path | provenance | | +| normalizedPaths.js:377:14:377:27 | req.query.path | normalizedPaths.js:377:7:377:27 | path | provenance | | +| normalizedPaths.js:381:25:381:28 | path | normalizedPaths.js:381:19:381:29 | slash(path) | provenance | Config | +| normalizedPaths.js:385:7:385:46 | path | normalizedPaths.js:388:19:388:22 | path | provenance | | +| normalizedPaths.js:385:7:385:46 | path | normalizedPaths.js:399:21:399:24 | path | provenance | | +| normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | normalizedPaths.js:385:7:385:46 | path | provenance | | +| normalizedPaths.js:385:35:385:45 | req.query.x | normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | provenance | Config | +| normalizedPaths.js:407:45:407:55 | req.query.x | normalizedPaths.js:407:45:407:66 | req.que ... it('/') | provenance | Config | +| normalizedPaths.js:407:45:407:66 | req.que ... it('/') | normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | provenance | Config | +| normalizedPaths.js:408:38:408:48 | req.query.x | normalizedPaths.js:408:38:408:59 | req.que ... it('/') | provenance | Config | +| normalizedPaths.js:408:38:408:59 | req.que ... it('/') | normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | provenance | Config | +| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | provenance | | +| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | provenance | | +| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | provenance | | +| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:14:27:14:30 | path | provenance | | +| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:16:34:16:37 | path | provenance | | +| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:17:35:17:38 | path | provenance | | +| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:19:56:19:59 | path | provenance | | +| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:24:35:24:38 | path | provenance | | +| other-fs-libraries.js:9:14:9:37 | url.par ... , true) | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | provenance | Config | +| other-fs-libraries.js:9:14:9:43 | url.par ... ).query | other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | provenance | Config | +| other-fs-libraries.js:9:14:9:48 | url.par ... ry.path | other-fs-libraries.js:9:7:9:48 | path | provenance | | +| other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | provenance | Config | +| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:40:35:40:38 | path | provenance | | +| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:41:50:41:53 | path | provenance | | +| other-fs-libraries.js:38:7:38:48 | path | other-fs-libraries.js:42:53:42:56 | path | provenance | | +| other-fs-libraries.js:38:14:38:37 | url.par ... , true) | other-fs-libraries.js:38:14:38:43 | url.par ... ).query | provenance | Config | +| other-fs-libraries.js:38:14:38:43 | url.par ... ).query | other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | provenance | Config | +| other-fs-libraries.js:38:14:38:48 | url.par ... ry.path | other-fs-libraries.js:38:7:38:48 | path | provenance | | +| other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:38:14:38:37 | url.par ... , true) | provenance | Config | +| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:51:19:51:22 | path | provenance | | +| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:52:24:52:27 | path | provenance | | +| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:54:36:54:39 | path | provenance | | +| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:55:36:55:39 | path | provenance | | +| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:57:46:57:49 | path | provenance | | +| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:59:39:59:42 | path | provenance | | +| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:62:43:62:46 | path | provenance | | +| other-fs-libraries.js:49:7:49:48 | path | other-fs-libraries.js:63:51:63:54 | path | provenance | | +| other-fs-libraries.js:49:14:49:37 | url.par ... , true) | other-fs-libraries.js:49:14:49:43 | url.par ... ).query | provenance | Config | +| other-fs-libraries.js:49:14:49:43 | url.par ... ).query | other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | provenance | Config | +| other-fs-libraries.js:49:14:49:48 | url.par ... ry.path | other-fs-libraries.js:49:7:49:48 | path | provenance | | +| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | provenance | Config | +| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:70:19:70:22 | path | provenance | | +| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:71:10:71:13 | path | provenance | | +| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:72:15:72:18 | path | provenance | | +| other-fs-libraries.js:68:7:68:48 | path | other-fs-libraries.js:73:8:73:11 | path | provenance | | +| other-fs-libraries.js:68:14:68:37 | url.par ... , true) | other-fs-libraries.js:68:14:68:43 | url.par ... ).query | provenance | Config | +| other-fs-libraries.js:68:14:68:43 | url.par ... ).query | other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | provenance | Config | +| other-fs-libraries.js:68:14:68:48 | url.par ... ry.path | other-fs-libraries.js:68:7:68:48 | path | provenance | | +| other-fs-libraries.js:68:24:68:30 | req.url | other-fs-libraries.js:68:14:68:37 | url.par ... , true) | provenance | Config | +| other-fs-libraries.js:73:8:73:11 | path | other-fs-libraries.js:75:15:75:15 | x | provenance | | +| other-fs-libraries.js:75:15:75:15 | x | other-fs-libraries.js:76:19:76:19 | x | provenance | | +| other-fs-libraries.js:81:7:81:48 | path | other-fs-libraries.js:83:16:83:19 | path | provenance | | +| other-fs-libraries.js:81:14:81:37 | url.par ... , true) | other-fs-libraries.js:81:14:81:43 | url.par ... ).query | provenance | Config | +| other-fs-libraries.js:81:14:81:43 | url.par ... ).query | other-fs-libraries.js:81:14:81:48 | url.par ... ry.path | provenance | Config | +| other-fs-libraries.js:81:14:81:48 | url.par ... ry.path | other-fs-libraries.js:81:7:81:48 | path | provenance | | +| other-fs-libraries.js:81:24:81:30 | req.url | other-fs-libraries.js:81:14:81:37 | url.par ... , true) | provenance | Config | +| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | provenance | | +| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | provenance | | +| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | provenance | | +| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted | provenance | | +| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:13:37:13:43 | tainted | provenance | | +| pupeteer.js:5:19:5:71 | "dir/" ... t.data" | pupeteer.js:5:9:5:71 | tainted | provenance | | +| pupeteer.js:5:28:5:53 | parseTo ... t).name | pupeteer.js:5:19:5:71 | "dir/" ... t.data" | provenance | Config | +| sharedlib-repro.js:13:22:13:43 | req.par ... spaceId | sharedlib-repro.js:21:27:21:34 | filepath | provenance | | +| sharedlib-repro.js:21:27:21:34 | filepath | sharedlib-repro.js:22:18:22:25 | filepath | provenance | | +| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:8:19:8:22 | path | provenance | | +| tainted-access-paths.js:6:7:6:48 | path | tainted-access-paths.js:10:33:10:36 | path | provenance | | +| tainted-access-paths.js:6:14:6:37 | url.par ... , true) | tainted-access-paths.js:6:14:6:43 | url.par ... ).query | provenance | Config | +| tainted-access-paths.js:6:14:6:43 | url.par ... ).query | tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | provenance | Config | +| tainted-access-paths.js:6:14:6:48 | url.par ... ry.path | tainted-access-paths.js:6:7:6:48 | path | provenance | | +| tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:6:14:6:37 | url.par ... , true) | provenance | Config | +| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:12:19:12:21 | obj | provenance | | +| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:26:19:26:21 | obj | provenance | | +| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:29:21:29:23 | obj | provenance | | +| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:30:23:30:25 | obj | provenance | | +| tainted-access-paths.js:10:7:10:36 | obj | tainted-access-paths.js:31:23:31:25 | obj | provenance | | +| tainted-access-paths.js:10:33:10:36 | path | tainted-access-paths.js:10:7:10:36 | obj | provenance | | +| tainted-access-paths.js:12:19:12:21 | obj | tainted-access-paths.js:12:19:12:25 | obj.sub | provenance | Config | +| tainted-access-paths.js:26:19:26:21 | obj | tainted-access-paths.js:26:19:26:26 | obj.sub3 | provenance | Config | +| tainted-access-paths.js:29:21:29:23 | obj | tainted-access-paths.js:29:21:29:28 | obj.sub4 | provenance | Config | +| tainted-access-paths.js:30:23:30:25 | obj | tainted-access-paths.js:30:23:30:30 | obj.sub4 | provenance | Config | +| tainted-access-paths.js:31:23:31:25 | obj | tainted-access-paths.js:31:23:31:30 | obj.sub4 | provenance | Config | +| tainted-access-paths.js:39:7:39:48 | path | tainted-access-paths.js:40:23:40:26 | path | provenance | | +| tainted-access-paths.js:39:14:39:37 | url.par ... , true) | tainted-access-paths.js:39:14:39:43 | url.par ... ).query | provenance | Config | +| tainted-access-paths.js:39:14:39:43 | url.par ... ).query | tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | provenance | Config | +| tainted-access-paths.js:39:14:39:48 | url.par ... ry.path | tainted-access-paths.js:39:7:39:48 | path | provenance | | +| tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | provenance | Config | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | provenance | | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | provenance | Config | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | provenance | Config | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | provenance | | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | provenance | Config | +| tainted-promise-steps.js:6:7:6:48 | path | tainted-promise-steps.js:7:26:7:29 | path | provenance | | +| tainted-promise-steps.js:6:14:6:37 | url.par ... , true) | tainted-promise-steps.js:6:14:6:43 | url.par ... ).query | provenance | Config | +| tainted-promise-steps.js:6:14:6:43 | url.par ... ).query | tainted-promise-steps.js:6:14:6:48 | url.par ... ry.path | provenance | Config | +| tainted-promise-steps.js:6:14:6:48 | url.par ... ry.path | tainted-promise-steps.js:6:7:6:48 | path | provenance | | +| tainted-promise-steps.js:6:24:6:30 | req.url | tainted-promise-steps.js:6:14:6:37 | url.par ... , true) | provenance | Config | +| tainted-promise-steps.js:7:10:7:30 | Promise ... e(path) [PromiseValue] | tainted-promise-steps.js:10:23:10:33 | pathPromise [PromiseValue] | provenance | | +| tainted-promise-steps.js:7:26:7:29 | path | tainted-promise-steps.js:7:10:7:30 | Promise ... e(path) [PromiseValue] | provenance | | +| tainted-promise-steps.js:10:23:10:33 | pathPromise [PromiseValue] | tainted-promise-steps.js:11:25:11:35 | pathPromise [PromiseValue] | provenance | | +| tainted-promise-steps.js:10:23:10:33 | pathPromise [PromiseValue] | tainted-promise-steps.js:12:3:12:13 | pathPromise [PromiseValue] | provenance | | +| tainted-promise-steps.js:11:25:11:35 | pathPromise [PromiseValue] | tainted-promise-steps.js:11:19:11:35 | await pathPromise | provenance | | +| tainted-promise-steps.js:12:3:12:13 | pathPromise [PromiseValue] | tainted-promise-steps.js:12:20:12:23 | path | provenance | | +| tainted-promise-steps.js:12:20:12:23 | path | tainted-promise-steps.js:12:44:12:47 | path | provenance | | +| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | provenance | Config | +| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | provenance | Config | +| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:8:18:8:21 | path | provenance | | +| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:9:18:9:21 | path | provenance | | +| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:10:18:10:21 | path | provenance | | +| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:11:18:11:21 | path | provenance | | +| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:13:18:13:21 | path | provenance | | +| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:14:33:14:36 | path | provenance | | +| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:15:42:15:45 | path | provenance | | +| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:17:18:17:21 | path | provenance | | +| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:18:18:18:21 | path | provenance | | +| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:22:18:22:21 | path | provenance | | +| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:23:18:23:21 | path | provenance | | +| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:24:18:24:21 | path | provenance | | +| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:26:18:26:21 | path | provenance | | +| tainted-string-steps.js:6:7:6:48 | path | tainted-string-steps.js:27:18:27:21 | path | provenance | | +| tainted-string-steps.js:6:14:6:37 | url.par ... , true) | tainted-string-steps.js:6:14:6:43 | url.par ... ).query | provenance | Config | +| tainted-string-steps.js:6:14:6:43 | url.par ... ).query | tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | provenance | Config | +| tainted-string-steps.js:6:14:6:48 | url.par ... ry.path | tainted-string-steps.js:6:7:6:48 | path | provenance | | +| tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:6:14:6:37 | url.par ... , true) | provenance | Config | +| tainted-string-steps.js:8:18:8:21 | path | tainted-string-steps.js:8:18:8:34 | path.substring(4) | provenance | Config | +| tainted-string-steps.js:9:18:9:21 | path | tainted-string-steps.js:9:18:9:37 | path.substring(0, i) | provenance | Config | +| tainted-string-steps.js:10:18:10:21 | path | tainted-string-steps.js:10:18:10:31 | path.substr(4) | provenance | Config | +| tainted-string-steps.js:11:18:11:21 | path | tainted-string-steps.js:11:18:11:30 | path.slice(4) | provenance | Config | +| tainted-string-steps.js:13:18:13:21 | path | tainted-string-steps.js:13:18:13:37 | path.concat(unknown) | provenance | Config | +| tainted-string-steps.js:14:33:14:36 | path | tainted-string-steps.js:14:18:14:37 | unknown.concat(path) | provenance | Config | +| tainted-string-steps.js:15:42:15:45 | path | tainted-string-steps.js:15:18:15:46 | unknown ... , path) | provenance | Config | +| tainted-string-steps.js:17:18:17:21 | path | tainted-string-steps.js:17:18:17:28 | path.trim() | provenance | Config | +| tainted-string-steps.js:18:18:18:21 | path | tainted-string-steps.js:18:18:18:35 | path.toLowerCase() | provenance | Config | +| tainted-string-steps.js:22:18:22:21 | path | tainted-string-steps.js:22:18:22:32 | path.split('/') | provenance | Config | +| tainted-string-steps.js:22:18:22:32 | path.split('/') | tainted-string-steps.js:22:18:22:35 | path.split('/')[i] | provenance | Config | +| tainted-string-steps.js:23:18:23:21 | path | tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | provenance | Config | +| tainted-string-steps.js:23:18:23:33 | path.split(/\\//) | tainted-string-steps.js:23:18:23:36 | path.split(/\\//)[i] | provenance | Config | +| tainted-string-steps.js:24:18:24:21 | path | tainted-string-steps.js:24:18:24:32 | path.split("?") | provenance | Config | +| tainted-string-steps.js:24:18:24:32 | path.split("?") | tainted-string-steps.js:24:18:24:35 | path.split("?")[0] | provenance | Config | +| tainted-string-steps.js:26:18:26:21 | path | tainted-string-steps.js:26:18:26:36 | path.split(unknown) | provenance | Config | +| tainted-string-steps.js:26:18:26:36 | path.split(unknown) | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | provenance | Config | +| tainted-string-steps.js:27:18:27:21 | path | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | provenance | Config | +| torrents.js:5:6:5:38 | name | torrents.js:6:24:6:27 | name | provenance | | +| torrents.js:5:13:5:38 | parseTo ... t).name | torrents.js:5:6:5:38 | name | provenance | | +| torrents.js:6:6:6:45 | loc | torrents.js:7:25:7:27 | loc | provenance | | +| torrents.js:6:12:6:45 | dir + " ... t.data" | torrents.js:6:6:6:45 | loc | provenance | | +| torrents.js:6:24:6:27 | name | torrents.js:6:12:6:45 | dir + " ... t.data" | provenance | Config | +| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path | provenance | | +| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path | provenance | | +| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path | provenance | | +| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path | provenance | | +| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query | provenance | Config | +| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path | provenance | Config | +| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path | provenance | | +| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) | provenance | Config | +| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 | provenance | | +| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 | provenance | | +| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 | provenance | | +| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 | provenance | | +| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 | provenance | | +| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 | provenance | | subpaths #select | TaintedPath-es6.js:10:26:10:45 | join("public", path) | TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:10:26:10:45 | join("public", path) | This path depends on a $@. | TaintedPath-es6.js:7:20:7:26 | req.url | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 893754ab47d..46dbe7ac431 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -1,5 +1,4 @@ nodes -<<<<<<< HEAD | addEventListener.js:1:43:1:47 | event | semmle.label | event | | addEventListener.js:2:20:2:24 | event | semmle.label | event | | addEventListener.js:2:20:2:29 | event.data | semmle.label | event.data | @@ -329,6 +328,10 @@ nodes | tooltip.jsx:6:20:6:30 | window.name | semmle.label | window.name | | tooltip.jsx:10:25:10:30 | source | semmle.label | source | | tooltip.jsx:11:25:11:30 | source | semmle.label | source | +| tooltip.jsx:18:51:18:59 | provide() | semmle.label | provide() | +| tooltip.jsx:22:11:22:30 | source | semmle.label | source | +| tooltip.jsx:22:20:22:30 | window.name | semmle.label | window.name | +| tooltip.jsx:23:38:23:43 | source | semmle.label | source | | translate.js:6:7:6:39 | target | semmle.label | target | | translate.js:6:16:6:39 | documen ... .search | semmle.label | documen ... .search | | translate.js:7:7:7:61 | searchParams | semmle.label | searchParams | @@ -621,1725 +624,595 @@ nodes | winjs.js:2:17:2:53 | documen ... ring(1) | semmle.label | documen ... ring(1) | | winjs.js:3:43:3:49 | tainted | semmle.label | tainted | | winjs.js:4:43:4:49 | tainted | semmle.label | tainted | -======= -| addEventListener.js:1:43:1:47 | event | -| addEventListener.js:1:43:1:47 | event | -| addEventListener.js:1:43:1:47 | event | -| addEventListener.js:2:20:2:24 | event | -| addEventListener.js:2:20:2:24 | event | -| addEventListener.js:2:20:2:29 | event.data | -| addEventListener.js:2:20:2:29 | event.data | -| addEventListener.js:2:20:2:29 | event.data | -| addEventListener.js:5:43:5:48 | data | -| addEventListener.js:5:43:5:48 | data | -| addEventListener.js:5:43:5:48 | {data} | -| addEventListener.js:5:43:5:48 | {data} | -| addEventListener.js:5:43:5:48 | {data} | -| addEventListener.js:5:44:5:47 | data | -| addEventListener.js:5:44:5:47 | data | -| addEventListener.js:6:20:6:23 | data | -| addEventListener.js:6:20:6:23 | data | -| addEventListener.js:6:20:6:23 | data | -| addEventListener.js:10:21:10:25 | event | -| addEventListener.js:10:21:10:25 | event | -| addEventListener.js:10:21:10:25 | event | -| addEventListener.js:12:24:12:28 | event | -| addEventListener.js:12:24:12:28 | event | -| addEventListener.js:12:24:12:33 | event.data | -| addEventListener.js:12:24:12:33 | event.data | -| addEventListener.js:12:24:12:33 | event.data | -| angular2-client.ts:22:44:22:71 | \\u0275getDOM ... ().href | -| angular2-client.ts:22:44:22:71 | \\u0275getDOM ... ().href | -| angular2-client.ts:22:44:22:71 | \\u0275getDOM ... ().href | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | -| angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | -| angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:26:44:26:71 | this.ro ... ragment | -| angular2-client.ts:26:44:26:71 | this.ro ... ragment | -| angular2-client.ts:26:44:26:71 | this.ro ... ragment | -| angular2-client.ts:26:44:26:71 | this.ro ... ragment | -| angular2-client.ts:27:44:27:82 | this.ro ... ('foo') | -| angular2-client.ts:27:44:27:82 | this.ro ... ('foo') | -| angular2-client.ts:27:44:27:82 | this.ro ... ('foo') | -| angular2-client.ts:27:44:27:82 | this.ro ... ('foo') | -| angular2-client.ts:28:44:28:87 | this.ro ... ('foo') | -| angular2-client.ts:28:44:28:87 | this.ro ... ('foo') | -| angular2-client.ts:28:44:28:87 | this.ro ... ('foo') | -| angular2-client.ts:28:44:28:87 | this.ro ... ('foo') | -| angular2-client.ts:30:46:30:59 | map.get('foo') | -| angular2-client.ts:30:46:30:59 | map.get('foo') | -| angular2-client.ts:30:46:30:59 | map.get('foo') | -| angular2-client.ts:30:46:30:59 | map.get('foo') | -| angular2-client.ts:33:44:33:74 | this.ro ... 1].path | -| angular2-client.ts:33:44:33:74 | this.ro ... 1].path | -| angular2-client.ts:33:44:33:74 | this.ro ... 1].path | -| angular2-client.ts:33:44:33:74 | this.ro ... 1].path | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | -| angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:35:44:35:91 | this.ro ... et('x') | -| angular2-client.ts:35:44:35:91 | this.ro ... et('x') | -| angular2-client.ts:35:44:35:91 | this.ro ... et('x') | -| angular2-client.ts:35:44:35:91 | this.ro ... et('x') | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | -| angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| angular2-client.ts:38:44:38:58 | this.router.url | -| angular2-client.ts:38:44:38:58 | this.router.url | -| angular2-client.ts:38:44:38:58 | this.router.url | -| angular2-client.ts:40:45:40:59 | this.router.url | -| angular2-client.ts:40:45:40:59 | this.router.url | -| angular2-client.ts:40:45:40:59 | this.router.url | -| angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | -| angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | -| angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | -| angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | -| classnames.js:7:31:7:84 | `` | -| classnames.js:7:31:7:84 | `` | -| classnames.js:7:47:7:69 | classNa ... w.name) | -| classnames.js:7:58:7:68 | window.name | -| classnames.js:7:58:7:68 | window.name | -| classnames.js:8:31:8:85 | `` | -| classnames.js:8:31:8:85 | `` | -| classnames.js:8:47:8:70 | classNa ... w.name) | -| classnames.js:8:59:8:69 | window.name | -| classnames.js:8:59:8:69 | window.name | -| classnames.js:9:31:9:85 | `` | -| classnames.js:9:31:9:85 | `` | -| classnames.js:9:47:9:70 | classNa ... w.name) | -| classnames.js:9:59:9:69 | window.name | -| classnames.js:9:59:9:69 | window.name | -| classnames.js:10:45:10:55 | window.name | -| classnames.js:10:45:10:55 | window.name | -| classnames.js:11:31:11:79 | `` | -| classnames.js:11:31:11:79 | `` | -| classnames.js:11:47:11:64 | unsafeStyle('foo') | -| classnames.js:13:31:13:83 | `` | -| classnames.js:13:31:13:83 | `` | -| classnames.js:13:47:13:68 | safeSty ... w.name) | -| classnames.js:13:57:13:67 | window.name | -| classnames.js:13:57:13:67 | window.name | -| classnames.js:15:31:15:78 | `` | -| classnames.js:15:31:15:78 | `` | -| classnames.js:15:47:15:63 | clsx(window.name) | -| classnames.js:15:52:15:62 | window.name | -| classnames.js:15:52:15:62 | window.name | -| classnames.js:17:32:17:79 | `` | -| classnames.js:17:32:17:79 | `` | -| classnames.js:17:48:17:64 | clsx(window.name) | -| classnames.js:17:53:17:63 | window.name | -| classnames.js:17:53:17:63 | window.name | -| clipboard.ts:8:11:8:51 | html | -| clipboard.ts:8:11:8:51 | html | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | -| clipboard.ts:15:25:15:28 | html | -| clipboard.ts:15:25:15:28 | html | -| clipboard.ts:15:25:15:28 | html | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:43:15:43:55 | html | -| clipboard.ts:43:15:43:55 | html | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | -| clipboard.ts:50:29:50:32 | html | -| clipboard.ts:50:29:50:32 | html | -| clipboard.ts:50:29:50:32 | html | -| clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | -| clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:98:15:98:54 | html | -| clipboard.ts:98:15:98:54 | html | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | -| clipboard.ts:99:23:99:26 | html | -| clipboard.ts:99:23:99:26 | html | -| clipboard.ts:99:23:99:26 | html | -| custom-element.js:5:26:5:36 | window.name | -| custom-element.js:5:26:5:36 | window.name | -| custom-element.js:5:26:5:36 | window.name | -| custom-element.js:5:26:5:36 | window.name | -| d3.js:4:12:4:22 | window.name | -| d3.js:4:12:4:22 | window.name | -| d3.js:4:12:4:22 | window.name | -| d3.js:11:15:11:24 | getTaint() | -| d3.js:11:15:11:24 | getTaint() | -| d3.js:11:15:11:24 | getTaint() | -| d3.js:12:20:12:29 | getTaint() | -| d3.js:12:20:12:29 | getTaint() | -| d3.js:12:20:12:29 | getTaint() | -| d3.js:14:20:14:29 | getTaint() | -| d3.js:14:20:14:29 | getTaint() | -| d3.js:14:20:14:29 | getTaint() | -| d3.js:21:15:21:24 | getTaint() | -| d3.js:21:15:21:24 | getTaint() | -| d3.js:21:15:21:24 | getTaint() | -| dates.js:9:9:9:69 | taint | -| dates.js:9:9:9:69 | taint | -| dates.js:9:17:9:69 | decodeU ... ing(1)) | -| dates.js:9:17:9:69 | decodeU ... ing(1)) | -| dates.js:9:36:9:55 | window.location.hash | -| dates.js:9:36:9:55 | window.location.hash | -| dates.js:9:36:9:68 | window. ... ring(1) | -| dates.js:9:36:9:68 | window. ... ring(1) | -| dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:42:11:68 | dateFns ... taint) | -| dates.js:11:42:11:68 | dateFns ... taint) | -| dates.js:11:63:11:67 | taint | -| dates.js:11:63:11:67 | taint | -| dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:42:12:71 | dateFns ... taint) | -| dates.js:12:42:12:71 | dateFns ... taint) | -| dates.js:12:66:12:70 | taint | -| dates.js:12:66:12:70 | taint | -| dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:42:13:70 | dateFns ... )(time) | -| dates.js:13:42:13:70 | dateFns ... )(time) | -| dates.js:13:59:13:63 | taint | -| dates.js:13:59:13:63 | taint | -| dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:42:16:67 | moment( ... (taint) | -| dates.js:16:42:16:67 | moment( ... (taint) | -| dates.js:16:62:16:66 | taint | -| dates.js:16:62:16:66 | taint | -| dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:42:18:64 | datefor ... taint) | -| dates.js:18:42:18:64 | datefor ... taint) | -| dates.js:18:59:18:63 | taint | -| dates.js:18:59:18:63 | taint | -| dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | -| dates.js:21:61:21:65 | taint | -| dates.js:21:61:21:65 | taint | -| dates.js:30:9:30:69 | taint | -| dates.js:30:9:30:69 | taint | -| dates.js:30:17:30:69 | decodeU ... ing(1)) | -| dates.js:30:17:30:69 | decodeU ... ing(1)) | -| dates.js:30:36:30:55 | window.location.hash | -| dates.js:30:36:30:55 | window.location.hash | -| dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:42:37:82 | dateFns ... taint) | -| dates.js:37:42:37:82 | dateFns ... taint) | -| dates.js:37:77:37:81 | taint | -| dates.js:37:77:37:81 | taint | -| dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:42:38:82 | luxon.f ... taint) | -| dates.js:38:42:38:82 | luxon.f ... taint) | -| dates.js:38:77:38:81 | taint | -| dates.js:38:77:38:81 | taint | -| dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:42:39:84 | moment. ... taint) | -| dates.js:39:42:39:84 | moment. ... taint) | -| dates.js:39:79:39:83 | taint | -| dates.js:39:79:39:83 | taint | -| dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:42:40:82 | dayjs.f ... taint) | -| dates.js:40:42:40:82 | dayjs.f ... taint) | -| dates.js:40:77:40:81 | taint | -| dates.js:40:77:40:81 | taint | -| dates.js:46:9:46:69 | taint | -| dates.js:46:9:46:69 | taint | -| dates.js:46:17:46:69 | decodeU ... ing(1)) | -| dates.js:46:17:46:69 | decodeU ... ing(1)) | -| dates.js:46:36:46:55 | window.location.hash | -| dates.js:46:36:46:55 | window.location.hash | -| dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:42:48:88 | DateTim ... (taint) | -| dates.js:48:42:48:88 | DateTim ... (taint) | -| dates.js:48:83:48:87 | taint | -| dates.js:48:83:48:87 | taint | -| dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:42:49:87 | new Dat ... (taint) | -| dates.js:49:42:49:87 | new Dat ... (taint) | -| dates.js:49:82:49:86 | taint | -| dates.js:49:82:49:86 | taint | -| dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:42:50:102 | DateTim ... (taint) | -| dates.js:50:42:50:102 | DateTim ... (taint) | -| dates.js:50:97:50:101 | taint | -| dates.js:50:97:50:101 | taint | -| dates.js:54:9:54:69 | taint | -| dates.js:54:9:54:69 | taint | -| dates.js:54:17:54:69 | decodeU ... ing(1)) | -| dates.js:54:17:54:69 | decodeU ... ing(1)) | -| dates.js:54:36:54:55 | window.location.hash | -| dates.js:54:36:54:55 | window.location.hash | -| dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:42:57:99 | moment. ... (taint) | -| dates.js:57:42:57:99 | moment. ... (taint) | -| dates.js:57:94:57:98 | taint | -| dates.js:57:94:57:98 | taint | -| dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:42:59:85 | luxon.e ... (taint) | -| dates.js:59:42:59:85 | luxon.e ... (taint) | -| dates.js:59:80:59:84 | taint | -| dates.js:59:80:59:84 | taint | -| dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | -| dates.js:61:81:61:85 | taint | -| dates.js:61:81:61:85 | taint | -| dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | -| dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | -| dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:71:13:71:61 | droppedHtml | -| dragAndDrop.ts:71:13:71:61 | droppedHtml | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | -| dragAndDrop.ts:73:29:73:39 | droppedHtml | -| dragAndDrop.ts:73:29:73:39 | droppedHtml | -| dragAndDrop.ts:73:29:73:39 | droppedHtml | -| event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:49:2:61 | location.href | -| event-handler-receiver.js:2:49:2:61 | location.href | -| express.js:7:15:7:33 | req.param("wobble") | -| express.js:7:15:7:33 | req.param("wobble") | -| express.js:7:15:7:33 | req.param("wobble") | -| express.js:7:15:7:33 | req.param("wobble") | -| jquery.js:2:7:2:40 | tainted | -| jquery.js:2:17:2:40 | documen ... .search | -| jquery.js:2:17:2:40 | documen ... .search | -| jquery.js:7:5:7:34 | "
" | -| jquery.js:7:5:7:34 | "
" | -| jquery.js:7:20:7:26 | tainted | -| jquery.js:8:18:8:34 | "XSS: " + tainted | -| jquery.js:8:18:8:34 | "XSS: " + tainted | -| jquery.js:8:28:8:34 | tainted | -| jquery.js:10:5:10:40 | "" + ... "" | -| jquery.js:10:5:10:40 | "" + ... "" | -| jquery.js:10:13:10:20 | location | -| jquery.js:10:13:10:20 | location | -| jquery.js:10:13:10:31 | location.toString() | -| jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:14:38:14:57 | window.location.hash | -| jquery.js:14:38:14:57 | window.location.hash | -| jquery.js:15:19:15:60 | decodeU ... search) | -| jquery.js:15:19:15:60 | decodeU ... search) | -| jquery.js:15:38:15:59 | window. ... .search | -| jquery.js:15:38:15:59 | window. ... .search | -| jquery.js:16:19:16:64 | decodeU ... ring()) | -| jquery.js:16:19:16:64 | decodeU ... ring()) | -| jquery.js:16:38:16:52 | window.location | -| jquery.js:16:38:16:52 | window.location | -| jquery.js:16:38:16:63 | window. ... tring() | -| jquery.js:18:7:18:33 | hash | -| jquery.js:18:14:18:33 | window.location.hash | -| jquery.js:18:14:18:33 | window.location.hash | -| jquery.js:21:5:21:8 | hash | -| jquery.js:21:5:21:21 | hash.substring(1) | -| jquery.js:21:5:21:21 | hash.substring(1) | -| jquery.js:21:5:21:21 | hash.substring(1) | -| jquery.js:22:5:22:8 | hash | -| jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:23:5:23:8 | hash | -| jquery.js:23:5:23:18 | hash.substr(1) | -| jquery.js:23:5:23:18 | hash.substr(1) | -| jquery.js:23:5:23:18 | hash.substr(1) | -| jquery.js:24:5:24:8 | hash | -| jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:27:5:27:8 | hash | -| jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:28:5:28:26 | window. ... .search | -| jquery.js:28:5:28:26 | window. ... .search | -| jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:34:5:34:25 | '' + ... '' | -| jquery.js:34:5:34:25 | '' + ... '' | -| jquery.js:34:13:34:16 | hash | -| jquery.js:36:25:36:31 | tainted | -| jquery.js:36:25:36:31 | tainted | -| jquery.js:37:25:37:37 | () => tainted | -| jquery.js:37:25:37:37 | () => tainted | -| jquery.js:37:31:37:37 | tainted | -| json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | -| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | -| json-stringify.jsx:11:51:11:56 | locale | -| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | -| json-stringify.jsx:19:56:19:61 | locale | -| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:55:31:60 | locale | -| json-stringify.jsx:31:55:31:60 | locale | -| json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | -| json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | -| jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:7:17:7:35 | req.param("wobble") | -| jwt-server.js:7:17:7:35 | req.param("wobble") | -| jwt-server.js:7:17:7:35 | req.param("wobble") | -| jwt-server.js:9:16:9:20 | taint | -| jwt-server.js:9:16:9:20 | taint | -| jwt-server.js:9:55:9:61 | decoded | -| jwt-server.js:9:55:9:61 | decoded | -| jwt-server.js:11:19:11:25 | decoded | -| jwt-server.js:11:19:11:25 | decoded | -| jwt-server.js:11:19:11:29 | decoded.foo | -| jwt-server.js:11:19:11:29 | decoded.foo | -| jwt-server.js:11:19:11:29 | decoded.foo | -| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| nodemailer.js:13:50:13:66 | req.query.message | -| nodemailer.js:13:50:13:66 | req.query.message | -| optionalSanitizer.js:2:7:2:39 | target | -| optionalSanitizer.js:2:16:2:39 | documen ... .search | -| optionalSanitizer.js:2:16:2:39 | documen ... .search | -| optionalSanitizer.js:6:18:6:23 | target | -| optionalSanitizer.js:6:18:6:23 | target | -| optionalSanitizer.js:8:7:8:22 | tainted | -| optionalSanitizer.js:8:17:8:22 | target | -| optionalSanitizer.js:9:18:9:24 | tainted | -| optionalSanitizer.js:9:18:9:24 | tainted | -| optionalSanitizer.js:15:9:15:14 | target | -| optionalSanitizer.js:16:18:16:18 | x | -| optionalSanitizer.js:17:20:17:20 | x | -| optionalSanitizer.js:17:20:17:20 | x | -| optionalSanitizer.js:26:7:26:39 | target | -| optionalSanitizer.js:26:16:26:39 | documen ... .search | -| optionalSanitizer.js:26:16:26:39 | documen ... .search | -| optionalSanitizer.js:31:7:31:23 | tainted2 | -| optionalSanitizer.js:31:18:31:23 | target | -| optionalSanitizer.js:32:18:32:25 | tainted2 | -| optionalSanitizer.js:32:18:32:25 | tainted2 | -| optionalSanitizer.js:34:5:34:36 | tainted2 | -| optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | -| optionalSanitizer.js:34:28:34:35 | tainted2 | -| optionalSanitizer.js:36:18:36:25 | tainted2 | -| optionalSanitizer.js:36:18:36:25 | tainted2 | -| optionalSanitizer.js:38:7:38:23 | tainted3 | -| optionalSanitizer.js:38:18:38:23 | target | -| optionalSanitizer.js:39:18:39:25 | tainted3 | -| optionalSanitizer.js:39:18:39:25 | tainted3 | -| optionalSanitizer.js:41:5:41:36 | tainted3 | -| optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | -| optionalSanitizer.js:41:28:41:35 | tainted3 | -| optionalSanitizer.js:43:18:43:25 | tainted3 | -| optionalSanitizer.js:43:18:43:25 | tainted3 | -| optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | -| optionalSanitizer.js:45:41:45:46 | target | -| optionalSanitizer.js:45:51:45:56 | target | -| pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:5:9:5:29 | id | -| pages/[id].jsx:5:9:5:29 | id | -| pages/[id].jsx:5:11:5:12 | id | -| pages/[id].jsx:5:11:5:12 | id | -| pages/[id].jsx:5:18:5:29 | router.query | -| pages/[id].jsx:5:18:5:29 | router.query | -| pages/[id].jsx:5:18:5:29 | router.query | -| pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:25:11:25:24 | context.params | -| pages/[id].jsx:25:11:25:24 | context.params | -| pages/[id].jsx:25:11:25:24 | context.params | -| pages/[id].jsx:25:11:25:27 | context.params.id | -| pages/[id].jsx:25:11:25:27 | context.params.id | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | -| pages/[id].jsx:26:10:26:22 | context.query | -| pages/[id].jsx:26:10:26:22 | context.query | -| pages/[id].jsx:26:10:26:22 | context.query | -| pages/[id].jsx:26:10:26:30 | context ... .foobar | -| pages/[id].jsx:26:10:26:30 | context ... .foobar | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | -| react-native.js:7:7:7:33 | tainted | -| react-native.js:7:7:7:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:8:18:8:24 | tainted | -| react-native.js:8:18:8:24 | tainted | -| react-native.js:8:18:8:24 | tainted | -| react-native.js:9:27:9:33 | tainted | -| react-native.js:9:27:9:33 | tainted | -| react-native.js:9:27:9:33 | tainted | -| react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:16:26:16:36 | window.name | -| react-use-context.js:16:26:16:36 | window.name | -| react-use-context.js:16:26:16:36 | window.name | -| react-use-context.js:16:26:16:36 | window.name | -| react-use-router.js:4:9:4:28 | router | -| react-use-router.js:4:18:4:28 | useRouter() | -| react-use-router.js:8:21:8:26 | router | -| react-use-router.js:8:21:8:32 | router.query | -| react-use-router.js:8:21:8:32 | router.query | -| react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:11:24:11:29 | router | -| react-use-router.js:11:24:11:35 | router.query | -| react-use-router.js:11:24:11:35 | router.query | -| react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:22:15:22:24 | router | -| react-use-router.js:22:17:22:22 | router | -| react-use-router.js:23:43:23:48 | router | -| react-use-router.js:23:43:23:54 | router.query | -| react-use-router.js:23:43:23:54 | router.query | -| react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:29:9:29:30 | router | -| react-use-router.js:29:18:29:30 | myUseRouter() | -| react-use-router.js:33:21:33:26 | router | -| react-use-router.js:33:21:33:32 | router.query | -| react-use-router.js:33:21:33:32 | router.query | -| react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-state.js:4:9:4:49 | state | -| react-use-state.js:4:9:4:49 | state | -| react-use-state.js:4:10:4:14 | state | -| react-use-state.js:4:10:4:14 | state | -| react-use-state.js:4:38:4:48 | window.name | -| react-use-state.js:4:38:4:48 | window.name | -| react-use-state.js:4:38:4:48 | window.name | -| react-use-state.js:5:51:5:55 | state | -| react-use-state.js:5:51:5:55 | state | -| react-use-state.js:5:51:5:55 | state | -| react-use-state.js:9:9:9:43 | state | -| react-use-state.js:9:9:9:43 | state | -| react-use-state.js:9:10:9:14 | state | -| react-use-state.js:9:10:9:14 | state | -| react-use-state.js:10:14:10:24 | window.name | -| react-use-state.js:10:14:10:24 | window.name | -| react-use-state.js:10:14:10:24 | window.name | -| react-use-state.js:11:51:11:55 | state | -| react-use-state.js:11:51:11:55 | state | -| react-use-state.js:11:51:11:55 | state | -| react-use-state.js:15:9:15:43 | state | -| react-use-state.js:15:9:15:43 | state | -| react-use-state.js:15:10:15:14 | state | -| react-use-state.js:15:10:15:14 | state | -| react-use-state.js:16:20:16:30 | window.name | -| react-use-state.js:16:20:16:30 | window.name | -| react-use-state.js:16:20:16:30 | window.name | -| react-use-state.js:17:51:17:55 | state | -| react-use-state.js:17:51:17:55 | state | -| react-use-state.js:17:51:17:55 | state | -| react-use-state.js:21:10:21:14 | state | -| react-use-state.js:21:10:21:14 | state | -| react-use-state.js:22:14:22:17 | prev | -| react-use-state.js:22:14:22:17 | prev | -| react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:25:20:25:30 | window.name | -| react-use-state.js:25:20:25:30 | window.name | -| react-use-state.js:25:20:25:30 | window.name | -| sanitiser.js:16:7:16:27 | tainted | -| sanitiser.js:16:7:16:27 | tainted | -| sanitiser.js:16:17:16:27 | window.name | -| sanitiser.js:16:17:16:27 | window.name | -| sanitiser.js:16:17:16:27 | window.name | -| sanitiser.js:23:21:23:44 | '' + ... '' | -| sanitiser.js:23:21:23:44 | '' + ... '' | -| sanitiser.js:23:29:23:35 | tainted | -| sanitiser.js:30:21:30:44 | '' + ... '' | -| sanitiser.js:30:21:30:44 | '' + ... '' | -| sanitiser.js:30:29:30:35 | tainted | -| sanitiser.js:33:21:33:44 | '' + ... '' | -| sanitiser.js:33:21:33:44 | '' + ... '' | -| sanitiser.js:33:29:33:35 | tainted | -| sanitiser.js:38:21:38:44 | '' + ... '' | -| sanitiser.js:38:21:38:44 | '' + ... '' | -| sanitiser.js:38:29:38:35 | tainted | -| sanitiser.js:45:21:45:44 | '' + ... '' | -| sanitiser.js:45:21:45:44 | '' + ... '' | -| sanitiser.js:45:29:45:35 | tainted | -| sanitiser.js:48:19:48:25 | tainted | -| sanitiser.js:48:19:48:25 | tainted | -| sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| stored-xss.js:2:39:2:62 | documen ... .search | -| stored-xss.js:2:39:2:62 | documen ... .search | -| stored-xss.js:3:35:3:58 | documen ... .search | -| stored-xss.js:3:35:3:58 | documen ... .search | -| stored-xss.js:5:20:5:52 | session ... ssion') | -| stored-xss.js:5:20:5:52 | session ... ssion') | -| stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:10:9:10:44 | href | -| stored-xss.js:10:16:10:44 | localSt ... local') | -| stored-xss.js:12:20:12:54 | "" | -| stored-xss.js:12:20:12:54 | "" | -| stored-xss.js:12:20:12:54 | "" | -| stored-xss.js:12:35:12:38 | href | -| string-manipulations.js:3:16:3:32 | document.location | -| string-manipulations.js:3:16:3:32 | document.location | -| string-manipulations.js:3:16:3:32 | document.location | -| string-manipulations.js:4:16:4:37 | documen ... on.href | -| string-manipulations.js:4:16:4:37 | documen ... on.href | -| string-manipulations.js:4:16:4:37 | documen ... on.href | -| string-manipulations.js:5:16:5:37 | documen ... on.href | -| string-manipulations.js:5:16:5:37 | documen ... on.href | -| string-manipulations.js:5:16:5:47 | documen ... lueOf() | -| string-manipulations.js:5:16:5:47 | documen ... lueOf() | -| string-manipulations.js:6:16:6:37 | documen ... on.href | -| string-manipulations.js:6:16:6:37 | documen ... on.href | -| string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:7:16:7:37 | documen ... on.href | -| string-manipulations.js:7:16:7:37 | documen ... on.href | -| string-manipulations.js:7:16:7:51 | documen ... rCase() | -| string-manipulations.js:7:16:7:51 | documen ... rCase() | -| string-manipulations.js:8:16:8:37 | documen ... on.href | -| string-manipulations.js:8:16:8:37 | documen ... on.href | -| string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:9:16:9:58 | String. ... n.href) | -| string-manipulations.js:9:16:9:58 | String. ... n.href) | -| string-manipulations.js:9:36:9:57 | documen ... on.href | -| string-manipulations.js:9:36:9:57 | documen ... on.href | -| string-manipulations.js:10:16:10:45 | String( ... n.href) | -| string-manipulations.js:10:16:10:45 | String( ... n.href) | -| string-manipulations.js:10:23:10:44 | documen ... on.href | -| string-manipulations.js:10:23:10:44 | documen ... on.href | -| tooltip.jsx:6:11:6:30 | source | -| tooltip.jsx:6:11:6:30 | source | -| tooltip.jsx:6:20:6:30 | window.name | -| tooltip.jsx:6:20:6:30 | window.name | -| tooltip.jsx:6:20:6:30 | window.name | -| tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:22:11:22:30 | source | -| tooltip.jsx:22:11:22:30 | source | -| tooltip.jsx:22:20:22:30 | window.name | -| tooltip.jsx:22:20:22:30 | window.name | -| tooltip.jsx:22:20:22:30 | window.name | -| tooltip.jsx:23:38:23:43 | source | -| tooltip.jsx:23:38:23:43 | source | -| translate.js:6:7:6:39 | target | -| translate.js:6:16:6:39 | documen ... .search | -| translate.js:6:16:6:39 | documen ... .search | -| translate.js:7:7:7:61 | searchParams | -| translate.js:7:22:7:61 | new URL ... ing(1)) | -| translate.js:7:42:7:47 | target | -| translate.js:7:42:7:60 | target.substring(1) | -| translate.js:7:42:7:60 | target.substring(1) | -| translate.js:7:42:7:60 | target.substring(1) | -| translate.js:9:27:9:38 | searchParams | -| translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:9:27:9:50 | searchP ... 'term') | -| trusted-types-lib.js:1:28:1:28 | x | -| trusted-types-lib.js:1:28:1:28 | x | -| trusted-types-lib.js:2:12:2:12 | x | -| trusted-types-lib.js:2:12:2:12 | x | -| trusted-types-lib.js:2:12:2:12 | x | -| trusted-types.js:3:62:3:62 | x | -| trusted-types.js:3:62:3:62 | x | -| trusted-types.js:3:67:3:67 | x | -| trusted-types.js:3:67:3:67 | x | -| trusted-types.js:3:67:3:67 | x | -| trusted-types.js:4:20:4:30 | window.name | -| trusted-types.js:4:20:4:30 | window.name | -| trusted-types.js:4:20:4:30 | window.name | -| trusted-types.js:13:20:13:30 | window.name | -| trusted-types.js:13:20:13:30 | window.name | -| trusted-types.js:13:20:13:30 | window.name | -| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | -| tst3.js:2:23:2:74 | decodeU ... str(1)) | -| tst3.js:2:42:2:63 | window. ... .search | -| tst3.js:2:42:2:63 | window. ... .search | -| tst3.js:2:42:2:73 | window. ... bstr(1) | -| tst3.js:4:25:4:28 | data | -| tst3.js:4:25:4:32 | data.src | -| tst3.js:4:25:4:32 | data.src | -| tst3.js:5:26:5:29 | data | -| tst3.js:5:26:5:31 | data.p | -| tst3.js:5:26:5:31 | data.p | -| tst3.js:7:32:7:35 | data | -| tst3.js:7:32:7:37 | data.p | -| tst3.js:7:32:7:37 | data.p | -| tst3.js:9:37:9:40 | data | -| tst3.js:9:37:9:42 | data.p | -| tst3.js:9:37:9:42 | data.p | -| tst3.js:10:38:10:41 | data | -| tst3.js:10:38:10:43 | data.p | -| tst3.js:10:38:10:43 | data.p | -| tst.js:2:7:2:39 | target | -| tst.js:2:16:2:39 | documen ... .search | -| tst.js:2:16:2:39 | documen ... .search | -| tst.js:5:18:5:23 | target | -| tst.js:5:18:5:23 | target | -| tst.js:8:18:8:126 | "" | -| tst.js:8:18:8:126 | "" | -| tst.js:8:18:8:126 | "" | -| tst.js:8:37:8:58 | documen ... on.href | -| tst.js:8:37:8:58 | documen ... on.href | -| tst.js:8:37:8:114 | documen ... t=")+8) | -| tst.js:8:37:8:114 | documen ... t=")+8) | -| tst.js:12:5:12:42 | '
' | -| tst.js:12:5:12:42 | '
' | -| tst.js:12:28:12:33 | target | -| tst.js:17:7:17:56 | params | -| tst.js:17:16:17:56 | (new UR ... hParams | -| tst.js:17:25:17:41 | document.location | -| tst.js:17:25:17:41 | document.location | -| tst.js:18:18:18:23 | params | -| tst.js:18:18:18:35 | params.get('name') | -| tst.js:18:18:18:35 | params.get('name') | -| tst.js:18:18:18:35 | params.get('name') | -| tst.js:18:18:18:35 | params.get('name') | -| tst.js:20:7:20:61 | searchParams | -| tst.js:20:22:20:61 | new URL ... ing(1)) | -| tst.js:20:42:20:47 | target | -| tst.js:20:42:20:60 | target.substring(1) | -| tst.js:20:42:20:60 | target.substring(1) | -| tst.js:20:42:20:60 | target.substring(1) | -| tst.js:21:18:21:29 | searchParams | -| tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:24:14:24:19 | target | -| tst.js:26:18:26:23 | target | -| tst.js:26:18:26:23 | target | -| tst.js:28:5:28:28 | documen ... .search | -| tst.js:28:5:28:28 | documen ... .search | -| tst.js:31:10:31:33 | documen ... .search | -| tst.js:31:10:31:33 | documen ... .search | -| tst.js:34:16:34:20 | bar() | -| tst.js:34:16:34:20 | bar() | -| tst.js:40:16:40:44 | baz(doc ... search) | -| tst.js:40:16:40:44 | baz(doc ... search) | -| tst.js:40:20:40:43 | documen ... .search | -| tst.js:40:20:40:43 | documen ... .search | -| tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:21:46:44 | documen ... .search | -| tst.js:46:21:46:44 | documen ... .search | -| tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | -| tst.js:54:21:54:44 | documen ... .search | -| tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | -| tst.js:56:21:56:44 | documen ... .search | -| tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:21:58:31 | chop(bar()) | -| tst.js:58:21:58:31 | chop(bar()) | -| tst.js:58:26:58:30 | bar() | -| tst.js:60:34:60:34 | s | -| tst.js:62:18:62:18 | s | -| tst.js:62:18:62:18 | s | -| tst.js:64:25:64:48 | documen ... .search | -| tst.js:64:25:64:48 | documen ... .search | -| tst.js:65:25:65:48 | documen ... .search | -| tst.js:65:25:65:48 | documen ... .search | -| tst.js:68:16:68:20 | bar() | -| tst.js:68:16:68:20 | bar() | -| tst.js:70:1:70:27 | [,docum ... search] | -| tst.js:70:3:70:26 | documen ... .search | -| tst.js:70:3:70:26 | documen ... .search | -| tst.js:70:46:70:46 | x | -| tst.js:73:20:73:20 | x | -| tst.js:73:20:73:20 | x | -| tst.js:77:49:77:72 | documen ... .search | -| tst.js:77:49:77:72 | documen ... .search | -| tst.js:77:49:77:72 | documen ... .search | -| tst.js:81:26:81:49 | documen ... .search | -| tst.js:81:26:81:49 | documen ... .search | -| tst.js:81:26:81:49 | documen ... .search | -| tst.js:82:25:82:48 | documen ... .search | -| tst.js:82:25:82:48 | documen ... .search | -| tst.js:82:25:82:48 | documen ... .search | -| tst.js:84:33:84:56 | documen ... .search | -| tst.js:84:33:84:56 | documen ... .search | -| tst.js:84:33:84:56 | documen ... .search | -| tst.js:85:32:85:55 | documen ... .search | -| tst.js:85:32:85:55 | documen ... .search | -| tst.js:85:32:85:55 | documen ... .search | -| tst.js:90:39:90:62 | documen ... .search | -| tst.js:90:39:90:62 | documen ... .search | -| tst.js:90:39:90:62 | documen ... .search | -| tst.js:96:30:96:53 | documen ... .search | -| tst.js:96:30:96:53 | documen ... .search | -| tst.js:96:30:96:53 | documen ... .search | -| tst.js:102:25:102:48 | documen ... .search | -| tst.js:102:25:102:48 | documen ... .search | -| tst.js:102:25:102:48 | documen ... .search | -| tst.js:107:7:107:44 | v | -| tst.js:107:7:107:44 | v | -| tst.js:107:7:107:44 | v | -| tst.js:107:11:107:34 | documen ... .search | -| tst.js:107:11:107:34 | documen ... .search | -| tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:110:18:110:18 | v | -| tst.js:110:18:110:18 | v | -| tst.js:110:18:110:18 | v | -| tst.js:110:18:110:18 | v | -| tst.js:136:18:136:18 | v | -| tst.js:136:18:136:18 | v | -| tst.js:136:18:136:18 | v | -| tst.js:136:18:136:18 | v | -| tst.js:148:29:148:50 | window. ... .search | -| tst.js:148:29:148:50 | window. ... .search | -| tst.js:151:29:151:29 | v | -| tst.js:151:49:151:49 | v | -| tst.js:151:49:151:49 | v | -| tst.js:155:29:155:46 | xssSourceService() | -| tst.js:155:29:155:46 | xssSourceService() | -| tst.js:158:40:158:61 | window. ... .search | -| tst.js:158:40:158:61 | window. ... .search | -| tst.js:177:9:177:41 | target | -| tst.js:177:18:177:41 | documen ... .search | -| tst.js:177:18:177:41 | documen ... .search | -| tst.js:180:28:180:33 | target | -| tst.js:180:28:180:33 | target | -| tst.js:184:9:184:42 | tainted | -| tst.js:184:19:184:42 | documen ... .search | -| tst.js:184:19:184:42 | documen ... .search | -| tst.js:186:31:186:37 | tainted | -| tst.js:186:31:186:37 | tainted | -| tst.js:188:42:188:48 | tainted | -| tst.js:188:42:188:48 | tainted | -| tst.js:189:33:189:39 | tainted | -| tst.js:189:33:189:39 | tainted | -| tst.js:191:54:191:60 | tainted | -| tst.js:191:54:191:60 | tainted | -| tst.js:192:45:192:51 | tainted | -| tst.js:192:45:192:51 | tainted | -| tst.js:193:49:193:55 | tainted | -| tst.js:193:49:193:55 | tainted | -| tst.js:197:9:197:42 | tainted | -| tst.js:197:19:197:42 | documen ... .search | -| tst.js:197:19:197:42 | documen ... .search | -| tst.js:199:67:199:73 | tainted | -| tst.js:199:67:199:73 | tainted | -| tst.js:200:67:200:73 | tainted | -| tst.js:200:67:200:73 | tainted | -| tst.js:204:35:204:41 | tainted | -| tst.js:206:46:206:52 | tainted | -| tst.js:207:38:207:44 | tainted | -| tst.js:208:35:208:41 | tainted | -| tst.js:212:28:212:46 | this.state.tainted1 | -| tst.js:212:28:212:46 | this.state.tainted1 | -| tst.js:213:28:213:46 | this.state.tainted2 | -| tst.js:213:28:213:46 | this.state.tainted2 | -| tst.js:214:28:214:46 | this.state.tainted3 | -| tst.js:214:28:214:46 | this.state.tainted3 | -| tst.js:218:32:218:49 | prevState.tainted4 | -| tst.js:218:32:218:49 | prevState.tainted4 | -| tst.js:225:28:225:46 | this.props.tainted1 | -| tst.js:225:28:225:46 | this.props.tainted1 | -| tst.js:226:28:226:46 | this.props.tainted2 | -| tst.js:226:28:226:46 | this.props.tainted2 | -| tst.js:227:28:227:46 | this.props.tainted3 | -| tst.js:227:28:227:46 | this.props.tainted3 | -| tst.js:231:32:231:49 | prevProps.tainted4 | -| tst.js:231:32:231:49 | prevProps.tainted4 | -| tst.js:236:35:236:41 | tainted | -| tst.js:238:20:238:26 | tainted | -| tst.js:240:23:240:29 | tainted | -| tst.js:241:23:241:29 | tainted | -| tst.js:247:39:247:55 | props.propTainted | -| tst.js:251:60:251:82 | this.st ... Tainted | -| tst.js:251:60:251:82 | this.st ... Tainted | -| tst.js:255:23:255:29 | tainted | -| tst.js:259:7:259:17 | window.name | -| tst.js:259:7:259:17 | window.name | -| tst.js:259:7:259:17 | window.name | -| tst.js:259:7:259:17 | window.name | -| tst.js:260:7:260:10 | name | -| tst.js:260:7:260:10 | name | -| tst.js:260:7:260:10 | name | -| tst.js:260:7:260:10 | name | -| tst.js:264:11:264:21 | window.name | -| tst.js:264:11:264:21 | window.name | -| tst.js:264:11:264:21 | window.name | -| tst.js:264:11:264:21 | window.name | -| tst.js:280:22:280:29 | location | -| tst.js:280:22:280:29 | location | -| tst.js:280:22:280:29 | location | -| tst.js:285:9:285:29 | tainted | -| tst.js:285:9:285:29 | tainted | -| tst.js:285:19:285:29 | window.name | -| tst.js:285:19:285:29 | window.name | -| tst.js:285:19:285:29 | window.name | -| tst.js:288:59:288:65 | tainted | -| tst.js:288:59:288:65 | tainted | -| tst.js:288:59:288:65 | tainted | -| tst.js:301:9:301:16 | location | -| tst.js:301:9:301:16 | location | -| tst.js:302:10:302:10 | e | -| tst.js:303:20:303:20 | e | -| tst.js:303:20:303:20 | e | -| tst.js:308:10:308:17 | location | -| tst.js:308:10:308:17 | location | -| tst.js:310:10:310:10 | e | -| tst.js:311:20:311:20 | e | -| tst.js:311:20:311:20 | e | -| tst.js:316:35:316:42 | location | -| tst.js:316:35:316:42 | location | -| tst.js:316:35:316:42 | location | -| tst.js:327:18:327:34 | document.location | -| tst.js:327:18:327:34 | document.location | -| tst.js:331:7:331:43 | params | -| tst.js:331:16:331:43 | getTain ... hParams | -| tst.js:332:18:332:23 | params | -| tst.js:332:18:332:35 | params.get('name') | -| tst.js:332:18:332:35 | params.get('name') | -| tst.js:332:18:332:35 | params.get('name') | -| tst.js:332:18:332:35 | params.get('name') | -| tst.js:341:20:341:36 | document.location | -| tst.js:341:20:341:36 | document.location | -| tst.js:343:5:343:17 | getUrl().hash | -| tst.js:343:5:343:30 | getUrl( ... ring(1) | -| tst.js:343:5:343:30 | getUrl( ... ring(1) | -| tst.js:343:5:343:30 | getUrl( ... ring(1) | -| tst.js:348:7:348:39 | target | -| tst.js:348:16:348:39 | documen ... .search | -| tst.js:348:16:348:39 | documen ... .search | -| tst.js:349:12:349:17 | target | -| tst.js:349:12:349:17 | target | -| tst.js:355:10:355:42 | target | -| tst.js:355:19:355:42 | documen ... .search | -| tst.js:355:19:355:42 | documen ... .search | -| tst.js:356:16:356:21 | target | -| tst.js:356:16:356:21 | target | -| tst.js:360:21:360:26 | target | -| tst.js:360:21:360:26 | target | -| tst.js:363:18:363:23 | target | -| tst.js:363:18:363:23 | target | -| tst.js:371:7:371:39 | target | -| tst.js:371:16:371:39 | documen ... .search | -| tst.js:371:16:371:39 | documen ... .search | -| tst.js:374:18:374:23 | target | -| tst.js:374:18:374:23 | target | -| tst.js:381:7:381:39 | target | -| tst.js:381:16:381:39 | documen ... .search | -| tst.js:381:16:381:39 | documen ... .search | -| tst.js:384:18:384:23 | target | -| tst.js:384:18:384:23 | target | -| tst.js:386:18:386:23 | target | -| tst.js:386:18:386:29 | target.taint | -| tst.js:386:18:386:29 | target.taint | -| tst.js:391:19:391:42 | documen ... .search | -| tst.js:391:19:391:42 | documen ... .search | -| tst.js:392:18:392:30 | target.taint3 | -| tst.js:392:18:392:30 | target.taint3 | -| tst.js:397:18:397:23 | target | -| tst.js:397:18:397:30 | target.taint5 | -| tst.js:397:18:397:30 | target.taint5 | -| tst.js:406:18:406:23 | target | -| tst.js:406:18:406:30 | target.taint7 | -| tst.js:406:18:406:30 | target.taint7 | -| tst.js:408:19:408:24 | target | -| tst.js:408:19:408:31 | target.taint8 | -| tst.js:409:18:409:30 | target.taint8 | -| tst.js:409:18:409:30 | target.taint8 | -| tst.js:416:7:416:46 | payload | -| tst.js:416:7:416:46 | payload | -| tst.js:416:7:416:46 | payload | -| tst.js:416:17:416:36 | window.location.hash | -| tst.js:416:17:416:36 | window.location.hash | -| tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:417:18:417:24 | payload | -| tst.js:417:18:417:24 | payload | -| tst.js:417:18:417:24 | payload | -| tst.js:417:18:417:24 | payload | -| tst.js:419:7:419:55 | match | -| tst.js:419:15:419:34 | window.location.hash | -| tst.js:419:15:419:34 | window.location.hash | -| tst.js:419:15:419:55 | window. ... (\\w+)/) | -| tst.js:421:20:421:24 | match | -| tst.js:421:20:421:27 | match[1] | -| tst.js:421:20:421:27 | match[1] | -| tst.js:424:18:424:37 | window.location.hash | -| tst.js:424:18:424:37 | window.location.hash | -| tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:428:7:428:39 | target | -| tst.js:428:16:428:39 | documen ... .search | -| tst.js:428:16:428:39 | documen ... .search | -| tst.js:430:18:430:23 | target | -| tst.js:430:18:430:89 | target. ... data>') | -| tst.js:430:18:430:89 | target. ... data>') | -| tst.js:436:6:436:38 | source | -| tst.js:436:15:436:38 | documen ... .search | -| tst.js:436:15:436:38 | documen ... .search | -| tst.js:440:28:440:33 | source | -| tst.js:440:28:440:33 | source | -| tst.js:441:33:441:38 | source | -| tst.js:441:33:441:38 | source | -| tst.js:442:34:442:39 | source | -| tst.js:442:34:442:39 | source | -| tst.js:443:41:443:46 | source | -| tst.js:443:41:443:46 | source | -| tst.js:444:44:444:49 | source | -| tst.js:444:44:444:49 | source | -| tst.js:445:32:445:37 | source | -| tst.js:445:32:445:37 | source | -| tst.js:453:7:453:39 | source | -| tst.js:453:16:453:39 | documen ... .search | -| tst.js:453:16:453:39 | documen ... .search | -| tst.js:455:18:455:23 | source | -| tst.js:455:18:455:23 | source | -| tst.js:456:18:456:42 | ansiToH ... source) | -| tst.js:456:18:456:42 | ansiToH ... source) | -| tst.js:456:36:456:41 | source | -| tst.js:460:6:460:38 | source | -| tst.js:460:15:460:38 | documen ... .search | -| tst.js:460:15:460:38 | documen ... .search | -| tst.js:463:21:463:26 | source | -| tst.js:463:21:463:26 | source | -| tst.js:465:19:465:24 | source | -| tst.js:465:19:465:24 | source | -| tst.js:467:20:467:25 | source | -| tst.js:467:20:467:25 | source | -| tst.js:471:7:471:46 | url | -| tst.js:471:13:471:36 | documen ... .search | -| tst.js:471:13:471:36 | documen ... .search | -| tst.js:471:13:471:46 | documen ... bstr(1) | -| tst.js:473:19:473:21 | url | -| tst.js:473:19:473:21 | url | -| tst.js:474:26:474:28 | url | -| tst.js:474:26:474:28 | url | -| tst.js:475:25:475:27 | url | -| tst.js:475:25:475:27 | url | -| tst.js:476:20:476:22 | url | -| tst.js:476:20:476:22 | url | -| tst.js:486:22:486:24 | url | -| tst.js:486:22:486:24 | url | -| tst.js:491:23:491:35 | location.hash | -| tst.js:491:23:491:35 | location.hash | -| tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:494:18:494:30 | location.hash | -| tst.js:494:18:494:30 | location.hash | -| tst.js:494:18:494:40 | locatio ... bstr(1) | -| tst.js:494:18:494:40 | locatio ... bstr(1) | -| tst.js:501:33:501:63 | decodeU ... n.hash) | -| tst.js:501:33:501:63 | decodeU ... n.hash) | -| tst.js:501:43:501:62 | window.location.hash | -| tst.js:501:43:501:62 | window.location.hash | -| typeahead.js:20:13:20:45 | target | -| typeahead.js:20:22:20:45 | documen ... .search | -| typeahead.js:20:22:20:45 | documen ... .search | -| typeahead.js:21:12:21:17 | target | -| typeahead.js:24:30:24:32 | val | -| typeahead.js:25:18:25:20 | val | -| typeahead.js:25:18:25:20 | val | -| v-html.vue:2:8:2:23 | v-html=tainted | -| v-html.vue:2:8:2:23 | v-html=tainted | -| v-html.vue:6:42:6:58 | document.location | -| v-html.vue:6:42:6:58 | document.location | -| various-concat-obfuscations.js:2:6:2:39 | tainted | -| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | -| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | -| various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | -| various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | -| various-concat-obfuscations.js:4:14:4:20 | tainted | -| various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | -| various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | -| various-concat-obfuscations.js:5:12:5:18 | tainted | -| various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | -| various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | -| various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | -| various-concat-obfuscations.js:6:19:6:25 | tainted | -| various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | -| various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | -| various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | -| various-concat-obfuscations.js:7:14:7:20 | tainted | -| various-concat-obfuscations.js:9:4:9:34 | "
" | -| various-concat-obfuscations.js:9:4:9:34 | "
" | -| various-concat-obfuscations.js:9:19:9:25 | tainted | -| various-concat-obfuscations.js:10:4:10:27 | `
` | -| various-concat-obfuscations.js:10:4:10:27 | `
` | -| various-concat-obfuscations.js:10:16:10:22 | tainted | -| various-concat-obfuscations.js:11:4:11:31 | "
") | -| various-concat-obfuscations.js:11:4:11:44 | "
") | -| various-concat-obfuscations.js:11:24:11:30 | tainted | -| various-concat-obfuscations.js:12:4:12:34 | ["
"] | -| various-concat-obfuscations.js:12:4:12:41 | ["
>>>>>> main edges -| addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | -| addEventListener.js:2:20:2:24 | event | addEventListener.js:2:20:2:29 | event.data | -| addEventListener.js:5:43:5:48 | data | addEventListener.js:6:20:6:23 | data | -| addEventListener.js:5:43:5:48 | {data} | addEventListener.js:5:44:5:47 | data | -| addEventListener.js:5:44:5:47 | data | addEventListener.js:5:43:5:48 | data | -| addEventListener.js:10:21:10:25 | event | addEventListener.js:12:24:12:28 | event | -| addEventListener.js:12:24:12:28 | event | addEventListener.js:12:24:12:33 | event.data | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| classnames.js:7:47:7:69 | classNa ... w.name) | classnames.js:7:31:7:84 | `` | -| classnames.js:7:58:7:68 | window.name | classnames.js:7:47:7:69 | classNa ... w.name) | -| classnames.js:8:47:8:70 | classNa ... w.name) | classnames.js:8:31:8:85 | `` | -| classnames.js:8:59:8:69 | window.name | classnames.js:8:47:8:70 | classNa ... w.name) | -| classnames.js:9:47:9:70 | classNa ... w.name) | classnames.js:9:31:9:85 | `` | -| classnames.js:9:59:9:69 | window.name | classnames.js:9:47:9:70 | classNa ... w.name) | -| classnames.js:10:45:10:55 | window.name | classnames.js:11:47:11:64 | unsafeStyle('foo') | -| classnames.js:11:47:11:64 | unsafeStyle('foo') | classnames.js:11:31:11:79 | `` | -| classnames.js:13:47:13:68 | safeSty ... w.name) | classnames.js:13:31:13:83 | `` | -| classnames.js:13:57:13:67 | window.name | classnames.js:13:47:13:68 | safeSty ... w.name) | -| classnames.js:15:47:15:63 | clsx(window.name) | classnames.js:15:31:15:78 | `` | -| classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) | -| classnames.js:17:48:17:64 | clsx(window.name) | classnames.js:17:32:17:79 | `` | -| classnames.js:17:53:17:63 | window.name | classnames.js:17:48:17:64 | clsx(window.name) | -| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html | -| clipboard.ts:43:15:43:55 | html | clipboard.ts:50:29:50:32 | html | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | clipboard.ts:43:15:43:55 | html | -| clipboard.ts:71:13:71:62 | droppedHtml | clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:98:15:98:54 | html | clipboard.ts:99:23:99:26 | html | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | clipboard.ts:98:15:98:54 | html | -| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | -| dates.js:9:9:9:69 | taint | dates.js:11:63:11:67 | taint | -| dates.js:9:9:9:69 | taint | dates.js:12:66:12:70 | taint | -| dates.js:9:9:9:69 | taint | dates.js:13:59:13:63 | taint | -| dates.js:9:9:9:69 | taint | dates.js:16:62:16:66 | taint | -| dates.js:9:9:9:69 | taint | dates.js:18:59:18:63 | taint | -| dates.js:9:9:9:69 | taint | dates.js:21:61:21:65 | taint | -| dates.js:9:17:9:69 | decodeU ... ing(1)) | dates.js:9:9:9:69 | taint | -| dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | -| dates.js:9:36:9:68 | window. ... ring(1) | dates.js:9:17:9:69 | decodeU ... ing(1)) | -| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:63:11:67 | taint | dates.js:11:42:11:68 | dateFns ... taint) | -| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:66:12:70 | taint | dates.js:12:42:12:71 | dateFns ... taint) | -| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:59:13:63 | taint | dates.js:13:42:13:70 | dateFns ... )(time) | -| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:62:16:66 | taint | dates.js:16:42:16:67 | moment( ... (taint) | -| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:59:18:63 | taint | dates.js:18:42:18:64 | datefor ... taint) | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:61:21:65 | taint | dates.js:21:42:21:66 | dayjs(t ... (taint) | -| dates.js:30:9:30:69 | taint | dates.js:37:77:37:81 | taint | -| dates.js:30:9:30:69 | taint | dates.js:38:77:38:81 | taint | -| dates.js:30:9:30:69 | taint | dates.js:39:79:39:83 | taint | -| dates.js:30:9:30:69 | taint | dates.js:40:77:40:81 | taint | -| dates.js:30:17:30:69 | decodeU ... ing(1)) | dates.js:30:9:30:69 | taint | -| dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:30:36:30:68 | window. ... ring(1) | dates.js:30:17:30:69 | decodeU ... ing(1)) | -| dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:77:37:81 | taint | dates.js:37:42:37:82 | dateFns ... taint) | -| dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:77:38:81 | taint | dates.js:38:42:38:82 | luxon.f ... taint) | -| dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:79:39:83 | taint | dates.js:39:42:39:84 | moment. ... taint) | -| dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:77:40:81 | taint | dates.js:40:42:40:82 | dayjs.f ... taint) | -| dates.js:46:9:46:69 | taint | dates.js:48:83:48:87 | taint | -| dates.js:46:9:46:69 | taint | dates.js:49:82:49:86 | taint | -| dates.js:46:9:46:69 | taint | dates.js:50:97:50:101 | taint | -| dates.js:46:17:46:69 | decodeU ... ing(1)) | dates.js:46:9:46:69 | taint | -| dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:46:36:46:68 | window. ... ring(1) | dates.js:46:17:46:69 | decodeU ... ing(1)) | -| dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:83:48:87 | taint | dates.js:48:42:48:88 | DateTim ... (taint) | -| dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:82:49:86 | taint | dates.js:49:42:49:87 | new Dat ... (taint) | -| dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:97:50:101 | taint | dates.js:50:42:50:102 | DateTim ... (taint) | -| dates.js:54:9:54:69 | taint | dates.js:57:94:57:98 | taint | -| dates.js:54:9:54:69 | taint | dates.js:59:80:59:84 | taint | -| dates.js:54:9:54:69 | taint | dates.js:61:81:61:85 | taint | -| dates.js:54:17:54:69 | decodeU ... ing(1)) | dates.js:54:9:54:69 | taint | -| dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:54:36:54:68 | window. ... ring(1) | dates.js:54:17:54:69 | decodeU ... ing(1)) | -| dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:94:57:98 | taint | dates.js:57:42:57:99 | moment. ... (taint) | -| dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:80:59:84 | taint | dates.js:59:42:59:85 | luxon.e ... (taint) | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:81:61:85 | taint | dates.js:61:42:61:86 | dayjs.s ... (taint) | -| dragAndDrop.ts:8:11:8:50 | html | dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:43:15:43:54 | html | dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:71:13:71:61 | droppedHtml | dragAndDrop.ts:73:29:73:39 | droppedHtml | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | -| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | -| jquery.js:2:7:2:40 | tainted | jquery.js:7:20:7:26 | tainted | -| jquery.js:2:7:2:40 | tainted | jquery.js:8:28:8:34 | tainted | -| jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | -| jquery.js:2:7:2:40 | tainted | jquery.js:37:31:37:37 | tainted | -| jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | -| jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "
" | -| jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | -| jquery.js:10:13:10:20 | location | jquery.js:10:13:10:31 | location.toString() | -| jquery.js:10:13:10:31 | location.toString() | jquery.js:10:5:10:40 | "" + ... "" | -| jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | -| jquery.js:16:38:16:52 | window.location | jquery.js:16:38:16:63 | window. ... tring() | -| jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) | -| jquery.js:18:7:18:33 | hash | jquery.js:21:5:21:8 | hash | -| jquery.js:18:7:18:33 | hash | jquery.js:22:5:22:8 | hash | -| jquery.js:18:7:18:33 | hash | jquery.js:23:5:23:8 | hash | -| jquery.js:18:7:18:33 | hash | jquery.js:24:5:24:8 | hash | -| jquery.js:18:7:18:33 | hash | jquery.js:27:5:27:8 | hash | -| jquery.js:18:7:18:33 | hash | jquery.js:34:13:34:16 | hash | -| jquery.js:18:14:18:33 | window.location.hash | jquery.js:18:7:18:33 | hash | -| jquery.js:21:5:21:8 | hash | jquery.js:21:5:21:21 | hash.substring(1) | -| jquery.js:22:5:22:8 | hash | jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:23:5:23:8 | hash | jquery.js:23:5:23:18 | hash.substr(1) | -| jquery.js:24:5:24:8 | hash | jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:27:5:27:8 | hash | jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '' + ... '' | -| jquery.js:37:31:37:37 | tainted | jquery.js:37:25:37:37 | () => tainted | -| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:11:51:11:56 | locale | -| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:19:56:19:61 | locale | -| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:31:55:31:60 | locale | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | -| json-stringify.jsx:11:51:11:56 | locale | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | -| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | -| json-stringify.jsx:19:56:19:61 | locale | json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | -| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| jwt-server.js:7:9:7:35 | taint | jwt-server.js:9:16:9:20 | taint | -| jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:9:16:9:20 | taint | jwt-server.js:9:55:9:61 | decoded | -| jwt-server.js:9:55:9:61 | decoded | jwt-server.js:11:19:11:25 | decoded | -| jwt-server.js:11:19:11:25 | decoded | jwt-server.js:11:19:11:29 | decoded.foo | -| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:6:18:6:23 | target | -| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:8:17:8:22 | target | -| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:15:9:15:14 | target | -| optionalSanitizer.js:2:16:2:39 | documen ... .search | optionalSanitizer.js:2:7:2:39 | target | -| optionalSanitizer.js:8:7:8:22 | tainted | optionalSanitizer.js:9:18:9:24 | tainted | -| optionalSanitizer.js:8:17:8:22 | target | optionalSanitizer.js:8:7:8:22 | tainted | -| optionalSanitizer.js:15:9:15:14 | target | optionalSanitizer.js:16:18:16:18 | x | -| optionalSanitizer.js:16:18:16:18 | x | optionalSanitizer.js:17:20:17:20 | x | -| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:31:18:31:23 | target | -| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:38:18:38:23 | target | -| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:45:41:45:46 | target | -| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:45:51:45:56 | target | -| optionalSanitizer.js:26:16:26:39 | documen ... .search | optionalSanitizer.js:26:7:26:39 | target | -| optionalSanitizer.js:28:24:28:24 | x | optionalSanitizer.js:29:12:29:12 | x | -| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:32:18:32:25 | tainted2 | -| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:34:28:34:35 | tainted2 | -| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 | -| optionalSanitizer.js:31:18:31:23 | target | optionalSanitizer.js:31:7:31:23 | tainted2 | -| optionalSanitizer.js:34:5:34:36 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 | -| optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | optionalSanitizer.js:34:5:34:36 | tainted2 | -| optionalSanitizer.js:34:28:34:35 | tainted2 | optionalSanitizer.js:28:24:28:24 | x | -| optionalSanitizer.js:34:28:34:35 | tainted2 | optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | -| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:39:18:39:25 | tainted3 | -| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:41:28:41:35 | tainted3 | -| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 | -| optionalSanitizer.js:38:18:38:23 | target | optionalSanitizer.js:38:7:38:23 | tainted3 | -| optionalSanitizer.js:41:5:41:36 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 | -| optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | optionalSanitizer.js:41:5:41:36 | tainted3 | -| optionalSanitizer.js:41:28:41:35 | tainted3 | optionalSanitizer.js:28:24:28:24 | x | -| optionalSanitizer.js:41:28:41:35 | tainted3 | optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | -| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| optionalSanitizer.js:45:41:45:46 | target | optionalSanitizer.js:28:24:28:24 | x | -| optionalSanitizer.js:45:41:45:46 | target | optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | -| optionalSanitizer.js:45:51:45:56 | target | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| pages/[id].jsx:3:30:3:35 | params [id] | pages/[id].jsx:13:44:13:49 | params [id] | -| pages/[id].jsx:3:30:3:35 | params [q] | pages/[id].jsx:16:44:16:49 | params [q] | -| pages/[id].jsx:5:9:5:14 | { id } | pages/[id].jsx:5:11:5:12 | id | -| pages/[id].jsx:5:9:5:29 | id | pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:5:11:5:12 | id | pages/[id].jsx:5:9:5:29 | id | -| pages/[id].jsx:5:18:5:29 | router.query | pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:13:44:13:49 | params [id] | pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:16:44:16:49 | params [q] | pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | pages/[id].jsx:3:30:3:35 | params [id] | -| pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | pages/[id].jsx:3:30:3:35 | params [q] | -| pages/[id].jsx:25:11:25:24 | context.params | pages/[id].jsx:25:11:25:27 | context.params.id | -| pages/[id].jsx:25:11:25:27 | context.params.id | pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | -| pages/[id].jsx:26:10:26:22 | context.query | pages/[id].jsx:26:10:26:30 | context ... .foobar | -| pages/[id].jsx:26:10:26:30 | context ... .foobar | pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | -| react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | -| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:23:31:23:36 | [post update] router | react-use-router.js:23:43:23:48 | router | -| react-use-router.js:23:43:23:48 | router | react-use-router.js:23:43:23:54 | router.query | -| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:31:23:36 | [post update] router | -| react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | -| react-use-state.js:4:10:4:14 | state | react-use-state.js:4:9:4:49 | state | -| react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:10:4:14 | state | -| react-use-state.js:9:9:9:43 | state | react-use-state.js:11:51:11:55 | state | -| react-use-state.js:9:10:9:14 | state | react-use-state.js:9:9:9:43 | state | -| react-use-state.js:10:14:10:24 | window.name | react-use-state.js:9:10:9:14 | state | -| react-use-state.js:15:9:15:43 | state | react-use-state.js:17:51:17:55 | state | -| react-use-state.js:15:10:15:14 | state | react-use-state.js:15:9:15:43 | state | -| react-use-state.js:16:20:16:30 | window.name | react-use-state.js:15:10:15:14 | state | -| react-use-state.js:21:10:21:14 | state | react-use-state.js:22:14:22:17 | prev | -| react-use-state.js:22:14:22:17 | prev | react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:25:20:25:30 | window.name | react-use-state.js:21:10:21:14 | state | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:23:29:23:35 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:25:29:25:35 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:28:29:28:35 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:30:29:30:35 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:33:29:33:35 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:35:29:35:35 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:38:29:38:35 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:45:29:45:35 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:48:19:48:25 | tainted | -| sanitiser.js:16:17:16:27 | window.name | sanitiser.js:16:7:16:27 | tainted | -| sanitiser.js:23:29:23:35 | tainted | sanitiser.js:23:21:23:44 | '' + ... '' | -| sanitiser.js:25:29:25:35 | tainted | sanitiser.js:25:21:25:44 | '' + ... '' | -| sanitiser.js:28:29:28:35 | tainted | sanitiser.js:28:21:28:44 | '' + ... '' | -| sanitiser.js:30:29:30:35 | tainted | sanitiser.js:30:21:30:44 | '' + ... '' | -| sanitiser.js:33:29:33:35 | tainted | sanitiser.js:33:21:33:44 | '' + ... '' | -| sanitiser.js:35:29:35:35 | tainted | sanitiser.js:35:21:35:44 | '' + ... '' | -| sanitiser.js:38:29:38:35 | tainted | sanitiser.js:38:21:38:44 | '' + ... '' | -| sanitiser.js:45:29:45:35 | tainted | sanitiser.js:45:21:45:44 | '' + ... '' | -| sanitiser.js:48:19:48:25 | tainted | sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | -| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:10:16:10:44 | localSt ... local') | -| stored-xss.js:10:9:10:44 | href | stored-xss.js:12:35:12:38 | href | -| stored-xss.js:10:16:10:44 | localSt ... local') | stored-xss.js:10:9:10:44 | href | -| stored-xss.js:12:35:12:38 | href | stored-xss.js:12:20:12:54 | "" | -| string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | -| string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | -| string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | -| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | -| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source | -| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:23:38:23:43 | source | -| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:23:38:23:43 | source | -| tooltip.jsx:22:20:22:30 | window.name | tooltip.jsx:22:11:22:30 | source | -| tooltip.jsx:22:20:22:30 | window.name | tooltip.jsx:22:11:22:30 | source | -| tooltip.jsx:22:20:22:30 | window.name | tooltip.jsx:22:11:22:30 | source | -| tooltip.jsx:22:20:22:30 | window.name | tooltip.jsx:22:11:22:30 | source | -| tooltip.jsx:23:38:23:43 | source | tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:23:38:23:43 | source | tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:23:38:23:43 | source | tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:23:38:23:43 | source | tooltip.jsx:18:51:18:59 | provide() | -| translate.js:6:7:6:39 | target | translate.js:7:42:7:47 | target | -| translate.js:6:16:6:39 | documen ... .search | translate.js:6:7:6:39 | target | -| translate.js:7:7:7:61 | searchParams | translate.js:9:27:9:38 | searchParams | -| translate.js:7:22:7:61 | new URL ... ing(1)) | translate.js:7:7:7:61 | searchParams | -| translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | -| translate.js:7:42:7:60 | target.substring(1) | translate.js:7:22:7:61 | new URL ... ing(1)) | -| translate.js:9:27:9:38 | searchParams | translate.js:9:27:9:50 | searchP ... 'term') | -| trusted-types-lib.js:1:28:1:28 | x | trusted-types-lib.js:2:12:2:12 | x | -| trusted-types.js:3:62:3:62 | x | trusted-types.js:3:67:3:67 | x | -| trusted-types.js:4:20:4:30 | window.name | trusted-types.js:3:62:3:62 | x | -| trusted-types.js:13:20:13:30 | window.name | trusted-types-lib.js:1:28:1:28 | x | -| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:4:25:4:28 | data | -| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:5:26:5:29 | data | -| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:7:32:7:35 | data | -| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:9:37:9:40 | data | -| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:10:38:10:41 | data | -| tst3.js:2:23:2:74 | decodeU ... str(1)) | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | -| tst3.js:2:42:2:63 | window. ... .search | tst3.js:2:42:2:73 | window. ... bstr(1) | -| tst3.js:2:42:2:73 | window. ... bstr(1) | tst3.js:2:23:2:74 | decodeU ... str(1)) | -| tst3.js:4:25:4:28 | data | tst3.js:4:25:4:32 | data.src | -| tst3.js:5:26:5:29 | data | tst3.js:5:26:5:31 | data.p | -| tst3.js:7:32:7:35 | data | tst3.js:7:32:7:37 | data.p | -| tst3.js:9:37:9:40 | data | tst3.js:9:37:9:42 | data.p | -| tst3.js:10:38:10:41 | data | tst3.js:10:38:10:43 | data.p | -| tst.js:2:7:2:39 | target | tst.js:5:18:5:23 | target | -| tst.js:2:7:2:39 | target | tst.js:12:28:12:33 | target | -| tst.js:2:7:2:39 | target | tst.js:20:42:20:47 | target | -| tst.js:2:16:2:39 | documen ... .search | tst.js:2:7:2:39 | target | -| tst.js:8:37:8:58 | documen ... on.href | tst.js:8:37:8:114 | documen ... t=")+8) | -| tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:126 | "" | -| tst.js:12:28:12:33 | target | tst.js:12:5:12:42 | '
' | -| tst.js:17:7:17:56 | params | tst.js:18:18:18:23 | params | -| tst.js:17:16:17:43 | (new UR ... ation)) [searchParams] | tst.js:17:16:17:56 | (new UR ... hParams | -| tst.js:17:16:17:56 | (new UR ... hParams | tst.js:17:7:17:56 | params | -| tst.js:17:17:17:42 | new URL ... cation) [searchParams] | tst.js:17:16:17:43 | (new UR ... ation)) [searchParams] | -| tst.js:17:25:17:41 | document.location | tst.js:17:17:17:42 | new URL ... cation) [searchParams] | -| tst.js:18:18:18:23 | params | tst.js:18:18:18:35 | params.get('name') | -| tst.js:20:7:20:61 | searchParams | tst.js:21:18:21:29 | searchParams | -| tst.js:20:22:20:61 | new URL ... ing(1)) | tst.js:20:7:20:61 | searchParams | -| tst.js:20:42:20:47 | target | tst.js:20:42:20:60 | target.substring(1) | -| tst.js:20:42:20:60 | target.substring(1) | tst.js:20:22:20:61 | new URL ... ing(1)) | -| tst.js:21:18:21:29 | searchParams | tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:24:14:24:19 | target | tst.js:26:18:26:23 | target | -| tst.js:28:5:28:28 | documen ... .search | tst.js:24:14:24:19 | target | -| tst.js:31:10:31:33 | documen ... .search | tst.js:34:16:34:20 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:58:26:58:30 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:68:16:68:20 | bar() | -| tst.js:36:14:36:14 | x | tst.js:37:10:37:10 | x | -| tst.js:40:20:40:43 | documen ... .search | tst.js:36:14:36:14 | x | -| tst.js:40:20:40:43 | documen ... .search | tst.js:40:16:40:44 | baz(doc ... search) | -| tst.js:42:15:42:15 | s | tst.js:43:20:43:20 | s | -| tst.js:43:20:43:20 | s | tst.js:43:10:43:31 | "
" ...
" | -| tst.js:46:21:46:44 | documen ... .search | tst.js:42:15:42:15 | s | -| tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:48:15:48:15 | s | tst.js:50:12:50:12 | s | -| tst.js:50:12:50:12 | s | tst.js:50:12:50:22 | s.substr(1) | -| tst.js:54:21:54:44 | documen ... .search | tst.js:48:15:48:15 | s | -| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | tst.js:48:15:48:15 | s | -| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:58:21:58:31 | chop(bar()) | tst.js:42:15:42:15 | s | -| tst.js:58:21:58:31 | chop(bar()) | tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:26:58:30 | bar() | tst.js:48:15:48:15 | s | -| tst.js:58:26:58:30 | bar() | tst.js:58:21:58:31 | chop(bar()) | -| tst.js:60:34:60:34 | s | tst.js:62:18:62:18 | s | -| tst.js:64:25:64:48 | documen ... .search | tst.js:60:34:60:34 | s | -| tst.js:65:25:65:48 | documen ... .search | tst.js:60:34:60:34 | s | -| tst.js:70:1:70:27 | [,docum ... search] | tst.js:70:46:70:46 | x | -| tst.js:70:1:70:27 | [,docum ... search] [1] | tst.js:70:46:70:46 | x | -| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] | -| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] [1] | -| tst.js:70:46:70:46 | x | tst.js:73:20:73:20 | x | -| tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | -| tst.js:107:7:107:44 | v | tst.js:136:18:136:18 | v | -| tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:44 | documen ... bstr(1) | tst.js:107:7:107:44 | v | -| tst.js:148:29:148:50 | window. ... .search | tst.js:151:29:151:29 | v | -| tst.js:151:29:151:29 | v | tst.js:151:49:151:49 | v | -| tst.js:158:40:158:61 | window. ... .search | tst.js:155:29:155:46 | xssSourceService() | -| tst.js:177:9:177:41 | target | tst.js:180:28:180:33 | target | -| tst.js:177:18:177:41 | documen ... .search | tst.js:177:9:177:41 | target | -| tst.js:184:9:184:42 | tainted | tst.js:186:31:186:37 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:188:42:188:48 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:189:33:189:39 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:191:54:191:60 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:192:45:192:51 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:193:49:193:55 | tainted | -| tst.js:184:19:184:42 | documen ... .search | tst.js:184:9:184:42 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:199:67:199:73 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:200:67:200:73 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:204:35:204:41 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:206:46:206:52 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:207:38:207:44 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:208:35:208:41 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:236:35:236:41 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:238:20:238:26 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:240:23:240:29 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:241:23:241:29 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:255:23:255:29 | tainted | -| tst.js:197:19:197:42 | documen ... .search | tst.js:197:9:197:42 | tainted | -| tst.js:204:35:204:41 | tainted | tst.js:212:28:212:46 | this.state.tainted1 | -| tst.js:206:46:206:52 | tainted | tst.js:213:28:213:46 | this.state.tainted2 | -| tst.js:207:38:207:44 | tainted | tst.js:214:28:214:46 | this.state.tainted3 | -| tst.js:208:35:208:41 | tainted | tst.js:218:32:218:49 | prevState.tainted4 | -| tst.js:236:35:236:41 | tainted | tst.js:225:28:225:46 | this.props.tainted1 | -| tst.js:238:20:238:26 | tainted | tst.js:226:28:226:46 | this.props.tainted2 | -| tst.js:240:23:240:29 | tainted | tst.js:227:28:227:46 | this.props.tainted3 | -| tst.js:241:23:241:29 | tainted | tst.js:231:32:231:49 | prevProps.tainted4 | -| tst.js:247:39:247:55 | props.propTainted | tst.js:251:60:251:82 | this.st ... Tainted | -| tst.js:255:23:255:29 | tainted | tst.js:247:39:247:55 | props.propTainted | -| tst.js:285:9:285:29 | tainted | tst.js:288:59:288:65 | tainted | -| tst.js:285:19:285:29 | window.name | tst.js:285:9:285:29 | tainted | -| tst.js:301:9:301:16 | location | tst.js:302:10:302:10 | e | -| tst.js:302:10:302:10 | e | tst.js:303:20:303:20 | e | -| tst.js:308:10:308:17 | location | tst.js:310:10:310:10 | e | -| tst.js:310:10:310:10 | e | tst.js:311:20:311:20 | e | -| tst.js:327:10:327:35 | new URL ... cation) [searchParams] | tst.js:331:16:331:30 | getTaintedUrl() [searchParams] | -| tst.js:327:18:327:34 | document.location | tst.js:327:10:327:35 | new URL ... cation) [searchParams] | -| tst.js:331:7:331:43 | params | tst.js:332:18:332:23 | params | -| tst.js:331:16:331:30 | getTaintedUrl() [searchParams] | tst.js:331:16:331:43 | getTain ... hParams | -| tst.js:331:16:331:43 | getTain ... hParams | tst.js:331:7:331:43 | params | -| tst.js:332:18:332:23 | params | tst.js:332:18:332:35 | params.get('name') | -| tst.js:341:12:341:37 | new URL ... cation) [hash] | tst.js:343:5:343:12 | getUrl() [hash] | -| tst.js:341:20:341:36 | document.location | tst.js:341:12:341:37 | new URL ... cation) [hash] | -| tst.js:343:5:343:12 | getUrl() [hash] | tst.js:343:5:343:17 | getUrl().hash | -| tst.js:343:5:343:17 | getUrl().hash | tst.js:343:5:343:30 | getUrl( ... ring(1) | -| tst.js:348:7:348:39 | target | tst.js:349:12:349:17 | target | -| tst.js:348:16:348:39 | documen ... .search | tst.js:348:7:348:39 | target | -| tst.js:355:10:355:42 | target | tst.js:356:16:356:21 | target | -| tst.js:355:10:355:42 | target | tst.js:360:21:360:26 | target | -| tst.js:355:10:355:42 | target | tst.js:363:18:363:23 | target | -| tst.js:355:19:355:42 | documen ... .search | tst.js:355:10:355:42 | target | -| tst.js:371:7:371:39 | target | tst.js:374:18:374:23 | target | -| tst.js:371:16:371:39 | documen ... .search | tst.js:371:7:371:39 | target | -| tst.js:381:7:381:39 | target | tst.js:384:18:384:23 | target | -| tst.js:381:7:381:39 | target | tst.js:386:18:386:23 | target | -| tst.js:381:7:381:39 | target | tst.js:397:18:397:23 | target | -| tst.js:381:7:381:39 | target | tst.js:406:18:406:23 | target | -| tst.js:381:7:381:39 | target | tst.js:408:19:408:24 | target | -| tst.js:381:7:381:39 | target [taint3] | tst.js:392:18:392:23 | target [taint3] | -| tst.js:381:7:381:39 | target [taint8] | tst.js:408:19:408:24 | target [taint8] | -| tst.js:381:7:381:39 | target [taint8] | tst.js:409:18:409:23 | target [taint8] | -| tst.js:381:16:381:39 | documen ... .search | tst.js:381:7:381:39 | target | -| tst.js:386:18:386:23 | target | tst.js:386:18:386:29 | target.taint | -| tst.js:391:3:391:8 | [post update] target [taint3] | tst.js:381:7:381:39 | target [taint3] | -| tst.js:391:19:391:42 | documen ... .search | tst.js:391:3:391:8 | [post update] target [taint3] | -| tst.js:392:18:392:23 | target [taint3] | tst.js:392:18:392:30 | target.taint3 | -| tst.js:397:18:397:23 | target | tst.js:397:18:397:30 | target.taint5 | -| tst.js:406:18:406:23 | target | tst.js:406:18:406:30 | target.taint7 | -| tst.js:408:3:408:8 | [post update] target [taint8] | tst.js:381:7:381:39 | target [taint8] | -| tst.js:408:19:408:24 | target | tst.js:408:19:408:31 | target.taint8 | -| tst.js:408:19:408:24 | target [taint8] | tst.js:408:19:408:31 | target.taint8 | -| tst.js:408:19:408:31 | target.taint8 | tst.js:408:3:408:8 | [post update] target [taint8] | -| tst.js:409:18:409:23 | target [taint8] | tst.js:409:18:409:30 | target.taint8 | -| tst.js:416:7:416:46 | payload | tst.js:417:18:417:24 | payload | -| tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:46 | window. ... bstr(1) | tst.js:416:7:416:46 | payload | -| tst.js:419:7:419:55 | match | tst.js:421:20:421:24 | match | -| tst.js:419:15:419:34 | window.location.hash | tst.js:419:15:419:55 | window. ... (\\w+)/) | -| tst.js:419:15:419:55 | window. ... (\\w+)/) | tst.js:419:7:419:55 | match | -| tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:428:7:428:39 | target | tst.js:430:18:430:23 | target | -| tst.js:428:16:428:39 | documen ... .search | tst.js:428:7:428:39 | target | -| tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | -| tst.js:436:6:436:38 | source | tst.js:440:28:440:33 | source | -| tst.js:436:6:436:38 | source | tst.js:441:33:441:38 | source | -| tst.js:436:6:436:38 | source | tst.js:442:34:442:39 | source | -| tst.js:436:6:436:38 | source | tst.js:443:41:443:46 | source | -| tst.js:436:6:436:38 | source | tst.js:444:44:444:49 | source | -| tst.js:436:6:436:38 | source | tst.js:445:32:445:37 | source | -| tst.js:436:15:436:38 | documen ... .search | tst.js:436:6:436:38 | source | -| tst.js:453:7:453:39 | source | tst.js:455:18:455:23 | source | -| tst.js:453:7:453:39 | source | tst.js:456:36:456:41 | source | -| tst.js:453:16:453:39 | documen ... .search | tst.js:453:7:453:39 | source | -| tst.js:456:36:456:41 | source | tst.js:456:18:456:42 | ansiToH ... source) | -| tst.js:460:6:460:38 | source | tst.js:463:21:463:26 | source | -| tst.js:460:6:460:38 | source | tst.js:465:19:465:24 | source | -| tst.js:460:6:460:38 | source | tst.js:467:20:467:25 | source | -| tst.js:460:15:460:38 | documen ... .search | tst.js:460:6:460:38 | source | -| tst.js:471:7:471:46 | url | tst.js:473:19:473:21 | url | -| tst.js:471:7:471:46 | url | tst.js:474:26:474:28 | url | -| tst.js:471:7:471:46 | url | tst.js:475:25:475:27 | url | -| tst.js:471:7:471:46 | url | tst.js:476:20:476:22 | url | -| tst.js:471:7:471:46 | url | tst.js:486:22:486:24 | url | -| tst.js:471:13:471:36 | documen ... .search | tst.js:471:13:471:46 | documen ... bstr(1) | -| tst.js:471:13:471:46 | documen ... bstr(1) | tst.js:471:7:471:46 | url | -| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | -| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | -| typeahead.js:20:13:20:45 | target | typeahead.js:21:12:21:17 | target | -| typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target | -| typeahead.js:21:12:21:17 | target | typeahead.js:24:30:24:32 | val | -| typeahead.js:24:30:24:32 | val | typeahead.js:25:18:25:20 | val | -| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:4:14:4:20 | tainted | -| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:5:12:5:18 | tainted | -| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:6:19:6:25 | tainted | -| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:7:14:7:20 | tainted | -| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:9:19:9:25 | tainted | -| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:10:16:10:22 | tainted | -| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:11:24:11:30 | tainted | -| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:12:19:12:25 | tainted | -| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:2:6:2:39 | tainted | -| various-concat-obfuscations.js:4:14:4:20 | tainted | various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | -| various-concat-obfuscations.js:5:12:5:18 | tainted | various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | -| various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | -| various-concat-obfuscations.js:6:19:6:25 | tainted | various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | -| various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | -| various-concat-obfuscations.js:7:14:7:20 | tainted | various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | -| various-concat-obfuscations.js:9:19:9:25 | tainted | various-concat-obfuscations.js:9:4:9:34 | "
" | -| various-concat-obfuscations.js:10:16:10:22 | tainted | various-concat-obfuscations.js:10:4:10:27 | `
` | -| various-concat-obfuscations.js:11:4:11:31 | "
") | -| various-concat-obfuscations.js:11:24:11:30 | tainted | various-concat-obfuscations.js:11:4:11:31 | "
"] | various-concat-obfuscations.js:12:4:12:41 | ["
"] | -| various-concat-obfuscations.js:14:24:14:28 | attrs | various-concat-obfuscations.js:15:28:15:32 | attrs | -| various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | various-concat-obfuscations.js:15:10:15:83 | '
' | -| various-concat-obfuscations.js:15:28:15:32 | attrs | various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | -| various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | -| various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:32:18:36 | attrs | -| various-concat-obfuscations.js:18:10:18:59 | '
') | -| various-concat-obfuscations.js:18:10:18:88 | '
') | -| various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | -| various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | -| various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | various-concat-obfuscations.js:18:10:18:59 | '
` | provenance | | +| classnames.js:7:58:7:68 | window.name | classnames.js:7:47:7:69 | classNa ... w.name) | provenance | | +| classnames.js:8:47:8:70 | classNa ... w.name) | classnames.js:8:31:8:85 | `` | provenance | | +| classnames.js:8:59:8:69 | window.name | classnames.js:8:47:8:70 | classNa ... w.name) | provenance | | +| classnames.js:9:47:9:70 | classNa ... w.name) | classnames.js:9:31:9:85 | `` | provenance | | +| classnames.js:9:59:9:69 | window.name | classnames.js:9:47:9:70 | classNa ... w.name) | provenance | | +| classnames.js:10:45:10:55 | window.name | classnames.js:11:47:11:64 | unsafeStyle('foo') | provenance | | +| classnames.js:11:47:11:64 | unsafeStyle('foo') | classnames.js:11:31:11:79 | `` | provenance | | +| classnames.js:13:47:13:68 | safeSty ... w.name) | classnames.js:13:31:13:83 | `` | provenance | | +| classnames.js:13:57:13:67 | window.name | classnames.js:13:47:13:68 | safeSty ... w.name) | provenance | | +| classnames.js:15:47:15:63 | clsx(window.name) | classnames.js:15:31:15:78 | `` | provenance | | +| classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) | provenance | | +| classnames.js:17:48:17:64 | clsx(window.name) | classnames.js:17:32:17:79 | `` | provenance | | +| classnames.js:17:53:17:63 | window.name | classnames.js:17:48:17:64 | clsx(window.name) | provenance | | +| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | provenance | | +| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html | provenance | | +| clipboard.ts:43:15:43:55 | html | clipboard.ts:50:29:50:32 | html | provenance | | +| clipboard.ts:43:22:43:55 | clipboa ... /html') | clipboard.ts:43:15:43:55 | html | provenance | | +| clipboard.ts:71:13:71:62 | droppedHtml | clipboard.ts:73:29:73:39 | droppedHtml | provenance | | +| clipboard.ts:71:27:71:62 | e.clipb ... /html') | clipboard.ts:71:13:71:62 | droppedHtml | provenance | | +| clipboard.ts:98:15:98:54 | html | clipboard.ts:99:23:99:26 | html | provenance | | +| clipboard.ts:98:22:98:54 | dataTra ... /html') | clipboard.ts:98:15:98:54 | html | provenance | | +| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | provenance | | +| d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | provenance | | +| d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | provenance | | +| d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | provenance | | +| dates.js:9:9:9:69 | taint | dates.js:11:63:11:67 | taint | provenance | | +| dates.js:9:9:9:69 | taint | dates.js:12:66:12:70 | taint | provenance | | +| dates.js:9:9:9:69 | taint | dates.js:13:59:13:63 | taint | provenance | | +| dates.js:9:9:9:69 | taint | dates.js:16:62:16:66 | taint | provenance | | +| dates.js:9:9:9:69 | taint | dates.js:18:59:18:63 | taint | provenance | | +| dates.js:9:9:9:69 | taint | dates.js:21:61:21:65 | taint | provenance | | +| dates.js:9:17:9:69 | decodeU ... ing(1)) | dates.js:9:9:9:69 | taint | provenance | | +| dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | provenance | | +| dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | provenance | Config | +| dates.js:9:36:9:68 | window. ... ring(1) | dates.js:9:17:9:69 | decodeU ... ing(1)) | provenance | | +| dates.js:9:36:9:68 | window. ... ring(1) | dates.js:9:17:9:69 | decodeU ... ing(1)) | provenance | Config | +| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | provenance | | +| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | provenance | Config | +| dates.js:11:63:11:67 | taint | dates.js:11:42:11:68 | dateFns ... taint) | provenance | | +| dates.js:11:63:11:67 | taint | dates.js:11:42:11:68 | dateFns ... taint) | provenance | Config | +| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | provenance | | +| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | provenance | Config | +| dates.js:12:66:12:70 | taint | dates.js:12:42:12:71 | dateFns ... taint) | provenance | | +| dates.js:12:66:12:70 | taint | dates.js:12:42:12:71 | dateFns ... taint) | provenance | Config | +| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | provenance | | +| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | provenance | Config | +| dates.js:13:59:13:63 | taint | dates.js:13:42:13:70 | dateFns ... )(time) | provenance | | +| dates.js:13:59:13:63 | taint | dates.js:13:42:13:70 | dateFns ... )(time) | provenance | Config | +| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | provenance | | +| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | provenance | Config | +| dates.js:16:62:16:66 | taint | dates.js:16:42:16:67 | moment( ... (taint) | provenance | | +| dates.js:16:62:16:66 | taint | dates.js:16:42:16:67 | moment( ... (taint) | provenance | Config | +| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | provenance | | +| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | provenance | Config | +| dates.js:18:59:18:63 | taint | dates.js:18:42:18:64 | datefor ... taint) | provenance | | +| dates.js:18:59:18:63 | taint | dates.js:18:42:18:64 | datefor ... taint) | provenance | Config | +| dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | provenance | | +| dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | provenance | Config | +| dates.js:21:61:21:65 | taint | dates.js:21:42:21:66 | dayjs(t ... (taint) | provenance | | +| dates.js:21:61:21:65 | taint | dates.js:21:42:21:66 | dayjs(t ... (taint) | provenance | Config | +| dates.js:30:9:30:69 | taint | dates.js:37:77:37:81 | taint | provenance | | +| dates.js:30:9:30:69 | taint | dates.js:38:77:38:81 | taint | provenance | | +| dates.js:30:9:30:69 | taint | dates.js:39:79:39:83 | taint | provenance | | +| dates.js:30:9:30:69 | taint | dates.js:40:77:40:81 | taint | provenance | | +| dates.js:30:17:30:69 | decodeU ... ing(1)) | dates.js:30:9:30:69 | taint | provenance | | +| dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | provenance | | +| dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | provenance | Config | +| dates.js:30:36:30:68 | window. ... ring(1) | dates.js:30:17:30:69 | decodeU ... ing(1)) | provenance | | +| dates.js:30:36:30:68 | window. ... ring(1) | dates.js:30:17:30:69 | decodeU ... ing(1)) | provenance | Config | +| dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | provenance | | +| dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | provenance | Config | +| dates.js:37:77:37:81 | taint | dates.js:37:42:37:82 | dateFns ... taint) | provenance | | +| dates.js:37:77:37:81 | taint | dates.js:37:42:37:82 | dateFns ... taint) | provenance | Config | +| dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | provenance | | +| dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | provenance | Config | +| dates.js:38:77:38:81 | taint | dates.js:38:42:38:82 | luxon.f ... taint) | provenance | | +| dates.js:38:77:38:81 | taint | dates.js:38:42:38:82 | luxon.f ... taint) | provenance | Config | +| dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | provenance | | +| dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | provenance | Config | +| dates.js:39:79:39:83 | taint | dates.js:39:42:39:84 | moment. ... taint) | provenance | | +| dates.js:39:79:39:83 | taint | dates.js:39:42:39:84 | moment. ... taint) | provenance | Config | +| dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | provenance | | +| dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | provenance | Config | +| dates.js:40:77:40:81 | taint | dates.js:40:42:40:82 | dayjs.f ... taint) | provenance | | +| dates.js:40:77:40:81 | taint | dates.js:40:42:40:82 | dayjs.f ... taint) | provenance | Config | +| dates.js:46:9:46:69 | taint | dates.js:48:83:48:87 | taint | provenance | | +| dates.js:46:9:46:69 | taint | dates.js:49:82:49:86 | taint | provenance | | +| dates.js:46:9:46:69 | taint | dates.js:50:97:50:101 | taint | provenance | | +| dates.js:46:17:46:69 | decodeU ... ing(1)) | dates.js:46:9:46:69 | taint | provenance | | +| dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | provenance | | +| dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | provenance | Config | +| dates.js:46:36:46:68 | window. ... ring(1) | dates.js:46:17:46:69 | decodeU ... ing(1)) | provenance | | +| dates.js:46:36:46:68 | window. ... ring(1) | dates.js:46:17:46:69 | decodeU ... ing(1)) | provenance | Config | +| dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | provenance | | +| dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | provenance | Config | +| dates.js:48:83:48:87 | taint | dates.js:48:42:48:88 | DateTim ... (taint) | provenance | | +| dates.js:48:83:48:87 | taint | dates.js:48:42:48:88 | DateTim ... (taint) | provenance | Config | +| dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | provenance | | +| dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | provenance | Config | +| dates.js:49:82:49:86 | taint | dates.js:49:42:49:87 | new Dat ... (taint) | provenance | | +| dates.js:49:82:49:86 | taint | dates.js:49:42:49:87 | new Dat ... (taint) | provenance | Config | +| dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | provenance | | +| dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | provenance | Config | +| dates.js:50:97:50:101 | taint | dates.js:50:42:50:102 | DateTim ... (taint) | provenance | | +| dates.js:50:97:50:101 | taint | dates.js:50:42:50:102 | DateTim ... (taint) | provenance | Config | +| dates.js:54:9:54:69 | taint | dates.js:57:94:57:98 | taint | provenance | | +| dates.js:54:9:54:69 | taint | dates.js:59:80:59:84 | taint | provenance | | +| dates.js:54:9:54:69 | taint | dates.js:61:81:61:85 | taint | provenance | | +| dates.js:54:17:54:69 | decodeU ... ing(1)) | dates.js:54:9:54:69 | taint | provenance | | +| dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | provenance | | +| dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | provenance | Config | +| dates.js:54:36:54:68 | window. ... ring(1) | dates.js:54:17:54:69 | decodeU ... ing(1)) | provenance | | +| dates.js:54:36:54:68 | window. ... ring(1) | dates.js:54:17:54:69 | decodeU ... ing(1)) | provenance | Config | +| dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | provenance | | +| dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | provenance | Config | +| dates.js:57:94:57:98 | taint | dates.js:57:42:57:99 | moment. ... (taint) | provenance | | +| dates.js:57:94:57:98 | taint | dates.js:57:42:57:99 | moment. ... (taint) | provenance | Config | +| dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | provenance | | +| dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | provenance | Config | +| dates.js:59:80:59:84 | taint | dates.js:59:42:59:85 | luxon.e ... (taint) | provenance | | +| dates.js:59:80:59:84 | taint | dates.js:59:42:59:85 | luxon.e ... (taint) | provenance | Config | +| dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | provenance | | +| dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | provenance | Config | +| dates.js:61:81:61:85 | taint | dates.js:61:42:61:86 | dayjs.s ... (taint) | provenance | | +| dates.js:61:81:61:85 | taint | dates.js:61:42:61:86 | dayjs.s ... (taint) | provenance | Config | +| dragAndDrop.ts:8:11:8:50 | html | dragAndDrop.ts:15:25:15:28 | html | provenance | | +| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | dragAndDrop.ts:8:11:8:50 | html | provenance | | +| dragAndDrop.ts:43:15:43:54 | html | dragAndDrop.ts:50:29:50:32 | html | provenance | | +| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | dragAndDrop.ts:43:15:43:54 | html | provenance | | +| dragAndDrop.ts:71:13:71:61 | droppedHtml | dragAndDrop.ts:73:29:73:39 | droppedHtml | provenance | | +| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | provenance | | +| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | provenance | | +| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | provenance | Config | +| jquery.js:2:7:2:40 | tainted | jquery.js:7:20:7:26 | tainted | provenance | | +| jquery.js:2:7:2:40 | tainted | jquery.js:8:28:8:34 | tainted | provenance | | +| jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | provenance | | +| jquery.js:2:7:2:40 | tainted | jquery.js:37:31:37:37 | tainted | provenance | | +| jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | provenance | | +| jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "
" | provenance | Config | +| jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | provenance | | +| jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | provenance | Config | +| jquery.js:10:13:10:20 | location | jquery.js:10:13:10:31 | location.toString() | provenance | | +| jquery.js:10:13:10:20 | location | jquery.js:10:13:10:31 | location.toString() | provenance | Config | +| jquery.js:10:13:10:31 | location.toString() | jquery.js:10:5:10:40 | "" + ... "" | provenance | Config | +| jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | provenance | | +| jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | provenance | Config | +| jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | provenance | | +| jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | provenance | Config | +| jquery.js:16:38:16:52 | window.location | jquery.js:16:38:16:63 | window. ... tring() | provenance | | +| jquery.js:16:38:16:52 | window.location | jquery.js:16:38:16:63 | window. ... tring() | provenance | Config | +| jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) | provenance | | +| jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) | provenance | Config | +| jquery.js:18:7:18:33 | hash | jquery.js:21:5:21:8 | hash | provenance | | +| jquery.js:18:7:18:33 | hash | jquery.js:22:5:22:8 | hash | provenance | | +| jquery.js:18:7:18:33 | hash | jquery.js:23:5:23:8 | hash | provenance | | +| jquery.js:18:7:18:33 | hash | jquery.js:24:5:24:8 | hash | provenance | | +| jquery.js:18:7:18:33 | hash | jquery.js:27:5:27:8 | hash | provenance | | +| jquery.js:18:7:18:33 | hash | jquery.js:34:13:34:16 | hash | provenance | | +| jquery.js:18:14:18:33 | window.location.hash | jquery.js:18:7:18:33 | hash | provenance | | +| jquery.js:21:5:21:8 | hash | jquery.js:21:5:21:21 | hash.substring(1) | provenance | Config | +| jquery.js:22:5:22:8 | hash | jquery.js:22:5:22:25 | hash.su ... (1, 10) | provenance | Config | +| jquery.js:23:5:23:8 | hash | jquery.js:23:5:23:18 | hash.substr(1) | provenance | Config | +| jquery.js:24:5:24:8 | hash | jquery.js:24:5:24:17 | hash.slice(1) | provenance | Config | +| jquery.js:27:5:27:8 | hash | jquery.js:27:5:27:25 | hash.re ... #', '') | provenance | Config | +| jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | provenance | Config | +| jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '' + ... '' | provenance | Config | +| jquery.js:37:31:37:37 | tainted | jquery.js:37:25:37:37 | () => tainted | provenance | Config | +| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:11:51:11:56 | locale | provenance | | +| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:19:56:19:61 | locale | provenance | | +| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:31:55:31:60 | locale | provenance | | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | provenance | | +| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | provenance | | +| json-stringify.jsx:11:51:11:56 | locale | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | provenance | | +| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | provenance | | +| json-stringify.jsx:19:56:19:61 | locale | json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | provenance | | +| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | provenance | | +| jwt-server.js:7:9:7:35 | taint | jwt-server.js:9:16:9:20 | taint | provenance | | +| jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint | provenance | | +| jwt-server.js:9:16:9:20 | taint | jwt-server.js:9:55:9:61 | decoded | provenance | | +| jwt-server.js:9:55:9:61 | decoded | jwt-server.js:11:19:11:25 | decoded | provenance | | +| jwt-server.js:11:19:11:25 | decoded | jwt-server.js:11:19:11:29 | decoded.foo | provenance | | +| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | provenance | | +| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:6:18:6:23 | target | provenance | | +| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:8:17:8:22 | target | provenance | | +| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:15:9:15:14 | target | provenance | | +| optionalSanitizer.js:2:16:2:39 | documen ... .search | optionalSanitizer.js:2:7:2:39 | target | provenance | | +| optionalSanitizer.js:8:7:8:22 | tainted | optionalSanitizer.js:9:18:9:24 | tainted | provenance | | +| optionalSanitizer.js:8:17:8:22 | target | optionalSanitizer.js:8:7:8:22 | tainted | provenance | | +| optionalSanitizer.js:15:9:15:14 | target | optionalSanitizer.js:16:18:16:18 | x | provenance | | +| optionalSanitizer.js:16:18:16:18 | x | optionalSanitizer.js:17:20:17:20 | x | provenance | | +| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:31:18:31:23 | target | provenance | | +| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:38:18:38:23 | target | provenance | | +| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:45:41:45:46 | target | provenance | | +| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:45:51:45:56 | target | provenance | | +| optionalSanitizer.js:26:16:26:39 | documen ... .search | optionalSanitizer.js:26:7:26:39 | target | provenance | | +| optionalSanitizer.js:28:24:28:24 | x | optionalSanitizer.js:29:12:29:12 | x | provenance | | +| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:32:18:32:25 | tainted2 | provenance | | +| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:34:28:34:35 | tainted2 | provenance | | +| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 | provenance | | +| optionalSanitizer.js:31:18:31:23 | target | optionalSanitizer.js:31:7:31:23 | tainted2 | provenance | | +| optionalSanitizer.js:34:5:34:36 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 | provenance | | +| optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | optionalSanitizer.js:34:5:34:36 | tainted2 | provenance | | +| optionalSanitizer.js:34:28:34:35 | tainted2 | optionalSanitizer.js:28:24:28:24 | x | provenance | | +| optionalSanitizer.js:34:28:34:35 | tainted2 | optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | provenance | | +| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:39:18:39:25 | tainted3 | provenance | | +| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:41:28:41:35 | tainted3 | provenance | | +| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 | provenance | | +| optionalSanitizer.js:38:18:38:23 | target | optionalSanitizer.js:38:7:38:23 | tainted3 | provenance | | +| optionalSanitizer.js:41:5:41:36 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 | provenance | | +| optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | optionalSanitizer.js:41:5:41:36 | tainted3 | provenance | | +| optionalSanitizer.js:41:28:41:35 | tainted3 | optionalSanitizer.js:28:24:28:24 | x | provenance | | +| optionalSanitizer.js:41:28:41:35 | tainted3 | optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | provenance | | +| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | provenance | | +| optionalSanitizer.js:45:41:45:46 | target | optionalSanitizer.js:28:24:28:24 | x | provenance | | +| optionalSanitizer.js:45:41:45:46 | target | optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | provenance | | +| optionalSanitizer.js:45:51:45:56 | target | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | provenance | | +| pages/[id].jsx:3:30:3:35 | params [id] | pages/[id].jsx:13:44:13:49 | params [id] | provenance | | +| pages/[id].jsx:3:30:3:35 | params [q] | pages/[id].jsx:16:44:16:49 | params [q] | provenance | | +| pages/[id].jsx:5:9:5:14 | { id } | pages/[id].jsx:5:11:5:12 | id | provenance | | +| pages/[id].jsx:5:9:5:29 | id | pages/[id].jsx:10:44:10:45 | id | provenance | | +| pages/[id].jsx:5:11:5:12 | id | pages/[id].jsx:5:9:5:29 | id | provenance | | +| pages/[id].jsx:5:18:5:29 | router.query | pages/[id].jsx:5:9:5:14 | { id } | provenance | | +| pages/[id].jsx:13:44:13:49 | params [id] | pages/[id].jsx:13:44:13:52 | params.id | provenance | | +| pages/[id].jsx:16:44:16:49 | params [q] | pages/[id].jsx:16:44:16:51 | params.q | provenance | | +| pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | pages/[id].jsx:3:30:3:35 | params [id] | provenance | | +| pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | pages/[id].jsx:3:30:3:35 | params [q] | provenance | | +| pages/[id].jsx:25:11:25:24 | context.params | pages/[id].jsx:25:11:25:27 | context.params.id | provenance | | +| pages/[id].jsx:25:11:25:27 | context.params.id | pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | provenance | | +| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | provenance | | +| pages/[id].jsx:26:10:26:22 | context.query | pages/[id].jsx:26:10:26:30 | context ... .foobar | provenance | | +| pages/[id].jsx:26:10:26:30 | context ... .foobar | pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | provenance | | +| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | provenance | | +| react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted | provenance | | +| react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted | provenance | | +| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | provenance | | +| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | provenance | | +| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | provenance | | +| react-use-router.js:23:31:23:36 | [post update] router | react-use-router.js:23:43:23:48 | router | provenance | | +| react-use-router.js:23:43:23:48 | router | react-use-router.js:23:43:23:54 | router.query | provenance | | +| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | provenance | | +| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:31:23:36 | [post update] router | provenance | | +| react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | provenance | | +| react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | provenance | | +| react-use-state.js:4:10:4:14 | state | react-use-state.js:4:9:4:49 | state | provenance | | +| react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:10:4:14 | state | provenance | | +| react-use-state.js:9:9:9:43 | state | react-use-state.js:11:51:11:55 | state | provenance | | +| react-use-state.js:9:10:9:14 | state | react-use-state.js:9:9:9:43 | state | provenance | | +| react-use-state.js:10:14:10:24 | window.name | react-use-state.js:9:10:9:14 | state | provenance | | +| react-use-state.js:15:9:15:43 | state | react-use-state.js:17:51:17:55 | state | provenance | | +| react-use-state.js:15:10:15:14 | state | react-use-state.js:15:9:15:43 | state | provenance | | +| react-use-state.js:16:20:16:30 | window.name | react-use-state.js:15:10:15:14 | state | provenance | | +| react-use-state.js:21:10:21:14 | state | react-use-state.js:22:14:22:17 | prev | provenance | | +| react-use-state.js:22:14:22:17 | prev | react-use-state.js:23:35:23:38 | prev | provenance | | +| react-use-state.js:25:20:25:30 | window.name | react-use-state.js:21:10:21:14 | state | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:23:29:23:35 | tainted | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:25:29:25:35 | tainted | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:28:29:28:35 | tainted | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:30:29:30:35 | tainted | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:33:29:33:35 | tainted | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:35:29:35:35 | tainted | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:38:29:38:35 | tainted | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:45:29:45:35 | tainted | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:48:19:48:25 | tainted | provenance | | +| sanitiser.js:16:17:16:27 | window.name | sanitiser.js:16:7:16:27 | tainted | provenance | | +| sanitiser.js:23:29:23:35 | tainted | sanitiser.js:23:21:23:44 | '' + ... '' | provenance | | +| sanitiser.js:25:29:25:35 | tainted | sanitiser.js:25:21:25:44 | '' + ... '' | provenance | | +| sanitiser.js:28:29:28:35 | tainted | sanitiser.js:28:21:28:44 | '' + ... '' | provenance | | +| sanitiser.js:30:29:30:35 | tainted | sanitiser.js:30:21:30:44 | '' + ... '' | provenance | | +| sanitiser.js:33:29:33:35 | tainted | sanitiser.js:33:21:33:44 | '' + ... '' | provenance | | +| sanitiser.js:35:29:35:35 | tainted | sanitiser.js:35:21:35:44 | '' + ... '' | provenance | | +| sanitiser.js:38:29:38:35 | tainted | sanitiser.js:38:21:38:44 | '' + ... '' | provenance | | +| sanitiser.js:45:29:45:35 | tainted | sanitiser.js:45:21:45:44 | '' + ... '' | provenance | | +| sanitiser.js:48:19:48:25 | tainted | sanitiser.js:48:19:48:46 | tainted ... /g, '') | provenance | | +| stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | provenance | | +| stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | provenance | Config | +| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | provenance | | +| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | provenance | Config | +| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:10:16:10:44 | localSt ... local') | provenance | | +| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:10:16:10:44 | localSt ... local') | provenance | Config | +| stored-xss.js:10:9:10:44 | href | stored-xss.js:12:35:12:38 | href | provenance | | +| stored-xss.js:10:16:10:44 | localSt ... local') | stored-xss.js:10:9:10:44 | href | provenance | | +| stored-xss.js:12:35:12:38 | href | stored-xss.js:12:20:12:54 | "" | provenance | | +| stored-xss.js:12:35:12:38 | href | stored-xss.js:12:20:12:54 | "" | provenance | Config | +| string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | provenance | | +| string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | provenance | Config | +| string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | provenance | | +| string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | provenance | Config | +| string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | provenance | | +| string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | provenance | Config | +| string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | provenance | | +| string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | provenance | Config | +| string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | provenance | | +| string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | provenance | Config | +| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | provenance | | +| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | provenance | Config | +| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | provenance | | +| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | provenance | | +| tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source | provenance | | +| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:23:38:23:43 | source | provenance | | +| tooltip.jsx:22:20:22:30 | window.name | tooltip.jsx:22:11:22:30 | source | provenance | | +| tooltip.jsx:23:38:23:43 | source | tooltip.jsx:18:51:18:59 | provide() | provenance | | +| translate.js:6:7:6:39 | target | translate.js:7:42:7:47 | target | provenance | | +| translate.js:6:16:6:39 | documen ... .search | translate.js:6:7:6:39 | target | provenance | | +| translate.js:7:7:7:61 | searchParams | translate.js:9:27:9:38 | searchParams | provenance | | +| translate.js:7:22:7:61 | new URL ... ing(1)) | translate.js:7:7:7:61 | searchParams | provenance | | +| translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | provenance | | +| translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | provenance | Config | +| translate.js:7:42:7:60 | target.substring(1) | translate.js:7:22:7:61 | new URL ... ing(1)) | provenance | | +| translate.js:9:27:9:38 | searchParams | translate.js:9:27:9:50 | searchP ... 'term') | provenance | Config | +| trusted-types-lib.js:1:28:1:28 | x | trusted-types-lib.js:2:12:2:12 | x | provenance | | +| trusted-types.js:3:62:3:62 | x | trusted-types.js:3:67:3:67 | x | provenance | | +| trusted-types.js:4:20:4:30 | window.name | trusted-types.js:3:62:3:62 | x | provenance | | +| trusted-types.js:13:20:13:30 | window.name | trusted-types-lib.js:1:28:1:28 | x | provenance | | +| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:4:25:4:28 | data | provenance | | +| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:5:26:5:29 | data | provenance | | +| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:7:32:7:35 | data | provenance | | +| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:9:37:9:40 | data | provenance | | +| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:10:38:10:41 | data | provenance | | +| tst3.js:2:23:2:74 | decodeU ... str(1)) | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | provenance | | +| tst3.js:2:42:2:63 | window. ... .search | tst3.js:2:42:2:73 | window. ... bstr(1) | provenance | Config | +| tst3.js:2:42:2:73 | window. ... bstr(1) | tst3.js:2:23:2:74 | decodeU ... str(1)) | provenance | | +| tst3.js:4:25:4:28 | data | tst3.js:4:25:4:32 | data.src | provenance | | +| tst3.js:5:26:5:29 | data | tst3.js:5:26:5:31 | data.p | provenance | | +| tst3.js:7:32:7:35 | data | tst3.js:7:32:7:37 | data.p | provenance | | +| tst3.js:9:37:9:40 | data | tst3.js:9:37:9:42 | data.p | provenance | | +| tst3.js:10:38:10:41 | data | tst3.js:10:38:10:43 | data.p | provenance | | +| tst.js:2:7:2:39 | target | tst.js:5:18:5:23 | target | provenance | | +| tst.js:2:7:2:39 | target | tst.js:12:28:12:33 | target | provenance | | +| tst.js:2:7:2:39 | target | tst.js:20:42:20:47 | target | provenance | | +| tst.js:2:16:2:39 | documen ... .search | tst.js:2:7:2:39 | target | provenance | | +| tst.js:8:37:8:58 | documen ... on.href | tst.js:8:37:8:114 | documen ... t=")+8) | provenance | | +| tst.js:8:37:8:58 | documen ... on.href | tst.js:8:37:8:114 | documen ... t=")+8) | provenance | Config | +| tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:126 | "" | provenance | | +| tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:126 | "" | provenance | Config | +| tst.js:12:28:12:33 | target | tst.js:12:5:12:42 | '
' | provenance | Config | +| tst.js:17:7:17:56 | params | tst.js:18:18:18:23 | params | provenance | | +| tst.js:17:16:17:43 | (new UR ... ation)) [searchParams] | tst.js:17:16:17:56 | (new UR ... hParams | provenance | | +| tst.js:17:16:17:56 | (new UR ... hParams | tst.js:17:7:17:56 | params | provenance | | +| tst.js:17:17:17:42 | new URL ... cation) [searchParams] | tst.js:17:16:17:43 | (new UR ... ation)) [searchParams] | provenance | | +| tst.js:17:25:17:41 | document.location | tst.js:17:17:17:42 | new URL ... cation) [searchParams] | provenance | | +| tst.js:18:18:18:23 | params | tst.js:18:18:18:35 | params.get('name') | provenance | Config | +| tst.js:20:7:20:61 | searchParams | tst.js:21:18:21:29 | searchParams | provenance | | +| tst.js:20:22:20:61 | new URL ... ing(1)) | tst.js:20:7:20:61 | searchParams | provenance | | +| tst.js:20:42:20:47 | target | tst.js:20:42:20:60 | target.substring(1) | provenance | | +| tst.js:20:42:20:47 | target | tst.js:20:42:20:60 | target.substring(1) | provenance | Config | +| tst.js:20:42:20:60 | target.substring(1) | tst.js:20:22:20:61 | new URL ... ing(1)) | provenance | | +| tst.js:21:18:21:29 | searchParams | tst.js:21:18:21:41 | searchP ... 'name') | provenance | Config | +| tst.js:24:14:24:19 | target | tst.js:26:18:26:23 | target | provenance | | +| tst.js:28:5:28:28 | documen ... .search | tst.js:24:14:24:19 | target | provenance | | +| tst.js:31:10:31:33 | documen ... .search | tst.js:34:16:34:20 | bar() | provenance | | +| tst.js:31:10:31:33 | documen ... .search | tst.js:58:26:58:30 | bar() | provenance | | +| tst.js:31:10:31:33 | documen ... .search | tst.js:68:16:68:20 | bar() | provenance | | +| tst.js:36:14:36:14 | x | tst.js:37:10:37:10 | x | provenance | | +| tst.js:40:20:40:43 | documen ... .search | tst.js:36:14:36:14 | x | provenance | | +| tst.js:40:20:40:43 | documen ... .search | tst.js:40:16:40:44 | baz(doc ... search) | provenance | | +| tst.js:42:15:42:15 | s | tst.js:43:20:43:20 | s | provenance | | +| tst.js:43:20:43:20 | s | tst.js:43:10:43:31 | "
" ...
" | provenance | | +| tst.js:43:20:43:20 | s | tst.js:43:10:43:31 | "
" ...
" | provenance | Config | +| tst.js:46:21:46:44 | documen ... .search | tst.js:42:15:42:15 | s | provenance | | +| tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | provenance | | +| tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | provenance | Config | +| tst.js:48:15:48:15 | s | tst.js:50:12:50:12 | s | provenance | | +| tst.js:50:12:50:12 | s | tst.js:50:12:50:22 | s.substr(1) | provenance | | +| tst.js:50:12:50:12 | s | tst.js:50:12:50:22 | s.substr(1) | provenance | Config | +| tst.js:54:21:54:44 | documen ... .search | tst.js:48:15:48:15 | s | provenance | | +| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | provenance | | +| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | provenance | Config | +| tst.js:56:21:56:44 | documen ... .search | tst.js:48:15:48:15 | s | provenance | | +| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | provenance | | +| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | provenance | Config | +| tst.js:58:21:58:31 | chop(bar()) | tst.js:42:15:42:15 | s | provenance | | +| tst.js:58:21:58:31 | chop(bar()) | tst.js:58:16:58:32 | wrap(chop(bar())) | provenance | | +| tst.js:58:21:58:31 | chop(bar()) | tst.js:58:16:58:32 | wrap(chop(bar())) | provenance | Config | +| tst.js:58:26:58:30 | bar() | tst.js:48:15:48:15 | s | provenance | | +| tst.js:58:26:58:30 | bar() | tst.js:58:21:58:31 | chop(bar()) | provenance | | +| tst.js:58:26:58:30 | bar() | tst.js:58:21:58:31 | chop(bar()) | provenance | Config | +| tst.js:60:34:60:34 | s | tst.js:62:18:62:18 | s | provenance | | +| tst.js:64:25:64:48 | documen ... .search | tst.js:60:34:60:34 | s | provenance | | +| tst.js:65:25:65:48 | documen ... .search | tst.js:60:34:60:34 | s | provenance | | +| tst.js:70:1:70:27 | [,docum ... search] | tst.js:70:46:70:46 | x | provenance | | +| tst.js:70:1:70:27 | [,docum ... search] | tst.js:70:46:70:46 | x | provenance | Config | +| tst.js:70:1:70:27 | [,docum ... search] [1] | tst.js:70:46:70:46 | x | provenance | | +| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] | provenance | | +| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] | provenance | Config | +| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] [1] | provenance | | +| tst.js:70:46:70:46 | x | tst.js:73:20:73:20 | x | provenance | | +| tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | provenance | | +| tst.js:107:7:107:44 | v | tst.js:136:18:136:18 | v | provenance | | +| tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | provenance | | +| tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | provenance | Config | +| tst.js:107:11:107:44 | documen ... bstr(1) | tst.js:107:7:107:44 | v | provenance | | +| tst.js:148:29:148:50 | window. ... .search | tst.js:151:29:151:29 | v | provenance | | +| tst.js:151:29:151:29 | v | tst.js:151:49:151:49 | v | provenance | | +| tst.js:158:40:158:61 | window. ... .search | tst.js:155:29:155:46 | xssSourceService() | provenance | | +| tst.js:177:9:177:41 | target | tst.js:180:28:180:33 | target | provenance | | +| tst.js:177:18:177:41 | documen ... .search | tst.js:177:9:177:41 | target | provenance | | +| tst.js:184:9:184:42 | tainted | tst.js:186:31:186:37 | tainted | provenance | | +| tst.js:184:9:184:42 | tainted | tst.js:188:42:188:48 | tainted | provenance | | +| tst.js:184:9:184:42 | tainted | tst.js:189:33:189:39 | tainted | provenance | | +| tst.js:184:9:184:42 | tainted | tst.js:191:54:191:60 | tainted | provenance | | +| tst.js:184:9:184:42 | tainted | tst.js:192:45:192:51 | tainted | provenance | | +| tst.js:184:9:184:42 | tainted | tst.js:193:49:193:55 | tainted | provenance | | +| tst.js:184:19:184:42 | documen ... .search | tst.js:184:9:184:42 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:199:67:199:73 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:200:67:200:73 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:204:35:204:41 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:206:46:206:52 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:207:38:207:44 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:208:35:208:41 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:236:35:236:41 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:238:20:238:26 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:240:23:240:29 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:241:23:241:29 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:255:23:255:29 | tainted | provenance | | +| tst.js:197:19:197:42 | documen ... .search | tst.js:197:9:197:42 | tainted | provenance | | +| tst.js:204:35:204:41 | tainted | tst.js:212:28:212:46 | this.state.tainted1 | provenance | | +| tst.js:204:35:204:41 | tainted | tst.js:212:28:212:46 | this.state.tainted1 | provenance | Config | +| tst.js:206:46:206:52 | tainted | tst.js:213:28:213:46 | this.state.tainted2 | provenance | | +| tst.js:206:46:206:52 | tainted | tst.js:213:28:213:46 | this.state.tainted2 | provenance | Config | +| tst.js:207:38:207:44 | tainted | tst.js:214:28:214:46 | this.state.tainted3 | provenance | | +| tst.js:207:38:207:44 | tainted | tst.js:214:28:214:46 | this.state.tainted3 | provenance | Config | +| tst.js:208:35:208:41 | tainted | tst.js:218:32:218:49 | prevState.tainted4 | provenance | | +| tst.js:208:35:208:41 | tainted | tst.js:218:32:218:49 | prevState.tainted4 | provenance | Config | +| tst.js:236:35:236:41 | tainted | tst.js:225:28:225:46 | this.props.tainted1 | provenance | | +| tst.js:238:20:238:26 | tainted | tst.js:226:28:226:46 | this.props.tainted2 | provenance | | +| tst.js:240:23:240:29 | tainted | tst.js:227:28:227:46 | this.props.tainted3 | provenance | | +| tst.js:241:23:241:29 | tainted | tst.js:231:32:231:49 | prevProps.tainted4 | provenance | | +| tst.js:247:39:247:55 | props.propTainted | tst.js:251:60:251:82 | this.st ... Tainted | provenance | | +| tst.js:247:39:247:55 | props.propTainted | tst.js:251:60:251:82 | this.st ... Tainted | provenance | Config | +| tst.js:255:23:255:29 | tainted | tst.js:247:39:247:55 | props.propTainted | provenance | | +| tst.js:285:9:285:29 | tainted | tst.js:288:59:288:65 | tainted | provenance | | +| tst.js:285:19:285:29 | window.name | tst.js:285:9:285:29 | tainted | provenance | | +| tst.js:301:9:301:16 | location | tst.js:302:10:302:10 | e | provenance | | +| tst.js:302:10:302:10 | e | tst.js:303:20:303:20 | e | provenance | | +| tst.js:308:10:308:17 | location | tst.js:310:10:310:10 | e | provenance | | +| tst.js:310:10:310:10 | e | tst.js:311:20:311:20 | e | provenance | | +| tst.js:327:10:327:35 | new URL ... cation) [searchParams] | tst.js:331:16:331:30 | getTaintedUrl() [searchParams] | provenance | | +| tst.js:327:18:327:34 | document.location | tst.js:327:10:327:35 | new URL ... cation) [searchParams] | provenance | | +| tst.js:331:7:331:43 | params | tst.js:332:18:332:23 | params | provenance | | +| tst.js:331:16:331:30 | getTaintedUrl() [searchParams] | tst.js:331:16:331:43 | getTain ... hParams | provenance | | +| tst.js:331:16:331:43 | getTain ... hParams | tst.js:331:7:331:43 | params | provenance | | +| tst.js:332:18:332:23 | params | tst.js:332:18:332:35 | params.get('name') | provenance | Config | +| tst.js:341:12:341:37 | new URL ... cation) [hash] | tst.js:343:5:343:12 | getUrl() [hash] | provenance | | +| tst.js:341:20:341:36 | document.location | tst.js:341:12:341:37 | new URL ... cation) [hash] | provenance | | +| tst.js:343:5:343:12 | getUrl() [hash] | tst.js:343:5:343:17 | getUrl().hash | provenance | | +| tst.js:343:5:343:17 | getUrl().hash | tst.js:343:5:343:30 | getUrl( ... ring(1) | provenance | Config | +| tst.js:348:7:348:39 | target | tst.js:349:12:349:17 | target | provenance | | +| tst.js:348:16:348:39 | documen ... .search | tst.js:348:7:348:39 | target | provenance | | +| tst.js:355:10:355:42 | target | tst.js:356:16:356:21 | target | provenance | | +| tst.js:355:10:355:42 | target | tst.js:360:21:360:26 | target | provenance | | +| tst.js:355:10:355:42 | target | tst.js:363:18:363:23 | target | provenance | | +| tst.js:355:19:355:42 | documen ... .search | tst.js:355:10:355:42 | target | provenance | | +| tst.js:371:7:371:39 | target | tst.js:374:18:374:23 | target | provenance | | +| tst.js:371:16:371:39 | documen ... .search | tst.js:371:7:371:39 | target | provenance | | +| tst.js:381:7:381:39 | target | tst.js:384:18:384:23 | target | provenance | | +| tst.js:381:7:381:39 | target | tst.js:386:18:386:23 | target | provenance | | +| tst.js:381:7:381:39 | target | tst.js:397:18:397:23 | target | provenance | | +| tst.js:381:7:381:39 | target | tst.js:406:18:406:23 | target | provenance | | +| tst.js:381:7:381:39 | target | tst.js:408:19:408:24 | target | provenance | | +| tst.js:381:7:381:39 | target [taint3] | tst.js:392:18:392:23 | target [taint3] | provenance | | +| tst.js:381:7:381:39 | target [taint8] | tst.js:408:19:408:24 | target [taint8] | provenance | | +| tst.js:381:7:381:39 | target [taint8] | tst.js:409:18:409:23 | target [taint8] | provenance | | +| tst.js:381:16:381:39 | documen ... .search | tst.js:381:7:381:39 | target | provenance | | +| tst.js:386:18:386:23 | target | tst.js:386:18:386:29 | target.taint | provenance | | +| tst.js:386:18:386:23 | target | tst.js:386:18:386:29 | target.taint | provenance | Config | +| tst.js:391:3:391:8 | [post update] target [taint3] | tst.js:381:7:381:39 | target [taint3] | provenance | | +| tst.js:391:19:391:42 | documen ... .search | tst.js:391:3:391:8 | [post update] target [taint3] | provenance | | +| tst.js:392:18:392:23 | target [taint3] | tst.js:392:18:392:30 | target.taint3 | provenance | | +| tst.js:397:18:397:23 | target | tst.js:397:18:397:30 | target.taint5 | provenance | | +| tst.js:397:18:397:23 | target | tst.js:397:18:397:30 | target.taint5 | provenance | Config | +| tst.js:406:18:406:23 | target | tst.js:406:18:406:30 | target.taint7 | provenance | | +| tst.js:406:18:406:23 | target | tst.js:406:18:406:30 | target.taint7 | provenance | Config | +| tst.js:408:3:408:8 | [post update] target [taint8] | tst.js:381:7:381:39 | target [taint8] | provenance | | +| tst.js:408:19:408:24 | target | tst.js:408:19:408:31 | target.taint8 | provenance | | +| tst.js:408:19:408:24 | target | tst.js:408:19:408:31 | target.taint8 | provenance | Config | +| tst.js:408:19:408:24 | target [taint8] | tst.js:408:19:408:31 | target.taint8 | provenance | | +| tst.js:408:19:408:31 | target.taint8 | tst.js:408:3:408:8 | [post update] target [taint8] | provenance | | +| tst.js:409:18:409:23 | target [taint8] | tst.js:409:18:409:30 | target.taint8 | provenance | | +| tst.js:416:7:416:46 | payload | tst.js:417:18:417:24 | payload | provenance | | +| tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | provenance | | +| tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | provenance | Config | +| tst.js:416:17:416:46 | window. ... bstr(1) | tst.js:416:7:416:46 | payload | provenance | | +| tst.js:419:7:419:55 | match | tst.js:421:20:421:24 | match | provenance | | +| tst.js:419:15:419:34 | window.location.hash | tst.js:419:15:419:55 | window. ... (\\w+)/) | provenance | | +| tst.js:419:15:419:34 | window.location.hash | tst.js:419:15:419:55 | window. ... (\\w+)/) | provenance | Config | +| tst.js:419:15:419:55 | window. ... (\\w+)/) | tst.js:419:7:419:55 | match | provenance | | +| tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | provenance | | +| tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | provenance | Config | +| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | provenance | | +| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | provenance | Config | +| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | +| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | Config | +| tst.js:428:7:428:39 | target | tst.js:430:18:430:23 | target | provenance | | +| tst.js:428:16:428:39 | documen ... .search | tst.js:428:7:428:39 | target | provenance | | +| tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | provenance | | +| tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | provenance | Config | +| tst.js:436:6:436:38 | source | tst.js:440:28:440:33 | source | provenance | | +| tst.js:436:6:436:38 | source | tst.js:441:33:441:38 | source | provenance | | +| tst.js:436:6:436:38 | source | tst.js:442:34:442:39 | source | provenance | | +| tst.js:436:6:436:38 | source | tst.js:443:41:443:46 | source | provenance | | +| tst.js:436:6:436:38 | source | tst.js:444:44:444:49 | source | provenance | | +| tst.js:436:6:436:38 | source | tst.js:445:32:445:37 | source | provenance | | +| tst.js:436:15:436:38 | documen ... .search | tst.js:436:6:436:38 | source | provenance | | +| tst.js:453:7:453:39 | source | tst.js:455:18:455:23 | source | provenance | | +| tst.js:453:7:453:39 | source | tst.js:456:36:456:41 | source | provenance | | +| tst.js:453:16:453:39 | documen ... .search | tst.js:453:7:453:39 | source | provenance | | +| tst.js:456:36:456:41 | source | tst.js:456:18:456:42 | ansiToH ... source) | provenance | | +| tst.js:456:36:456:41 | source | tst.js:456:18:456:42 | ansiToH ... source) | provenance | Config | +| tst.js:460:6:460:38 | source | tst.js:463:21:463:26 | source | provenance | | +| tst.js:460:6:460:38 | source | tst.js:465:19:465:24 | source | provenance | | +| tst.js:460:6:460:38 | source | tst.js:467:20:467:25 | source | provenance | | +| tst.js:460:15:460:38 | documen ... .search | tst.js:460:6:460:38 | source | provenance | | +| tst.js:471:7:471:46 | url | tst.js:473:19:473:21 | url | provenance | | +| tst.js:471:7:471:46 | url | tst.js:474:26:474:28 | url | provenance | | +| tst.js:471:7:471:46 | url | tst.js:475:25:475:27 | url | provenance | | +| tst.js:471:7:471:46 | url | tst.js:476:20:476:22 | url | provenance | | +| tst.js:471:7:471:46 | url | tst.js:486:22:486:24 | url | provenance | | +| tst.js:471:13:471:36 | documen ... .search | tst.js:471:13:471:46 | documen ... bstr(1) | provenance | Config | +| tst.js:471:13:471:46 | documen ... bstr(1) | tst.js:471:7:471:46 | url | provenance | | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | provenance | Config | +| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | provenance | Config | +| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | provenance | | +| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | provenance | Config | +| typeahead.js:20:13:20:45 | target | typeahead.js:21:12:21:17 | target | provenance | | +| typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target | provenance | | +| typeahead.js:21:12:21:17 | target | typeahead.js:24:30:24:32 | val | provenance | | +| typeahead.js:21:12:21:17 | target | typeahead.js:24:30:24:32 | val | provenance | Config | +| typeahead.js:24:30:24:32 | val | typeahead.js:25:18:25:20 | val | provenance | | +| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:4:14:4:20 | tainted | provenance | | +| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:5:12:5:18 | tainted | provenance | | +| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:6:19:6:25 | tainted | provenance | | +| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:7:14:7:20 | tainted | provenance | | +| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:9:19:9:25 | tainted | provenance | | +| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:10:16:10:22 | tainted | provenance | | +| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:11:24:11:30 | tainted | provenance | | +| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:12:19:12:25 | tainted | provenance | | +| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:2:6:2:39 | tainted | provenance | | +| various-concat-obfuscations.js:4:14:4:20 | tainted | various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | provenance | Config | +| various-concat-obfuscations.js:5:12:5:18 | tainted | various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | provenance | Config | +| various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | provenance | | +| various-concat-obfuscations.js:6:19:6:25 | tainted | various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | provenance | Config | +| various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | provenance | | +| various-concat-obfuscations.js:7:14:7:20 | tainted | various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | provenance | Config | +| various-concat-obfuscations.js:9:19:9:25 | tainted | various-concat-obfuscations.js:9:4:9:34 | "
" | provenance | Config | +| various-concat-obfuscations.js:10:16:10:22 | tainted | various-concat-obfuscations.js:10:4:10:27 | `
` | provenance | Config | +| various-concat-obfuscations.js:11:4:11:31 | "
") | provenance | | +| various-concat-obfuscations.js:11:24:11:30 | tainted | various-concat-obfuscations.js:11:4:11:31 | "
"] | various-concat-obfuscations.js:12:4:12:41 | ["
"] | provenance | Config | +| various-concat-obfuscations.js:14:24:14:28 | attrs | various-concat-obfuscations.js:15:28:15:32 | attrs | provenance | | +| various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | various-concat-obfuscations.js:15:10:15:83 | '
' | provenance | Config | +| various-concat-obfuscations.js:15:28:15:32 | attrs | various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | provenance | | +| various-concat-obfuscations.js:15:28:15:32 | attrs | various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | provenance | Config | +| various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | provenance | | +| various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:32:18:36 | attrs | provenance | | +| various-concat-obfuscations.js:18:10:18:59 | '
') | provenance | | +| various-concat-obfuscations.js:18:10:18:88 | '
') | provenance | | +| various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | provenance | | +| various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | provenance | Config | +| various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | provenance | | +| various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | various-concat-obfuscations.js:18:10:18:59 | '
` | -| classnames.js:7:31:7:84 | `` | -| classnames.js:7:47:7:69 | classNa ... w.name) | -| classnames.js:7:58:7:68 | window.name | -| classnames.js:7:58:7:68 | window.name | -| classnames.js:8:31:8:85 | `` | -| classnames.js:8:31:8:85 | `` | -| classnames.js:8:47:8:70 | classNa ... w.name) | -| classnames.js:8:59:8:69 | window.name | -| classnames.js:8:59:8:69 | window.name | -| classnames.js:9:31:9:85 | `` | -| classnames.js:9:31:9:85 | `` | -| classnames.js:9:47:9:70 | classNa ... w.name) | -| classnames.js:9:59:9:69 | window.name | -| classnames.js:9:59:9:69 | window.name | -| classnames.js:10:45:10:55 | window.name | -| classnames.js:10:45:10:55 | window.name | -| classnames.js:11:31:11:79 | `` | -| classnames.js:11:31:11:79 | `` | -| classnames.js:11:47:11:64 | unsafeStyle('foo') | -| classnames.js:13:31:13:83 | `` | -| classnames.js:13:31:13:83 | `` | -| classnames.js:13:47:13:68 | safeSty ... w.name) | -| classnames.js:13:57:13:67 | window.name | -| classnames.js:13:57:13:67 | window.name | -| classnames.js:15:31:15:78 | `` | -| classnames.js:15:31:15:78 | `` | -| classnames.js:15:47:15:63 | clsx(window.name) | -| classnames.js:15:52:15:62 | window.name | -| classnames.js:15:52:15:62 | window.name | -| classnames.js:17:32:17:79 | `` | -| classnames.js:17:32:17:79 | `` | -| classnames.js:17:48:17:64 | clsx(window.name) | -| classnames.js:17:53:17:63 | window.name | -| classnames.js:17:53:17:63 | window.name | -| clipboard.ts:8:11:8:51 | html | -| clipboard.ts:8:11:8:51 | html | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | -| clipboard.ts:15:25:15:28 | html | -| clipboard.ts:15:25:15:28 | html | -| clipboard.ts:15:25:15:28 | html | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:24:23:24:58 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:29:19:29:54 | e.clipb ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:33:19:33:68 | e.origi ... /html') | -| clipboard.ts:43:15:43:55 | html | -| clipboard.ts:43:15:43:55 | html | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | -| clipboard.ts:50:29:50:32 | html | -| clipboard.ts:50:29:50:32 | html | -| clipboard.ts:50:29:50:32 | html | -| clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | -| clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:98:15:98:54 | html | -| clipboard.ts:98:15:98:54 | html | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | -| clipboard.ts:99:23:99:26 | html | -| clipboard.ts:99:23:99:26 | html | -| clipboard.ts:99:23:99:26 | html | -| custom-element.js:5:26:5:36 | window.name | -| custom-element.js:5:26:5:36 | window.name | -| custom-element.js:5:26:5:36 | window.name | -| custom-element.js:5:26:5:36 | window.name | -| d3.js:4:12:4:22 | window.name | -| d3.js:4:12:4:22 | window.name | -| d3.js:4:12:4:22 | window.name | -| d3.js:11:15:11:24 | getTaint() | -| d3.js:11:15:11:24 | getTaint() | -| d3.js:11:15:11:24 | getTaint() | -| d3.js:12:20:12:29 | getTaint() | -| d3.js:12:20:12:29 | getTaint() | -| d3.js:12:20:12:29 | getTaint() | -| d3.js:14:20:14:29 | getTaint() | -| d3.js:14:20:14:29 | getTaint() | -| d3.js:14:20:14:29 | getTaint() | -| d3.js:21:15:21:24 | getTaint() | -| d3.js:21:15:21:24 | getTaint() | -| d3.js:21:15:21:24 | getTaint() | -| dates.js:9:9:9:69 | taint | -| dates.js:9:9:9:69 | taint | -| dates.js:9:17:9:69 | decodeU ... ing(1)) | -| dates.js:9:17:9:69 | decodeU ... ing(1)) | -| dates.js:9:36:9:55 | window.location.hash | -| dates.js:9:36:9:55 | window.location.hash | -| dates.js:9:36:9:68 | window. ... ring(1) | -| dates.js:9:36:9:68 | window. ... ring(1) | -| dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:42:11:68 | dateFns ... taint) | -| dates.js:11:42:11:68 | dateFns ... taint) | -| dates.js:11:63:11:67 | taint | -| dates.js:11:63:11:67 | taint | -| dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:42:12:71 | dateFns ... taint) | -| dates.js:12:42:12:71 | dateFns ... taint) | -| dates.js:12:66:12:70 | taint | -| dates.js:12:66:12:70 | taint | -| dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:42:13:70 | dateFns ... )(time) | -| dates.js:13:42:13:70 | dateFns ... )(time) | -| dates.js:13:59:13:63 | taint | -| dates.js:13:59:13:63 | taint | -| dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:42:16:67 | moment( ... (taint) | -| dates.js:16:42:16:67 | moment( ... (taint) | -| dates.js:16:62:16:66 | taint | -| dates.js:16:62:16:66 | taint | -| dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:42:18:64 | datefor ... taint) | -| dates.js:18:42:18:64 | datefor ... taint) | -| dates.js:18:59:18:63 | taint | -| dates.js:18:59:18:63 | taint | -| dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | -| dates.js:21:61:21:65 | taint | -| dates.js:21:61:21:65 | taint | -| dates.js:30:9:30:69 | taint | -| dates.js:30:9:30:69 | taint | -| dates.js:30:17:30:69 | decodeU ... ing(1)) | -| dates.js:30:17:30:69 | decodeU ... ing(1)) | -| dates.js:30:36:30:55 | window.location.hash | -| dates.js:30:36:30:55 | window.location.hash | -| dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:42:37:82 | dateFns ... taint) | -| dates.js:37:42:37:82 | dateFns ... taint) | -| dates.js:37:77:37:81 | taint | -| dates.js:37:77:37:81 | taint | -| dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:42:38:82 | luxon.f ... taint) | -| dates.js:38:42:38:82 | luxon.f ... taint) | -| dates.js:38:77:38:81 | taint | -| dates.js:38:77:38:81 | taint | -| dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:42:39:84 | moment. ... taint) | -| dates.js:39:42:39:84 | moment. ... taint) | -| dates.js:39:79:39:83 | taint | -| dates.js:39:79:39:83 | taint | -| dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:42:40:82 | dayjs.f ... taint) | -| dates.js:40:42:40:82 | dayjs.f ... taint) | -| dates.js:40:77:40:81 | taint | -| dates.js:40:77:40:81 | taint | -| dates.js:46:9:46:69 | taint | -| dates.js:46:9:46:69 | taint | -| dates.js:46:17:46:69 | decodeU ... ing(1)) | -| dates.js:46:17:46:69 | decodeU ... ing(1)) | -| dates.js:46:36:46:55 | window.location.hash | -| dates.js:46:36:46:55 | window.location.hash | -| dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:42:48:88 | DateTim ... (taint) | -| dates.js:48:42:48:88 | DateTim ... (taint) | -| dates.js:48:83:48:87 | taint | -| dates.js:48:83:48:87 | taint | -| dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:42:49:87 | new Dat ... (taint) | -| dates.js:49:42:49:87 | new Dat ... (taint) | -| dates.js:49:82:49:86 | taint | -| dates.js:49:82:49:86 | taint | -| dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:42:50:102 | DateTim ... (taint) | -| dates.js:50:42:50:102 | DateTim ... (taint) | -| dates.js:50:97:50:101 | taint | -| dates.js:50:97:50:101 | taint | -| dates.js:54:9:54:69 | taint | -| dates.js:54:9:54:69 | taint | -| dates.js:54:17:54:69 | decodeU ... ing(1)) | -| dates.js:54:17:54:69 | decodeU ... ing(1)) | -| dates.js:54:36:54:55 | window.location.hash | -| dates.js:54:36:54:55 | window.location.hash | -| dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:42:57:99 | moment. ... (taint) | -| dates.js:57:42:57:99 | moment. ... (taint) | -| dates.js:57:94:57:98 | taint | -| dates.js:57:94:57:98 | taint | -| dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:42:59:85 | luxon.e ... (taint) | -| dates.js:59:42:59:85 | luxon.e ... (taint) | -| dates.js:59:80:59:84 | taint | -| dates.js:59:80:59:84 | taint | -| dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | -| dates.js:61:81:61:85 | taint | -| dates.js:61:81:61:85 | taint | -| dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | -| dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | -| dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | -| dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:71:13:71:61 | droppedHtml | -| dragAndDrop.ts:71:13:71:61 | droppedHtml | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | -| dragAndDrop.ts:73:29:73:39 | droppedHtml | -| dragAndDrop.ts:73:29:73:39 | droppedHtml | -| dragAndDrop.ts:73:29:73:39 | droppedHtml | -| event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:31:2:83 | '

' | -| event-handler-receiver.js:2:49:2:61 | location.href | -| event-handler-receiver.js:2:49:2:61 | location.href | -| express.js:7:15:7:33 | req.param("wobble") | -| express.js:7:15:7:33 | req.param("wobble") | -| express.js:7:15:7:33 | req.param("wobble") | -| express.js:7:15:7:33 | req.param("wobble") | -| jquery.js:2:7:2:40 | tainted | -| jquery.js:2:17:2:40 | documen ... .search | -| jquery.js:2:17:2:40 | documen ... .search | -| jquery.js:7:5:7:34 | "
" | -| jquery.js:7:5:7:34 | "
" | -| jquery.js:7:20:7:26 | tainted | -| jquery.js:8:18:8:34 | "XSS: " + tainted | -| jquery.js:8:18:8:34 | "XSS: " + tainted | -| jquery.js:8:28:8:34 | tainted | -| jquery.js:10:5:10:40 | "" + ... "" | -| jquery.js:10:5:10:40 | "" + ... "" | -| jquery.js:10:13:10:20 | location | -| jquery.js:10:13:10:20 | location | -| jquery.js:10:13:10:31 | location.toString() | -| jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:14:38:14:57 | window.location.hash | -| jquery.js:14:38:14:57 | window.location.hash | -| jquery.js:15:19:15:60 | decodeU ... search) | -| jquery.js:15:19:15:60 | decodeU ... search) | -| jquery.js:15:38:15:59 | window. ... .search | -| jquery.js:15:38:15:59 | window. ... .search | -| jquery.js:16:19:16:64 | decodeU ... ring()) | -| jquery.js:16:19:16:64 | decodeU ... ring()) | -| jquery.js:16:38:16:52 | window.location | -| jquery.js:16:38:16:52 | window.location | -| jquery.js:16:38:16:63 | window. ... tring() | -| jquery.js:18:7:18:33 | hash | -| jquery.js:18:14:18:33 | window.location.hash | -| jquery.js:18:14:18:33 | window.location.hash | -| jquery.js:21:5:21:8 | hash | -| jquery.js:21:5:21:21 | hash.substring(1) | -| jquery.js:21:5:21:21 | hash.substring(1) | -| jquery.js:21:5:21:21 | hash.substring(1) | -| jquery.js:22:5:22:8 | hash | -| jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:23:5:23:8 | hash | -| jquery.js:23:5:23:18 | hash.substr(1) | -| jquery.js:23:5:23:18 | hash.substr(1) | -| jquery.js:23:5:23:18 | hash.substr(1) | -| jquery.js:24:5:24:8 | hash | -| jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:27:5:27:8 | hash | -| jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:28:5:28:26 | window. ... .search | -| jquery.js:28:5:28:26 | window. ... .search | -| jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:34:5:34:25 | '' + ... '' | -| jquery.js:34:5:34:25 | '' + ... '' | -| jquery.js:34:13:34:16 | hash | -| jquery.js:36:25:36:31 | tainted | -| jquery.js:36:25:36:31 | tainted | -| jquery.js:37:25:37:37 | () => tainted | -| jquery.js:37:25:37:37 | () => tainted | -| jquery.js:37:31:37:37 | tainted | -| json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | -| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | -| json-stringify.jsx:11:51:11:56 | locale | -| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | -| json-stringify.jsx:19:56:19:61 | locale | -| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:31:55:31:60 | locale | -| json-stringify.jsx:31:55:31:60 | locale | -| json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | -| json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | -| jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:7:17:7:35 | req.param("wobble") | -| jwt-server.js:7:17:7:35 | req.param("wobble") | -| jwt-server.js:7:17:7:35 | req.param("wobble") | -| jwt-server.js:9:16:9:20 | taint | -| jwt-server.js:9:16:9:20 | taint | -| jwt-server.js:9:55:9:61 | decoded | -| jwt-server.js:9:55:9:61 | decoded | -| jwt-server.js:11:19:11:25 | decoded | -| jwt-server.js:11:19:11:25 | decoded | -| jwt-server.js:11:19:11:29 | decoded.foo | -| jwt-server.js:11:19:11:29 | decoded.foo | -| jwt-server.js:11:19:11:29 | decoded.foo | -| jwt.js:4:36:4:39 | data | -| jwt.js:4:36:4:39 | data | -| jwt.js:4:36:4:39 | data | -| jwt.js:5:9:5:34 | decoded | -| jwt.js:5:9:5:34 | decoded | -| jwt.js:5:19:5:34 | jwt_decode(data) | -| jwt.js:5:19:5:34 | jwt_decode(data) | -| jwt.js:5:30:5:33 | data | -| jwt.js:5:30:5:33 | data | -| jwt.js:6:14:6:20 | decoded | -| jwt.js:6:14:6:20 | decoded | -| jwt.js:6:14:6:20 | decoded | -| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| nodemailer.js:13:50:13:66 | req.query.message | -| nodemailer.js:13:50:13:66 | req.query.message | -| optionalSanitizer.js:2:7:2:39 | target | -| optionalSanitizer.js:2:16:2:39 | documen ... .search | -| optionalSanitizer.js:2:16:2:39 | documen ... .search | -| optionalSanitizer.js:6:18:6:23 | target | -| optionalSanitizer.js:6:18:6:23 | target | -| optionalSanitizer.js:8:7:8:22 | tainted | -| optionalSanitizer.js:8:17:8:22 | target | -| optionalSanitizer.js:9:18:9:24 | tainted | -| optionalSanitizer.js:9:18:9:24 | tainted | -| optionalSanitizer.js:15:9:15:14 | target | -| optionalSanitizer.js:16:18:16:18 | x | -| optionalSanitizer.js:17:20:17:20 | x | -| optionalSanitizer.js:17:20:17:20 | x | -| optionalSanitizer.js:26:7:26:39 | target | -| optionalSanitizer.js:26:16:26:39 | documen ... .search | -| optionalSanitizer.js:26:16:26:39 | documen ... .search | -| optionalSanitizer.js:31:7:31:23 | tainted2 | -| optionalSanitizer.js:31:18:31:23 | target | -| optionalSanitizer.js:32:18:32:25 | tainted2 | -| optionalSanitizer.js:32:18:32:25 | tainted2 | -| optionalSanitizer.js:34:5:34:36 | tainted2 | -| optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | -| optionalSanitizer.js:34:28:34:35 | tainted2 | -| optionalSanitizer.js:36:18:36:25 | tainted2 | -| optionalSanitizer.js:36:18:36:25 | tainted2 | -| optionalSanitizer.js:38:7:38:23 | tainted3 | -| optionalSanitizer.js:38:18:38:23 | target | -| optionalSanitizer.js:39:18:39:25 | tainted3 | -| optionalSanitizer.js:39:18:39:25 | tainted3 | -| optionalSanitizer.js:41:5:41:36 | tainted3 | -| optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | -| optionalSanitizer.js:41:28:41:35 | tainted3 | -| optionalSanitizer.js:43:18:43:25 | tainted3 | -| optionalSanitizer.js:43:18:43:25 | tainted3 | -| optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | -| optionalSanitizer.js:45:41:45:46 | target | -| optionalSanitizer.js:45:51:45:56 | target | -| pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:5:9:5:29 | id | -| pages/[id].jsx:5:9:5:29 | id | -| pages/[id].jsx:5:11:5:12 | id | -| pages/[id].jsx:5:11:5:12 | id | -| pages/[id].jsx:5:18:5:29 | router.query | -| pages/[id].jsx:5:18:5:29 | router.query | -| pages/[id].jsx:5:18:5:29 | router.query | -| pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:25:11:25:24 | context.params | -| pages/[id].jsx:25:11:25:24 | context.params | -| pages/[id].jsx:25:11:25:24 | context.params | -| pages/[id].jsx:25:11:25:27 | context.params.id | -| pages/[id].jsx:25:11:25:27 | context.params.id | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | -| pages/[id].jsx:26:10:26:22 | context.query | -| pages/[id].jsx:26:10:26:22 | context.query | -| pages/[id].jsx:26:10:26:22 | context.query | -| pages/[id].jsx:26:10:26:30 | context ... .foobar | -| pages/[id].jsx:26:10:26:30 | context ... .foobar | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | -| react-native.js:7:7:7:33 | tainted | -| react-native.js:7:7:7:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:7:17:7:33 | req.param("code") | -| react-native.js:8:18:8:24 | tainted | -| react-native.js:8:18:8:24 | tainted | -| react-native.js:8:18:8:24 | tainted | -| react-native.js:9:27:9:33 | tainted | -| react-native.js:9:27:9:33 | tainted | -| react-native.js:9:27:9:33 | tainted | -| react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:10:22:10:32 | window.name | -| react-use-context.js:16:26:16:36 | window.name | -| react-use-context.js:16:26:16:36 | window.name | -| react-use-context.js:16:26:16:36 | window.name | -| react-use-context.js:16:26:16:36 | window.name | -| react-use-router.js:4:9:4:28 | router | -| react-use-router.js:4:18:4:28 | useRouter() | -| react-use-router.js:8:21:8:26 | router | -| react-use-router.js:8:21:8:32 | router.query | -| react-use-router.js:8:21:8:32 | router.query | -| react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:11:24:11:29 | router | -| react-use-router.js:11:24:11:35 | router.query | -| react-use-router.js:11:24:11:35 | router.query | -| react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:22:15:22:24 | router | -| react-use-router.js:22:17:22:22 | router | -| react-use-router.js:23:43:23:48 | router | -| react-use-router.js:23:43:23:54 | router.query | -| react-use-router.js:23:43:23:54 | router.query | -| react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:29:9:29:30 | router | -| react-use-router.js:29:18:29:30 | myUseRouter() | -| react-use-router.js:33:21:33:26 | router | -| react-use-router.js:33:21:33:32 | router.query | -| react-use-router.js:33:21:33:32 | router.query | -| react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-state.js:4:9:4:49 | state | -| react-use-state.js:4:9:4:49 | state | -| react-use-state.js:4:10:4:14 | state | -| react-use-state.js:4:10:4:14 | state | -| react-use-state.js:4:38:4:48 | window.name | -| react-use-state.js:4:38:4:48 | window.name | -| react-use-state.js:4:38:4:48 | window.name | -| react-use-state.js:5:51:5:55 | state | -| react-use-state.js:5:51:5:55 | state | -| react-use-state.js:5:51:5:55 | state | -| react-use-state.js:9:9:9:43 | state | -| react-use-state.js:9:9:9:43 | state | -| react-use-state.js:9:10:9:14 | state | -| react-use-state.js:9:10:9:14 | state | -| react-use-state.js:10:14:10:24 | window.name | -| react-use-state.js:10:14:10:24 | window.name | -| react-use-state.js:10:14:10:24 | window.name | -| react-use-state.js:11:51:11:55 | state | -| react-use-state.js:11:51:11:55 | state | -| react-use-state.js:11:51:11:55 | state | -| react-use-state.js:15:9:15:43 | state | -| react-use-state.js:15:9:15:43 | state | -| react-use-state.js:15:10:15:14 | state | -| react-use-state.js:15:10:15:14 | state | -| react-use-state.js:16:20:16:30 | window.name | -| react-use-state.js:16:20:16:30 | window.name | -| react-use-state.js:16:20:16:30 | window.name | -| react-use-state.js:17:51:17:55 | state | -| react-use-state.js:17:51:17:55 | state | -| react-use-state.js:17:51:17:55 | state | -| react-use-state.js:21:10:21:14 | state | -| react-use-state.js:21:10:21:14 | state | -| react-use-state.js:22:14:22:17 | prev | -| react-use-state.js:22:14:22:17 | prev | -| react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:25:20:25:30 | window.name | -| react-use-state.js:25:20:25:30 | window.name | -| react-use-state.js:25:20:25:30 | window.name | -| sanitiser.js:16:7:16:27 | tainted | -| sanitiser.js:16:7:16:27 | tainted | -| sanitiser.js:16:17:16:27 | window.name | -| sanitiser.js:16:17:16:27 | window.name | -| sanitiser.js:16:17:16:27 | window.name | -| sanitiser.js:23:21:23:44 | '' + ... '' | -| sanitiser.js:23:21:23:44 | '' + ... '' | -| sanitiser.js:23:29:23:35 | tainted | -| sanitiser.js:30:21:30:44 | '' + ... '' | -| sanitiser.js:30:21:30:44 | '' + ... '' | -| sanitiser.js:30:29:30:35 | tainted | -| sanitiser.js:33:21:33:44 | '' + ... '' | -| sanitiser.js:33:21:33:44 | '' + ... '' | -| sanitiser.js:33:29:33:35 | tainted | -| sanitiser.js:38:21:38:44 | '' + ... '' | -| sanitiser.js:38:21:38:44 | '' + ... '' | -| sanitiser.js:38:29:38:35 | tainted | -| sanitiser.js:45:21:45:44 | '' + ... '' | -| sanitiser.js:45:21:45:44 | '' + ... '' | -| sanitiser.js:45:29:45:35 | tainted | -| sanitiser.js:48:19:48:25 | tainted | -| sanitiser.js:48:19:48:25 | tainted | -| sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| stored-xss.js:2:39:2:62 | documen ... .search | -| stored-xss.js:2:39:2:62 | documen ... .search | -| stored-xss.js:3:35:3:58 | documen ... .search | -| stored-xss.js:3:35:3:58 | documen ... .search | -| stored-xss.js:5:20:5:52 | session ... ssion') | -| stored-xss.js:5:20:5:52 | session ... ssion') | -| stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:10:9:10:44 | href | -| stored-xss.js:10:16:10:44 | localSt ... local') | -| stored-xss.js:12:20:12:54 | "" | -| stored-xss.js:12:20:12:54 | "" | -| stored-xss.js:12:20:12:54 | "" | -| stored-xss.js:12:35:12:38 | href | -| string-manipulations.js:3:16:3:32 | document.location | -| string-manipulations.js:3:16:3:32 | document.location | -| string-manipulations.js:3:16:3:32 | document.location | -| string-manipulations.js:4:16:4:37 | documen ... on.href | -| string-manipulations.js:4:16:4:37 | documen ... on.href | -| string-manipulations.js:4:16:4:37 | documen ... on.href | -| string-manipulations.js:5:16:5:37 | documen ... on.href | -| string-manipulations.js:5:16:5:37 | documen ... on.href | -| string-manipulations.js:5:16:5:47 | documen ... lueOf() | -| string-manipulations.js:5:16:5:47 | documen ... lueOf() | -| string-manipulations.js:6:16:6:37 | documen ... on.href | -| string-manipulations.js:6:16:6:37 | documen ... on.href | -| string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:7:16:7:37 | documen ... on.href | -| string-manipulations.js:7:16:7:37 | documen ... on.href | -| string-manipulations.js:7:16:7:51 | documen ... rCase() | -| string-manipulations.js:7:16:7:51 | documen ... rCase() | -| string-manipulations.js:8:16:8:37 | documen ... on.href | -| string-manipulations.js:8:16:8:37 | documen ... on.href | -| string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:9:16:9:58 | String. ... n.href) | -| string-manipulations.js:9:16:9:58 | String. ... n.href) | -| string-manipulations.js:9:36:9:57 | documen ... on.href | -| string-manipulations.js:9:36:9:57 | documen ... on.href | -| string-manipulations.js:10:16:10:45 | String( ... n.href) | -| string-manipulations.js:10:16:10:45 | String( ... n.href) | -| string-manipulations.js:10:23:10:44 | documen ... on.href | -| string-manipulations.js:10:23:10:44 | documen ... on.href | -| tooltip.jsx:6:11:6:30 | source | -| tooltip.jsx:6:11:6:30 | source | -| tooltip.jsx:6:20:6:30 | window.name | -| tooltip.jsx:6:20:6:30 | window.name | -| tooltip.jsx:6:20:6:30 | window.name | -| tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:22:11:22:30 | source | -| tooltip.jsx:22:11:22:30 | source | -| tooltip.jsx:22:20:22:30 | window.name | -| tooltip.jsx:22:20:22:30 | window.name | -| tooltip.jsx:22:20:22:30 | window.name | -| tooltip.jsx:23:38:23:43 | source | -| tooltip.jsx:23:38:23:43 | source | -| translate.js:6:7:6:39 | target | -| translate.js:6:16:6:39 | documen ... .search | -| translate.js:6:16:6:39 | documen ... .search | -| translate.js:7:7:7:61 | searchParams | -| translate.js:7:22:7:61 | new URL ... ing(1)) | -| translate.js:7:42:7:47 | target | -| translate.js:7:42:7:60 | target.substring(1) | -| translate.js:7:42:7:60 | target.substring(1) | -| translate.js:7:42:7:60 | target.substring(1) | -| translate.js:9:27:9:38 | searchParams | -| translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:9:27:9:50 | searchP ... 'term') | -| translate.js:9:27:9:50 | searchP ... 'term') | -| trusted-types-lib.js:1:28:1:28 | x | -| trusted-types-lib.js:1:28:1:28 | x | -| trusted-types-lib.js:2:12:2:12 | x | -| trusted-types-lib.js:2:12:2:12 | x | -| trusted-types-lib.js:2:12:2:12 | x | -| trusted-types.js:3:62:3:62 | x | -| trusted-types.js:3:62:3:62 | x | -| trusted-types.js:3:67:3:67 | x | -| trusted-types.js:3:67:3:67 | x | -| trusted-types.js:3:67:3:67 | x | -| trusted-types.js:4:20:4:30 | window.name | -| trusted-types.js:4:20:4:30 | window.name | -| trusted-types.js:4:20:4:30 | window.name | -| trusted-types.js:13:20:13:30 | window.name | -| trusted-types.js:13:20:13:30 | window.name | -| trusted-types.js:13:20:13:30 | window.name | -| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | -| tst3.js:2:23:2:74 | decodeU ... str(1)) | -| tst3.js:2:42:2:63 | window. ... .search | -| tst3.js:2:42:2:63 | window. ... .search | -| tst3.js:2:42:2:73 | window. ... bstr(1) | -| tst3.js:4:25:4:28 | data | -| tst3.js:4:25:4:32 | data.src | -| tst3.js:4:25:4:32 | data.src | -| tst3.js:5:26:5:29 | data | -| tst3.js:5:26:5:31 | data.p | -| tst3.js:5:26:5:31 | data.p | -| tst3.js:7:32:7:35 | data | -| tst3.js:7:32:7:37 | data.p | -| tst3.js:7:32:7:37 | data.p | -| tst3.js:9:37:9:40 | data | -| tst3.js:9:37:9:42 | data.p | -| tst3.js:9:37:9:42 | data.p | -| tst3.js:10:38:10:41 | data | -| tst3.js:10:38:10:43 | data.p | -| tst3.js:10:38:10:43 | data.p | -| tst.js:2:7:2:39 | target | -| tst.js:2:16:2:39 | documen ... .search | -| tst.js:2:16:2:39 | documen ... .search | -| tst.js:5:18:5:23 | target | -| tst.js:5:18:5:23 | target | -| tst.js:8:18:8:126 | "" | -| tst.js:8:18:8:126 | "" | -| tst.js:8:18:8:126 | "" | -| tst.js:8:37:8:58 | documen ... on.href | -| tst.js:8:37:8:58 | documen ... on.href | -| tst.js:8:37:8:114 | documen ... t=")+8) | -| tst.js:8:37:8:114 | documen ... t=")+8) | -| tst.js:12:5:12:42 | '
' | -| tst.js:12:5:12:42 | '
' | -| tst.js:12:28:12:33 | target | -| tst.js:17:7:17:56 | params | -| tst.js:17:16:17:56 | (new UR ... hParams | -| tst.js:17:25:17:41 | document.location | -| tst.js:17:25:17:41 | document.location | -| tst.js:18:18:18:23 | params | -| tst.js:18:18:18:35 | params.get('name') | -| tst.js:18:18:18:35 | params.get('name') | -| tst.js:18:18:18:35 | params.get('name') | -| tst.js:18:18:18:35 | params.get('name') | -| tst.js:20:7:20:61 | searchParams | -| tst.js:20:22:20:61 | new URL ... ing(1)) | -| tst.js:20:42:20:47 | target | -| tst.js:20:42:20:60 | target.substring(1) | -| tst.js:20:42:20:60 | target.substring(1) | -| tst.js:20:42:20:60 | target.substring(1) | -| tst.js:21:18:21:29 | searchParams | -| tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:24:14:24:19 | target | -| tst.js:26:18:26:23 | target | -| tst.js:26:18:26:23 | target | -| tst.js:28:5:28:28 | documen ... .search | -| tst.js:28:5:28:28 | documen ... .search | -| tst.js:31:10:31:33 | documen ... .search | -| tst.js:31:10:31:33 | documen ... .search | -| tst.js:34:16:34:20 | bar() | -| tst.js:34:16:34:20 | bar() | -| tst.js:40:16:40:44 | baz(doc ... search) | -| tst.js:40:16:40:44 | baz(doc ... search) | -| tst.js:40:20:40:43 | documen ... .search | -| tst.js:40:20:40:43 | documen ... .search | -| tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:46:21:46:44 | documen ... .search | -| tst.js:46:21:46:44 | documen ... .search | -| tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:54:21:54:44 | documen ... .search | -| tst.js:54:21:54:44 | documen ... .search | -| tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | -| tst.js:56:21:56:44 | documen ... .search | -| tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:21:58:31 | chop(bar()) | -| tst.js:58:21:58:31 | chop(bar()) | -| tst.js:58:26:58:30 | bar() | -| tst.js:60:34:60:34 | s | -| tst.js:62:18:62:18 | s | -| tst.js:62:18:62:18 | s | -| tst.js:64:25:64:48 | documen ... .search | -| tst.js:64:25:64:48 | documen ... .search | -| tst.js:65:25:65:48 | documen ... .search | -| tst.js:65:25:65:48 | documen ... .search | -| tst.js:68:16:68:20 | bar() | -| tst.js:68:16:68:20 | bar() | -| tst.js:70:1:70:27 | [,docum ... search] | -| tst.js:70:3:70:26 | documen ... .search | -| tst.js:70:3:70:26 | documen ... .search | -| tst.js:70:46:70:46 | x | -| tst.js:73:20:73:20 | x | -| tst.js:73:20:73:20 | x | -| tst.js:77:49:77:72 | documen ... .search | -| tst.js:77:49:77:72 | documen ... .search | -| tst.js:77:49:77:72 | documen ... .search | -| tst.js:81:26:81:49 | documen ... .search | -| tst.js:81:26:81:49 | documen ... .search | -| tst.js:81:26:81:49 | documen ... .search | -| tst.js:82:25:82:48 | documen ... .search | -| tst.js:82:25:82:48 | documen ... .search | -| tst.js:82:25:82:48 | documen ... .search | -| tst.js:84:33:84:56 | documen ... .search | -| tst.js:84:33:84:56 | documen ... .search | -| tst.js:84:33:84:56 | documen ... .search | -| tst.js:85:32:85:55 | documen ... .search | -| tst.js:85:32:85:55 | documen ... .search | -| tst.js:85:32:85:55 | documen ... .search | -| tst.js:90:39:90:62 | documen ... .search | -| tst.js:90:39:90:62 | documen ... .search | -| tst.js:90:39:90:62 | documen ... .search | -| tst.js:96:30:96:53 | documen ... .search | -| tst.js:96:30:96:53 | documen ... .search | -| tst.js:96:30:96:53 | documen ... .search | -| tst.js:102:25:102:48 | documen ... .search | -| tst.js:102:25:102:48 | documen ... .search | -| tst.js:102:25:102:48 | documen ... .search | -| tst.js:107:7:107:44 | v | -| tst.js:107:7:107:44 | v | -| tst.js:107:7:107:44 | v | -| tst.js:107:11:107:34 | documen ... .search | -| tst.js:107:11:107:34 | documen ... .search | -| tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:110:18:110:18 | v | -| tst.js:110:18:110:18 | v | -| tst.js:110:18:110:18 | v | -| tst.js:110:18:110:18 | v | -| tst.js:136:18:136:18 | v | -| tst.js:136:18:136:18 | v | -| tst.js:136:18:136:18 | v | -| tst.js:136:18:136:18 | v | -| tst.js:148:29:148:50 | window. ... .search | -| tst.js:148:29:148:50 | window. ... .search | -| tst.js:151:29:151:29 | v | -| tst.js:151:49:151:49 | v | -| tst.js:151:49:151:49 | v | -| tst.js:155:29:155:46 | xssSourceService() | -| tst.js:155:29:155:46 | xssSourceService() | -| tst.js:158:40:158:61 | window. ... .search | -| tst.js:158:40:158:61 | window. ... .search | -| tst.js:177:9:177:41 | target | -| tst.js:177:18:177:41 | documen ... .search | -| tst.js:177:18:177:41 | documen ... .search | -| tst.js:180:28:180:33 | target | -| tst.js:180:28:180:33 | target | -| tst.js:184:9:184:42 | tainted | -| tst.js:184:19:184:42 | documen ... .search | -| tst.js:184:19:184:42 | documen ... .search | -| tst.js:186:31:186:37 | tainted | -| tst.js:186:31:186:37 | tainted | -| tst.js:188:42:188:48 | tainted | -| tst.js:188:42:188:48 | tainted | -| tst.js:189:33:189:39 | tainted | -| tst.js:189:33:189:39 | tainted | -| tst.js:191:54:191:60 | tainted | -| tst.js:191:54:191:60 | tainted | -| tst.js:192:45:192:51 | tainted | -| tst.js:192:45:192:51 | tainted | -| tst.js:193:49:193:55 | tainted | -| tst.js:193:49:193:55 | tainted | -| tst.js:197:9:197:42 | tainted | -| tst.js:197:19:197:42 | documen ... .search | -| tst.js:197:19:197:42 | documen ... .search | -| tst.js:199:67:199:73 | tainted | -| tst.js:199:67:199:73 | tainted | -| tst.js:200:67:200:73 | tainted | -| tst.js:200:67:200:73 | tainted | -| tst.js:204:35:204:41 | tainted | -| tst.js:206:46:206:52 | tainted | -| tst.js:207:38:207:44 | tainted | -| tst.js:208:35:208:41 | tainted | -| tst.js:212:28:212:46 | this.state.tainted1 | -| tst.js:212:28:212:46 | this.state.tainted1 | -| tst.js:213:28:213:46 | this.state.tainted2 | -| tst.js:213:28:213:46 | this.state.tainted2 | -| tst.js:214:28:214:46 | this.state.tainted3 | -| tst.js:214:28:214:46 | this.state.tainted3 | -| tst.js:218:32:218:49 | prevState.tainted4 | -| tst.js:218:32:218:49 | prevState.tainted4 | -| tst.js:225:28:225:46 | this.props.tainted1 | -| tst.js:225:28:225:46 | this.props.tainted1 | -| tst.js:226:28:226:46 | this.props.tainted2 | -| tst.js:226:28:226:46 | this.props.tainted2 | -| tst.js:227:28:227:46 | this.props.tainted3 | -| tst.js:227:28:227:46 | this.props.tainted3 | -| tst.js:231:32:231:49 | prevProps.tainted4 | -| tst.js:231:32:231:49 | prevProps.tainted4 | -| tst.js:236:35:236:41 | tainted | -| tst.js:238:20:238:26 | tainted | -| tst.js:240:23:240:29 | tainted | -| tst.js:241:23:241:29 | tainted | -| tst.js:247:39:247:55 | props.propTainted | -| tst.js:251:60:251:82 | this.st ... Tainted | -| tst.js:251:60:251:82 | this.st ... Tainted | -| tst.js:255:23:255:29 | tainted | -| tst.js:259:7:259:17 | window.name | -| tst.js:259:7:259:17 | window.name | -| tst.js:259:7:259:17 | window.name | -| tst.js:259:7:259:17 | window.name | -| tst.js:260:7:260:10 | name | -| tst.js:260:7:260:10 | name | -| tst.js:260:7:260:10 | name | -| tst.js:260:7:260:10 | name | -| tst.js:264:11:264:21 | window.name | -| tst.js:264:11:264:21 | window.name | -| tst.js:264:11:264:21 | window.name | -| tst.js:264:11:264:21 | window.name | -| tst.js:280:22:280:29 | location | -| tst.js:280:22:280:29 | location | -| tst.js:280:22:280:29 | location | -| tst.js:285:9:285:29 | tainted | -| tst.js:285:9:285:29 | tainted | -| tst.js:285:19:285:29 | window.name | -| tst.js:285:19:285:29 | window.name | -| tst.js:285:19:285:29 | window.name | -| tst.js:288:59:288:65 | tainted | -| tst.js:288:59:288:65 | tainted | -| tst.js:288:59:288:65 | tainted | -| tst.js:301:9:301:16 | location | -| tst.js:301:9:301:16 | location | -| tst.js:302:10:302:10 | e | -| tst.js:303:20:303:20 | e | -| tst.js:303:20:303:20 | e | -| tst.js:308:10:308:17 | location | -| tst.js:308:10:308:17 | location | -| tst.js:310:10:310:10 | e | -| tst.js:311:20:311:20 | e | -| tst.js:311:20:311:20 | e | -| tst.js:316:35:316:42 | location | -| tst.js:316:35:316:42 | location | -| tst.js:316:35:316:42 | location | -| tst.js:327:18:327:34 | document.location | -| tst.js:327:18:327:34 | document.location | -| tst.js:331:7:331:43 | params | -| tst.js:331:16:331:43 | getTain ... hParams | -| tst.js:332:18:332:23 | params | -| tst.js:332:18:332:35 | params.get('name') | -| tst.js:332:18:332:35 | params.get('name') | -| tst.js:332:18:332:35 | params.get('name') | -| tst.js:332:18:332:35 | params.get('name') | -| tst.js:341:20:341:36 | document.location | -| tst.js:341:20:341:36 | document.location | -| tst.js:343:5:343:17 | getUrl().hash | -| tst.js:343:5:343:30 | getUrl( ... ring(1) | -| tst.js:343:5:343:30 | getUrl( ... ring(1) | -| tst.js:343:5:343:30 | getUrl( ... ring(1) | -| tst.js:348:7:348:39 | target | -| tst.js:348:16:348:39 | documen ... .search | -| tst.js:348:16:348:39 | documen ... .search | -| tst.js:349:12:349:17 | target | -| tst.js:349:12:349:17 | target | -| tst.js:355:10:355:42 | target | -| tst.js:355:19:355:42 | documen ... .search | -| tst.js:355:19:355:42 | documen ... .search | -| tst.js:356:16:356:21 | target | -| tst.js:356:16:356:21 | target | -| tst.js:360:21:360:26 | target | -| tst.js:360:21:360:26 | target | -| tst.js:363:18:363:23 | target | -| tst.js:363:18:363:23 | target | -| tst.js:371:7:371:39 | target | -| tst.js:371:16:371:39 | documen ... .search | -| tst.js:371:16:371:39 | documen ... .search | -| tst.js:374:18:374:23 | target | -| tst.js:374:18:374:23 | target | -| tst.js:381:7:381:39 | target | -| tst.js:381:16:381:39 | documen ... .search | -| tst.js:381:16:381:39 | documen ... .search | -| tst.js:384:18:384:23 | target | -| tst.js:384:18:384:23 | target | -| tst.js:386:18:386:23 | target | -| tst.js:386:18:386:29 | target.taint | -| tst.js:386:18:386:29 | target.taint | -| tst.js:391:19:391:42 | documen ... .search | -| tst.js:391:19:391:42 | documen ... .search | -| tst.js:392:18:392:30 | target.taint3 | -| tst.js:392:18:392:30 | target.taint3 | -| tst.js:397:18:397:23 | target | -| tst.js:397:18:397:30 | target.taint5 | -| tst.js:397:18:397:30 | target.taint5 | -| tst.js:406:18:406:23 | target | -| tst.js:406:18:406:30 | target.taint7 | -| tst.js:406:18:406:30 | target.taint7 | -| tst.js:408:19:408:24 | target | -| tst.js:408:19:408:31 | target.taint8 | -| tst.js:409:18:409:30 | target.taint8 | -| tst.js:409:18:409:30 | target.taint8 | -| tst.js:416:7:416:46 | payload | -| tst.js:416:7:416:46 | payload | -| tst.js:416:7:416:46 | payload | -| tst.js:416:17:416:36 | window.location.hash | -| tst.js:416:17:416:36 | window.location.hash | -| tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:417:18:417:24 | payload | -| tst.js:417:18:417:24 | payload | -| tst.js:417:18:417:24 | payload | -| tst.js:417:18:417:24 | payload | -| tst.js:419:7:419:55 | match | -| tst.js:419:15:419:34 | window.location.hash | -| tst.js:419:15:419:34 | window.location.hash | -| tst.js:419:15:419:55 | window. ... (\\w+)/) | -| tst.js:421:20:421:24 | match | -| tst.js:421:20:421:27 | match[1] | -| tst.js:421:20:421:27 | match[1] | -| tst.js:424:18:424:37 | window.location.hash | -| tst.js:424:18:424:37 | window.location.hash | -| tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:428:7:428:39 | target | -| tst.js:428:16:428:39 | documen ... .search | -| tst.js:428:16:428:39 | documen ... .search | -| tst.js:430:18:430:23 | target | -| tst.js:430:18:430:89 | target. ... data>') | -| tst.js:430:18:430:89 | target. ... data>') | -| tst.js:436:6:436:38 | source | -| tst.js:436:15:436:38 | documen ... .search | -| tst.js:436:15:436:38 | documen ... .search | -| tst.js:440:28:440:33 | source | -| tst.js:440:28:440:33 | source | -| tst.js:441:33:441:38 | source | -| tst.js:441:33:441:38 | source | -| tst.js:442:34:442:39 | source | -| tst.js:442:34:442:39 | source | -| tst.js:443:41:443:46 | source | -| tst.js:443:41:443:46 | source | -| tst.js:444:44:444:49 | source | -| tst.js:444:44:444:49 | source | -| tst.js:445:32:445:37 | source | -| tst.js:445:32:445:37 | source | -| tst.js:453:7:453:39 | source | -| tst.js:453:16:453:39 | documen ... .search | -| tst.js:453:16:453:39 | documen ... .search | -| tst.js:455:18:455:23 | source | -| tst.js:455:18:455:23 | source | -| tst.js:456:18:456:42 | ansiToH ... source) | -| tst.js:456:18:456:42 | ansiToH ... source) | -| tst.js:456:36:456:41 | source | -| tst.js:460:6:460:38 | source | -| tst.js:460:15:460:38 | documen ... .search | -| tst.js:460:15:460:38 | documen ... .search | -| tst.js:463:21:463:26 | source | -| tst.js:463:21:463:26 | source | -| tst.js:465:19:465:24 | source | -| tst.js:465:19:465:24 | source | -| tst.js:467:20:467:25 | source | -| tst.js:467:20:467:25 | source | -| tst.js:471:7:471:46 | url | -| tst.js:471:13:471:36 | documen ... .search | -| tst.js:471:13:471:36 | documen ... .search | -| tst.js:471:13:471:46 | documen ... bstr(1) | -| tst.js:473:19:473:21 | url | -| tst.js:473:19:473:21 | url | -| tst.js:474:26:474:28 | url | -| tst.js:474:26:474:28 | url | -| tst.js:475:25:475:27 | url | -| tst.js:475:25:475:27 | url | -| tst.js:476:20:476:22 | url | -| tst.js:476:20:476:22 | url | -| tst.js:486:22:486:24 | url | -| tst.js:486:22:486:24 | url | -| tst.js:491:23:491:35 | location.hash | -| tst.js:491:23:491:35 | location.hash | -| tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:494:18:494:30 | location.hash | -| tst.js:494:18:494:30 | location.hash | -| tst.js:494:18:494:40 | locatio ... bstr(1) | -| tst.js:494:18:494:40 | locatio ... bstr(1) | -| tst.js:501:33:501:63 | decodeU ... n.hash) | -| tst.js:501:33:501:63 | decodeU ... n.hash) | -| tst.js:501:43:501:62 | window.location.hash | -| tst.js:501:43:501:62 | window.location.hash | -| typeahead.js:9:28:9:30 | loc | -| typeahead.js:9:28:9:30 | loc | -| typeahead.js:9:28:9:30 | loc | -| typeahead.js:10:16:10:18 | loc | -| typeahead.js:10:16:10:18 | loc | -| typeahead.js:10:16:10:18 | loc | -| typeahead.js:20:13:20:45 | target | -| typeahead.js:20:22:20:45 | documen ... .search | -| typeahead.js:20:22:20:45 | documen ... .search | -| typeahead.js:21:12:21:17 | target | -| typeahead.js:24:30:24:32 | val | -| typeahead.js:25:18:25:20 | val | -| typeahead.js:25:18:25:20 | val | -| v-html.vue:2:8:2:23 | v-html=tainted | -| v-html.vue:2:8:2:23 | v-html=tainted | -| v-html.vue:6:42:6:58 | document.location | -| v-html.vue:6:42:6:58 | document.location | -| various-concat-obfuscations.js:2:6:2:39 | tainted | -| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | -| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | -| various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | -| various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | -| various-concat-obfuscations.js:4:14:4:20 | tainted | -| various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | -| various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | -| various-concat-obfuscations.js:5:12:5:18 | tainted | -| various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | -| various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | -| various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | -| various-concat-obfuscations.js:6:19:6:25 | tainted | -| various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | -| various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | -| various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | -| various-concat-obfuscations.js:7:14:7:20 | tainted | -| various-concat-obfuscations.js:9:4:9:34 | "
" | -| various-concat-obfuscations.js:9:4:9:34 | "
" | -| various-concat-obfuscations.js:9:19:9:25 | tainted | -| various-concat-obfuscations.js:10:4:10:27 | `
` | -| various-concat-obfuscations.js:10:4:10:27 | `
` | -| various-concat-obfuscations.js:10:16:10:22 | tainted | -| various-concat-obfuscations.js:11:4:11:31 | "
") | -| various-concat-obfuscations.js:11:4:11:44 | "
") | -| various-concat-obfuscations.js:11:24:11:30 | tainted | -| various-concat-obfuscations.js:12:4:12:34 | ["
"] | -| various-concat-obfuscations.js:12:4:12:41 | ["
>>>>>> main edges -| addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | -| addEventListener.js:2:20:2:24 | event | addEventListener.js:2:20:2:29 | event.data | -| addEventListener.js:5:43:5:48 | data | addEventListener.js:6:20:6:23 | data | -| addEventListener.js:5:43:5:48 | {data} | addEventListener.js:5:44:5:47 | data | -| addEventListener.js:5:44:5:47 | data | addEventListener.js:5:43:5:48 | data | -| addEventListener.js:10:21:10:25 | event | addEventListener.js:12:24:12:28 | event | -| addEventListener.js:12:24:12:28 | event | addEventListener.js:12:24:12:33 | event.data | -| angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | -| angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | -| angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | -| angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | -| classnames.js:7:47:7:69 | classNa ... w.name) | classnames.js:7:31:7:84 | `` | -| classnames.js:7:58:7:68 | window.name | classnames.js:7:47:7:69 | classNa ... w.name) | -| classnames.js:8:47:8:70 | classNa ... w.name) | classnames.js:8:31:8:85 | `` | -| classnames.js:8:59:8:69 | window.name | classnames.js:8:47:8:70 | classNa ... w.name) | -| classnames.js:9:47:9:70 | classNa ... w.name) | classnames.js:9:31:9:85 | `` | -| classnames.js:9:59:9:69 | window.name | classnames.js:9:47:9:70 | classNa ... w.name) | -| classnames.js:10:45:10:55 | window.name | classnames.js:11:47:11:64 | unsafeStyle('foo') | -| classnames.js:11:47:11:64 | unsafeStyle('foo') | classnames.js:11:31:11:79 | `` | -| classnames.js:13:47:13:68 | safeSty ... w.name) | classnames.js:13:31:13:83 | `` | -| classnames.js:13:57:13:67 | window.name | classnames.js:13:47:13:68 | safeSty ... w.name) | -| classnames.js:15:47:15:63 | clsx(window.name) | classnames.js:15:31:15:78 | `` | -| classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) | -| classnames.js:17:48:17:64 | clsx(window.name) | classnames.js:17:32:17:79 | `` | -| classnames.js:17:53:17:63 | window.name | classnames.js:17:48:17:64 | clsx(window.name) | -| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | -| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html | -| clipboard.ts:43:15:43:55 | html | clipboard.ts:50:29:50:32 | html | -| clipboard.ts:43:22:43:55 | clipboa ... /html') | clipboard.ts:43:15:43:55 | html | -| clipboard.ts:71:13:71:62 | droppedHtml | clipboard.ts:73:29:73:39 | droppedHtml | -| clipboard.ts:71:27:71:62 | e.clipb ... /html') | clipboard.ts:71:13:71:62 | droppedHtml | -| clipboard.ts:98:15:98:54 | html | clipboard.ts:99:23:99:26 | html | -| clipboard.ts:98:22:98:54 | dataTra ... /html') | clipboard.ts:98:15:98:54 | html | -| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | -| d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | -| dates.js:9:9:9:69 | taint | dates.js:11:63:11:67 | taint | -| dates.js:9:9:9:69 | taint | dates.js:12:66:12:70 | taint | -| dates.js:9:9:9:69 | taint | dates.js:13:59:13:63 | taint | -| dates.js:9:9:9:69 | taint | dates.js:16:62:16:66 | taint | -| dates.js:9:9:9:69 | taint | dates.js:18:59:18:63 | taint | -| dates.js:9:9:9:69 | taint | dates.js:21:61:21:65 | taint | -| dates.js:9:17:9:69 | decodeU ... ing(1)) | dates.js:9:9:9:69 | taint | -| dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | -| dates.js:9:36:9:68 | window. ... ring(1) | dates.js:9:17:9:69 | decodeU ... ing(1)) | -| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | -| dates.js:11:63:11:67 | taint | dates.js:11:42:11:68 | dateFns ... taint) | -| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | -| dates.js:12:66:12:70 | taint | dates.js:12:42:12:71 | dateFns ... taint) | -| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | -| dates.js:13:59:13:63 | taint | dates.js:13:42:13:70 | dateFns ... )(time) | -| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | -| dates.js:16:62:16:66 | taint | dates.js:16:42:16:67 | moment( ... (taint) | -| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | -| dates.js:18:59:18:63 | taint | dates.js:18:42:18:64 | datefor ... taint) | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | -| dates.js:21:61:21:65 | taint | dates.js:21:42:21:66 | dayjs(t ... (taint) | -| dates.js:30:9:30:69 | taint | dates.js:37:77:37:81 | taint | -| dates.js:30:9:30:69 | taint | dates.js:38:77:38:81 | taint | -| dates.js:30:9:30:69 | taint | dates.js:39:79:39:83 | taint | -| dates.js:30:9:30:69 | taint | dates.js:40:77:40:81 | taint | -| dates.js:30:17:30:69 | decodeU ... ing(1)) | dates.js:30:9:30:69 | taint | -| dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | -| dates.js:30:36:30:68 | window. ... ring(1) | dates.js:30:17:30:69 | decodeU ... ing(1)) | -| dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | -| dates.js:37:77:37:81 | taint | dates.js:37:42:37:82 | dateFns ... taint) | -| dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | -| dates.js:38:77:38:81 | taint | dates.js:38:42:38:82 | luxon.f ... taint) | -| dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | -| dates.js:39:79:39:83 | taint | dates.js:39:42:39:84 | moment. ... taint) | -| dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | -| dates.js:40:77:40:81 | taint | dates.js:40:42:40:82 | dayjs.f ... taint) | -| dates.js:46:9:46:69 | taint | dates.js:48:83:48:87 | taint | -| dates.js:46:9:46:69 | taint | dates.js:49:82:49:86 | taint | -| dates.js:46:9:46:69 | taint | dates.js:50:97:50:101 | taint | -| dates.js:46:17:46:69 | decodeU ... ing(1)) | dates.js:46:9:46:69 | taint | -| dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | -| dates.js:46:36:46:68 | window. ... ring(1) | dates.js:46:17:46:69 | decodeU ... ing(1)) | -| dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | -| dates.js:48:83:48:87 | taint | dates.js:48:42:48:88 | DateTim ... (taint) | -| dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | -| dates.js:49:82:49:86 | taint | dates.js:49:42:49:87 | new Dat ... (taint) | -| dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | -| dates.js:50:97:50:101 | taint | dates.js:50:42:50:102 | DateTim ... (taint) | -| dates.js:54:9:54:69 | taint | dates.js:57:94:57:98 | taint | -| dates.js:54:9:54:69 | taint | dates.js:59:80:59:84 | taint | -| dates.js:54:9:54:69 | taint | dates.js:61:81:61:85 | taint | -| dates.js:54:17:54:69 | decodeU ... ing(1)) | dates.js:54:9:54:69 | taint | -| dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | -| dates.js:54:36:54:68 | window. ... ring(1) | dates.js:54:17:54:69 | decodeU ... ing(1)) | -| dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | -| dates.js:57:94:57:98 | taint | dates.js:57:42:57:99 | moment. ... (taint) | -| dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | -| dates.js:59:80:59:84 | taint | dates.js:59:42:59:85 | luxon.e ... (taint) | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | -| dates.js:61:81:61:85 | taint | dates.js:61:42:61:86 | dayjs.s ... (taint) | -| dragAndDrop.ts:8:11:8:50 | html | dragAndDrop.ts:15:25:15:28 | html | -| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | dragAndDrop.ts:8:11:8:50 | html | -| dragAndDrop.ts:43:15:43:54 | html | dragAndDrop.ts:50:29:50:32 | html | -| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | dragAndDrop.ts:43:15:43:54 | html | -| dragAndDrop.ts:71:13:71:61 | droppedHtml | dragAndDrop.ts:73:29:73:39 | droppedHtml | -| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | -| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | -| jquery.js:2:7:2:40 | tainted | jquery.js:7:20:7:26 | tainted | -| jquery.js:2:7:2:40 | tainted | jquery.js:8:28:8:34 | tainted | -| jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | -| jquery.js:2:7:2:40 | tainted | jquery.js:37:31:37:37 | tainted | -| jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | -| jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "
" | -| jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | -| jquery.js:10:13:10:20 | location | jquery.js:10:13:10:31 | location.toString() | -| jquery.js:10:13:10:31 | location.toString() | jquery.js:10:5:10:40 | "" + ... "" | -| jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | -| jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | -| jquery.js:16:38:16:52 | window.location | jquery.js:16:38:16:63 | window. ... tring() | -| jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) | -| jquery.js:18:7:18:33 | hash | jquery.js:21:5:21:8 | hash | -| jquery.js:18:7:18:33 | hash | jquery.js:22:5:22:8 | hash | -| jquery.js:18:7:18:33 | hash | jquery.js:23:5:23:8 | hash | -| jquery.js:18:7:18:33 | hash | jquery.js:24:5:24:8 | hash | -| jquery.js:18:7:18:33 | hash | jquery.js:27:5:27:8 | hash | -| jquery.js:18:7:18:33 | hash | jquery.js:34:13:34:16 | hash | -| jquery.js:18:14:18:33 | window.location.hash | jquery.js:18:7:18:33 | hash | -| jquery.js:21:5:21:8 | hash | jquery.js:21:5:21:21 | hash.substring(1) | -| jquery.js:22:5:22:8 | hash | jquery.js:22:5:22:25 | hash.su ... (1, 10) | -| jquery.js:23:5:23:8 | hash | jquery.js:23:5:23:18 | hash.substr(1) | -| jquery.js:24:5:24:8 | hash | jquery.js:24:5:24:17 | hash.slice(1) | -| jquery.js:27:5:27:8 | hash | jquery.js:27:5:27:25 | hash.re ... #', '') | -| jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | -| jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '' + ... '' | -| jquery.js:37:31:37:37 | tainted | jquery.js:37:25:37:37 | () => tainted | -| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:11:51:11:56 | locale | -| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:19:56:19:61 | locale | -| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:31:55:31:60 | locale | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | -| json-stringify.jsx:11:51:11:56 | locale | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | -| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | -| json-stringify.jsx:19:56:19:61 | locale | json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | -| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| jwt-server.js:7:9:7:35 | taint | jwt-server.js:9:16:9:20 | taint | -| jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint | -| jwt-server.js:9:16:9:20 | taint | jwt-server.js:9:55:9:61 | decoded | -| jwt-server.js:9:55:9:61 | decoded | jwt-server.js:11:19:11:25 | decoded | -| jwt-server.js:11:19:11:25 | decoded | jwt-server.js:11:19:11:29 | decoded.foo | -| jwt.js:4:36:4:39 | data | jwt.js:5:30:5:33 | data | -| jwt.js:5:9:5:34 | decoded | jwt.js:6:14:6:20 | decoded | -| jwt.js:5:19:5:34 | jwt_decode(data) | jwt.js:5:9:5:34 | decoded | -| jwt.js:5:30:5:33 | data | jwt.js:5:19:5:34 | jwt_decode(data) | -| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | -| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:6:18:6:23 | target | -| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:8:17:8:22 | target | -| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:15:9:15:14 | target | -| optionalSanitizer.js:2:16:2:39 | documen ... .search | optionalSanitizer.js:2:7:2:39 | target | -| optionalSanitizer.js:8:7:8:22 | tainted | optionalSanitizer.js:9:18:9:24 | tainted | -| optionalSanitizer.js:8:17:8:22 | target | optionalSanitizer.js:8:7:8:22 | tainted | -| optionalSanitizer.js:15:9:15:14 | target | optionalSanitizer.js:16:18:16:18 | x | -| optionalSanitizer.js:16:18:16:18 | x | optionalSanitizer.js:17:20:17:20 | x | -| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:31:18:31:23 | target | -| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:38:18:38:23 | target | -| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:45:41:45:46 | target | -| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:45:51:45:56 | target | -| optionalSanitizer.js:26:16:26:39 | documen ... .search | optionalSanitizer.js:26:7:26:39 | target | -| optionalSanitizer.js:28:24:28:24 | x | optionalSanitizer.js:29:12:29:12 | x | -| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:32:18:32:25 | tainted2 | -| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:34:28:34:35 | tainted2 | -| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 | -| optionalSanitizer.js:31:18:31:23 | target | optionalSanitizer.js:31:7:31:23 | tainted2 | -| optionalSanitizer.js:34:5:34:36 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 | -| optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | optionalSanitizer.js:34:5:34:36 | tainted2 | -| optionalSanitizer.js:34:28:34:35 | tainted2 | optionalSanitizer.js:28:24:28:24 | x | -| optionalSanitizer.js:34:28:34:35 | tainted2 | optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | -| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:39:18:39:25 | tainted3 | -| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:41:28:41:35 | tainted3 | -| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 | -| optionalSanitizer.js:38:18:38:23 | target | optionalSanitizer.js:38:7:38:23 | tainted3 | -| optionalSanitizer.js:41:5:41:36 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 | -| optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | optionalSanitizer.js:41:5:41:36 | tainted3 | -| optionalSanitizer.js:41:28:41:35 | tainted3 | optionalSanitizer.js:28:24:28:24 | x | -| optionalSanitizer.js:41:28:41:35 | tainted3 | optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | -| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| optionalSanitizer.js:45:41:45:46 | target | optionalSanitizer.js:28:24:28:24 | x | -| optionalSanitizer.js:45:41:45:46 | target | optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | -| optionalSanitizer.js:45:51:45:56 | target | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | -| pages/[id].jsx:3:30:3:35 | params [id] | pages/[id].jsx:13:44:13:49 | params [id] | -| pages/[id].jsx:3:30:3:35 | params [q] | pages/[id].jsx:16:44:16:49 | params [q] | -| pages/[id].jsx:5:9:5:14 | { id } | pages/[id].jsx:5:11:5:12 | id | -| pages/[id].jsx:5:9:5:29 | id | pages/[id].jsx:10:44:10:45 | id | -| pages/[id].jsx:5:11:5:12 | id | pages/[id].jsx:5:9:5:29 | id | -| pages/[id].jsx:5:18:5:29 | router.query | pages/[id].jsx:5:9:5:14 | { id } | -| pages/[id].jsx:13:44:13:49 | params [id] | pages/[id].jsx:13:44:13:52 | params.id | -| pages/[id].jsx:16:44:16:49 | params [q] | pages/[id].jsx:16:44:16:51 | params.q | -| pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | pages/[id].jsx:3:30:3:35 | params [id] | -| pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | pages/[id].jsx:3:30:3:35 | params [q] | -| pages/[id].jsx:25:11:25:24 | context.params | pages/[id].jsx:25:11:25:27 | context.params.id | -| pages/[id].jsx:25:11:25:27 | context.params.id | pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | -| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | -| pages/[id].jsx:26:10:26:22 | context.query | pages/[id].jsx:26:10:26:30 | context ... .foobar | -| pages/[id].jsx:26:10:26:30 | context ... .foobar | pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | -| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | -| react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted | -| react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted | -| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | -| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | -| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | -| react-use-router.js:23:31:23:36 | [post update] router | react-use-router.js:23:43:23:48 | router | -| react-use-router.js:23:43:23:48 | router | react-use-router.js:23:43:23:54 | router.query | -| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | -| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:31:23:36 | [post update] router | -| react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | -| react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | -| react-use-state.js:4:10:4:14 | state | react-use-state.js:4:9:4:49 | state | -| react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:10:4:14 | state | -| react-use-state.js:9:9:9:43 | state | react-use-state.js:11:51:11:55 | state | -| react-use-state.js:9:10:9:14 | state | react-use-state.js:9:9:9:43 | state | -| react-use-state.js:10:14:10:24 | window.name | react-use-state.js:9:10:9:14 | state | -| react-use-state.js:15:9:15:43 | state | react-use-state.js:17:51:17:55 | state | -| react-use-state.js:15:10:15:14 | state | react-use-state.js:15:9:15:43 | state | -| react-use-state.js:16:20:16:30 | window.name | react-use-state.js:15:10:15:14 | state | -| react-use-state.js:21:10:21:14 | state | react-use-state.js:22:14:22:17 | prev | -| react-use-state.js:22:14:22:17 | prev | react-use-state.js:23:35:23:38 | prev | -| react-use-state.js:25:20:25:30 | window.name | react-use-state.js:21:10:21:14 | state | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:23:29:23:35 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:25:29:25:35 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:28:29:28:35 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:30:29:30:35 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:33:29:33:35 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:35:29:35:35 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:38:29:38:35 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:45:29:45:35 | tainted | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:48:19:48:25 | tainted | -| sanitiser.js:16:17:16:27 | window.name | sanitiser.js:16:7:16:27 | tainted | -| sanitiser.js:23:29:23:35 | tainted | sanitiser.js:23:21:23:44 | '' + ... '' | -| sanitiser.js:25:29:25:35 | tainted | sanitiser.js:25:21:25:44 | '' + ... '' | -| sanitiser.js:28:29:28:35 | tainted | sanitiser.js:28:21:28:44 | '' + ... '' | -| sanitiser.js:30:29:30:35 | tainted | sanitiser.js:30:21:30:44 | '' + ... '' | -| sanitiser.js:33:29:33:35 | tainted | sanitiser.js:33:21:33:44 | '' + ... '' | -| sanitiser.js:35:29:35:35 | tainted | sanitiser.js:35:21:35:44 | '' + ... '' | -| sanitiser.js:38:29:38:35 | tainted | sanitiser.js:38:21:38:44 | '' + ... '' | -| sanitiser.js:45:29:45:35 | tainted | sanitiser.js:45:21:45:44 | '' + ... '' | -| sanitiser.js:48:19:48:25 | tainted | sanitiser.js:48:19:48:46 | tainted ... /g, '') | -| stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | -| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | -| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:10:16:10:44 | localSt ... local') | -| stored-xss.js:10:9:10:44 | href | stored-xss.js:12:35:12:38 | href | -| stored-xss.js:10:16:10:44 | localSt ... local') | stored-xss.js:10:9:10:44 | href | -| stored-xss.js:12:35:12:38 | href | stored-xss.js:12:20:12:54 | "" | -| string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | -| string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | -| string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | -| string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | -| string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | -| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | -| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | -| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | -| tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source | -| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:23:38:23:43 | source | -| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:23:38:23:43 | source | -| tooltip.jsx:22:20:22:30 | window.name | tooltip.jsx:22:11:22:30 | source | -| tooltip.jsx:22:20:22:30 | window.name | tooltip.jsx:22:11:22:30 | source | -| tooltip.jsx:22:20:22:30 | window.name | tooltip.jsx:22:11:22:30 | source | -| tooltip.jsx:22:20:22:30 | window.name | tooltip.jsx:22:11:22:30 | source | -| tooltip.jsx:23:38:23:43 | source | tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:23:38:23:43 | source | tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:23:38:23:43 | source | tooltip.jsx:18:51:18:59 | provide() | -| tooltip.jsx:23:38:23:43 | source | tooltip.jsx:18:51:18:59 | provide() | -| translate.js:6:7:6:39 | target | translate.js:7:42:7:47 | target | -| translate.js:6:16:6:39 | documen ... .search | translate.js:6:7:6:39 | target | -| translate.js:7:7:7:61 | searchParams | translate.js:9:27:9:38 | searchParams | -| translate.js:7:22:7:61 | new URL ... ing(1)) | translate.js:7:7:7:61 | searchParams | -| translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | -| translate.js:7:42:7:60 | target.substring(1) | translate.js:7:22:7:61 | new URL ... ing(1)) | -| translate.js:9:27:9:38 | searchParams | translate.js:9:27:9:50 | searchP ... 'term') | -| trusted-types-lib.js:1:28:1:28 | x | trusted-types-lib.js:2:12:2:12 | x | -| trusted-types.js:3:62:3:62 | x | trusted-types.js:3:67:3:67 | x | -| trusted-types.js:4:20:4:30 | window.name | trusted-types.js:3:62:3:62 | x | -| trusted-types.js:13:20:13:30 | window.name | trusted-types-lib.js:1:28:1:28 | x | -| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:4:25:4:28 | data | -| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:5:26:5:29 | data | -| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:7:32:7:35 | data | -| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:9:37:9:40 | data | -| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:10:38:10:41 | data | -| tst3.js:2:23:2:74 | decodeU ... str(1)) | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | -| tst3.js:2:42:2:63 | window. ... .search | tst3.js:2:42:2:73 | window. ... bstr(1) | -| tst3.js:2:42:2:73 | window. ... bstr(1) | tst3.js:2:23:2:74 | decodeU ... str(1)) | -| tst3.js:4:25:4:28 | data | tst3.js:4:25:4:32 | data.src | -| tst3.js:5:26:5:29 | data | tst3.js:5:26:5:31 | data.p | -| tst3.js:7:32:7:35 | data | tst3.js:7:32:7:37 | data.p | -| tst3.js:9:37:9:40 | data | tst3.js:9:37:9:42 | data.p | -| tst3.js:10:38:10:41 | data | tst3.js:10:38:10:43 | data.p | -| tst.js:2:7:2:39 | target | tst.js:5:18:5:23 | target | -| tst.js:2:7:2:39 | target | tst.js:12:28:12:33 | target | -| tst.js:2:7:2:39 | target | tst.js:20:42:20:47 | target | -| tst.js:2:16:2:39 | documen ... .search | tst.js:2:7:2:39 | target | -| tst.js:8:37:8:58 | documen ... on.href | tst.js:8:37:8:114 | documen ... t=")+8) | -| tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:126 | "" | -| tst.js:12:28:12:33 | target | tst.js:12:5:12:42 | '
' | -| tst.js:17:7:17:56 | params | tst.js:18:18:18:23 | params | -| tst.js:17:16:17:43 | (new UR ... ation)) [searchParams] | tst.js:17:16:17:56 | (new UR ... hParams | -| tst.js:17:16:17:56 | (new UR ... hParams | tst.js:17:7:17:56 | params | -| tst.js:17:17:17:42 | new URL ... cation) [searchParams] | tst.js:17:16:17:43 | (new UR ... ation)) [searchParams] | -| tst.js:17:25:17:41 | document.location | tst.js:17:17:17:42 | new URL ... cation) [searchParams] | -| tst.js:18:18:18:23 | params | tst.js:18:18:18:35 | params.get('name') | -| tst.js:20:7:20:61 | searchParams | tst.js:21:18:21:29 | searchParams | -| tst.js:20:22:20:61 | new URL ... ing(1)) | tst.js:20:7:20:61 | searchParams | -| tst.js:20:42:20:47 | target | tst.js:20:42:20:60 | target.substring(1) | -| tst.js:20:42:20:60 | target.substring(1) | tst.js:20:22:20:61 | new URL ... ing(1)) | -| tst.js:21:18:21:29 | searchParams | tst.js:21:18:21:41 | searchP ... 'name') | -| tst.js:24:14:24:19 | target | tst.js:26:18:26:23 | target | -| tst.js:28:5:28:28 | documen ... .search | tst.js:24:14:24:19 | target | -| tst.js:31:10:31:33 | documen ... .search | tst.js:34:16:34:20 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:58:26:58:30 | bar() | -| tst.js:31:10:31:33 | documen ... .search | tst.js:68:16:68:20 | bar() | -| tst.js:36:14:36:14 | x | tst.js:37:10:37:10 | x | -| tst.js:40:20:40:43 | documen ... .search | tst.js:36:14:36:14 | x | -| tst.js:40:20:40:43 | documen ... .search | tst.js:40:16:40:44 | baz(doc ... search) | -| tst.js:42:15:42:15 | s | tst.js:43:20:43:20 | s | -| tst.js:43:20:43:20 | s | tst.js:43:10:43:31 | "
" ...
" | -| tst.js:46:21:46:44 | documen ... .search | tst.js:42:15:42:15 | s | -| tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | -| tst.js:48:15:48:15 | s | tst.js:50:12:50:12 | s | -| tst.js:50:12:50:12 | s | tst.js:50:12:50:22 | s.substr(1) | -| tst.js:54:21:54:44 | documen ... .search | tst.js:48:15:48:15 | s | -| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | -| tst.js:56:21:56:44 | documen ... .search | tst.js:48:15:48:15 | s | -| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | -| tst.js:58:21:58:31 | chop(bar()) | tst.js:42:15:42:15 | s | -| tst.js:58:21:58:31 | chop(bar()) | tst.js:58:16:58:32 | wrap(chop(bar())) | -| tst.js:58:26:58:30 | bar() | tst.js:48:15:48:15 | s | -| tst.js:58:26:58:30 | bar() | tst.js:58:21:58:31 | chop(bar()) | -| tst.js:60:34:60:34 | s | tst.js:62:18:62:18 | s | -| tst.js:64:25:64:48 | documen ... .search | tst.js:60:34:60:34 | s | -| tst.js:65:25:65:48 | documen ... .search | tst.js:60:34:60:34 | s | -| tst.js:70:1:70:27 | [,docum ... search] | tst.js:70:46:70:46 | x | -| tst.js:70:1:70:27 | [,docum ... search] [1] | tst.js:70:46:70:46 | x | -| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] | -| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] [1] | -| tst.js:70:46:70:46 | x | tst.js:73:20:73:20 | x | -| tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | -| tst.js:107:7:107:44 | v | tst.js:136:18:136:18 | v | -| tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | -| tst.js:107:11:107:44 | documen ... bstr(1) | tst.js:107:7:107:44 | v | -| tst.js:148:29:148:50 | window. ... .search | tst.js:151:29:151:29 | v | -| tst.js:151:29:151:29 | v | tst.js:151:49:151:49 | v | -| tst.js:158:40:158:61 | window. ... .search | tst.js:155:29:155:46 | xssSourceService() | -| tst.js:177:9:177:41 | target | tst.js:180:28:180:33 | target | -| tst.js:177:18:177:41 | documen ... .search | tst.js:177:9:177:41 | target | -| tst.js:184:9:184:42 | tainted | tst.js:186:31:186:37 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:188:42:188:48 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:189:33:189:39 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:191:54:191:60 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:192:45:192:51 | tainted | -| tst.js:184:9:184:42 | tainted | tst.js:193:49:193:55 | tainted | -| tst.js:184:19:184:42 | documen ... .search | tst.js:184:9:184:42 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:199:67:199:73 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:200:67:200:73 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:204:35:204:41 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:206:46:206:52 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:207:38:207:44 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:208:35:208:41 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:236:35:236:41 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:238:20:238:26 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:240:23:240:29 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:241:23:241:29 | tainted | -| tst.js:197:9:197:42 | tainted | tst.js:255:23:255:29 | tainted | -| tst.js:197:19:197:42 | documen ... .search | tst.js:197:9:197:42 | tainted | -| tst.js:204:35:204:41 | tainted | tst.js:212:28:212:46 | this.state.tainted1 | -| tst.js:206:46:206:52 | tainted | tst.js:213:28:213:46 | this.state.tainted2 | -| tst.js:207:38:207:44 | tainted | tst.js:214:28:214:46 | this.state.tainted3 | -| tst.js:208:35:208:41 | tainted | tst.js:218:32:218:49 | prevState.tainted4 | -| tst.js:236:35:236:41 | tainted | tst.js:225:28:225:46 | this.props.tainted1 | -| tst.js:238:20:238:26 | tainted | tst.js:226:28:226:46 | this.props.tainted2 | -| tst.js:240:23:240:29 | tainted | tst.js:227:28:227:46 | this.props.tainted3 | -| tst.js:241:23:241:29 | tainted | tst.js:231:32:231:49 | prevProps.tainted4 | -| tst.js:247:39:247:55 | props.propTainted | tst.js:251:60:251:82 | this.st ... Tainted | -| tst.js:255:23:255:29 | tainted | tst.js:247:39:247:55 | props.propTainted | -| tst.js:285:9:285:29 | tainted | tst.js:288:59:288:65 | tainted | -| tst.js:285:19:285:29 | window.name | tst.js:285:9:285:29 | tainted | -| tst.js:301:9:301:16 | location | tst.js:302:10:302:10 | e | -| tst.js:302:10:302:10 | e | tst.js:303:20:303:20 | e | -| tst.js:308:10:308:17 | location | tst.js:310:10:310:10 | e | -| tst.js:310:10:310:10 | e | tst.js:311:20:311:20 | e | -| tst.js:327:10:327:35 | new URL ... cation) [searchParams] | tst.js:331:16:331:30 | getTaintedUrl() [searchParams] | -| tst.js:327:18:327:34 | document.location | tst.js:327:10:327:35 | new URL ... cation) [searchParams] | -| tst.js:331:7:331:43 | params | tst.js:332:18:332:23 | params | -| tst.js:331:16:331:30 | getTaintedUrl() [searchParams] | tst.js:331:16:331:43 | getTain ... hParams | -| tst.js:331:16:331:43 | getTain ... hParams | tst.js:331:7:331:43 | params | -| tst.js:332:18:332:23 | params | tst.js:332:18:332:35 | params.get('name') | -| tst.js:341:12:341:37 | new URL ... cation) [hash] | tst.js:343:5:343:12 | getUrl() [hash] | -| tst.js:341:20:341:36 | document.location | tst.js:341:12:341:37 | new URL ... cation) [hash] | -| tst.js:343:5:343:12 | getUrl() [hash] | tst.js:343:5:343:17 | getUrl().hash | -| tst.js:343:5:343:17 | getUrl().hash | tst.js:343:5:343:30 | getUrl( ... ring(1) | -| tst.js:348:7:348:39 | target | tst.js:349:12:349:17 | target | -| tst.js:348:16:348:39 | documen ... .search | tst.js:348:7:348:39 | target | -| tst.js:355:10:355:42 | target | tst.js:356:16:356:21 | target | -| tst.js:355:10:355:42 | target | tst.js:360:21:360:26 | target | -| tst.js:355:10:355:42 | target | tst.js:363:18:363:23 | target | -| tst.js:355:19:355:42 | documen ... .search | tst.js:355:10:355:42 | target | -| tst.js:371:7:371:39 | target | tst.js:374:18:374:23 | target | -| tst.js:371:16:371:39 | documen ... .search | tst.js:371:7:371:39 | target | -| tst.js:381:7:381:39 | target | tst.js:384:18:384:23 | target | -| tst.js:381:7:381:39 | target | tst.js:386:18:386:23 | target | -| tst.js:381:7:381:39 | target | tst.js:397:18:397:23 | target | -| tst.js:381:7:381:39 | target | tst.js:406:18:406:23 | target | -| tst.js:381:7:381:39 | target | tst.js:408:19:408:24 | target | -| tst.js:381:7:381:39 | target [taint3] | tst.js:392:18:392:23 | target [taint3] | -| tst.js:381:7:381:39 | target [taint8] | tst.js:408:19:408:24 | target [taint8] | -| tst.js:381:7:381:39 | target [taint8] | tst.js:409:18:409:23 | target [taint8] | -| tst.js:381:16:381:39 | documen ... .search | tst.js:381:7:381:39 | target | -| tst.js:386:18:386:23 | target | tst.js:386:18:386:29 | target.taint | -| tst.js:391:3:391:8 | [post update] target [taint3] | tst.js:381:7:381:39 | target [taint3] | -| tst.js:391:19:391:42 | documen ... .search | tst.js:391:3:391:8 | [post update] target [taint3] | -| tst.js:392:18:392:23 | target [taint3] | tst.js:392:18:392:30 | target.taint3 | -| tst.js:397:18:397:23 | target | tst.js:397:18:397:30 | target.taint5 | -| tst.js:406:18:406:23 | target | tst.js:406:18:406:30 | target.taint7 | -| tst.js:408:3:408:8 | [post update] target [taint8] | tst.js:381:7:381:39 | target [taint8] | -| tst.js:408:19:408:24 | target | tst.js:408:19:408:31 | target.taint8 | -| tst.js:408:19:408:24 | target [taint8] | tst.js:408:19:408:31 | target.taint8 | -| tst.js:408:19:408:31 | target.taint8 | tst.js:408:3:408:8 | [post update] target [taint8] | -| tst.js:409:18:409:23 | target [taint8] | tst.js:409:18:409:30 | target.taint8 | -| tst.js:416:7:416:46 | payload | tst.js:417:18:417:24 | payload | -| tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | -| tst.js:416:17:416:46 | window. ... bstr(1) | tst.js:416:7:416:46 | payload | -| tst.js:419:7:419:55 | match | tst.js:421:20:421:24 | match | -| tst.js:419:15:419:34 | window.location.hash | tst.js:419:15:419:55 | window. ... (\\w+)/) | -| tst.js:419:15:419:55 | window. ... (\\w+)/) | tst.js:419:7:419:55 | match | -| tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | -| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | -| tst.js:428:7:428:39 | target | tst.js:430:18:430:23 | target | -| tst.js:428:16:428:39 | documen ... .search | tst.js:428:7:428:39 | target | -| tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | -| tst.js:436:6:436:38 | source | tst.js:440:28:440:33 | source | -| tst.js:436:6:436:38 | source | tst.js:441:33:441:38 | source | -| tst.js:436:6:436:38 | source | tst.js:442:34:442:39 | source | -| tst.js:436:6:436:38 | source | tst.js:443:41:443:46 | source | -| tst.js:436:6:436:38 | source | tst.js:444:44:444:49 | source | -| tst.js:436:6:436:38 | source | tst.js:445:32:445:37 | source | -| tst.js:436:15:436:38 | documen ... .search | tst.js:436:6:436:38 | source | -| tst.js:453:7:453:39 | source | tst.js:455:18:455:23 | source | -| tst.js:453:7:453:39 | source | tst.js:456:36:456:41 | source | -| tst.js:453:16:453:39 | documen ... .search | tst.js:453:7:453:39 | source | -| tst.js:456:36:456:41 | source | tst.js:456:18:456:42 | ansiToH ... source) | -| tst.js:460:6:460:38 | source | tst.js:463:21:463:26 | source | -| tst.js:460:6:460:38 | source | tst.js:465:19:465:24 | source | -| tst.js:460:6:460:38 | source | tst.js:467:20:467:25 | source | -| tst.js:460:15:460:38 | documen ... .search | tst.js:460:6:460:38 | source | -| tst.js:471:7:471:46 | url | tst.js:473:19:473:21 | url | -| tst.js:471:7:471:46 | url | tst.js:474:26:474:28 | url | -| tst.js:471:7:471:46 | url | tst.js:475:25:475:27 | url | -| tst.js:471:7:471:46 | url | tst.js:476:20:476:22 | url | -| tst.js:471:7:471:46 | url | tst.js:486:22:486:24 | url | -| tst.js:471:13:471:36 | documen ... .search | tst.js:471:13:471:46 | documen ... bstr(1) | -| tst.js:471:13:471:46 | documen ... bstr(1) | tst.js:471:7:471:46 | url | -| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | -| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | -| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | -| typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | -| typeahead.js:20:13:20:45 | target | typeahead.js:21:12:21:17 | target | -| typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target | -| typeahead.js:21:12:21:17 | target | typeahead.js:24:30:24:32 | val | -| typeahead.js:24:30:24:32 | val | typeahead.js:25:18:25:20 | val | -| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:4:14:4:20 | tainted | -| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:5:12:5:18 | tainted | -| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:6:19:6:25 | tainted | -| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:7:14:7:20 | tainted | -| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:9:19:9:25 | tainted | -| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:10:16:10:22 | tainted | -| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:11:24:11:30 | tainted | -| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:12:19:12:25 | tainted | -| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:2:6:2:39 | tainted | -| various-concat-obfuscations.js:4:14:4:20 | tainted | various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | -| various-concat-obfuscations.js:5:12:5:18 | tainted | various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | -| various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | -| various-concat-obfuscations.js:6:19:6:25 | tainted | various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | -| various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | -| various-concat-obfuscations.js:7:14:7:20 | tainted | various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | -| various-concat-obfuscations.js:9:19:9:25 | tainted | various-concat-obfuscations.js:9:4:9:34 | "
" | -| various-concat-obfuscations.js:10:16:10:22 | tainted | various-concat-obfuscations.js:10:4:10:27 | `
` | -| various-concat-obfuscations.js:11:4:11:31 | "
") | -| various-concat-obfuscations.js:11:24:11:30 | tainted | various-concat-obfuscations.js:11:4:11:31 | "
"] | various-concat-obfuscations.js:12:4:12:41 | ["
"] | -| various-concat-obfuscations.js:14:24:14:28 | attrs | various-concat-obfuscations.js:15:28:15:32 | attrs | -| various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | various-concat-obfuscations.js:15:10:15:83 | '
' | -| various-concat-obfuscations.js:15:28:15:32 | attrs | various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | -| various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | -| various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:32:18:36 | attrs | -| various-concat-obfuscations.js:18:10:18:59 | '
') | -| various-concat-obfuscations.js:18:10:18:88 | '
') | -| various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | -| various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | -| various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | various-concat-obfuscations.js:18:10:18:59 | '
` | provenance | | +| classnames.js:7:58:7:68 | window.name | classnames.js:7:47:7:69 | classNa ... w.name) | provenance | | +| classnames.js:8:47:8:70 | classNa ... w.name) | classnames.js:8:31:8:85 | `` | provenance | | +| classnames.js:8:59:8:69 | window.name | classnames.js:8:47:8:70 | classNa ... w.name) | provenance | | +| classnames.js:9:47:9:70 | classNa ... w.name) | classnames.js:9:31:9:85 | `` | provenance | | +| classnames.js:9:59:9:69 | window.name | classnames.js:9:47:9:70 | classNa ... w.name) | provenance | | +| classnames.js:10:45:10:55 | window.name | classnames.js:11:47:11:64 | unsafeStyle('foo') | provenance | | +| classnames.js:11:47:11:64 | unsafeStyle('foo') | classnames.js:11:31:11:79 | `` | provenance | | +| classnames.js:13:47:13:68 | safeSty ... w.name) | classnames.js:13:31:13:83 | `` | provenance | | +| classnames.js:13:57:13:67 | window.name | classnames.js:13:47:13:68 | safeSty ... w.name) | provenance | | +| classnames.js:15:47:15:63 | clsx(window.name) | classnames.js:15:31:15:78 | `` | provenance | | +| classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) | provenance | | +| classnames.js:17:48:17:64 | clsx(window.name) | classnames.js:17:32:17:79 | `` | provenance | | +| classnames.js:17:53:17:63 | window.name | classnames.js:17:48:17:64 | clsx(window.name) | provenance | | +| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | provenance | | +| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html | provenance | | +| clipboard.ts:43:15:43:55 | html | clipboard.ts:50:29:50:32 | html | provenance | | +| clipboard.ts:43:22:43:55 | clipboa ... /html') | clipboard.ts:43:15:43:55 | html | provenance | | +| clipboard.ts:71:13:71:62 | droppedHtml | clipboard.ts:73:29:73:39 | droppedHtml | provenance | | +| clipboard.ts:71:27:71:62 | e.clipb ... /html') | clipboard.ts:71:13:71:62 | droppedHtml | provenance | | +| clipboard.ts:98:15:98:54 | html | clipboard.ts:99:23:99:26 | html | provenance | | +| clipboard.ts:98:22:98:54 | dataTra ... /html') | clipboard.ts:98:15:98:54 | html | provenance | | +| d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | provenance | | +| d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | provenance | | +| d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | provenance | | +| d3.js:4:12:4:22 | window.name | d3.js:21:15:21:24 | getTaint() | provenance | | +| dates.js:9:9:9:69 | taint | dates.js:11:63:11:67 | taint | provenance | | +| dates.js:9:9:9:69 | taint | dates.js:12:66:12:70 | taint | provenance | | +| dates.js:9:9:9:69 | taint | dates.js:13:59:13:63 | taint | provenance | | +| dates.js:9:9:9:69 | taint | dates.js:16:62:16:66 | taint | provenance | | +| dates.js:9:9:9:69 | taint | dates.js:18:59:18:63 | taint | provenance | | +| dates.js:9:9:9:69 | taint | dates.js:21:61:21:65 | taint | provenance | | +| dates.js:9:17:9:69 | decodeU ... ing(1)) | dates.js:9:9:9:69 | taint | provenance | | +| dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | provenance | | +| dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | provenance | Config | +| dates.js:9:36:9:68 | window. ... ring(1) | dates.js:9:17:9:69 | decodeU ... ing(1)) | provenance | | +| dates.js:9:36:9:68 | window. ... ring(1) | dates.js:9:17:9:69 | decodeU ... ing(1)) | provenance | Config | +| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | provenance | | +| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | provenance | Config | +| dates.js:11:63:11:67 | taint | dates.js:11:42:11:68 | dateFns ... taint) | provenance | | +| dates.js:11:63:11:67 | taint | dates.js:11:42:11:68 | dateFns ... taint) | provenance | Config | +| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | provenance | | +| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | provenance | Config | +| dates.js:12:66:12:70 | taint | dates.js:12:42:12:71 | dateFns ... taint) | provenance | | +| dates.js:12:66:12:70 | taint | dates.js:12:42:12:71 | dateFns ... taint) | provenance | Config | +| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | provenance | | +| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | provenance | Config | +| dates.js:13:59:13:63 | taint | dates.js:13:42:13:70 | dateFns ... )(time) | provenance | | +| dates.js:13:59:13:63 | taint | dates.js:13:42:13:70 | dateFns ... )(time) | provenance | Config | +| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | provenance | | +| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | provenance | Config | +| dates.js:16:62:16:66 | taint | dates.js:16:42:16:67 | moment( ... (taint) | provenance | | +| dates.js:16:62:16:66 | taint | dates.js:16:42:16:67 | moment( ... (taint) | provenance | Config | +| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | provenance | | +| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | provenance | Config | +| dates.js:18:59:18:63 | taint | dates.js:18:42:18:64 | datefor ... taint) | provenance | | +| dates.js:18:59:18:63 | taint | dates.js:18:42:18:64 | datefor ... taint) | provenance | Config | +| dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | provenance | | +| dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | provenance | Config | +| dates.js:21:61:21:65 | taint | dates.js:21:42:21:66 | dayjs(t ... (taint) | provenance | | +| dates.js:21:61:21:65 | taint | dates.js:21:42:21:66 | dayjs(t ... (taint) | provenance | Config | +| dates.js:30:9:30:69 | taint | dates.js:37:77:37:81 | taint | provenance | | +| dates.js:30:9:30:69 | taint | dates.js:38:77:38:81 | taint | provenance | | +| dates.js:30:9:30:69 | taint | dates.js:39:79:39:83 | taint | provenance | | +| dates.js:30:9:30:69 | taint | dates.js:40:77:40:81 | taint | provenance | | +| dates.js:30:17:30:69 | decodeU ... ing(1)) | dates.js:30:9:30:69 | taint | provenance | | +| dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | provenance | | +| dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | provenance | Config | +| dates.js:30:36:30:68 | window. ... ring(1) | dates.js:30:17:30:69 | decodeU ... ing(1)) | provenance | | +| dates.js:30:36:30:68 | window. ... ring(1) | dates.js:30:17:30:69 | decodeU ... ing(1)) | provenance | Config | +| dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | provenance | | +| dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | provenance | Config | +| dates.js:37:77:37:81 | taint | dates.js:37:42:37:82 | dateFns ... taint) | provenance | | +| dates.js:37:77:37:81 | taint | dates.js:37:42:37:82 | dateFns ... taint) | provenance | Config | +| dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | provenance | | +| dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | provenance | Config | +| dates.js:38:77:38:81 | taint | dates.js:38:42:38:82 | luxon.f ... taint) | provenance | | +| dates.js:38:77:38:81 | taint | dates.js:38:42:38:82 | luxon.f ... taint) | provenance | Config | +| dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | provenance | | +| dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | provenance | Config | +| dates.js:39:79:39:83 | taint | dates.js:39:42:39:84 | moment. ... taint) | provenance | | +| dates.js:39:79:39:83 | taint | dates.js:39:42:39:84 | moment. ... taint) | provenance | Config | +| dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | provenance | | +| dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | provenance | Config | +| dates.js:40:77:40:81 | taint | dates.js:40:42:40:82 | dayjs.f ... taint) | provenance | | +| dates.js:40:77:40:81 | taint | dates.js:40:42:40:82 | dayjs.f ... taint) | provenance | Config | +| dates.js:46:9:46:69 | taint | dates.js:48:83:48:87 | taint | provenance | | +| dates.js:46:9:46:69 | taint | dates.js:49:82:49:86 | taint | provenance | | +| dates.js:46:9:46:69 | taint | dates.js:50:97:50:101 | taint | provenance | | +| dates.js:46:17:46:69 | decodeU ... ing(1)) | dates.js:46:9:46:69 | taint | provenance | | +| dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | provenance | | +| dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | provenance | Config | +| dates.js:46:36:46:68 | window. ... ring(1) | dates.js:46:17:46:69 | decodeU ... ing(1)) | provenance | | +| dates.js:46:36:46:68 | window. ... ring(1) | dates.js:46:17:46:69 | decodeU ... ing(1)) | provenance | Config | +| dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | provenance | | +| dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | provenance | Config | +| dates.js:48:83:48:87 | taint | dates.js:48:42:48:88 | DateTim ... (taint) | provenance | | +| dates.js:48:83:48:87 | taint | dates.js:48:42:48:88 | DateTim ... (taint) | provenance | Config | +| dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | provenance | | +| dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | provenance | Config | +| dates.js:49:82:49:86 | taint | dates.js:49:42:49:87 | new Dat ... (taint) | provenance | | +| dates.js:49:82:49:86 | taint | dates.js:49:42:49:87 | new Dat ... (taint) | provenance | Config | +| dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | provenance | | +| dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | provenance | Config | +| dates.js:50:97:50:101 | taint | dates.js:50:42:50:102 | DateTim ... (taint) | provenance | | +| dates.js:50:97:50:101 | taint | dates.js:50:42:50:102 | DateTim ... (taint) | provenance | Config | +| dates.js:54:9:54:69 | taint | dates.js:57:94:57:98 | taint | provenance | | +| dates.js:54:9:54:69 | taint | dates.js:59:80:59:84 | taint | provenance | | +| dates.js:54:9:54:69 | taint | dates.js:61:81:61:85 | taint | provenance | | +| dates.js:54:17:54:69 | decodeU ... ing(1)) | dates.js:54:9:54:69 | taint | provenance | | +| dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | provenance | | +| dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | provenance | Config | +| dates.js:54:36:54:68 | window. ... ring(1) | dates.js:54:17:54:69 | decodeU ... ing(1)) | provenance | | +| dates.js:54:36:54:68 | window. ... ring(1) | dates.js:54:17:54:69 | decodeU ... ing(1)) | provenance | Config | +| dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | provenance | | +| dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | provenance | Config | +| dates.js:57:94:57:98 | taint | dates.js:57:42:57:99 | moment. ... (taint) | provenance | | +| dates.js:57:94:57:98 | taint | dates.js:57:42:57:99 | moment. ... (taint) | provenance | Config | +| dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | provenance | | +| dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | provenance | Config | +| dates.js:59:80:59:84 | taint | dates.js:59:42:59:85 | luxon.e ... (taint) | provenance | | +| dates.js:59:80:59:84 | taint | dates.js:59:42:59:85 | luxon.e ... (taint) | provenance | Config | +| dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | provenance | | +| dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | provenance | Config | +| dates.js:61:81:61:85 | taint | dates.js:61:42:61:86 | dayjs.s ... (taint) | provenance | | +| dates.js:61:81:61:85 | taint | dates.js:61:42:61:86 | dayjs.s ... (taint) | provenance | Config | +| dragAndDrop.ts:8:11:8:50 | html | dragAndDrop.ts:15:25:15:28 | html | provenance | | +| dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | dragAndDrop.ts:8:11:8:50 | html | provenance | | +| dragAndDrop.ts:43:15:43:54 | html | dragAndDrop.ts:50:29:50:32 | html | provenance | | +| dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | dragAndDrop.ts:43:15:43:54 | html | provenance | | +| dragAndDrop.ts:71:13:71:61 | droppedHtml | dragAndDrop.ts:73:29:73:39 | droppedHtml | provenance | | +| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | provenance | | +| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | provenance | | +| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | provenance | Config | +| jquery.js:2:7:2:40 | tainted | jquery.js:7:20:7:26 | tainted | provenance | | +| jquery.js:2:7:2:40 | tainted | jquery.js:8:28:8:34 | tainted | provenance | | +| jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | provenance | | +| jquery.js:2:7:2:40 | tainted | jquery.js:37:31:37:37 | tainted | provenance | | +| jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | provenance | | +| jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "
" | provenance | Config | +| jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | provenance | | +| jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | provenance | Config | +| jquery.js:10:13:10:20 | location | jquery.js:10:13:10:31 | location.toString() | provenance | | +| jquery.js:10:13:10:20 | location | jquery.js:10:13:10:31 | location.toString() | provenance | Config | +| jquery.js:10:13:10:31 | location.toString() | jquery.js:10:5:10:40 | "" + ... "" | provenance | Config | +| jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | provenance | | +| jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | provenance | Config | +| jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | provenance | | +| jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | provenance | Config | +| jquery.js:16:38:16:52 | window.location | jquery.js:16:38:16:63 | window. ... tring() | provenance | | +| jquery.js:16:38:16:52 | window.location | jquery.js:16:38:16:63 | window. ... tring() | provenance | Config | +| jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) | provenance | | +| jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) | provenance | Config | +| jquery.js:18:7:18:33 | hash | jquery.js:21:5:21:8 | hash | provenance | | +| jquery.js:18:7:18:33 | hash | jquery.js:22:5:22:8 | hash | provenance | | +| jquery.js:18:7:18:33 | hash | jquery.js:23:5:23:8 | hash | provenance | | +| jquery.js:18:7:18:33 | hash | jquery.js:24:5:24:8 | hash | provenance | | +| jquery.js:18:7:18:33 | hash | jquery.js:27:5:27:8 | hash | provenance | | +| jquery.js:18:7:18:33 | hash | jquery.js:34:13:34:16 | hash | provenance | | +| jquery.js:18:14:18:33 | window.location.hash | jquery.js:18:7:18:33 | hash | provenance | | +| jquery.js:21:5:21:8 | hash | jquery.js:21:5:21:21 | hash.substring(1) | provenance | Config | +| jquery.js:22:5:22:8 | hash | jquery.js:22:5:22:25 | hash.su ... (1, 10) | provenance | Config | +| jquery.js:23:5:23:8 | hash | jquery.js:23:5:23:18 | hash.substr(1) | provenance | Config | +| jquery.js:24:5:24:8 | hash | jquery.js:24:5:24:17 | hash.slice(1) | provenance | Config | +| jquery.js:27:5:27:8 | hash | jquery.js:27:5:27:25 | hash.re ... #', '') | provenance | Config | +| jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | provenance | Config | +| jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '' + ... '' | provenance | Config | +| jquery.js:37:31:37:37 | tainted | jquery.js:37:25:37:37 | () => tainted | provenance | Config | +| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:11:51:11:56 | locale | provenance | | +| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:19:56:19:61 | locale | provenance | | +| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:31:55:31:60 | locale | provenance | | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | provenance | | +| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | provenance | | +| json-stringify.jsx:11:51:11:56 | locale | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | provenance | | +| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | provenance | | +| json-stringify.jsx:19:56:19:61 | locale | json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | provenance | | +| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | provenance | | +| jwt-server.js:7:9:7:35 | taint | jwt-server.js:9:16:9:20 | taint | provenance | | +| jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint | provenance | | +| jwt-server.js:9:16:9:20 | taint | jwt-server.js:9:55:9:61 | decoded | provenance | | +| jwt-server.js:9:55:9:61 | decoded | jwt-server.js:11:19:11:25 | decoded | provenance | | +| jwt-server.js:11:19:11:25 | decoded | jwt-server.js:11:19:11:29 | decoded.foo | provenance | | +| jwt.js:4:36:4:39 | data | jwt.js:5:30:5:33 | data | provenance | | +| jwt.js:5:9:5:34 | decoded | jwt.js:6:14:6:20 | decoded | provenance | | +| jwt.js:5:19:5:34 | jwt_decode(data) | jwt.js:5:9:5:34 | decoded | provenance | | +| jwt.js:5:30:5:33 | data | jwt.js:5:19:5:34 | jwt_decode(data) | provenance | | +| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | provenance | | +| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:6:18:6:23 | target | provenance | | +| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:8:17:8:22 | target | provenance | | +| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:15:9:15:14 | target | provenance | | +| optionalSanitizer.js:2:16:2:39 | documen ... .search | optionalSanitizer.js:2:7:2:39 | target | provenance | | +| optionalSanitizer.js:8:7:8:22 | tainted | optionalSanitizer.js:9:18:9:24 | tainted | provenance | | +| optionalSanitizer.js:8:17:8:22 | target | optionalSanitizer.js:8:7:8:22 | tainted | provenance | | +| optionalSanitizer.js:15:9:15:14 | target | optionalSanitizer.js:16:18:16:18 | x | provenance | | +| optionalSanitizer.js:16:18:16:18 | x | optionalSanitizer.js:17:20:17:20 | x | provenance | | +| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:31:18:31:23 | target | provenance | | +| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:38:18:38:23 | target | provenance | | +| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:45:41:45:46 | target | provenance | | +| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:45:51:45:56 | target | provenance | | +| optionalSanitizer.js:26:16:26:39 | documen ... .search | optionalSanitizer.js:26:7:26:39 | target | provenance | | +| optionalSanitizer.js:28:24:28:24 | x | optionalSanitizer.js:29:12:29:12 | x | provenance | | +| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:32:18:32:25 | tainted2 | provenance | | +| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:34:28:34:35 | tainted2 | provenance | | +| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 | provenance | | +| optionalSanitizer.js:31:18:31:23 | target | optionalSanitizer.js:31:7:31:23 | tainted2 | provenance | | +| optionalSanitizer.js:34:5:34:36 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 | provenance | | +| optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | optionalSanitizer.js:34:5:34:36 | tainted2 | provenance | | +| optionalSanitizer.js:34:28:34:35 | tainted2 | optionalSanitizer.js:28:24:28:24 | x | provenance | | +| optionalSanitizer.js:34:28:34:35 | tainted2 | optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | provenance | | +| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:39:18:39:25 | tainted3 | provenance | | +| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:41:28:41:35 | tainted3 | provenance | | +| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 | provenance | | +| optionalSanitizer.js:38:18:38:23 | target | optionalSanitizer.js:38:7:38:23 | tainted3 | provenance | | +| optionalSanitizer.js:41:5:41:36 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 | provenance | | +| optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | optionalSanitizer.js:41:5:41:36 | tainted3 | provenance | | +| optionalSanitizer.js:41:28:41:35 | tainted3 | optionalSanitizer.js:28:24:28:24 | x | provenance | | +| optionalSanitizer.js:41:28:41:35 | tainted3 | optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | provenance | | +| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | provenance | | +| optionalSanitizer.js:45:41:45:46 | target | optionalSanitizer.js:28:24:28:24 | x | provenance | | +| optionalSanitizer.js:45:41:45:46 | target | optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | provenance | | +| optionalSanitizer.js:45:51:45:56 | target | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | provenance | | +| pages/[id].jsx:3:30:3:35 | params [id] | pages/[id].jsx:13:44:13:49 | params [id] | provenance | | +| pages/[id].jsx:3:30:3:35 | params [q] | pages/[id].jsx:16:44:16:49 | params [q] | provenance | | +| pages/[id].jsx:5:9:5:14 | { id } | pages/[id].jsx:5:11:5:12 | id | provenance | | +| pages/[id].jsx:5:9:5:29 | id | pages/[id].jsx:10:44:10:45 | id | provenance | | +| pages/[id].jsx:5:11:5:12 | id | pages/[id].jsx:5:9:5:29 | id | provenance | | +| pages/[id].jsx:5:18:5:29 | router.query | pages/[id].jsx:5:9:5:14 | { id } | provenance | | +| pages/[id].jsx:13:44:13:49 | params [id] | pages/[id].jsx:13:44:13:52 | params.id | provenance | | +| pages/[id].jsx:16:44:16:49 | params [q] | pages/[id].jsx:16:44:16:51 | params.q | provenance | | +| pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | pages/[id].jsx:3:30:3:35 | params [id] | provenance | | +| pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | pages/[id].jsx:3:30:3:35 | params [q] | provenance | | +| pages/[id].jsx:25:11:25:24 | context.params | pages/[id].jsx:25:11:25:27 | context.params.id | provenance | | +| pages/[id].jsx:25:11:25:27 | context.params.id | pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | provenance | | +| pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | provenance | | +| pages/[id].jsx:26:10:26:22 | context.query | pages/[id].jsx:26:10:26:30 | context ... .foobar | provenance | | +| pages/[id].jsx:26:10:26:30 | context ... .foobar | pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | provenance | | +| pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | provenance | | +| react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted | provenance | | +| react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted | provenance | | +| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | provenance | | +| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | provenance | | +| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | provenance | | +| react-use-router.js:23:31:23:36 | [post update] router | react-use-router.js:23:43:23:48 | router | provenance | | +| react-use-router.js:23:43:23:48 | router | react-use-router.js:23:43:23:54 | router.query | provenance | | +| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | provenance | | +| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:31:23:36 | [post update] router | provenance | | +| react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | provenance | | +| react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | provenance | | +| react-use-state.js:4:10:4:14 | state | react-use-state.js:4:9:4:49 | state | provenance | | +| react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:10:4:14 | state | provenance | | +| react-use-state.js:9:9:9:43 | state | react-use-state.js:11:51:11:55 | state | provenance | | +| react-use-state.js:9:10:9:14 | state | react-use-state.js:9:9:9:43 | state | provenance | | +| react-use-state.js:10:14:10:24 | window.name | react-use-state.js:9:10:9:14 | state | provenance | | +| react-use-state.js:15:9:15:43 | state | react-use-state.js:17:51:17:55 | state | provenance | | +| react-use-state.js:15:10:15:14 | state | react-use-state.js:15:9:15:43 | state | provenance | | +| react-use-state.js:16:20:16:30 | window.name | react-use-state.js:15:10:15:14 | state | provenance | | +| react-use-state.js:21:10:21:14 | state | react-use-state.js:22:14:22:17 | prev | provenance | | +| react-use-state.js:22:14:22:17 | prev | react-use-state.js:23:35:23:38 | prev | provenance | | +| react-use-state.js:25:20:25:30 | window.name | react-use-state.js:21:10:21:14 | state | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:23:29:23:35 | tainted | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:25:29:25:35 | tainted | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:28:29:28:35 | tainted | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:30:29:30:35 | tainted | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:33:29:33:35 | tainted | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:35:29:35:35 | tainted | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:38:29:38:35 | tainted | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:45:29:45:35 | tainted | provenance | | +| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:48:19:48:25 | tainted | provenance | | +| sanitiser.js:16:17:16:27 | window.name | sanitiser.js:16:7:16:27 | tainted | provenance | | +| sanitiser.js:23:29:23:35 | tainted | sanitiser.js:23:21:23:44 | '' + ... '' | provenance | | +| sanitiser.js:25:29:25:35 | tainted | sanitiser.js:25:21:25:44 | '' + ... '' | provenance | | +| sanitiser.js:28:29:28:35 | tainted | sanitiser.js:28:21:28:44 | '' + ... '' | provenance | | +| sanitiser.js:30:29:30:35 | tainted | sanitiser.js:30:21:30:44 | '' + ... '' | provenance | | +| sanitiser.js:33:29:33:35 | tainted | sanitiser.js:33:21:33:44 | '' + ... '' | provenance | | +| sanitiser.js:35:29:35:35 | tainted | sanitiser.js:35:21:35:44 | '' + ... '' | provenance | | +| sanitiser.js:38:29:38:35 | tainted | sanitiser.js:38:21:38:44 | '' + ... '' | provenance | | +| sanitiser.js:45:29:45:35 | tainted | sanitiser.js:45:21:45:44 | '' + ... '' | provenance | | +| sanitiser.js:48:19:48:25 | tainted | sanitiser.js:48:19:48:46 | tainted ... /g, '') | provenance | | +| stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | provenance | | +| stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | provenance | Config | +| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | provenance | | +| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | provenance | Config | +| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:10:16:10:44 | localSt ... local') | provenance | | +| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:10:16:10:44 | localSt ... local') | provenance | Config | +| stored-xss.js:10:9:10:44 | href | stored-xss.js:12:35:12:38 | href | provenance | | +| stored-xss.js:10:16:10:44 | localSt ... local') | stored-xss.js:10:9:10:44 | href | provenance | | +| stored-xss.js:12:35:12:38 | href | stored-xss.js:12:20:12:54 | "" | provenance | | +| stored-xss.js:12:35:12:38 | href | stored-xss.js:12:20:12:54 | "" | provenance | Config | +| string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | provenance | | +| string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | provenance | Config | +| string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | provenance | | +| string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | provenance | Config | +| string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | provenance | | +| string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | provenance | Config | +| string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | provenance | | +| string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | provenance | Config | +| string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | provenance | | +| string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | provenance | Config | +| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | provenance | | +| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | provenance | Config | +| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | provenance | | +| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | provenance | | +| tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source | provenance | | +| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:23:38:23:43 | source | provenance | | +| tooltip.jsx:22:20:22:30 | window.name | tooltip.jsx:22:11:22:30 | source | provenance | | +| tooltip.jsx:23:38:23:43 | source | tooltip.jsx:18:51:18:59 | provide() | provenance | | +| translate.js:6:7:6:39 | target | translate.js:7:42:7:47 | target | provenance | | +| translate.js:6:16:6:39 | documen ... .search | translate.js:6:7:6:39 | target | provenance | | +| translate.js:7:7:7:61 | searchParams | translate.js:9:27:9:38 | searchParams | provenance | | +| translate.js:7:22:7:61 | new URL ... ing(1)) | translate.js:7:7:7:61 | searchParams | provenance | | +| translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | provenance | | +| translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | provenance | Config | +| translate.js:7:42:7:60 | target.substring(1) | translate.js:7:22:7:61 | new URL ... ing(1)) | provenance | | +| translate.js:9:27:9:38 | searchParams | translate.js:9:27:9:50 | searchP ... 'term') | provenance | Config | +| trusted-types-lib.js:1:28:1:28 | x | trusted-types-lib.js:2:12:2:12 | x | provenance | | +| trusted-types.js:3:62:3:62 | x | trusted-types.js:3:67:3:67 | x | provenance | | +| trusted-types.js:4:20:4:30 | window.name | trusted-types.js:3:62:3:62 | x | provenance | | +| trusted-types.js:13:20:13:30 | window.name | trusted-types-lib.js:1:28:1:28 | x | provenance | | +| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:4:25:4:28 | data | provenance | | +| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:5:26:5:29 | data | provenance | | +| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:7:32:7:35 | data | provenance | | +| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:9:37:9:40 | data | provenance | | +| tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:10:38:10:41 | data | provenance | | +| tst3.js:2:23:2:74 | decodeU ... str(1)) | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | provenance | | +| tst3.js:2:42:2:63 | window. ... .search | tst3.js:2:42:2:73 | window. ... bstr(1) | provenance | Config | +| tst3.js:2:42:2:73 | window. ... bstr(1) | tst3.js:2:23:2:74 | decodeU ... str(1)) | provenance | | +| tst3.js:4:25:4:28 | data | tst3.js:4:25:4:32 | data.src | provenance | | +| tst3.js:5:26:5:29 | data | tst3.js:5:26:5:31 | data.p | provenance | | +| tst3.js:7:32:7:35 | data | tst3.js:7:32:7:37 | data.p | provenance | | +| tst3.js:9:37:9:40 | data | tst3.js:9:37:9:42 | data.p | provenance | | +| tst3.js:10:38:10:41 | data | tst3.js:10:38:10:43 | data.p | provenance | | +| tst.js:2:7:2:39 | target | tst.js:5:18:5:23 | target | provenance | | +| tst.js:2:7:2:39 | target | tst.js:12:28:12:33 | target | provenance | | +| tst.js:2:7:2:39 | target | tst.js:20:42:20:47 | target | provenance | | +| tst.js:2:16:2:39 | documen ... .search | tst.js:2:7:2:39 | target | provenance | | +| tst.js:8:37:8:58 | documen ... on.href | tst.js:8:37:8:114 | documen ... t=")+8) | provenance | | +| tst.js:8:37:8:58 | documen ... on.href | tst.js:8:37:8:114 | documen ... t=")+8) | provenance | Config | +| tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:126 | "" | provenance | | +| tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:126 | "" | provenance | Config | +| tst.js:12:28:12:33 | target | tst.js:12:5:12:42 | '
' | provenance | Config | +| tst.js:17:7:17:56 | params | tst.js:18:18:18:23 | params | provenance | | +| tst.js:17:16:17:43 | (new UR ... ation)) [searchParams] | tst.js:17:16:17:56 | (new UR ... hParams | provenance | | +| tst.js:17:16:17:56 | (new UR ... hParams | tst.js:17:7:17:56 | params | provenance | | +| tst.js:17:17:17:42 | new URL ... cation) [searchParams] | tst.js:17:16:17:43 | (new UR ... ation)) [searchParams] | provenance | | +| tst.js:17:25:17:41 | document.location | tst.js:17:17:17:42 | new URL ... cation) [searchParams] | provenance | | +| tst.js:18:18:18:23 | params | tst.js:18:18:18:35 | params.get('name') | provenance | Config | +| tst.js:20:7:20:61 | searchParams | tst.js:21:18:21:29 | searchParams | provenance | | +| tst.js:20:22:20:61 | new URL ... ing(1)) | tst.js:20:7:20:61 | searchParams | provenance | | +| tst.js:20:42:20:47 | target | tst.js:20:42:20:60 | target.substring(1) | provenance | | +| tst.js:20:42:20:47 | target | tst.js:20:42:20:60 | target.substring(1) | provenance | Config | +| tst.js:20:42:20:60 | target.substring(1) | tst.js:20:22:20:61 | new URL ... ing(1)) | provenance | | +| tst.js:21:18:21:29 | searchParams | tst.js:21:18:21:41 | searchP ... 'name') | provenance | Config | +| tst.js:24:14:24:19 | target | tst.js:26:18:26:23 | target | provenance | | +| tst.js:28:5:28:28 | documen ... .search | tst.js:24:14:24:19 | target | provenance | | +| tst.js:31:10:31:33 | documen ... .search | tst.js:34:16:34:20 | bar() | provenance | | +| tst.js:31:10:31:33 | documen ... .search | tst.js:58:26:58:30 | bar() | provenance | | +| tst.js:31:10:31:33 | documen ... .search | tst.js:68:16:68:20 | bar() | provenance | | +| tst.js:36:14:36:14 | x | tst.js:37:10:37:10 | x | provenance | | +| tst.js:40:20:40:43 | documen ... .search | tst.js:36:14:36:14 | x | provenance | | +| tst.js:40:20:40:43 | documen ... .search | tst.js:40:16:40:44 | baz(doc ... search) | provenance | | +| tst.js:42:15:42:15 | s | tst.js:43:20:43:20 | s | provenance | | +| tst.js:43:20:43:20 | s | tst.js:43:10:43:31 | "
" ...
" | provenance | | +| tst.js:43:20:43:20 | s | tst.js:43:10:43:31 | "
" ...
" | provenance | Config | +| tst.js:46:21:46:44 | documen ... .search | tst.js:42:15:42:15 | s | provenance | | +| tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | provenance | | +| tst.js:46:21:46:44 | documen ... .search | tst.js:46:16:46:45 | wrap(do ... search) | provenance | Config | +| tst.js:48:15:48:15 | s | tst.js:50:12:50:12 | s | provenance | | +| tst.js:50:12:50:12 | s | tst.js:50:12:50:22 | s.substr(1) | provenance | | +| tst.js:50:12:50:12 | s | tst.js:50:12:50:22 | s.substr(1) | provenance | Config | +| tst.js:54:21:54:44 | documen ... .search | tst.js:48:15:48:15 | s | provenance | | +| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | provenance | | +| tst.js:54:21:54:44 | documen ... .search | tst.js:54:16:54:45 | chop(do ... search) | provenance | Config | +| tst.js:56:21:56:44 | documen ... .search | tst.js:48:15:48:15 | s | provenance | | +| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | provenance | | +| tst.js:56:21:56:44 | documen ... .search | tst.js:56:16:56:45 | chop(do ... search) | provenance | Config | +| tst.js:58:21:58:31 | chop(bar()) | tst.js:42:15:42:15 | s | provenance | | +| tst.js:58:21:58:31 | chop(bar()) | tst.js:58:16:58:32 | wrap(chop(bar())) | provenance | | +| tst.js:58:21:58:31 | chop(bar()) | tst.js:58:16:58:32 | wrap(chop(bar())) | provenance | Config | +| tst.js:58:26:58:30 | bar() | tst.js:48:15:48:15 | s | provenance | | +| tst.js:58:26:58:30 | bar() | tst.js:58:21:58:31 | chop(bar()) | provenance | | +| tst.js:58:26:58:30 | bar() | tst.js:58:21:58:31 | chop(bar()) | provenance | Config | +| tst.js:60:34:60:34 | s | tst.js:62:18:62:18 | s | provenance | | +| tst.js:64:25:64:48 | documen ... .search | tst.js:60:34:60:34 | s | provenance | | +| tst.js:65:25:65:48 | documen ... .search | tst.js:60:34:60:34 | s | provenance | | +| tst.js:70:1:70:27 | [,docum ... search] | tst.js:70:46:70:46 | x | provenance | | +| tst.js:70:1:70:27 | [,docum ... search] | tst.js:70:46:70:46 | x | provenance | Config | +| tst.js:70:1:70:27 | [,docum ... search] [1] | tst.js:70:46:70:46 | x | provenance | | +| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] | provenance | | +| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] | provenance | Config | +| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] [1] | provenance | | +| tst.js:70:46:70:46 | x | tst.js:73:20:73:20 | x | provenance | | +| tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | provenance | | +| tst.js:107:7:107:44 | v | tst.js:136:18:136:18 | v | provenance | | +| tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | provenance | | +| tst.js:107:11:107:34 | documen ... .search | tst.js:107:11:107:44 | documen ... bstr(1) | provenance | Config | +| tst.js:107:11:107:44 | documen ... bstr(1) | tst.js:107:7:107:44 | v | provenance | | +| tst.js:148:29:148:50 | window. ... .search | tst.js:151:29:151:29 | v | provenance | | +| tst.js:151:29:151:29 | v | tst.js:151:49:151:49 | v | provenance | | +| tst.js:158:40:158:61 | window. ... .search | tst.js:155:29:155:46 | xssSourceService() | provenance | | +| tst.js:177:9:177:41 | target | tst.js:180:28:180:33 | target | provenance | | +| tst.js:177:18:177:41 | documen ... .search | tst.js:177:9:177:41 | target | provenance | | +| tst.js:184:9:184:42 | tainted | tst.js:186:31:186:37 | tainted | provenance | | +| tst.js:184:9:184:42 | tainted | tst.js:188:42:188:48 | tainted | provenance | | +| tst.js:184:9:184:42 | tainted | tst.js:189:33:189:39 | tainted | provenance | | +| tst.js:184:9:184:42 | tainted | tst.js:191:54:191:60 | tainted | provenance | | +| tst.js:184:9:184:42 | tainted | tst.js:192:45:192:51 | tainted | provenance | | +| tst.js:184:9:184:42 | tainted | tst.js:193:49:193:55 | tainted | provenance | | +| tst.js:184:19:184:42 | documen ... .search | tst.js:184:9:184:42 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:199:67:199:73 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:200:67:200:73 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:204:35:204:41 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:206:46:206:52 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:207:38:207:44 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:208:35:208:41 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:236:35:236:41 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:238:20:238:26 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:240:23:240:29 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:241:23:241:29 | tainted | provenance | | +| tst.js:197:9:197:42 | tainted | tst.js:255:23:255:29 | tainted | provenance | | +| tst.js:197:19:197:42 | documen ... .search | tst.js:197:9:197:42 | tainted | provenance | | +| tst.js:204:35:204:41 | tainted | tst.js:212:28:212:46 | this.state.tainted1 | provenance | | +| tst.js:204:35:204:41 | tainted | tst.js:212:28:212:46 | this.state.tainted1 | provenance | Config | +| tst.js:206:46:206:52 | tainted | tst.js:213:28:213:46 | this.state.tainted2 | provenance | | +| tst.js:206:46:206:52 | tainted | tst.js:213:28:213:46 | this.state.tainted2 | provenance | Config | +| tst.js:207:38:207:44 | tainted | tst.js:214:28:214:46 | this.state.tainted3 | provenance | | +| tst.js:207:38:207:44 | tainted | tst.js:214:28:214:46 | this.state.tainted3 | provenance | Config | +| tst.js:208:35:208:41 | tainted | tst.js:218:32:218:49 | prevState.tainted4 | provenance | | +| tst.js:208:35:208:41 | tainted | tst.js:218:32:218:49 | prevState.tainted4 | provenance | Config | +| tst.js:236:35:236:41 | tainted | tst.js:225:28:225:46 | this.props.tainted1 | provenance | | +| tst.js:238:20:238:26 | tainted | tst.js:226:28:226:46 | this.props.tainted2 | provenance | | +| tst.js:240:23:240:29 | tainted | tst.js:227:28:227:46 | this.props.tainted3 | provenance | | +| tst.js:241:23:241:29 | tainted | tst.js:231:32:231:49 | prevProps.tainted4 | provenance | | +| tst.js:247:39:247:55 | props.propTainted | tst.js:251:60:251:82 | this.st ... Tainted | provenance | | +| tst.js:247:39:247:55 | props.propTainted | tst.js:251:60:251:82 | this.st ... Tainted | provenance | Config | +| tst.js:255:23:255:29 | tainted | tst.js:247:39:247:55 | props.propTainted | provenance | | +| tst.js:285:9:285:29 | tainted | tst.js:288:59:288:65 | tainted | provenance | | +| tst.js:285:19:285:29 | window.name | tst.js:285:9:285:29 | tainted | provenance | | +| tst.js:301:9:301:16 | location | tst.js:302:10:302:10 | e | provenance | | +| tst.js:302:10:302:10 | e | tst.js:303:20:303:20 | e | provenance | | +| tst.js:308:10:308:17 | location | tst.js:310:10:310:10 | e | provenance | | +| tst.js:310:10:310:10 | e | tst.js:311:20:311:20 | e | provenance | | +| tst.js:327:10:327:35 | new URL ... cation) [searchParams] | tst.js:331:16:331:30 | getTaintedUrl() [searchParams] | provenance | | +| tst.js:327:18:327:34 | document.location | tst.js:327:10:327:35 | new URL ... cation) [searchParams] | provenance | | +| tst.js:331:7:331:43 | params | tst.js:332:18:332:23 | params | provenance | | +| tst.js:331:16:331:30 | getTaintedUrl() [searchParams] | tst.js:331:16:331:43 | getTain ... hParams | provenance | | +| tst.js:331:16:331:43 | getTain ... hParams | tst.js:331:7:331:43 | params | provenance | | +| tst.js:332:18:332:23 | params | tst.js:332:18:332:35 | params.get('name') | provenance | Config | +| tst.js:341:12:341:37 | new URL ... cation) [hash] | tst.js:343:5:343:12 | getUrl() [hash] | provenance | | +| tst.js:341:20:341:36 | document.location | tst.js:341:12:341:37 | new URL ... cation) [hash] | provenance | | +| tst.js:343:5:343:12 | getUrl() [hash] | tst.js:343:5:343:17 | getUrl().hash | provenance | | +| tst.js:343:5:343:17 | getUrl().hash | tst.js:343:5:343:30 | getUrl( ... ring(1) | provenance | Config | +| tst.js:348:7:348:39 | target | tst.js:349:12:349:17 | target | provenance | | +| tst.js:348:16:348:39 | documen ... .search | tst.js:348:7:348:39 | target | provenance | | +| tst.js:355:10:355:42 | target | tst.js:356:16:356:21 | target | provenance | | +| tst.js:355:10:355:42 | target | tst.js:360:21:360:26 | target | provenance | | +| tst.js:355:10:355:42 | target | tst.js:363:18:363:23 | target | provenance | | +| tst.js:355:19:355:42 | documen ... .search | tst.js:355:10:355:42 | target | provenance | | +| tst.js:371:7:371:39 | target | tst.js:374:18:374:23 | target | provenance | | +| tst.js:371:16:371:39 | documen ... .search | tst.js:371:7:371:39 | target | provenance | | +| tst.js:381:7:381:39 | target | tst.js:384:18:384:23 | target | provenance | | +| tst.js:381:7:381:39 | target | tst.js:386:18:386:23 | target | provenance | | +| tst.js:381:7:381:39 | target | tst.js:397:18:397:23 | target | provenance | | +| tst.js:381:7:381:39 | target | tst.js:406:18:406:23 | target | provenance | | +| tst.js:381:7:381:39 | target | tst.js:408:19:408:24 | target | provenance | | +| tst.js:381:7:381:39 | target [taint3] | tst.js:392:18:392:23 | target [taint3] | provenance | | +| tst.js:381:7:381:39 | target [taint8] | tst.js:408:19:408:24 | target [taint8] | provenance | | +| tst.js:381:7:381:39 | target [taint8] | tst.js:409:18:409:23 | target [taint8] | provenance | | +| tst.js:381:16:381:39 | documen ... .search | tst.js:381:7:381:39 | target | provenance | | +| tst.js:386:18:386:23 | target | tst.js:386:18:386:29 | target.taint | provenance | | +| tst.js:386:18:386:23 | target | tst.js:386:18:386:29 | target.taint | provenance | Config | +| tst.js:391:3:391:8 | [post update] target [taint3] | tst.js:381:7:381:39 | target [taint3] | provenance | | +| tst.js:391:19:391:42 | documen ... .search | tst.js:391:3:391:8 | [post update] target [taint3] | provenance | | +| tst.js:392:18:392:23 | target [taint3] | tst.js:392:18:392:30 | target.taint3 | provenance | | +| tst.js:397:18:397:23 | target | tst.js:397:18:397:30 | target.taint5 | provenance | | +| tst.js:397:18:397:23 | target | tst.js:397:18:397:30 | target.taint5 | provenance | Config | +| tst.js:406:18:406:23 | target | tst.js:406:18:406:30 | target.taint7 | provenance | | +| tst.js:406:18:406:23 | target | tst.js:406:18:406:30 | target.taint7 | provenance | Config | +| tst.js:408:3:408:8 | [post update] target [taint8] | tst.js:381:7:381:39 | target [taint8] | provenance | | +| tst.js:408:19:408:24 | target | tst.js:408:19:408:31 | target.taint8 | provenance | | +| tst.js:408:19:408:24 | target | tst.js:408:19:408:31 | target.taint8 | provenance | Config | +| tst.js:408:19:408:24 | target [taint8] | tst.js:408:19:408:31 | target.taint8 | provenance | | +| tst.js:408:19:408:31 | target.taint8 | tst.js:408:3:408:8 | [post update] target [taint8] | provenance | | +| tst.js:409:18:409:23 | target [taint8] | tst.js:409:18:409:30 | target.taint8 | provenance | | +| tst.js:416:7:416:46 | payload | tst.js:417:18:417:24 | payload | provenance | | +| tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | provenance | | +| tst.js:416:17:416:36 | window.location.hash | tst.js:416:17:416:46 | window. ... bstr(1) | provenance | Config | +| tst.js:416:17:416:46 | window. ... bstr(1) | tst.js:416:7:416:46 | payload | provenance | | +| tst.js:419:7:419:55 | match | tst.js:421:20:421:24 | match | provenance | | +| tst.js:419:15:419:34 | window.location.hash | tst.js:419:15:419:55 | window. ... (\\w+)/) | provenance | | +| tst.js:419:15:419:34 | window.location.hash | tst.js:419:15:419:55 | window. ... (\\w+)/) | provenance | Config | +| tst.js:419:15:419:55 | window. ... (\\w+)/) | tst.js:419:7:419:55 | match | provenance | | +| tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | provenance | | +| tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | provenance | Config | +| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | provenance | | +| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | provenance | Config | +| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | +| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | Config | +| tst.js:428:7:428:39 | target | tst.js:430:18:430:23 | target | provenance | | +| tst.js:428:16:428:39 | documen ... .search | tst.js:428:7:428:39 | target | provenance | | +| tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | provenance | | +| tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | provenance | Config | +| tst.js:436:6:436:38 | source | tst.js:440:28:440:33 | source | provenance | | +| tst.js:436:6:436:38 | source | tst.js:441:33:441:38 | source | provenance | | +| tst.js:436:6:436:38 | source | tst.js:442:34:442:39 | source | provenance | | +| tst.js:436:6:436:38 | source | tst.js:443:41:443:46 | source | provenance | | +| tst.js:436:6:436:38 | source | tst.js:444:44:444:49 | source | provenance | | +| tst.js:436:6:436:38 | source | tst.js:445:32:445:37 | source | provenance | | +| tst.js:436:15:436:38 | documen ... .search | tst.js:436:6:436:38 | source | provenance | | +| tst.js:453:7:453:39 | source | tst.js:455:18:455:23 | source | provenance | | +| tst.js:453:7:453:39 | source | tst.js:456:36:456:41 | source | provenance | | +| tst.js:453:16:453:39 | documen ... .search | tst.js:453:7:453:39 | source | provenance | | +| tst.js:456:36:456:41 | source | tst.js:456:18:456:42 | ansiToH ... source) | provenance | | +| tst.js:456:36:456:41 | source | tst.js:456:18:456:42 | ansiToH ... source) | provenance | Config | +| tst.js:460:6:460:38 | source | tst.js:463:21:463:26 | source | provenance | | +| tst.js:460:6:460:38 | source | tst.js:465:19:465:24 | source | provenance | | +| tst.js:460:6:460:38 | source | tst.js:467:20:467:25 | source | provenance | | +| tst.js:460:15:460:38 | documen ... .search | tst.js:460:6:460:38 | source | provenance | | +| tst.js:471:7:471:46 | url | tst.js:473:19:473:21 | url | provenance | | +| tst.js:471:7:471:46 | url | tst.js:474:26:474:28 | url | provenance | | +| tst.js:471:7:471:46 | url | tst.js:475:25:475:27 | url | provenance | | +| tst.js:471:7:471:46 | url | tst.js:476:20:476:22 | url | provenance | | +| tst.js:471:7:471:46 | url | tst.js:486:22:486:24 | url | provenance | | +| tst.js:471:13:471:36 | documen ... .search | tst.js:471:13:471:46 | documen ... bstr(1) | provenance | Config | +| tst.js:471:13:471:46 | documen ... bstr(1) | tst.js:471:7:471:46 | url | provenance | | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | provenance | Config | +| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | provenance | Config | +| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | provenance | | +| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | provenance | Config | +| typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | provenance | | +| typeahead.js:20:13:20:45 | target | typeahead.js:21:12:21:17 | target | provenance | | +| typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target | provenance | | +| typeahead.js:21:12:21:17 | target | typeahead.js:24:30:24:32 | val | provenance | | +| typeahead.js:21:12:21:17 | target | typeahead.js:24:30:24:32 | val | provenance | Config | +| typeahead.js:24:30:24:32 | val | typeahead.js:25:18:25:20 | val | provenance | | +| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:4:14:4:20 | tainted | provenance | | +| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:5:12:5:18 | tainted | provenance | | +| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:6:19:6:25 | tainted | provenance | | +| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:7:14:7:20 | tainted | provenance | | +| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:9:19:9:25 | tainted | provenance | | +| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:10:16:10:22 | tainted | provenance | | +| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:11:24:11:30 | tainted | provenance | | +| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:12:19:12:25 | tainted | provenance | | +| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:2:6:2:39 | tainted | provenance | | +| various-concat-obfuscations.js:4:14:4:20 | tainted | various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | provenance | Config | +| various-concat-obfuscations.js:5:12:5:18 | tainted | various-concat-obfuscations.js:5:4:5:26 | `
$ ...
` | provenance | Config | +| various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "
" ... /div>") | provenance | | +| various-concat-obfuscations.js:6:19:6:25 | tainted | various-concat-obfuscations.js:6:4:6:26 | "
" ... ainted) | provenance | Config | +| various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | various-concat-obfuscations.js:7:4:7:38 | ["
... .join() | provenance | | +| various-concat-obfuscations.js:7:14:7:20 | tainted | various-concat-obfuscations.js:7:4:7:31 | ["
... /div>"] | provenance | Config | +| various-concat-obfuscations.js:9:19:9:25 | tainted | various-concat-obfuscations.js:9:4:9:34 | "
" | provenance | Config | +| various-concat-obfuscations.js:10:16:10:22 | tainted | various-concat-obfuscations.js:10:4:10:27 | `
` | provenance | Config | +| various-concat-obfuscations.js:11:4:11:31 | "
") | provenance | | +| various-concat-obfuscations.js:11:24:11:30 | tainted | various-concat-obfuscations.js:11:4:11:31 | "
"] | various-concat-obfuscations.js:12:4:12:41 | ["
"] | provenance | Config | +| various-concat-obfuscations.js:14:24:14:28 | attrs | various-concat-obfuscations.js:15:28:15:32 | attrs | provenance | | +| various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | various-concat-obfuscations.js:15:10:15:83 | '
' | provenance | Config | +| various-concat-obfuscations.js:15:28:15:32 | attrs | various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | provenance | | +| various-concat-obfuscations.js:15:28:15:32 | attrs | various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | provenance | Config | +| various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | provenance | | +| various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:32:18:36 | attrs | provenance | | +| various-concat-obfuscations.js:18:10:18:59 | '
') | provenance | | +| various-concat-obfuscations.js:18:10:18:88 | '
') | provenance | | +| various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | provenance | | +| various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | provenance | Config | +| various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | provenance | | +| various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | various-concat-obfuscations.js:18:10:18:59 | '
... /html>` | -| live-server.js:6:13:6:50 | ` ... /html>` | -| live-server.js:6:28:6:34 | tainted | -| live-server.js:10:11:10:27 | tainted | -| live-server.js:10:21:10:27 | req.url | -| live-server.js:10:21:10:27 | req.url | -| live-server.js:12:13:12:50 | ` ... /html>` | -| live-server.js:12:13:12:50 | ` ... /html>` | -| live-server.js:12:28:12:34 | tainted | -| pages/Next.jsx:8:13:8:19 | req.url | -| pages/Next.jsx:8:13:8:19 | req.url | -| pages/Next.jsx:8:13:8:19 | req.url | -| pages/Next.jsx:15:13:15:19 | req.url | -| pages/Next.jsx:15:13:15:19 | req.url | -| pages/Next.jsx:15:13:15:19 | req.url | -| pages/api/myapi.js:2:14:2:20 | req.url | -| pages/api/myapi.js:2:14:2:20 | req.url | -| pages/api/myapi.js:2:14:2:20 | req.url | -| partial.js:9:25:9:25 | x | -| partial.js:10:14:10:14 | x | -| partial.js:10:14:10:18 | x + y | -| partial.js:10:14:10:18 | x + y | -| partial.js:13:42:13:48 | req.url | -| partial.js:13:42:13:48 | req.url | -| partial.js:18:25:18:25 | x | -| partial.js:19:14:19:14 | x | -| partial.js:19:14:19:18 | x + y | -| partial.js:19:14:19:18 | x + y | -| partial.js:22:51:22:57 | req.url | -| partial.js:22:51:22:57 | req.url | -| partial.js:27:25:27:25 | x | -| partial.js:28:14:28:14 | x | -| partial.js:28:14:28:18 | x + y | -| partial.js:28:14:28:18 | x + y | -| partial.js:31:47:31:53 | req.url | -| partial.js:31:47:31:53 | req.url | -| partial.js:36:25:36:25 | x | -| partial.js:37:14:37:14 | x | -| partial.js:37:14:37:18 | x + y | -| partial.js:37:14:37:18 | x + y | -| partial.js:40:43:40:49 | req.url | -| partial.js:40:43:40:49 | req.url | -| promises.js:5:3:5:59 | new Pro ... .data)) | -| promises.js:5:44:5:57 | req.query.data | -| promises.js:5:44:5:57 | req.query.data | -| promises.js:6:11:6:11 | x | -| promises.js:6:25:6:25 | x | -| promises.js:6:25:6:25 | x | -| tst2.js:6:7:6:30 | p | -| tst2.js:6:7:6:30 | r | -| tst2.js:6:9:6:9 | p | -| tst2.js:6:9:6:9 | p | -| tst2.js:6:12:6:15 | q: r | -| tst2.js:6:12:6:15 | q: r | -| tst2.js:7:12:7:12 | p | -| tst2.js:7:12:7:12 | p | -| tst2.js:8:12:8:12 | r | -| tst2.js:8:12:8:12 | r | -| tst2.js:14:7:14:24 | p | -| tst2.js:14:9:14:9 | p | -| tst2.js:14:9:14:9 | p | -| tst2.js:18:12:18:12 | p | -| tst2.js:18:12:18:12 | p | -| tst2.js:21:14:21:14 | p | -| tst2.js:21:14:21:14 | p | -| tst2.js:30:7:30:24 | p | -| tst2.js:30:9:30:9 | p | -| tst2.js:30:9:30:9 | p | -| tst2.js:33:11:33:11 | p | -| tst2.js:36:12:36:12 | p | -| 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 | -| tst2.js:57:7:57:24 | p | -| tst2.js:57:9:57:9 | p | -| tst2.js:57:9:57:9 | p | -| tst2.js:60:11:60:11 | p | -| tst2.js:63:12:63:12 | p | -| tst2.js:63:12:63:12 | p | -| tst2.js:64:12:64:18 | other.p | -| tst2.js:64:12:64:18 | other.p | -| tst2.js:69:7:69:24 | p | -| tst2.js:69:9:69:9 | p | -| tst2.js:69:9:69:9 | p | -| tst2.js:72:11:72:11 | p | -| tst2.js:75:12:75:12 | p | -| tst2.js:75:12:75:12 | p | -| tst2.js:76:12:76:18 | other.p | -| tst2.js:76:12:76:18 | other.p | -| tst2.js:82:7:82:24 | p | -| tst2.js:82:9:82:9 | p | -| tst2.js:82:9:82:9 | p | -| tst2.js:85:11:85:11 | p | -| tst2.js:88:12:88:12 | p | -| tst2.js:88:12:88:12 | p | -| tst2.js:89:12:89:18 | other.p | -| tst2.js:89:12:89:18 | other.p | -| tst3.js:5:7:5:24 | p | -| tst3.js:5:9:5:9 | p | -| tst3.js:5:9:5:9 | p | -| tst3.js:6:12:6:12 | p | -| tst3.js:6:12:6:12 | p | -| tst3.js:11:9:11:74 | code | -| tst3.js:11:16:11:74 | prettie ... bel" }) | -| tst3.js:11:32:11:39 | reg.body | -| tst3.js:11:32:11:39 | reg.body | -| tst3.js:12:12:12:15 | code | -| tst3.js:12:12:12:15 | code | edges -| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | -| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | -| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | -| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | -| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | -| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | -| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | -| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | -| ReflectedXss.js:22:12:22:19 | req.body | ReflectedXss.js:22:12:22:19 | req.body | -| ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) | -| ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) | -| ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) | -| ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) | -| ReflectedXss.js:29:12:29:19 | req.body | ReflectedXss.js:29:12:29:19 | req.body | -| ReflectedXss.js:30:7:33:4 | mytable | ReflectedXss.js:34:12:34:18 | mytable | -| ReflectedXss.js:30:7:33:4 | mytable | ReflectedXss.js:34:12:34:18 | mytable | -| ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | ReflectedXss.js:30:7:33:4 | mytable | -| ReflectedXss.js:30:23:33:3 | [\\n [ ... dy]\\n ] | ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | -| ReflectedXss.js:32:5:32:22 | ['body', req.body] | ReflectedXss.js:30:23:33:3 | [\\n [ ... dy]\\n ] | -| ReflectedXss.js:32:14:32:21 | req.body | ReflectedXss.js:32:5:32:22 | ['body', req.body] | -| ReflectedXss.js:32:14:32:21 | req.body | ReflectedXss.js:32:5:32:22 | ['body', req.body] | -| ReflectedXss.js:41:12:41:19 | req.body | ReflectedXss.js:41:12:41:19 | req.body | -| ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) | -| ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) | -| ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) | -| ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) | -| ReflectedXss.js:56:12:56:19 | req.body | ReflectedXss.js:56:12:56:19 | req.body | -| ReflectedXss.js:64:14:64:21 | req.body | ReflectedXss.js:64:39:64:42 | file | -| ReflectedXss.js:64:14:64:21 | req.body | ReflectedXss.js:64:39:64:42 | file | -| ReflectedXss.js:64:39:64:42 | file | ReflectedXss.js:65:16:65:19 | file | -| ReflectedXss.js:64:39:64:42 | file | ReflectedXss.js:65:16:65:19 | file | -| ReflectedXss.js:68:12:68:41 | remark( ... q.body) | ReflectedXss.js:68:12:68:52 | remark( ... tring() | -| ReflectedXss.js:68:12:68:41 | remark( ... q.body) | ReflectedXss.js:68:12:68:52 | remark( ... tring() | -| ReflectedXss.js:68:33:68:40 | req.body | ReflectedXss.js:68:12:68:41 | remark( ... q.body) | -| ReflectedXss.js:68:33:68:40 | req.body | ReflectedXss.js:68:12:68:41 | remark( ... q.body) | -| ReflectedXss.js:72:12:72:56 | unified ... q.body) | ReflectedXss.js:72:12:72:65 | unified ... oString | -| ReflectedXss.js:72:12:72:56 | unified ... q.body) | ReflectedXss.js:72:12:72:65 | unified ... oString | -| ReflectedXss.js:72:48:72:55 | req.body | ReflectedXss.js:72:12:72:56 | unified ... q.body) | -| ReflectedXss.js:72:48:72:55 | req.body | ReflectedXss.js:72:12:72:56 | unified ... q.body) | -| ReflectedXss.js:74:20:74:27 | req.body | ReflectedXss.js:74:34:74:34 | f | -| ReflectedXss.js:74:20:74:27 | req.body | ReflectedXss.js:74:34:74:34 | f | -| ReflectedXss.js:74:34:74:34 | f | ReflectedXss.js:75:14:75:14 | f | -| ReflectedXss.js:74:34:74:34 | f | ReflectedXss.js:75:14:75:14 | f | -| ReflectedXss.js:83:12:83:19 | req.body | ReflectedXss.js:83:12:83:19 | req.body | -| ReflectedXss.js:84:22:84:29 | req.body | ReflectedXss.js:84:12:84:30 | snarkdown(req.body) | -| ReflectedXss.js:84:22:84:29 | req.body | ReflectedXss.js:84:12:84:30 | snarkdown(req.body) | -| ReflectedXss.js:84:22:84:29 | req.body | ReflectedXss.js:84:12:84:30 | snarkdown(req.body) | -| ReflectedXss.js:84:22:84:29 | req.body | ReflectedXss.js:84:12:84:30 | snarkdown(req.body) | -| ReflectedXss.js:85:23:85:30 | req.body | ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) | -| ReflectedXss.js:85:23:85:30 | req.body | ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) | -| ReflectedXss.js:85:23:85:30 | req.body | ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) | -| ReflectedXss.js:85:23:85:30 | req.body | ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) | -| ReflectedXss.js:97:12:97:19 | req.body | ReflectedXss.js:97:12:97:19 | req.body | -| ReflectedXss.js:98:30:98:37 | req.body | ReflectedXss.js:98:12:98:38 | markdow ... q.body) | -| ReflectedXss.js:98:30:98:37 | req.body | ReflectedXss.js:98:12:98:38 | markdow ... q.body) | -| ReflectedXss.js:98:30:98:37 | req.body | ReflectedXss.js:98:12:98:38 | markdow ... q.body) | -| ReflectedXss.js:98:30:98:37 | req.body | ReflectedXss.js:98:12:98:38 | markdow ... q.body) | -| ReflectedXss.js:100:31:100:38 | req.body | ReflectedXss.js:100:12:100:39 | markdow ... q.body) | -| ReflectedXss.js:100:31:100:38 | req.body | ReflectedXss.js:100:12:100:39 | markdow ... q.body) | -| ReflectedXss.js:100:31:100:38 | req.body | ReflectedXss.js:100:12:100:39 | markdow ... q.body) | -| ReflectedXss.js:100:31:100:38 | req.body | ReflectedXss.js:100:12:100:39 | markdow ... q.body) | -| ReflectedXss.js:103:76:103:83 | req.body | ReflectedXss.js:103:12:103:84 | markdow ... q.body) | -| ReflectedXss.js:103:76:103:83 | req.body | ReflectedXss.js:103:12:103:84 | markdow ... q.body) | -| ReflectedXss.js:103:76:103:83 | req.body | ReflectedXss.js:103:12:103:84 | markdow ... q.body) | -| ReflectedXss.js:103:76:103:83 | req.body | ReflectedXss.js:103:12:103:84 | markdow ... q.body) | -| ReflectedXss.js:110:16:110:30 | request.query.p | ReflectedXss.js:110:16:110:30 | request.query.p | -| ReflectedXss.js:114:11:114:41 | queryKeys | ReflectedXss.js:116:18:116:26 | queryKeys | -| ReflectedXss.js:114:13:114:27 | keys: queryKeys | ReflectedXss.js:114:11:114:41 | queryKeys | -| ReflectedXss.js:114:13:114:27 | keys: queryKeys | ReflectedXss.js:114:11:114:41 | queryKeys | -| ReflectedXss.js:116:11:116:45 | keys | ReflectedXss.js:118:50:118:53 | keys | -| ReflectedXss.js:116:11:116:45 | keys | ReflectedXss.js:118:58:118:61 | keys | -| ReflectedXss.js:116:18:116:26 | queryKeys | ReflectedXss.js:116:18:116:45 | queryKe ... s?.keys | -| ReflectedXss.js:116:18:116:45 | queryKe ... s?.keys | ReflectedXss.js:116:11:116:45 | keys | -| ReflectedXss.js:116:31:116:45 | paramKeys?.keys | ReflectedXss.js:116:18:116:45 | queryKe ... s?.keys | -| ReflectedXss.js:116:31:116:45 | paramKeys?.keys | ReflectedXss.js:116:18:116:45 | queryKe ... s?.keys | -| ReflectedXss.js:118:11:118:61 | keyArray | ReflectedXss.js:119:25:119:32 | keyArray | -| ReflectedXss.js:118:22:118:61 | typeof ... : keys | ReflectedXss.js:118:11:118:61 | keyArray | -| ReflectedXss.js:118:49:118:54 | [keys] | ReflectedXss.js:118:22:118:61 | typeof ... : keys | -| ReflectedXss.js:118:50:118:53 | keys | ReflectedXss.js:118:49:118:54 | [keys] | -| ReflectedXss.js:118:58:118:61 | keys | ReflectedXss.js:118:22:118:61 | typeof ... : keys | -| ReflectedXss.js:119:11:119:72 | invalidKeys | ReflectedXss.js:122:33:122:43 | invalidKeys | -| ReflectedXss.js:119:25:119:32 | keyArray | ReflectedXss.js:119:25:119:72 | keyArra ... s(key)) | -| ReflectedXss.js:119:25:119:72 | keyArra ... s(key)) | ReflectedXss.js:119:11:119:72 | invalidKeys | -| ReflectedXss.js:122:33:122:43 | invalidKeys | ReflectedXss.js:122:33:122:54 | invalid ... n(', ') | -| ReflectedXss.js:122:33:122:54 | invalid ... n(', ') | ReflectedXss.js:122:30:122:73 | `${inva ... telist` | -| ReflectedXss.js:122:33:122:54 | invalid ... n(', ') | ReflectedXss.js:122:30:122:73 | `${inva ... telist` | -| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:70:22:70:34 | req.params.id | ReflectedXssContentTypes.js:70:12:70:34 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:70:22:70:34 | req.params.id | ReflectedXssContentTypes.js:70:12:70:34 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:70:22:70:34 | req.params.id | ReflectedXssContentTypes.js:70:12:70:34 | "FOO: " ... rams.id | -| ReflectedXssContentTypes.js:70:22:70:34 | req.params.id | ReflectedXssContentTypes.js:70:12:70:34 | "FOO: " ... rams.id | -| ReflectedXssGood3.js:135:9:135:27 | url | ReflectedXssGood3.js:139:24:139:26 | url | -| ReflectedXssGood3.js:135:15:135:27 | req.params.id | ReflectedXssGood3.js:135:9:135:27 | url | -| ReflectedXssGood3.js:135:15:135:27 | req.params.id | ReflectedXssGood3.js:135:9:135:27 | url | -| ReflectedXssGood3.js:139:24:139:26 | url | ReflectedXssGood3.js:139:12:139:27 | escapeHtml3(url) | -| ReflectedXssGood3.js:139:24:139:26 | url | ReflectedXssGood3.js:139:12:139:27 | escapeHtml3(url) | -| etherpad.js:9:5:9:53 | response | etherpad.js:11:12:11:19 | response | -| etherpad.js:9:5:9:53 | response | etherpad.js:11:12:11:19 | response | -| etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:9:16:9:53 | req.que ... e + ")" | -| etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:9:16:9:53 | req.que ... e + ")" | -| etherpad.js:9:16:9:53 | req.que ... e + ")" | etherpad.js:9:5:9:53 | response | -| formatting.js:4:9:4:29 | evil | formatting.js:6:43:6:46 | evil | -| formatting.js:4:9:4:29 | evil | formatting.js:7:49:7:52 | evil | -| formatting.js:4:16:4:29 | req.query.evil | formatting.js:4:9:4:29 | evil | -| formatting.js:4:16:4:29 | req.query.evil | formatting.js:4:9:4:29 | evil | -| formatting.js:6:43:6:46 | evil | formatting.js:6:14:6:47 | util.fo ... , evil) | -| formatting.js:6:43:6:46 | evil | formatting.js:6:14:6:47 | util.fo ... , evil) | -| formatting.js:7:49:7:52 | evil | formatting.js:7:14:7:53 | require ... , evil) | -| formatting.js:7:49:7:52 | evil | formatting.js:7:14:7:53 | require ... , evil) | -| live-server.js:4:11:4:27 | tainted | live-server.js:6:28:6:34 | tainted | -| live-server.js:4:21:4:27 | req.url | live-server.js:4:11:4:27 | tainted | -| live-server.js:4:21:4:27 | req.url | live-server.js:4:11:4:27 | tainted | -| live-server.js:6:28:6:34 | tainted | live-server.js:6:13:6:50 | ` ... /html>` | -| live-server.js:6:28:6:34 | tainted | live-server.js:6:13:6:50 | ` ... /html>` | -| live-server.js:10:11:10:27 | tainted | live-server.js:12:28:12:34 | tainted | -| live-server.js:10:21:10:27 | req.url | live-server.js:10:11:10:27 | tainted | -| live-server.js:10:21:10:27 | req.url | live-server.js:10:11:10:27 | tainted | -| live-server.js:12:28:12:34 | tainted | live-server.js:12:13:12:50 | ` ... /html>` | -| live-server.js:12:28:12:34 | tainted | live-server.js:12:13:12:50 | ` ... /html>` | -| pages/Next.jsx:8:13:8:19 | req.url | pages/Next.jsx:8:13:8:19 | req.url | -| pages/Next.jsx:15:13:15:19 | req.url | pages/Next.jsx:15:13:15:19 | req.url | -| pages/api/myapi.js:2:14:2:20 | req.url | pages/api/myapi.js:2:14:2:20 | req.url | -| partial.js:9:25:9:25 | x | partial.js:10:14:10:14 | x | -| partial.js:10:14:10:14 | x | partial.js:10:14:10:18 | x + y | -| partial.js:10:14:10:14 | x | partial.js:10:14:10:18 | x + y | -| partial.js:13:42:13:48 | req.url | partial.js:9:25:9:25 | x | -| partial.js:13:42:13:48 | req.url | partial.js:9:25:9:25 | x | -| partial.js:18:25:18:25 | x | partial.js:19:14:19:14 | x | -| partial.js:19:14:19:14 | x | partial.js:19:14:19:18 | x + y | -| partial.js:19:14:19:14 | x | partial.js:19:14:19:18 | x + y | -| partial.js:22:51:22:57 | req.url | partial.js:18:25:18:25 | x | -| partial.js:22:51:22:57 | req.url | partial.js:18:25:18:25 | x | -| partial.js:27:25:27:25 | x | partial.js:28:14:28:14 | x | -| partial.js:28:14:28:14 | x | partial.js:28:14:28:18 | x + y | -| partial.js:28:14:28:14 | x | partial.js:28:14:28:18 | x + y | -| partial.js:31:47:31:53 | req.url | partial.js:27:25:27:25 | x | -| partial.js:31:47:31:53 | req.url | partial.js:27:25:27:25 | x | -| partial.js:36:25:36:25 | x | partial.js:37:14:37:14 | x | -| partial.js:37:14:37:14 | x | partial.js:37:14:37:18 | x + y | -| partial.js:37:14:37:14 | x | partial.js:37:14:37:18 | x + y | -| partial.js:40:43:40:49 | req.url | partial.js:36:25:36:25 | x | -| partial.js:40:43:40:49 | req.url | partial.js:36:25:36:25 | x | -| promises.js:5:3:5:59 | new Pro ... .data)) | promises.js:6:11:6:11 | x | -| promises.js:5:44:5:57 | req.query.data | promises.js:5:3:5:59 | new Pro ... .data)) | -| promises.js:5:44:5:57 | req.query.data | promises.js:5:3:5:59 | new Pro ... .data)) | -| promises.js:5:44:5:57 | req.query.data | promises.js:6:11:6:11 | x | -| promises.js:5:44:5:57 | req.query.data | promises.js:6:11:6:11 | x | -| promises.js:6:11:6:11 | x | promises.js:6:25:6:25 | x | -| promises.js:6:11:6:11 | x | promises.js:6:25:6:25 | x | -| tst2.js:6:7:6:30 | p | tst2.js:7:12:7:12 | p | -| tst2.js:6:7:6:30 | p | tst2.js:7:12:7:12 | p | -| tst2.js:6:7:6:30 | r | tst2.js:8:12:8:12 | r | -| tst2.js:6:7:6:30 | r | tst2.js:8:12:8:12 | r | -| tst2.js:6:9:6:9 | p | tst2.js:6:7:6:30 | p | -| tst2.js:6:9:6:9 | p | tst2.js:6:7:6:30 | p | -| tst2.js:6:12:6:15 | q: r | tst2.js:6:7:6:30 | r | -| tst2.js:6:12:6:15 | q: r | tst2.js:6:7:6:30 | r | -| tst2.js:14:7:14:24 | p | tst2.js:18:12:18:12 | p | -| tst2.js:14:7:14:24 | p | tst2.js:18:12:18:12 | p | -| tst2.js:14:7:14:24 | p | tst2.js:21:14:21:14 | p | -| tst2.js:14:7:14:24 | p | tst2.js:21:14:21:14 | p | -| tst2.js:14:9:14:9 | p | tst2.js:14:7:14:24 | p | -| tst2.js:14:9:14:9 | p | tst2.js:14:7:14:24 | p | -| tst2.js:30:7:30:24 | p | tst2.js:33:11:33:11 | p | -| tst2.js:30:7:30:24 | p | tst2.js:36:12:36:12 | p | -| tst2.js:30:7:30:24 | p | tst2.js:36:12:36:12 | p | -| tst2.js:30:9:30:9 | p | tst2.js:30:7:30:24 | p | -| 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}) | -| tst2.js:57:7:57:24 | p | tst2.js:60:11:60:11 | p | -| tst2.js:57:7:57:24 | p | tst2.js:63:12:63:12 | p | -| tst2.js:57:7:57:24 | p | tst2.js:63:12:63:12 | p | -| tst2.js:57:9:57:9 | p | tst2.js:57:7:57:24 | p | -| tst2.js:57:9:57:9 | p | tst2.js:57:7:57:24 | p | -| tst2.js:60:11:60:11 | p | tst2.js:64:12:64:18 | other.p | -| tst2.js:60:11:60:11 | p | tst2.js:64:12:64:18 | other.p | -| tst2.js:69:7:69:24 | p | tst2.js:72:11:72:11 | p | -| tst2.js:69:7:69:24 | p | tst2.js:75:12:75:12 | p | -| tst2.js:69:7:69:24 | p | tst2.js:75:12:75:12 | p | -| tst2.js:69:9:69:9 | p | tst2.js:69:7:69:24 | p | -| tst2.js:69:9:69:9 | p | tst2.js:69:7:69:24 | p | -| tst2.js:72:11:72:11 | p | tst2.js:76:12:76:18 | other.p | -| tst2.js:72:11:72:11 | p | tst2.js:76:12:76:18 | other.p | -| tst2.js:82:7:82:24 | p | tst2.js:85:11:85:11 | p | -| tst2.js:82:7:82:24 | p | tst2.js:88:12:88:12 | p | -| tst2.js:82:7:82:24 | p | tst2.js:88:12:88:12 | p | -| tst2.js:82:9:82:9 | p | tst2.js:82:7:82:24 | p | -| tst2.js:82:9:82:9 | p | tst2.js:82:7:82:24 | p | -| tst2.js:85:11:85:11 | p | tst2.js:89:12:89:18 | other.p | -| tst2.js:85:11:85:11 | p | tst2.js:89:12:89:18 | other.p | -| 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 | -| tst3.js:5:9:5:9 | p | tst3.js:5:7:5:24 | p | -| tst3.js:11:9:11:74 | code | tst3.js:12:12:12:15 | code | -| tst3.js:11:9:11:74 | code | tst3.js:12:12:12:15 | code | -| tst3.js:11:16:11:74 | prettie ... bel" }) | tst3.js:11:9:11:74 | code | -| tst3.js:11:32:11:39 | reg.body | tst3.js:11:16:11:74 | prettie ... bel" }) | -| tst3.js:11:32:11:39 | reg.body | tst3.js:11:16:11:74 | prettie ... bel" }) | +| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | provenance | | +| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | provenance | | +| ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) | provenance | | +| ReflectedXss.js:30:7:33:4 | mytable | ReflectedXss.js:34:12:34:18 | mytable | provenance | | +| ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | ReflectedXss.js:30:7:33:4 | mytable | provenance | | +| ReflectedXss.js:32:14:32:21 | req.body | ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | provenance | | +| ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) | provenance | | +| ReflectedXss.js:64:14:64:21 | req.body | ReflectedXss.js:64:39:64:42 | file | provenance | | +| ReflectedXss.js:64:39:64:42 | file | ReflectedXss.js:65:16:65:19 | file | provenance | | +| ReflectedXss.js:68:12:68:41 | remark( ... q.body) | ReflectedXss.js:68:12:68:52 | remark( ... tring() | provenance | | +| ReflectedXss.js:68:33:68:40 | req.body | ReflectedXss.js:68:12:68:41 | remark( ... q.body) | provenance | | +| ReflectedXss.js:72:12:72:56 | unified ... q.body) | ReflectedXss.js:72:12:72:65 | unified ... oString | provenance | | +| ReflectedXss.js:72:48:72:55 | req.body | ReflectedXss.js:72:12:72:56 | unified ... q.body) | provenance | | +| ReflectedXss.js:74:20:74:27 | req.body | ReflectedXss.js:74:34:74:34 | f | provenance | | +| ReflectedXss.js:74:34:74:34 | f | ReflectedXss.js:75:14:75:14 | f | provenance | | +| ReflectedXss.js:84:22:84:29 | req.body | ReflectedXss.js:84:12:84:30 | snarkdown(req.body) | provenance | | +| ReflectedXss.js:85:23:85:30 | req.body | ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) | provenance | | +| ReflectedXss.js:98:30:98:37 | req.body | ReflectedXss.js:98:12:98:38 | markdow ... q.body) | provenance | | +| ReflectedXss.js:100:31:100:38 | req.body | ReflectedXss.js:100:12:100:39 | markdow ... q.body) | provenance | | +| ReflectedXss.js:103:76:103:83 | req.body | ReflectedXss.js:103:12:103:84 | markdow ... q.body) | provenance | | +| ReflectedXss.js:114:11:114:41 | queryKeys | ReflectedXss.js:116:18:116:26 | queryKeys | provenance | | +| ReflectedXss.js:114:13:114:27 | keys: queryKeys | ReflectedXss.js:114:11:114:41 | queryKeys | provenance | | +| ReflectedXss.js:116:11:116:45 | keys | ReflectedXss.js:118:50:118:53 | keys | provenance | | +| ReflectedXss.js:116:11:116:45 | keys | ReflectedXss.js:118:58:118:61 | keys | provenance | | +| ReflectedXss.js:116:18:116:26 | queryKeys | ReflectedXss.js:116:11:116:45 | keys | provenance | | +| ReflectedXss.js:116:31:116:45 | paramKeys?.keys | ReflectedXss.js:116:11:116:45 | keys | provenance | | +| ReflectedXss.js:118:11:118:61 | keyArray | ReflectedXss.js:119:25:119:32 | keyArray | provenance | | +| ReflectedXss.js:118:50:118:53 | keys | ReflectedXss.js:118:11:118:61 | keyArray | provenance | | +| ReflectedXss.js:118:58:118:61 | keys | ReflectedXss.js:118:11:118:61 | keyArray | provenance | | +| ReflectedXss.js:119:11:119:72 | invalidKeys | ReflectedXss.js:122:33:122:43 | invalidKeys | provenance | | +| ReflectedXss.js:119:25:119:32 | keyArray | ReflectedXss.js:119:25:119:72 | keyArra ... s(key)) | provenance | | +| ReflectedXss.js:119:25:119:72 | keyArra ... s(key)) | ReflectedXss.js:119:11:119:72 | invalidKeys | provenance | | +| ReflectedXss.js:122:33:122:43 | invalidKeys | ReflectedXss.js:122:33:122:54 | invalid ... n(', ') | provenance | | +| ReflectedXss.js:122:33:122:54 | invalid ... n(', ') | ReflectedXss.js:122:30:122:73 | `${inva ... telist` | provenance | | +| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | provenance | | +| ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | provenance | | +| ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | provenance | | +| ReflectedXssContentTypes.js:70:22:70:34 | req.params.id | ReflectedXssContentTypes.js:70:12:70:34 | "FOO: " ... rams.id | provenance | | +| ReflectedXssGood3.js:68:22:68:26 | value | ReflectedXssGood3.js:77:16:77:20 | value | provenance | | +| ReflectedXssGood3.js:68:22:68:26 | value | ReflectedXssGood3.js:105:18:105:22 | value | provenance | | +| ReflectedXssGood3.js:77:7:77:37 | parts | ReflectedXssGood3.js:108:10:108:14 | parts | provenance | | +| ReflectedXssGood3.js:77:16:77:20 | value | ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | provenance | | +| ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | ReflectedXssGood3.js:77:7:77:37 | parts | provenance | | +| ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | provenance | | +| ReflectedXssGood3.js:105:7:105:11 | [post update] parts | ReflectedXssGood3.js:77:7:77:37 | parts | provenance | | +| ReflectedXssGood3.js:105:7:105:11 | [post update] parts | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | provenance | | +| ReflectedXssGood3.js:105:18:105:22 | value | ReflectedXssGood3.js:105:18:105:38 | value.s ... g(j, i) | provenance | | +| ReflectedXssGood3.js:105:18:105:38 | value.s ... g(j, i) | ReflectedXssGood3.js:105:7:105:11 | [post update] parts | provenance | | +| ReflectedXssGood3.js:108:10:108:14 | parts | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | provenance | | +| ReflectedXssGood3.js:135:9:135:27 | url | ReflectedXssGood3.js:139:24:139:26 | url | provenance | | +| ReflectedXssGood3.js:135:15:135:27 | req.params.id | ReflectedXssGood3.js:135:9:135:27 | url | provenance | | +| ReflectedXssGood3.js:139:24:139:26 | url | ReflectedXssGood3.js:68:22:68:26 | value | provenance | | +| ReflectedXssGood3.js:139:24:139:26 | url | ReflectedXssGood3.js:139:12:139:27 | escapeHtml3(url) | provenance | | +| etherpad.js:9:5:9:53 | response | etherpad.js:11:12:11:19 | response | provenance | | +| etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:9:5:9:53 | response | provenance | | +| formatting.js:4:9:4:29 | evil | formatting.js:6:43:6:46 | evil | provenance | | +| formatting.js:4:9:4:29 | evil | formatting.js:7:49:7:52 | evil | provenance | | +| formatting.js:4:16:4:29 | req.query.evil | formatting.js:4:9:4:29 | evil | provenance | | +| formatting.js:6:43:6:46 | evil | formatting.js:6:14:6:47 | util.fo ... , evil) | provenance | | +| formatting.js:7:49:7:52 | evil | formatting.js:7:14:7:53 | require ... , evil) | provenance | | +| live-server.js:4:11:4:27 | tainted | live-server.js:6:28:6:34 | tainted | provenance | | +| live-server.js:4:21:4:27 | req.url | live-server.js:4:11:4:27 | tainted | provenance | | +| live-server.js:6:28:6:34 | tainted | live-server.js:6:13:6:50 | ` ... /html>` | provenance | | +| live-server.js:10:11:10:27 | tainted | live-server.js:12:28:12:34 | tainted | provenance | | +| live-server.js:10:21:10:27 | req.url | live-server.js:10:11:10:27 | tainted | provenance | | +| live-server.js:12:28:12:34 | tainted | live-server.js:12:13:12:50 | ` ... /html>` | provenance | | +| partial.js:9:25:9:25 | x | partial.js:10:14:10:14 | x | provenance | | +| partial.js:10:14:10:14 | x | partial.js:10:14:10:18 | x + y | provenance | | +| partial.js:13:42:13:48 | req.url | partial.js:9:25:9:25 | x | provenance | | +| partial.js:18:25:18:25 | x | partial.js:19:14:19:14 | x | provenance | | +| partial.js:19:14:19:14 | x | partial.js:19:14:19:18 | x + y | provenance | | +| partial.js:22:51:22:57 | req.url | partial.js:18:25:18:25 | x | provenance | | +| partial.js:27:25:27:25 | x | partial.js:28:14:28:14 | x | provenance | | +| partial.js:28:14:28:14 | x | partial.js:28:14:28:18 | x + y | provenance | | +| partial.js:31:47:31:53 | req.url | partial.js:27:25:27:25 | x | provenance | | +| partial.js:36:25:36:25 | x | partial.js:37:14:37:14 | x | provenance | | +| partial.js:37:14:37:14 | x | partial.js:37:14:37:18 | x + y | provenance | | +| partial.js:40:43:40:49 | req.url | partial.js:36:25:36:25 | x | provenance | | +| promises.js:5:3:5:59 | new Pro ... .data)) [PromiseValue] | promises.js:6:11:6:11 | x | provenance | | +| promises.js:5:16:5:22 | resolve [Return] [resolve-value] | promises.js:5:3:5:59 | new Pro ... .data)) [PromiseValue] | provenance | | +| promises.js:5:36:5:42 | [post update] resolve [resolve-value] | promises.js:5:16:5:22 | resolve [Return] [resolve-value] | provenance | | +| promises.js:5:44:5:57 | req.query.data | promises.js:5:36:5:42 | [post update] resolve [resolve-value] | provenance | | +| promises.js:6:11:6:11 | x | promises.js:6:25:6:25 | x | provenance | | +| tst2.js:6:7:6:30 | p | tst2.js:7:12:7:12 | p | provenance | | +| tst2.js:6:7:6:30 | r | tst2.js:8:12:8:12 | r | provenance | | +| tst2.js:6:9:6:9 | p | tst2.js:6:7:6:30 | p | provenance | | +| tst2.js:6:12:6:15 | q: r | tst2.js:6:7:6:30 | r | provenance | | +| tst2.js:14:7:14:24 | p | tst2.js:18:12:18:12 | p | provenance | | +| tst2.js:14:7:14:24 | p | tst2.js:21:14:21:14 | p | provenance | | +| tst2.js:14:9:14:9 | p | tst2.js:14:7:14:24 | p | provenance | | +| tst2.js:30:7:30:24 | p | tst2.js:33:11:33:11 | p | provenance | | +| tst2.js:30:7:30:24 | p | tst2.js:36:12:36:12 | p | provenance | | +| tst2.js:30:9:30:9 | p | tst2.js:30:7:30:24 | p | provenance | | +| tst2.js:32:7:32:14 | obj [p] | tst2.js:34:21:34:23 | obj [p] | provenance | | +| tst2.js:33:3:33:5 | [post update] obj [p] | tst2.js:32:7:32:14 | obj [p] | provenance | | +| tst2.js:33:11:33:11 | p | tst2.js:33:3:33:5 | [post update] obj [p] | provenance | | +| tst2.js:34:7:34:24 | other [p] | tst2.js:37:12:37:16 | other [p] | provenance | | +| tst2.js:34:15:34:24 | clone(obj) [p] | tst2.js:34:7:34:24 | other [p] | provenance | | +| tst2.js:34:21:34:23 | obj [p] | tst2.js:34:15:34:24 | clone(obj) [p] | provenance | | +| tst2.js:37:12:37:16 | other [p] | tst2.js:37:12:37:18 | other.p | provenance | | +| tst2.js:43:7:43:24 | p | tst2.js:49:36:49:36 | p | provenance | | +| tst2.js:43:9:43:9 | p | tst2.js:43:7:43:24 | p | provenance | | +| tst2.js:49:7:49:53 | unsafe | tst2.js:51:12:51:17 | unsafe | provenance | | +| tst2.js:49:16:49:53 | seriali ... true}) | tst2.js:49:7:49:53 | unsafe | provenance | | +| tst2.js:49:36:49:36 | p | tst2.js:49:16:49:53 | seriali ... true}) | provenance | | +| tst2.js:57:7:57:24 | p | tst2.js:60:11:60:11 | p | provenance | | +| tst2.js:57:7:57:24 | p | tst2.js:63:12:63:12 | p | provenance | | +| tst2.js:57:9:57:9 | p | tst2.js:57:7:57:24 | p | provenance | | +| tst2.js:59:7:59:14 | obj [p] | tst2.js:61:22:61:24 | obj [p] | provenance | | +| tst2.js:60:3:60:5 | [post update] obj [p] | tst2.js:59:7:59:14 | obj [p] | provenance | | +| tst2.js:60:11:60:11 | p | tst2.js:60:3:60:5 | [post update] obj [p] | provenance | | +| tst2.js:61:7:61:25 | other [p] | tst2.js:64:12:64:16 | other [p] | provenance | | +| tst2.js:61:15:61:25 | fclone(obj) [p] | tst2.js:61:7:61:25 | other [p] | provenance | | +| tst2.js:61:22:61:24 | obj [p] | tst2.js:61:15:61:25 | fclone(obj) [p] | provenance | | +| tst2.js:64:12:64:16 | other [p] | tst2.js:64:12:64:18 | other.p | provenance | | +| tst2.js:69:7:69:24 | p | tst2.js:72:11:72:11 | p | provenance | | +| tst2.js:69:7:69:24 | p | tst2.js:75:12:75:12 | p | provenance | | +| tst2.js:69:9:69:9 | p | tst2.js:69:7:69:24 | p | provenance | | +| tst2.js:71:7:71:14 | obj [p] | tst2.js:73:40:73:42 | obj [p] | provenance | | +| tst2.js:72:3:72:5 | [post update] obj [p] | tst2.js:71:7:71:14 | obj [p] | provenance | | +| tst2.js:72:11:72:11 | p | tst2.js:72:3:72:5 | [post update] obj [p] | provenance | | +| tst2.js:73:7:73:44 | other [p] | tst2.js:76:12:76:16 | other [p] | provenance | | +| tst2.js:73:15:73:44 | jc.retr ... e(obj)) [p] | tst2.js:73:7:73:44 | other [p] | provenance | | +| tst2.js:73:29:73:43 | jc.decycle(obj) [p] | tst2.js:73:15:73:44 | jc.retr ... e(obj)) [p] | provenance | | +| tst2.js:73:40:73:42 | obj [p] | tst2.js:73:29:73:43 | jc.decycle(obj) [p] | provenance | | +| tst2.js:76:12:76:16 | other [p] | tst2.js:76:12:76:18 | other.p | provenance | | +| tst2.js:82:7:82:24 | p | tst2.js:85:11:85:11 | p | provenance | | +| tst2.js:82:7:82:24 | p | tst2.js:88:12:88:12 | p | provenance | | +| tst2.js:82:9:82:9 | p | tst2.js:82:7:82:24 | p | provenance | | +| tst2.js:84:7:84:14 | obj [p] | tst2.js:86:24:86:26 | obj [p] | provenance | | +| tst2.js:85:3:85:5 | [post update] obj [p] | tst2.js:84:7:84:14 | obj [p] | provenance | | +| tst2.js:85:11:85:11 | p | tst2.js:85:3:85:5 | [post update] obj [p] | provenance | | +| tst2.js:86:7:86:27 | other [p] | tst2.js:89:12:89:16 | other [p] | provenance | | +| tst2.js:86:15:86:27 | sortKeys(obj) [p] | tst2.js:86:7:86:27 | other [p] | provenance | | +| tst2.js:86:24:86:26 | obj [p] | tst2.js:86:15:86:27 | sortKeys(obj) [p] | provenance | | +| tst2.js:89:12:89:16 | other [p] | tst2.js:89:12:89:18 | other.p | provenance | | +| tst3.js:5:7:5:24 | p | tst3.js:6:12:6:12 | p | provenance | | +| tst3.js:5:9:5:9 | p | tst3.js:5:7:5:24 | p | provenance | | +| tst3.js:11:9:11:74 | code | tst3.js:12:12:12:15 | code | provenance | | +| tst3.js:11:16:11:74 | prettie ... bel" }) | tst3.js:11:9:11:74 | code | provenance | | +| tst3.js:11:32:11:39 | reg.body | tst3.js:11:16:11:74 | prettie ... bel" }) | provenance | | +nodes +| ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | semmle.label | "Unknow ... rams.id | +| ReflectedXss.js:8:33:8:45 | req.params.id | semmle.label | req.params.id | +| ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | semmle.label | "Unknow ... rams.id | +| ReflectedXss.js:17:31:17:39 | params.id | semmle.label | params.id | +| ReflectedXss.js:22:12:22:19 | req.body | semmle.label | req.body | +| ReflectedXss.js:23:12:23:27 | marked(req.body) | semmle.label | marked(req.body) | +| ReflectedXss.js:23:19:23:26 | req.body | semmle.label | req.body | +| ReflectedXss.js:29:12:29:19 | req.body | semmle.label | req.body | +| ReflectedXss.js:30:7:33:4 | mytable | semmle.label | mytable | +| ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | semmle.label | table([ ... y]\\n ]) | +| ReflectedXss.js:32:14:32:21 | req.body | semmle.label | req.body | +| ReflectedXss.js:34:12:34:18 | mytable | semmle.label | mytable | +| ReflectedXss.js:41:12:41:19 | req.body | semmle.label | req.body | +| ReflectedXss.js:42:12:42:39 | convert ... q.body) | semmle.label | convert ... q.body) | +| ReflectedXss.js:42:31:42:38 | req.body | semmle.label | req.body | +| ReflectedXss.js:56:12:56:19 | req.body | semmle.label | req.body | +| ReflectedXss.js:64:14:64:21 | req.body | semmle.label | req.body | +| ReflectedXss.js:64:39:64:42 | file | semmle.label | file | +| ReflectedXss.js:65:16:65:19 | file | semmle.label | file | +| ReflectedXss.js:68:12:68:41 | remark( ... q.body) | semmle.label | remark( ... q.body) | +| ReflectedXss.js:68:12:68:52 | remark( ... tring() | semmle.label | remark( ... tring() | +| ReflectedXss.js:68:33:68:40 | req.body | semmle.label | req.body | +| ReflectedXss.js:72:12:72:56 | unified ... q.body) | semmle.label | unified ... q.body) | +| ReflectedXss.js:72:12:72:65 | unified ... oString | semmle.label | unified ... oString | +| ReflectedXss.js:72:48:72:55 | req.body | semmle.label | req.body | +| ReflectedXss.js:74:20:74:27 | req.body | semmle.label | req.body | +| ReflectedXss.js:74:34:74:34 | f | semmle.label | f | +| ReflectedXss.js:75:14:75:14 | f | semmle.label | f | +| ReflectedXss.js:83:12:83:19 | req.body | semmle.label | req.body | +| ReflectedXss.js:84:12:84:30 | snarkdown(req.body) | semmle.label | snarkdown(req.body) | +| ReflectedXss.js:84:22:84:29 | req.body | semmle.label | req.body | +| ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) | semmle.label | snarkdown2(req.body) | +| ReflectedXss.js:85:23:85:30 | req.body | semmle.label | req.body | +| ReflectedXss.js:97:12:97:19 | req.body | semmle.label | req.body | +| ReflectedXss.js:98:12:98:38 | markdow ... q.body) | semmle.label | markdow ... q.body) | +| ReflectedXss.js:98:30:98:37 | req.body | semmle.label | req.body | +| ReflectedXss.js:100:12:100:39 | markdow ... q.body) | semmle.label | markdow ... q.body) | +| ReflectedXss.js:100:31:100:38 | req.body | semmle.label | req.body | +| ReflectedXss.js:103:12:103:84 | markdow ... q.body) | semmle.label | markdow ... q.body) | +| ReflectedXss.js:103:76:103:83 | req.body | semmle.label | req.body | +| ReflectedXss.js:110:16:110:30 | request.query.p | semmle.label | request.query.p | +| ReflectedXss.js:114:11:114:41 | queryKeys | semmle.label | queryKeys | +| ReflectedXss.js:114:13:114:27 | keys: queryKeys | semmle.label | keys: queryKeys | +| ReflectedXss.js:116:11:116:45 | keys | semmle.label | keys | +| ReflectedXss.js:116:18:116:26 | queryKeys | semmle.label | queryKeys | +| ReflectedXss.js:116:31:116:45 | paramKeys?.keys | semmle.label | paramKeys?.keys | +| ReflectedXss.js:118:11:118:61 | keyArray | semmle.label | keyArray | +| ReflectedXss.js:118:50:118:53 | keys | semmle.label | keys | +| ReflectedXss.js:118:58:118:61 | keys | semmle.label | keys | +| ReflectedXss.js:119:11:119:72 | invalidKeys | semmle.label | invalidKeys | +| ReflectedXss.js:119:25:119:32 | keyArray | semmle.label | keyArray | +| ReflectedXss.js:119:25:119:72 | keyArra ... s(key)) | semmle.label | keyArra ... s(key)) | +| ReflectedXss.js:122:30:122:73 | `${inva ... telist` | semmle.label | `${inva ... telist` | +| ReflectedXss.js:122:33:122:43 | invalidKeys | semmle.label | invalidKeys | +| ReflectedXss.js:122:33:122:54 | invalid ... n(', ') | semmle.label | invalid ... n(', ') | +| ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | semmle.label | "FOO: " ... rams.id | +| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | semmle.label | req.params.id | +| ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | semmle.label | "FOO: " ... rams.id | +| ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | semmle.label | req.params.id | +| ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | semmle.label | "FOO: " ... rams.id | +| ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | semmle.label | req.params.id | +| ReflectedXssContentTypes.js:70:12:70:34 | "FOO: " ... rams.id | semmle.label | "FOO: " ... rams.id | +| ReflectedXssContentTypes.js:70:22:70:34 | req.params.id | semmle.label | req.params.id | +| ReflectedXssGood3.js:68:22:68:26 | value | semmle.label | value | +| ReflectedXssGood3.js:77:7:77:37 | parts | semmle.label | parts | +| ReflectedXssGood3.js:77:16:77:20 | value | semmle.label | value | +| ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | semmle.label | value.s ... g(0, i) | +| ReflectedXssGood3.js:105:7:105:11 | [post update] parts | semmle.label | [post update] parts | +| ReflectedXssGood3.js:105:18:105:22 | value | semmle.label | value | +| ReflectedXssGood3.js:105:18:105:38 | value.s ... g(j, i) | semmle.label | value.s ... g(j, i) | +| ReflectedXssGood3.js:108:10:108:14 | parts | semmle.label | parts | +| ReflectedXssGood3.js:108:10:108:23 | parts.join('') | semmle.label | parts.join('') | +| ReflectedXssGood3.js:135:9:135:27 | url | semmle.label | url | +| ReflectedXssGood3.js:135:15:135:27 | req.params.id | semmle.label | req.params.id | +| ReflectedXssGood3.js:139:12:139:27 | escapeHtml3(url) | semmle.label | escapeHtml3(url) | +| ReflectedXssGood3.js:139:24:139:26 | url | semmle.label | url | +| etherpad.js:9:5:9:53 | response | semmle.label | response | +| etherpad.js:9:16:9:30 | req.query.jsonp | semmle.label | req.query.jsonp | +| etherpad.js:11:12:11:19 | response | semmle.label | response | +| formatting.js:4:9:4:29 | evil | semmle.label | evil | +| formatting.js:4:16:4:29 | req.query.evil | semmle.label | req.query.evil | +| formatting.js:6:14:6:47 | util.fo ... , evil) | semmle.label | util.fo ... , evil) | +| formatting.js:6:43:6:46 | evil | semmle.label | evil | +| formatting.js:7:14:7:53 | require ... , evil) | semmle.label | require ... , evil) | +| formatting.js:7:49:7:52 | evil | semmle.label | evil | +| live-server.js:4:11:4:27 | tainted | semmle.label | tainted | +| live-server.js:4:21:4:27 | req.url | semmle.label | req.url | +| live-server.js:6:13:6:50 | ` ... /html>` | semmle.label | ` ... /html>` | +| live-server.js:6:28:6:34 | tainted | semmle.label | tainted | +| live-server.js:10:11:10:27 | tainted | semmle.label | tainted | +| live-server.js:10:21:10:27 | req.url | semmle.label | req.url | +| live-server.js:12:13:12:50 | ` ... /html>` | semmle.label | ` ... /html>` | +| live-server.js:12:28:12:34 | tainted | semmle.label | tainted | +| pages/Next.jsx:8:13:8:19 | req.url | semmle.label | req.url | +| pages/Next.jsx:15:13:15:19 | req.url | semmle.label | req.url | +| pages/api/myapi.js:2:14:2:20 | req.url | semmle.label | req.url | +| partial.js:9:25:9:25 | x | semmle.label | x | +| partial.js:10:14:10:14 | x | semmle.label | x | +| partial.js:10:14:10:18 | x + y | semmle.label | x + y | +| partial.js:13:42:13:48 | req.url | semmle.label | req.url | +| partial.js:18:25:18:25 | x | semmle.label | x | +| partial.js:19:14:19:14 | x | semmle.label | x | +| partial.js:19:14:19:18 | x + y | semmle.label | x + y | +| partial.js:22:51:22:57 | req.url | semmle.label | req.url | +| partial.js:27:25:27:25 | x | semmle.label | x | +| partial.js:28:14:28:14 | x | semmle.label | x | +| partial.js:28:14:28:18 | x + y | semmle.label | x + y | +| partial.js:31:47:31:53 | req.url | semmle.label | req.url | +| partial.js:36:25:36:25 | x | semmle.label | x | +| partial.js:37:14:37:14 | x | semmle.label | x | +| partial.js:37:14:37:18 | x + y | semmle.label | x + y | +| partial.js:40:43:40:49 | req.url | semmle.label | req.url | +| promises.js:5:3:5:59 | new Pro ... .data)) [PromiseValue] | semmle.label | new Pro ... .data)) [PromiseValue] | +| promises.js:5:16:5:22 | resolve [Return] [resolve-value] | semmle.label | resolve [Return] [resolve-value] | +| promises.js:5:36:5:42 | [post update] resolve [resolve-value] | semmle.label | [post update] resolve [resolve-value] | +| promises.js:5:44:5:57 | req.query.data | semmle.label | req.query.data | +| promises.js:6:11:6:11 | x | semmle.label | x | +| promises.js:6:25:6:25 | x | semmle.label | x | +| tst2.js:6:7:6:30 | p | semmle.label | p | +| tst2.js:6:7:6:30 | r | semmle.label | r | +| tst2.js:6:9:6:9 | p | semmle.label | p | +| tst2.js:6:12:6:15 | q: r | semmle.label | q: r | +| tst2.js:7:12:7:12 | p | semmle.label | p | +| tst2.js:8:12:8:12 | r | semmle.label | r | +| tst2.js:14:7:14:24 | p | semmle.label | p | +| tst2.js:14:9:14:9 | p | semmle.label | p | +| tst2.js:18:12:18:12 | p | semmle.label | p | +| tst2.js:21:14:21:14 | p | semmle.label | p | +| tst2.js:30:7:30:24 | p | semmle.label | p | +| tst2.js:30:9:30:9 | p | semmle.label | p | +| tst2.js:32:7:32:14 | obj [p] | semmle.label | obj [p] | +| tst2.js:33:3:33:5 | [post update] obj [p] | semmle.label | [post update] obj [p] | +| tst2.js:33:11:33:11 | p | semmle.label | p | +| tst2.js:34:7:34:24 | other [p] | semmle.label | other [p] | +| tst2.js:34:15:34:24 | clone(obj) [p] | semmle.label | clone(obj) [p] | +| tst2.js:34:21:34:23 | obj [p] | semmle.label | obj [p] | +| tst2.js:36:12:36:12 | p | semmle.label | p | +| tst2.js:37:12:37:16 | other [p] | semmle.label | other [p] | +| tst2.js:37:12:37:18 | other.p | semmle.label | other.p | +| tst2.js:43:7:43:24 | p | semmle.label | p | +| tst2.js:43:9:43:9 | p | semmle.label | p | +| tst2.js:49:7:49:53 | unsafe | semmle.label | unsafe | +| tst2.js:49:16:49:53 | seriali ... true}) | semmle.label | seriali ... true}) | +| tst2.js:49:36:49:36 | p | semmle.label | p | +| tst2.js:51:12:51:17 | unsafe | semmle.label | unsafe | +| tst2.js:57:7:57:24 | p | semmle.label | p | +| tst2.js:57:9:57:9 | p | semmle.label | p | +| tst2.js:59:7:59:14 | obj [p] | semmle.label | obj [p] | +| tst2.js:60:3:60:5 | [post update] obj [p] | semmle.label | [post update] obj [p] | +| tst2.js:60:11:60:11 | p | semmle.label | p | +| tst2.js:61:7:61:25 | other [p] | semmle.label | other [p] | +| tst2.js:61:15:61:25 | fclone(obj) [p] | semmle.label | fclone(obj) [p] | +| tst2.js:61:22:61:24 | obj [p] | semmle.label | obj [p] | +| tst2.js:63:12:63:12 | p | semmle.label | p | +| tst2.js:64:12:64:16 | other [p] | semmle.label | other [p] | +| tst2.js:64:12:64:18 | other.p | semmle.label | other.p | +| tst2.js:69:7:69:24 | p | semmle.label | p | +| tst2.js:69:9:69:9 | p | semmle.label | p | +| tst2.js:71:7:71:14 | obj [p] | semmle.label | obj [p] | +| tst2.js:72:3:72:5 | [post update] obj [p] | semmle.label | [post update] obj [p] | +| tst2.js:72:11:72:11 | p | semmle.label | p | +| tst2.js:73:7:73:44 | other [p] | semmle.label | other [p] | +| tst2.js:73:15:73:44 | jc.retr ... e(obj)) [p] | semmle.label | jc.retr ... e(obj)) [p] | +| tst2.js:73:29:73:43 | jc.decycle(obj) [p] | semmle.label | jc.decycle(obj) [p] | +| tst2.js:73:40:73:42 | obj [p] | semmle.label | obj [p] | +| tst2.js:75:12:75:12 | p | semmle.label | p | +| tst2.js:76:12:76:16 | other [p] | semmle.label | other [p] | +| tst2.js:76:12:76:18 | other.p | semmle.label | other.p | +| tst2.js:82:7:82:24 | p | semmle.label | p | +| tst2.js:82:9:82:9 | p | semmle.label | p | +| tst2.js:84:7:84:14 | obj [p] | semmle.label | obj [p] | +| tst2.js:85:3:85:5 | [post update] obj [p] | semmle.label | [post update] obj [p] | +| tst2.js:85:11:85:11 | p | semmle.label | p | +| tst2.js:86:7:86:27 | other [p] | semmle.label | other [p] | +| tst2.js:86:15:86:27 | sortKeys(obj) [p] | semmle.label | sortKeys(obj) [p] | +| tst2.js:86:24:86:26 | obj [p] | semmle.label | obj [p] | +| tst2.js:88:12:88:12 | p | semmle.label | p | +| tst2.js:89:12:89:16 | other [p] | semmle.label | other [p] | +| tst2.js:89:12:89:18 | other.p | semmle.label | other.p | +| tst3.js:5:7:5:24 | p | semmle.label | p | +| tst3.js:5:9:5:9 | p | semmle.label | p | +| tst3.js:6:12:6:12 | p | semmle.label | p | +| tst3.js:11:9:11:74 | code | semmle.label | code | +| tst3.js:11:16:11:74 | prettie ... bel" }) | semmle.label | prettie ... bel" }) | +| tst3.js:11:32:11:39 | reg.body | semmle.label | reg.body | +| tst3.js:12:12:12:15 | code | semmle.label | code | +subpaths +| ReflectedXssGood3.js:139:24:139:26 | url | ReflectedXssGood3.js:68:22:68:26 | value | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | ReflectedXssGood3.js:139:12:139:27 | escapeHtml3(url) | #select | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:8:33:8:45 | req.params.id | user-provided value | | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:17:31:17:39 | params.id | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected index 53f02ae19f2..3b3b0501e19 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected @@ -1,32 +1,43 @@ edges -| xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 | -| xss-through-filenames.js:17:21:17:26 | files2 | xss-through-filenames.js:19:9:19:14 | files2 | -| xss-through-filenames.js:17:21:17:26 | files2 [ArrayElement] | xss-through-filenames.js:19:9:19:14 | files2 [ArrayElement] | -| xss-through-filenames.js:19:9:19:14 | files2 | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | -| xss-through-filenames.js:19:9:19:14 | files2 | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | -| xss-through-filenames.js:19:9:19:14 | files2 [ArrayElement] | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | -| xss-through-filenames.js:19:9:19:14 | files2 [ArrayElement] | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | -| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:22:16:22:21 | files3 | -| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:22:16:22:21 | files3 | -| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 | -| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 | -| xss-through-filenames.js:22:16:22:21 | files3 | xss-through-filenames.js:22:16:22:30 | files3.join('') | -| xss-through-filenames.js:22:16:22:21 | files3 | xss-through-filenames.js:22:16:22:30 | files3.join('') | -| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 | -| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:30:9:30:14 | files1 | -| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:33:19:33:24 | files2 | -| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:33:19:33:24 | files2 | -| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | -| xss-through-filenames.js:33:19:33:24 | files2 | xss-through-filenames.js:35:29:35:34 | files2 | -| xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | -| xss-through-filenames.js:35:13:35:35 | files3 | xss-through-filenames.js:37:19:37:24 | files3 | -| xss-through-filenames.js:35:22:35:35 | format(files2) | xss-through-filenames.js:35:13:35:35 | files3 | -| xss-through-filenames.js:35:29:35:34 | files2 | xss-through-filenames.js:17:21:17:26 | files2 | -| xss-through-filenames.js:35:29:35:34 | files2 | xss-through-filenames.js:35:22:35:35 | format(files2) | -| xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | xss-through-filenames.js:17:21:17:26 | files2 [ArrayElement] | -| xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | xss-through-filenames.js:35:22:35:35 | format(files2) | -| xss-through-torrent.js:6:6:6:24 | name | xss-through-torrent.js:7:11:7:14 | name | -| xss-through-torrent.js:6:13:6:24 | torrent.name | xss-through-torrent.js:6:6:6:24 | name | +| xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 | provenance | | +| xss-through-filenames.js:17:21:17:26 | files2 | xss-through-filenames.js:19:9:19:14 | files2 | provenance | | +| xss-through-filenames.js:17:21:17:26 | files2 [ArrayElement] | xss-through-filenames.js:19:9:19:14 | files2 [ArrayElement] | provenance | | +| xss-through-filenames.js:19:9:19:14 | files2 | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | provenance | | +| xss-through-filenames.js:19:9:19:14 | files2 | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | provenance | | +| xss-through-filenames.js:19:9:19:14 | files2 [ArrayElement] | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | provenance | | +| xss-through-filenames.js:19:9:19:14 | files2 [ArrayElement] | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | provenance | | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:19:45:19:48 | file | provenance | | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:19:45:19:48 | file | provenance | | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:22:16:22:21 | files3 | provenance | | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:22:16:22:21 | files3 | provenance | | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:19:45:19:48 | file | provenance | | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:19:45:19:48 | file | provenance | | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 | provenance | | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 | provenance | | +| xss-through-filenames.js:19:45:19:48 | file | xss-through-filenames.js:20:34:20:37 | file | provenance | | +| xss-through-filenames.js:20:25:20:47 | '
  • ' ... '
  • ' | xss-through-filenames.js:20:13:20:18 | [post update] files3 | provenance | | +| xss-through-filenames.js:20:34:20:37 | file | xss-through-filenames.js:20:25:20:47 | '
  • ' ... '
  • ' | provenance | | +| xss-through-filenames.js:22:16:22:21 | files3 | xss-through-filenames.js:22:16:22:30 | files3.join('') | provenance | | +| xss-through-filenames.js:22:16:22:21 | files3 | xss-through-filenames.js:22:16:22:30 | files3.join('') | provenance | | +| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 | provenance | | +| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:30:9:30:14 | files1 | provenance | | +| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:30:34:30:37 | file | provenance | | +| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:33:19:33:24 | files2 | provenance | | +| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:33:19:33:24 | files2 | provenance | | +| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | provenance | | +| xss-through-filenames.js:30:34:30:37 | file | xss-through-filenames.js:31:25:31:28 | file | provenance | | +| xss-through-filenames.js:31:25:31:28 | file | xss-through-filenames.js:31:13:31:18 | [post update] files2 | provenance | | +| xss-through-filenames.js:31:25:31:28 | file | xss-through-filenames.js:31:13:31:18 | [post update] files2 [ArrayElement] | provenance | | +| xss-through-filenames.js:33:19:33:24 | files2 | xss-through-filenames.js:35:29:35:34 | files2 | provenance | | +| xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | provenance | | +| xss-through-filenames.js:35:13:35:35 | files3 | xss-through-filenames.js:37:19:37:24 | files3 | provenance | | +| xss-through-filenames.js:35:22:35:35 | format(files2) | xss-through-filenames.js:35:13:35:35 | files3 | provenance | | +| xss-through-filenames.js:35:29:35:34 | files2 | xss-through-filenames.js:17:21:17:26 | files2 | provenance | | +| xss-through-filenames.js:35:29:35:34 | files2 | xss-through-filenames.js:35:22:35:35 | format(files2) | provenance | | +| xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | xss-through-filenames.js:17:21:17:26 | files2 [ArrayElement] | provenance | | +| xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | xss-through-filenames.js:35:22:35:35 | format(files2) | provenance | | +| xss-through-torrent.js:6:6:6:24 | name | xss-through-torrent.js:7:11:7:14 | name | provenance | | +| xss-through-torrent.js:6:13:6:24 | torrent.name | xss-through-torrent.js:6:6:6:24 | name | provenance | | nodes | xss-through-filenames.js:7:43:7:48 | files1 | semmle.label | files1 | | xss-through-filenames.js:8:18:8:23 | files1 | semmle.label | files1 | @@ -38,6 +49,10 @@ nodes | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | semmle.label | files2.sort(sort) | | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | semmle.label | files2.sort(sort) [ArrayElement] | | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | semmle.label | files2.sort(sort) [ArrayElement] | +| xss-through-filenames.js:19:45:19:48 | file | semmle.label | file | +| xss-through-filenames.js:20:13:20:18 | [post update] files3 | semmle.label | [post update] files3 | +| xss-through-filenames.js:20:25:20:47 | '
  • ' ... '
  • ' | semmle.label | '
  • ' ... '
  • ' | +| xss-through-filenames.js:20:34:20:37 | file | semmle.label | file | | xss-through-filenames.js:22:16:22:21 | files3 | semmle.label | files3 | | xss-through-filenames.js:22:16:22:21 | files3 | semmle.label | files3 | | xss-through-filenames.js:22:16:22:30 | files3.join('') | semmle.label | files3.join('') | @@ -45,6 +60,10 @@ nodes | xss-through-filenames.js:25:43:25:48 | files1 | semmle.label | files1 | | xss-through-filenames.js:26:19:26:24 | files1 | semmle.label | files1 | | xss-through-filenames.js:30:9:30:14 | files1 | semmle.label | files1 | +| xss-through-filenames.js:30:34:30:37 | file | semmle.label | file | +| xss-through-filenames.js:31:13:31:18 | [post update] files2 | semmle.label | [post update] files2 | +| xss-through-filenames.js:31:13:31:18 | [post update] files2 [ArrayElement] | semmle.label | [post update] files2 [ArrayElement] | +| xss-through-filenames.js:31:25:31:28 | file | semmle.label | file | | xss-through-filenames.js:33:19:33:24 | files2 | semmle.label | files2 | | xss-through-filenames.js:33:19:33:24 | files2 | semmle.label | files2 | | xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | semmle.label | files2 [ArrayElement] | @@ -57,6 +76,13 @@ nodes | xss-through-torrent.js:6:13:6:24 | torrent.name | semmle.label | torrent.name | | xss-through-torrent.js:7:11:7:14 | name | semmle.label | name | subpaths +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:19:45:19:48 | file | xss-through-filenames.js:20:13:20:18 | [post update] files3 | xss-through-filenames.js:22:16:22:21 | files3 | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:19:45:19:48 | file | xss-through-filenames.js:20:13:20:18 | [post update] files3 | xss-through-filenames.js:22:16:22:21 | files3 | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:19:45:19:48 | file | xss-through-filenames.js:20:13:20:18 | [post update] files3 | xss-through-filenames.js:22:16:22:21 | files3 | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:19:45:19:48 | file | xss-through-filenames.js:20:13:20:18 | [post update] files3 | xss-through-filenames.js:22:16:22:21 | files3 | +| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:30:34:30:37 | file | xss-through-filenames.js:31:13:31:18 | [post update] files2 | xss-through-filenames.js:33:19:33:24 | files2 | +| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:30:34:30:37 | file | xss-through-filenames.js:31:13:31:18 | [post update] files2 | xss-through-filenames.js:33:19:33:24 | files2 | +| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:30:34:30:37 | file | xss-through-filenames.js:31:13:31:18 | [post update] files2 [ArrayElement] | xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | | xss-through-filenames.js:35:29:35:34 | files2 | xss-through-filenames.js:17:21:17:26 | files2 | xss-through-filenames.js:22:16:22:30 | files3.join('') | xss-through-filenames.js:35:22:35:35 | format(files2) | | xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | xss-through-filenames.js:17:21:17:26 | files2 [ArrayElement] | xss-through-filenames.js:22:16:22:30 | files3.join('') | xss-through-filenames.js:35:22:35:35 | format(files2) | #select diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected index 997d26fb127..49092b05642 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected @@ -56,45 +56,48 @@ nodes | typed.ts:6:43:6:43 | s | semmle.label | s | | typed.ts:8:40:8:40 | s | semmle.label | s | edges -| jquery-plugin.js:11:27:11:31 | stuff | jquery-plugin.js:14:31:14:35 | stuff | -| jquery-plugin.js:11:34:11:40 | options | jquery-plugin.js:12:31:12:37 | options | -| jquery-plugin.js:12:31:12:37 | options | jquery-plugin.js:12:31:12:41 | options.foo | -| lib2/index.ts:1:28:1:28 | s | lib2/index.ts:2:27:2:27 | s | -| lib2/index.ts:6:29:6:36 | settings | lib2/index.ts:7:58:7:65 | settings | -| lib2/index.ts:6:29:6:36 | settings | lib2/index.ts:13:16:13:23 | settings | -| lib2/index.ts:13:9:13:41 | name | lib2/index.ts:18:62:18:65 | name | -| lib2/index.ts:13:16:13:23 | settings | lib2/index.ts:13:16:13:33 | settings.mySetting | -| lib2/index.ts:13:16:13:33 | settings.mySetting | lib2/index.ts:13:16:13:36 | setting ... ting[i] | -| lib2/index.ts:13:16:13:36 | setting ... ting[i] | lib2/index.ts:13:16:13:41 | setting ... i].name | -| lib2/index.ts:13:16:13:41 | setting ... i].name | lib2/index.ts:13:9:13:41 | name | -| lib2/src/MyNode.ts:1:28:1:28 | s | lib2/src/MyNode.ts:2:29:2:29 | s | -| lib/src/MyNode.ts:1:28:1:28 | s | lib/src/MyNode.ts:2:29:2:29 | s | -| main.js:1:55:1:55 | s | main.js:2:29:2:29 | s | -| main.js:6:49:6:49 | s | main.js:7:49:7:49 | s | -| main.js:11:60:11:60 | s | main.js:12:49:12:49 | s | -| main.js:21:47:21:47 | s | main.js:22:34:22:34 | s | -| main.js:56:28:56:34 | options | main.js:60:41:60:47 | options | -| main.js:57:11:59:5 | defaults | main.js:60:31:60:38 | defaults | -| main.js:57:22:59:5 | {\\n ... "\\n } | main.js:57:11:59:5 | defaults | -| main.js:60:11:60:48 | settings | main.js:62:19:62:26 | settings | -| main.js:60:22:60:48 | $.exten ... ptions) | main.js:60:11:60:48 | settings | -| main.js:60:31:60:38 | defaults | main.js:60:22:60:48 | $.exten ... ptions) | -| main.js:60:41:60:47 | options | main.js:57:22:59:5 | {\\n ... "\\n } | -| main.js:60:41:60:47 | options | main.js:60:22:60:48 | $.exten ... ptions) | -| main.js:62:19:62:26 | settings | main.js:62:19:62:31 | settings.name | -| main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | -| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | -| main.js:89:21:89:21 | x | main.js:90:23:90:23 | x | -| main.js:93:43:93:43 | x | main.js:94:31:94:31 | x | -| main.js:94:31:94:31 | x | main.js:89:21:89:21 | x | -| main.js:98:43:98:43 | x | main.js:99:28:99:28 | x | -| main.js:98:43:98:43 | x | main.js:103:43:103:43 | x | -| main.js:98:43:98:43 | x | main.js:105:26:105:26 | x | -| main.js:98:43:98:43 | x | main.js:109:41:109:41 | x | -| main.js:98:43:98:43 | x | main.js:111:37:111:37 | x | -| main.js:116:47:116:47 | s | main.js:117:34:117:34 | s | -| typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | -| typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s | +| jquery-plugin.js:11:27:11:31 | stuff | jquery-plugin.js:14:31:14:35 | stuff | provenance | | +| jquery-plugin.js:11:34:11:40 | options | jquery-plugin.js:12:31:12:37 | options | provenance | | +| jquery-plugin.js:12:31:12:37 | options | jquery-plugin.js:12:31:12:41 | options.foo | provenance | Config | +| lib2/index.ts:1:28:1:28 | s | lib2/index.ts:2:27:2:27 | s | provenance | | +| lib2/index.ts:6:29:6:36 | settings | lib2/index.ts:7:58:7:65 | settings | provenance | | +| lib2/index.ts:6:29:6:36 | settings | lib2/index.ts:13:16:13:23 | settings | provenance | | +| lib2/index.ts:13:9:13:41 | name | lib2/index.ts:18:62:18:65 | name | provenance | | +| lib2/index.ts:13:16:13:23 | settings | lib2/index.ts:13:16:13:33 | settings.mySetting | provenance | Config | +| lib2/index.ts:13:16:13:33 | settings.mySetting | lib2/index.ts:13:16:13:36 | setting ... ting[i] | provenance | Config | +| lib2/index.ts:13:16:13:36 | setting ... ting[i] | lib2/index.ts:13:16:13:41 | setting ... i].name | provenance | Config | +| lib2/index.ts:13:16:13:41 | setting ... i].name | lib2/index.ts:13:9:13:41 | name | provenance | | +| lib2/src/MyNode.ts:1:28:1:28 | s | lib2/src/MyNode.ts:2:29:2:29 | s | provenance | | +| lib/src/MyNode.ts:1:28:1:28 | s | lib/src/MyNode.ts:2:29:2:29 | s | provenance | | +| main.js:1:55:1:55 | s | main.js:2:29:2:29 | s | provenance | | +| main.js:6:49:6:49 | s | main.js:7:49:7:49 | s | provenance | | +| main.js:11:60:11:60 | s | main.js:12:49:12:49 | s | provenance | | +| main.js:21:47:21:47 | s | main.js:22:34:22:34 | s | provenance | | +| main.js:56:28:56:34 | options | main.js:60:41:60:47 | options | provenance | | +| main.js:57:11:59:5 | defaults | main.js:60:31:60:38 | defaults | provenance | | +| main.js:57:22:59:5 | {\\n ... "\\n } | main.js:57:11:59:5 | defaults | provenance | | +| main.js:60:11:60:48 | settings | main.js:62:19:62:26 | settings | provenance | | +| main.js:60:22:60:48 | $.exten ... ptions) | main.js:60:11:60:48 | settings | provenance | | +| main.js:60:31:60:38 | defaults | main.js:60:22:60:48 | $.exten ... ptions) | provenance | | +| main.js:60:31:60:38 | defaults | main.js:60:22:60:48 | $.exten ... ptions) | provenance | Config | +| main.js:60:41:60:47 | options | main.js:57:22:59:5 | {\\n ... "\\n } | provenance | | +| main.js:60:41:60:47 | options | main.js:57:22:59:5 | {\\n ... "\\n } | provenance | Config | +| main.js:60:41:60:47 | options | main.js:60:22:60:48 | $.exten ... ptions) | provenance | | +| main.js:60:41:60:47 | options | main.js:60:22:60:48 | $.exten ... ptions) | provenance | Config | +| main.js:62:19:62:26 | settings | main.js:62:19:62:31 | settings.name | provenance | Config | +| main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | provenance | | +| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | provenance | | +| main.js:89:21:89:21 | x | main.js:90:23:90:23 | x | provenance | | +| main.js:93:43:93:43 | x | main.js:94:31:94:31 | x | provenance | | +| main.js:94:31:94:31 | x | main.js:89:21:89:21 | x | provenance | | +| main.js:98:43:98:43 | x | main.js:99:28:99:28 | x | provenance | | +| main.js:98:43:98:43 | x | main.js:103:43:103:43 | x | provenance | | +| main.js:98:43:98:43 | x | main.js:105:26:105:26 | x | provenance | | +| main.js:98:43:98:43 | x | main.js:109:41:109:41 | x | provenance | | +| main.js:98:43:98:43 | x | main.js:111:37:111:37 | x | provenance | | +| main.js:116:47:116:47 | s | main.js:117:34:117:34 | s | provenance | | +| typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | provenance | | +| typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s | provenance | | subpaths #select | jquery-plugin.js:12:31:12:41 | options.foo | jquery-plugin.js:11:34:11:40 | options | jquery-plugin.js:12:31:12:41 | options.foo | This HTML construction which depends on $@ might later allow $@. | jquery-plugin.js:11:34:11:40 | options | library input | jquery-plugin.js:12:20:12:53 | " ... /span>" | cross-site scripting | diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected index f0b53a2bcc7..b70b13b4c1b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected @@ -280,358 +280,358 @@ nodes | tst.js:10:10:10:64 | 'SELECT ... d + '"' | semmle.label | 'SELECT ... d + '"' | | tst.js:10:46:10:58 | req.params.id | semmle.label | req.params.id | edges -| graphql.js:8:11:8:28 | id | graphql.js:12:46:12:47 | id | -| graphql.js:8:16:8:28 | req.params.id | graphql.js:8:11:8:28 | id | -| graphql.js:12:46:12:47 | id | graphql.js:10:34:20:5 | `\\n ... }\\n ` | -| graphql.js:26:11:26:28 | id | graphql.js:27:37:27:38 | id | -| graphql.js:26:11:26:28 | id | graphql.js:30:39:30:40 | id | -| graphql.js:26:11:26:28 | id | graphql.js:33:25:33:26 | id | -| graphql.js:26:16:26:28 | req.params.id | graphql.js:26:11:26:28 | id | -| graphql.js:27:37:27:38 | id | graphql.js:27:30:27:40 | `foo ${id}` | -| graphql.js:30:39:30:40 | id | graphql.js:30:32:30:42 | `foo ${id}` | -| graphql.js:33:25:33:26 | id | graphql.js:33:18:33:28 | `foo ${id}` | -| graphql.js:39:11:39:28 | id | graphql.js:44:21:44:22 | id | -| graphql.js:39:11:39:28 | id | graphql.js:48:51:48:52 | id | -| graphql.js:39:16:39:28 | req.params.id | graphql.js:39:11:39:28 | id | -| graphql.js:44:21:44:22 | id | graphql.js:44:14:44:24 | `foo ${id}` | -| graphql.js:48:51:48:52 | id | graphql.js:48:44:48:54 | `foo ${id}` | -| graphql.js:55:11:55:28 | id | graphql.js:56:46:56:47 | id | -| graphql.js:55:11:55:28 | id | graphql.js:58:73:58:74 | id | -| graphql.js:55:16:55:28 | req.params.id | graphql.js:55:11:55:28 | id | -| graphql.js:56:46:56:47 | id | graphql.js:56:39:56:49 | `foo ${id}` | -| graphql.js:58:73:58:74 | id | graphql.js:58:66:58:76 | `foo ${id}` | -| graphql.js:74:9:74:25 | id | graphql.js:75:56:75:57 | id | -| graphql.js:74:9:74:25 | id | graphql.js:88:13:88:14 | id | -| graphql.js:74:14:74:25 | req.query.id | graphql.js:74:9:74:25 | id | -| graphql.js:75:56:75:57 | id | graphql.js:75:46:75:64 | "{ foo" + id + " }" | -| graphql.js:88:13:88:14 | id | graphql.js:84:14:90:8 | `{\\n ... }` | -| graphql.js:119:11:119:28 | id | graphql.js:120:45:120:46 | id | -| graphql.js:119:16:119:28 | req.params.id | graphql.js:119:11:119:28 | id | -| graphql.js:120:45:120:46 | id | graphql.js:120:38:120:48 | `foo ${id}` | -| html-sanitizer.js:13:39:13:44 | param1 | html-sanitizer.js:14:18:14:23 | param1 | -| html-sanitizer.js:14:5:14:24 | param1 | html-sanitizer.js:16:54:16:59 | param1 | -| html-sanitizer.js:14:14:14:24 | xss(param1) | html-sanitizer.js:14:5:14:24 | param1 | -| html-sanitizer.js:14:18:14:23 | param1 | html-sanitizer.js:14:14:14:24 | xss(param1) | -| html-sanitizer.js:16:54:16:59 | param1 | html-sanitizer.js:16:9:16:59 | `SELECT ... param1 | -| json-schema-validator.js:25:15:25:48 | query | json-schema-validator.js:33:22:33:26 | query | -| json-schema-validator.js:25:15:25:48 | query | json-schema-validator.js:35:18:35:22 | query | -| json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | json-schema-validator.js:25:15:25:48 | query | -| json-schema-validator.js:25:34:25:47 | req.query.data | json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | -| json-schema-validator.js:50:15:50:48 | query | json-schema-validator.js:55:22:55:26 | query | -| json-schema-validator.js:50:15:50:48 | query | json-schema-validator.js:59:22:59:26 | query | -| json-schema-validator.js:50:15:50:48 | query | json-schema-validator.js:61:22:61:26 | query | -| json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) | json-schema-validator.js:50:15:50:48 | query | -| json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) | -| koarouter.js:5:11:5:33 | version | koarouter.js:14:38:14:44 | version | -| koarouter.js:5:13:5:19 | version | koarouter.js:5:11:5:33 | version | -| koarouter.js:11:11:11:28 | conditions | koarouter.js:17:52:17:61 | conditions | -| koarouter.js:14:9:14:18 | [post update] conditions | koarouter.js:11:11:11:28 | conditions | -| koarouter.js:14:25:14:46 | `versio ... rsion}` | koarouter.js:14:9:14:18 | [post update] conditions | -| koarouter.js:14:38:14:44 | version | koarouter.js:14:25:14:46 | `versio ... rsion}` | -| koarouter.js:17:52:17:61 | conditions | koarouter.js:17:52:17:75 | conditi ... and ') | -| koarouter.js:17:52:17:75 | conditi ... and ') | koarouter.js:17:27:17:77 | `SELECT ... nd ')}` | -| ldap.js:20:7:20:34 | q | ldap.js:22:18:22:18 | q | -| ldap.js:20:11:20:34 | url.par ... , true) | ldap.js:20:7:20:34 | q | -| ldap.js:20:21:20:27 | req.url | ldap.js:20:11:20:34 | url.par ... , true) | -| ldap.js:22:7:22:33 | username | ldap.js:25:24:25:31 | username | -| ldap.js:22:7:22:33 | username | ldap.js:25:46:25:53 | username | -| ldap.js:22:7:22:33 | username | ldap.js:32:26:32:33 | username | -| ldap.js:22:7:22:33 | username | ldap.js:32:48:32:55 | username | -| ldap.js:22:7:22:33 | username | ldap.js:64:16:64:23 | username | -| ldap.js:22:7:22:33 | username | ldap.js:64:38:64:45 | username | -| ldap.js:22:7:22:33 | username | ldap.js:68:33:68:40 | username | -| ldap.js:22:18:22:18 | q | ldap.js:22:7:22:33 | username | -| ldap.js:25:13:25:57 | `(\|(nam ... ame}))` | ldap.js:28:30:28:34 | opts1 | -| ldap.js:25:24:25:31 | username | ldap.js:25:13:25:57 | `(\|(nam ... ame}))` | -| ldap.js:25:46:25:53 | username | ldap.js:25:13:25:57 | `(\|(nam ... ame}))` | -| ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | ldap.js:32:5:32:61 | { filte ... e}))` } | -| ldap.js:32:26:32:33 | username | ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | -| ldap.js:32:48:32:55 | username | ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | -| ldap.js:63:9:65:3 | parsedFilter | ldap.js:66:40:66:51 | parsedFilter | -| ldap.js:63:24:65:3 | ldap.pa ... ))`\\n ) | ldap.js:63:9:65:3 | parsedFilter | -| ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | ldap.js:63:24:65:3 | ldap.pa ... ))`\\n ) | -| ldap.js:64:16:64:23 | username | ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | -| ldap.js:64:38:64:45 | username | ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | -| ldap.js:66:40:66:51 | parsedFilter | ldap.js:66:30:66:53 | { filte ... ilter } | -| ldap.js:68:33:68:40 | username | ldap.js:68:27:68:42 | `cn=${username}` | -| marsdb-flow-to.js:10:9:10:18 | query | marsdb-flow-to.js:14:17:14:21 | query | -| marsdb-flow-to.js:10:17:10:18 | {} | marsdb-flow-to.js:10:9:10:18 | query | -| marsdb-flow-to.js:11:17:11:24 | req.body | marsdb-flow-to.js:11:17:11:30 | req.body.title | -| marsdb-flow-to.js:11:17:11:30 | req.body.title | marsdb-flow-to.js:10:9:10:18 | query | -| marsdb-flow-to.js:11:17:11:30 | req.body.title | marsdb-flow-to.js:10:17:10:18 | {} | -| marsdb-flow-to.js:11:17:11:30 | req.body.title | marsdb-flow-to.js:14:17:14:21 | query | -| marsdb.js:12:9:12:18 | query | marsdb.js:16:12:16:16 | query | -| marsdb.js:12:17:12:18 | {} | marsdb.js:12:9:12:18 | query | -| marsdb.js:13:17:13:24 | req.body | marsdb.js:13:17:13:30 | req.body.title | -| marsdb.js:13:17:13:30 | req.body.title | marsdb.js:12:9:12:18 | query | -| marsdb.js:13:17:13:30 | req.body.title | marsdb.js:12:17:12:18 | {} | -| marsdb.js:13:17:13:30 | req.body.title | marsdb.js:16:12:16:16 | query | -| minimongo.js:14:9:14:18 | query | minimongo.js:18:12:18:16 | query | -| minimongo.js:14:17:14:18 | {} | minimongo.js:14:9:14:18 | query | -| minimongo.js:15:17:15:24 | req.body | minimongo.js:15:17:15:30 | req.body.title | -| minimongo.js:15:17:15:30 | req.body.title | minimongo.js:14:9:14:18 | query | -| minimongo.js:15:17:15:30 | req.body.title | minimongo.js:14:17:14:18 | {} | -| minimongo.js:15:17:15:30 | req.body.title | minimongo.js:18:12:18:16 | query | -| mongodb.js:12:11:12:20 | query | mongodb.js:13:5:13:9 | query | -| mongodb.js:12:19:12:20 | {} | mongodb.js:12:11:12:20 | query | -| mongodb.js:13:5:13:9 | query | mongodb.js:18:16:18:20 | query | -| mongodb.js:13:19:13:26 | req.body | mongodb.js:13:19:13:32 | req.body.title | -| mongodb.js:13:19:13:32 | req.body.title | mongodb.js:12:11:12:20 | query | -| mongodb.js:13:19:13:32 | req.body.title | mongodb.js:12:19:12:20 | {} | -| mongodb.js:13:19:13:32 | req.body.title | mongodb.js:13:5:13:9 | query | -| mongodb.js:13:19:13:32 | req.body.title | mongodb.js:18:16:18:20 | query | -| mongodb.js:26:11:26:32 | title | mongodb.js:32:38:32:42 | title | -| mongodb.js:26:19:26:26 | req.body | mongodb.js:26:19:26:32 | req.body.title | -| mongodb.js:26:19:26:32 | req.body.title | mongodb.js:26:11:26:32 | title | -| mongodb.js:32:27:32:43 | JSON.parse(title) | mongodb.js:32:18:32:45 | { title ... itle) } | -| mongodb.js:32:38:32:42 | title | mongodb.js:32:27:32:43 | JSON.parse(title) | -| mongodb.js:48:11:48:20 | query | mongodb.js:49:5:49:9 | query | -| mongodb.js:48:19:48:20 | {} | mongodb.js:48:11:48:20 | query | -| mongodb.js:49:5:49:9 | query | mongodb.js:54:16:54:20 | query | -| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:48:11:48:20 | query | -| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:48:19:48:20 | {} | -| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:49:5:49:9 | query | -| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:54:16:54:20 | query | -| mongodb.js:59:8:59:17 | query | mongodb.js:60:2:60:6 | query | -| mongodb.js:59:16:59:17 | {} | mongodb.js:59:8:59:17 | query | -| mongodb.js:60:2:60:6 | query | mongodb.js:65:12:65:16 | query | -| mongodb.js:60:16:60:30 | req.query.title | mongodb.js:59:8:59:17 | query | -| mongodb.js:60:16:60:30 | req.query.title | mongodb.js:59:16:59:17 | {} | -| mongodb.js:60:16:60:30 | req.query.title | mongodb.js:60:2:60:6 | query | -| mongodb.js:60:16:60:30 | req.query.title | mongodb.js:65:12:65:16 | query | -| mongodb.js:70:7:70:25 | tag | mongodb.js:77:22:77:24 | tag | -| mongodb.js:70:7:70:25 | tag | mongodb.js:85:20:85:22 | tag | -| mongodb.js:70:13:70:25 | req.query.tag | mongodb.js:70:7:70:25 | tag | -| mongodb.js:77:22:77:24 | tag | mongodb.js:77:14:77:26 | { tags: tag } | -| mongodb.js:85:20:85:22 | tag | mongodb.js:85:12:85:24 | { tags: tag } | -| mongodb.js:106:9:106:18 | query | mongodb.js:107:3:107:7 | query | -| mongodb.js:106:17:106:18 | {} | mongodb.js:106:9:106:18 | query | -| mongodb.js:107:3:107:7 | query | mongodb.js:112:14:112:18 | query | -| mongodb.js:107:17:107:29 | queries.title | mongodb.js:106:9:106:18 | query | -| mongodb.js:107:17:107:29 | queries.title | mongodb.js:106:17:106:18 | {} | -| mongodb.js:107:17:107:29 | queries.title | mongodb.js:107:3:107:7 | query | -| mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query | -| mongodb_bodySafe.js:23:11:23:20 | query | mongodb_bodySafe.js:24:5:24:9 | query | -| mongodb_bodySafe.js:23:19:23:20 | {} | mongodb_bodySafe.js:23:11:23:20 | query | -| mongodb_bodySafe.js:24:5:24:9 | query | mongodb_bodySafe.js:29:16:29:20 | query | -| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:23:11:23:20 | query | -| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:23:19:23:20 | {} | -| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:24:5:24:9 | query | -| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:21:2:21:6 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:24:22:24:26 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:27:17:27:21 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:30:22:30:26 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:33:21:33:25 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:36:28:36:32 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:39:16:39:20 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:42:19:42:23 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:45:28:45:32 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:48:28:48:32 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:51:28:51:32 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:54:22:54:26 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:57:18:57:22 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:60:22:60:26 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:63:21:63:25 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:65:32:65:36 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:67:27:67:31 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:68:8:68:12 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:71:17:71:21 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:72:10:72:14 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:73:8:73:12 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:74:7:74:11 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:75:16:75:20 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:76:12:76:16 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:77:10:77:14 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:81:37:81:41 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:82:46:82:50 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:83:47:83:51 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:104:21:104:25 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:111:14:111:18 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:113:31:113:35 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:133:38:133:42 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:134:30:134:34 | query | -| mongoose.js:20:8:20:17 | query | mongoose.js:136:30:136:34 | query | -| mongoose.js:20:16:20:17 | {} | mongoose.js:20:8:20:17 | query | -| mongoose.js:21:2:21:6 | query | mongoose.js:24:22:24:26 | query | -| mongoose.js:21:16:21:23 | req.body | mongoose.js:21:16:21:29 | req.body.title | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:20:8:20:17 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:20:16:20:17 | {} | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:21:2:21:6 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:24:22:24:26 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:27:17:27:21 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:30:22:30:26 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:33:21:33:25 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:36:28:36:32 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:39:16:39:20 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:42:19:42:23 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:45:28:45:32 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:48:28:48:32 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:51:28:51:32 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:54:22:54:26 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:57:18:57:22 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:60:22:60:26 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:63:21:63:25 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:65:32:65:36 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:67:27:67:31 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:68:8:68:12 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:71:17:71:21 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:72:10:72:14 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:73:8:73:12 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:74:7:74:11 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:75:16:75:20 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:76:12:76:16 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:77:10:77:14 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:81:37:81:41 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:82:46:82:50 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:83:47:83:51 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:85:46:85:50 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:87:51:87:55 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:89:46:89:50 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:92:46:92:50 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:94:51:94:55 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:96:46:96:50 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:104:21:104:25 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:111:14:111:18 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:113:31:113:35 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:133:38:133:42 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:134:30:134:34 | query | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:136:30:136:34 | query | -| mongoose.js:24:22:24:26 | query | mongoose.js:24:21:24:27 | [query] | -| mongoose.js:24:22:24:26 | query | mongoose.js:27:17:27:21 | query | -| mongoose.js:27:17:27:21 | query | mongoose.js:30:22:30:26 | query | -| mongoose.js:30:22:30:26 | query | mongoose.js:33:21:33:25 | query | -| mongoose.js:33:21:33:25 | query | mongoose.js:36:28:36:32 | query | -| mongoose.js:36:28:36:32 | query | mongoose.js:39:16:39:20 | query | -| mongoose.js:39:16:39:20 | query | mongoose.js:42:19:42:23 | query | -| mongoose.js:42:19:42:23 | query | mongoose.js:45:28:45:32 | query | -| mongoose.js:45:28:45:32 | query | mongoose.js:48:28:48:32 | query | -| mongoose.js:48:28:48:32 | query | mongoose.js:51:28:51:32 | query | -| mongoose.js:51:28:51:32 | query | mongoose.js:54:22:54:26 | query | -| mongoose.js:54:22:54:26 | query | mongoose.js:57:18:57:22 | query | -| mongoose.js:57:18:57:22 | query | mongoose.js:60:22:60:26 | query | -| mongoose.js:60:22:60:26 | query | mongoose.js:63:21:63:25 | query | -| mongoose.js:63:21:63:25 | query | mongoose.js:65:32:65:36 | query | -| mongoose.js:65:32:65:36 | query | mongoose.js:67:27:67:31 | query | -| mongoose.js:67:27:67:31 | query | mongoose.js:68:8:68:12 | query | -| mongoose.js:68:8:68:12 | query | mongoose.js:71:17:71:21 | query | -| mongoose.js:71:17:71:21 | query | mongoose.js:72:10:72:14 | query | -| mongoose.js:72:10:72:14 | query | mongoose.js:73:8:73:12 | query | -| mongoose.js:73:8:73:12 | query | mongoose.js:74:7:74:11 | query | -| mongoose.js:74:7:74:11 | query | mongoose.js:75:16:75:20 | query | -| mongoose.js:75:16:75:20 | query | mongoose.js:76:12:76:16 | query | -| mongoose.js:76:12:76:16 | query | mongoose.js:77:10:77:14 | query | -| mongoose.js:77:10:77:14 | query | mongoose.js:81:37:81:41 | query | -| mongoose.js:81:37:81:41 | query | mongoose.js:82:46:82:50 | query | -| mongoose.js:82:46:82:50 | query | mongoose.js:83:47:83:51 | query | -| mongoose.js:83:47:83:51 | query | mongoose.js:85:46:85:50 | query | -| mongoose.js:83:47:83:51 | query | mongoose.js:87:51:87:55 | query | -| mongoose.js:83:47:83:51 | query | mongoose.js:89:46:89:50 | query | -| mongoose.js:83:47:83:51 | query | mongoose.js:92:46:92:50 | query | -| mongoose.js:83:47:83:51 | query | mongoose.js:94:51:94:55 | query | -| mongoose.js:83:47:83:51 | query | mongoose.js:96:46:96:50 | query | -| mongoose.js:83:47:83:51 | query | mongoose.js:104:21:104:25 | query | -| mongoose.js:104:21:104:25 | query | mongoose.js:111:14:111:18 | query | -| mongoose.js:111:14:111:18 | query | mongoose.js:113:31:113:35 | query | -| mongoose.js:113:31:113:35 | query | mongoose.js:133:38:133:42 | query | -| mongoose.js:115:6:115:22 | id | mongoose.js:123:20:123:21 | id | -| mongoose.js:115:6:115:22 | id | mongoose.js:130:23:130:24 | id | -| mongoose.js:115:11:115:22 | req.query.id | mongoose.js:115:6:115:22 | id | -| mongoose.js:115:25:115:45 | cond | mongoose.js:116:22:116:25 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:117:21:117:24 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:118:21:118:24 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:119:18:119:21 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:120:22:120:25 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:121:16:121:19 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:122:19:122:22 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:124:28:124:31 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:125:28:125:31 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:126:28:126:31 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:127:18:127:21 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:128:22:128:25 | cond | -| mongoose.js:115:25:115:45 | cond | mongoose.js:129:21:129:24 | cond | -| mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:115:25:115:45 | cond | -| mongoose.js:130:23:130:24 | id | mongoose.js:130:16:130:26 | { _id: id } | -| mongoose.js:133:38:133:42 | query | mongoose.js:134:30:134:34 | query | -| mongoose.js:133:38:133:42 | query | mongoose.js:136:30:136:34 | query | -| mongooseJsonParse.js:19:11:19:20 | query | mongooseJsonParse.js:23:19:23:23 | query | -| mongooseJsonParse.js:19:19:19:20 | {} | mongooseJsonParse.js:19:11:19:20 | query | -| mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) | mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | -| mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | mongooseJsonParse.js:19:11:19:20 | query | -| mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | mongooseJsonParse.js:19:19:19:20 | {} | -| mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | mongooseJsonParse.js:23:19:23:23 | query | -| mongooseJsonParse.js:20:30:20:43 | req.query.data | mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) | -| mongooseModelClient.js:10:7:10:32 | v | mongooseModelClient.js:11:22:11:22 | v | -| mongooseModelClient.js:10:11:10:32 | JSON.pa ... body.x) | mongooseModelClient.js:10:7:10:32 | v | -| mongooseModelClient.js:10:22:10:29 | req.body | mongooseModelClient.js:10:22:10:31 | req.body.x | -| mongooseModelClient.js:10:22:10:31 | req.body.x | mongooseModelClient.js:10:11:10:32 | JSON.pa ... body.x) | -| mongooseModelClient.js:11:22:11:22 | v | mongooseModelClient.js:11:16:11:24 | { id: v } | -| mongooseModelClient.js:12:22:12:29 | req.body | mongooseModelClient.js:12:22:12:32 | req.body.id | -| mongooseModelClient.js:12:22:12:32 | req.body.id | mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | -| mysql.js:6:9:6:31 | temp | mysql.js:15:62:15:65 | temp | -| mysql.js:6:9:6:31 | temp | mysql.js:19:70:19:73 | temp | -| mysql.js:6:16:6:31 | req.params.value | mysql.js:6:9:6:31 | temp | -| mysql.js:15:62:15:65 | temp | mysql.js:15:18:15:65 | 'SELECT ... + temp | -| mysql.js:19:70:19:73 | temp | mysql.js:19:26:19:73 | 'SELECT ... + temp | -| pg-promise-types.ts:7:9:7:28 | taint | pg-promise-types.ts:8:17:8:21 | taint | -| pg-promise-types.ts:7:17:7:28 | req.params.x | pg-promise-types.ts:7:9:7:28 | taint | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:9:10:9:14 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:10:11:10:15 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:11:17:11:21 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:12:10:12:14 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:13:12:13:16 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:14:18:14:22 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:15:11:15:15 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:16:10:16:14 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:17:16:17:20 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:18:12:18:16 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:19:13:19:17 | query | -| pg-promise.js:6:7:7:55 | query | pg-promise.js:22:11:22:15 | query | -| pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:6:7:7:55 | query | -| pg-promise.js:9:10:9:14 | query | pg-promise.js:10:11:10:15 | query | -| pg-promise.js:10:11:10:15 | query | pg-promise.js:11:17:11:21 | query | -| pg-promise.js:11:17:11:21 | query | pg-promise.js:12:10:12:14 | query | -| pg-promise.js:12:10:12:14 | query | pg-promise.js:13:12:13:16 | query | -| pg-promise.js:13:12:13:16 | query | pg-promise.js:14:18:14:22 | query | -| pg-promise.js:14:18:14:22 | query | pg-promise.js:15:11:15:15 | query | -| pg-promise.js:15:11:15:15 | query | pg-promise.js:16:10:16:14 | query | -| pg-promise.js:16:10:16:14 | query | pg-promise.js:17:16:17:20 | query | -| pg-promise.js:17:16:17:20 | query | pg-promise.js:18:12:18:16 | query | -| pg-promise.js:18:12:18:16 | query | pg-promise.js:19:13:19:17 | query | -| pg-promise.js:19:13:19:17 | query | pg-promise.js:22:11:22:15 | query | -| pg-promise.js:22:11:22:15 | query | pg-promise.js:60:20:60:24 | query | -| pg-promise.js:22:11:22:15 | query | pg-promise.js:63:23:63:27 | query | -| pg-promise.js:22:11:22:15 | query | pg-promise.js:64:16:64:20 | query | -| pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| pg-promise.js:41:7:41:20 | req.params.foo | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | -| redis.js:10:16:10:23 | req.body | redis.js:10:16:10:27 | req.body.key | -| redis.js:12:9:12:26 | key | redis.js:13:16:13:18 | key | -| redis.js:12:9:12:26 | key | redis.js:18:16:18:18 | key | -| redis.js:12:9:12:26 | key | redis.js:19:43:19:45 | key | -| redis.js:12:9:12:26 | key | redis.js:25:14:25:16 | key | -| redis.js:12:9:12:26 | key | redis.js:26:14:26:16 | key | -| redis.js:12:9:12:26 | key | redis.js:32:28:32:30 | key | -| redis.js:12:15:12:22 | req.body | redis.js:12:15:12:26 | req.body.key | -| redis.js:12:15:12:26 | req.body.key | redis.js:12:9:12:26 | key | -| redis.js:13:16:13:18 | key | redis.js:18:16:18:18 | key | -| redis.js:18:16:18:18 | key | redis.js:19:43:19:45 | key | -| redis.js:19:43:19:45 | key | redis.js:25:14:25:16 | key | -| redis.js:25:14:25:16 | key | redis.js:26:14:26:16 | key | -| redis.js:26:14:26:16 | key | redis.js:30:23:30:25 | key | -| redis.js:26:14:26:16 | key | redis.js:32:28:32:30 | key | -| redis.js:38:11:38:28 | key | redis.js:39:16:39:18 | key | -| redis.js:38:11:38:28 | key | redis.js:43:27:43:29 | key | -| redis.js:38:11:38:28 | key | redis.js:46:34:46:36 | key | -| redis.js:38:17:38:24 | req.body | redis.js:38:17:38:28 | req.body.key | -| redis.js:38:17:38:28 | req.body.key | redis.js:38:11:38:28 | key | -| socketio.js:10:25:10:30 | handle | socketio.js:11:46:11:51 | handle | -| socketio.js:11:46:11:51 | handle | socketio.js:11:12:11:53 | `INSERT ... andle}` | -| tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" | -| tst3.js:7:7:8:55 | query1 | tst3.js:9:14:9:19 | query1 | -| tst3.js:8:16:8:34 | req.params.category | tst3.js:7:7:8:55 | query1 | -| tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | -| tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | +| graphql.js:8:11:8:28 | id | graphql.js:12:46:12:47 | id | provenance | | +| graphql.js:8:16:8:28 | req.params.id | graphql.js:8:11:8:28 | id | provenance | | +| graphql.js:12:46:12:47 | id | graphql.js:10:34:20:5 | `\\n ... }\\n ` | provenance | | +| graphql.js:26:11:26:28 | id | graphql.js:27:37:27:38 | id | provenance | | +| graphql.js:26:11:26:28 | id | graphql.js:30:39:30:40 | id | provenance | | +| graphql.js:26:11:26:28 | id | graphql.js:33:25:33:26 | id | provenance | | +| graphql.js:26:16:26:28 | req.params.id | graphql.js:26:11:26:28 | id | provenance | | +| graphql.js:27:37:27:38 | id | graphql.js:27:30:27:40 | `foo ${id}` | provenance | | +| graphql.js:30:39:30:40 | id | graphql.js:30:32:30:42 | `foo ${id}` | provenance | | +| graphql.js:33:25:33:26 | id | graphql.js:33:18:33:28 | `foo ${id}` | provenance | | +| graphql.js:39:11:39:28 | id | graphql.js:44:21:44:22 | id | provenance | | +| graphql.js:39:11:39:28 | id | graphql.js:48:51:48:52 | id | provenance | | +| graphql.js:39:16:39:28 | req.params.id | graphql.js:39:11:39:28 | id | provenance | | +| graphql.js:44:21:44:22 | id | graphql.js:44:14:44:24 | `foo ${id}` | provenance | | +| graphql.js:48:51:48:52 | id | graphql.js:48:44:48:54 | `foo ${id}` | provenance | | +| graphql.js:55:11:55:28 | id | graphql.js:56:46:56:47 | id | provenance | | +| graphql.js:55:11:55:28 | id | graphql.js:58:73:58:74 | id | provenance | | +| graphql.js:55:16:55:28 | req.params.id | graphql.js:55:11:55:28 | id | provenance | | +| graphql.js:56:46:56:47 | id | graphql.js:56:39:56:49 | `foo ${id}` | provenance | | +| graphql.js:58:73:58:74 | id | graphql.js:58:66:58:76 | `foo ${id}` | provenance | | +| graphql.js:74:9:74:25 | id | graphql.js:75:56:75:57 | id | provenance | | +| graphql.js:74:9:74:25 | id | graphql.js:88:13:88:14 | id | provenance | | +| graphql.js:74:14:74:25 | req.query.id | graphql.js:74:9:74:25 | id | provenance | | +| graphql.js:75:56:75:57 | id | graphql.js:75:46:75:64 | "{ foo" + id + " }" | provenance | | +| graphql.js:88:13:88:14 | id | graphql.js:84:14:90:8 | `{\\n ... }` | provenance | | +| graphql.js:119:11:119:28 | id | graphql.js:120:45:120:46 | id | provenance | | +| graphql.js:119:16:119:28 | req.params.id | graphql.js:119:11:119:28 | id | provenance | | +| graphql.js:120:45:120:46 | id | graphql.js:120:38:120:48 | `foo ${id}` | provenance | | +| html-sanitizer.js:13:39:13:44 | param1 | html-sanitizer.js:14:18:14:23 | param1 | provenance | | +| html-sanitizer.js:14:5:14:24 | param1 | html-sanitizer.js:16:54:16:59 | param1 | provenance | | +| html-sanitizer.js:14:14:14:24 | xss(param1) | html-sanitizer.js:14:5:14:24 | param1 | provenance | | +| html-sanitizer.js:14:18:14:23 | param1 | html-sanitizer.js:14:14:14:24 | xss(param1) | provenance | Config | +| html-sanitizer.js:16:54:16:59 | param1 | html-sanitizer.js:16:9:16:59 | `SELECT ... param1 | provenance | | +| json-schema-validator.js:25:15:25:48 | query | json-schema-validator.js:33:22:33:26 | query | provenance | | +| json-schema-validator.js:25:15:25:48 | query | json-schema-validator.js:35:18:35:22 | query | provenance | | +| json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | json-schema-validator.js:25:15:25:48 | query | provenance | | +| json-schema-validator.js:25:34:25:47 | req.query.data | json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | provenance | Config | +| json-schema-validator.js:50:15:50:48 | query | json-schema-validator.js:55:22:55:26 | query | provenance | | +| json-schema-validator.js:50:15:50:48 | query | json-schema-validator.js:59:22:59:26 | query | provenance | | +| json-schema-validator.js:50:15:50:48 | query | json-schema-validator.js:61:22:61:26 | query | provenance | | +| json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) | json-schema-validator.js:50:15:50:48 | query | provenance | | +| json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) | provenance | Config | +| koarouter.js:5:11:5:33 | version | koarouter.js:14:38:14:44 | version | provenance | | +| koarouter.js:5:13:5:19 | version | koarouter.js:5:11:5:33 | version | provenance | | +| koarouter.js:11:11:11:28 | conditions | koarouter.js:17:52:17:61 | conditions | provenance | | +| koarouter.js:14:9:14:18 | [post update] conditions | koarouter.js:11:11:11:28 | conditions | provenance | | +| koarouter.js:14:25:14:46 | `versio ... rsion}` | koarouter.js:14:9:14:18 | [post update] conditions | provenance | | +| koarouter.js:14:38:14:44 | version | koarouter.js:14:25:14:46 | `versio ... rsion}` | provenance | | +| koarouter.js:17:52:17:61 | conditions | koarouter.js:17:52:17:75 | conditi ... and ') | provenance | | +| koarouter.js:17:52:17:75 | conditi ... and ') | koarouter.js:17:27:17:77 | `SELECT ... nd ')}` | provenance | | +| ldap.js:20:7:20:34 | q | ldap.js:22:18:22:18 | q | provenance | | +| ldap.js:20:11:20:34 | url.par ... , true) | ldap.js:20:7:20:34 | q | provenance | | +| ldap.js:20:21:20:27 | req.url | ldap.js:20:11:20:34 | url.par ... , true) | provenance | | +| ldap.js:22:7:22:33 | username | ldap.js:25:24:25:31 | username | provenance | | +| ldap.js:22:7:22:33 | username | ldap.js:25:46:25:53 | username | provenance | | +| ldap.js:22:7:22:33 | username | ldap.js:32:26:32:33 | username | provenance | | +| ldap.js:22:7:22:33 | username | ldap.js:32:48:32:55 | username | provenance | | +| ldap.js:22:7:22:33 | username | ldap.js:64:16:64:23 | username | provenance | | +| ldap.js:22:7:22:33 | username | ldap.js:64:38:64:45 | username | provenance | | +| ldap.js:22:7:22:33 | username | ldap.js:68:33:68:40 | username | provenance | | +| ldap.js:22:18:22:18 | q | ldap.js:22:7:22:33 | username | provenance | | +| ldap.js:25:13:25:57 | `(\|(nam ... ame}))` | ldap.js:28:30:28:34 | opts1 | provenance | Config | +| ldap.js:25:24:25:31 | username | ldap.js:25:13:25:57 | `(\|(nam ... ame}))` | provenance | | +| ldap.js:25:46:25:53 | username | ldap.js:25:13:25:57 | `(\|(nam ... ame}))` | provenance | | +| ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | ldap.js:32:5:32:61 | { filte ... e}))` } | provenance | Config | +| ldap.js:32:26:32:33 | username | ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | provenance | | +| ldap.js:32:48:32:55 | username | ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | provenance | | +| ldap.js:63:9:65:3 | parsedFilter | ldap.js:66:40:66:51 | parsedFilter | provenance | | +| ldap.js:63:24:65:3 | ldap.pa ... ))`\\n ) | ldap.js:63:9:65:3 | parsedFilter | provenance | | +| ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | ldap.js:63:24:65:3 | ldap.pa ... ))`\\n ) | provenance | Config | +| ldap.js:64:16:64:23 | username | ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | provenance | | +| ldap.js:64:38:64:45 | username | ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | provenance | | +| ldap.js:66:40:66:51 | parsedFilter | ldap.js:66:30:66:53 | { filte ... ilter } | provenance | Config | +| ldap.js:68:33:68:40 | username | ldap.js:68:27:68:42 | `cn=${username}` | provenance | | +| marsdb-flow-to.js:10:9:10:18 | query | marsdb-flow-to.js:14:17:14:21 | query | provenance | | +| marsdb-flow-to.js:10:17:10:18 | {} | marsdb-flow-to.js:10:9:10:18 | query | provenance | | +| marsdb-flow-to.js:11:17:11:24 | req.body | marsdb-flow-to.js:11:17:11:30 | req.body.title | provenance | Config | +| marsdb-flow-to.js:11:17:11:30 | req.body.title | marsdb-flow-to.js:10:9:10:18 | query | provenance | Config | +| marsdb-flow-to.js:11:17:11:30 | req.body.title | marsdb-flow-to.js:10:17:10:18 | {} | provenance | Config | +| marsdb-flow-to.js:11:17:11:30 | req.body.title | marsdb-flow-to.js:14:17:14:21 | query | provenance | Config | +| marsdb.js:12:9:12:18 | query | marsdb.js:16:12:16:16 | query | provenance | | +| marsdb.js:12:17:12:18 | {} | marsdb.js:12:9:12:18 | query | provenance | | +| marsdb.js:13:17:13:24 | req.body | marsdb.js:13:17:13:30 | req.body.title | provenance | Config | +| marsdb.js:13:17:13:30 | req.body.title | marsdb.js:12:9:12:18 | query | provenance | Config | +| marsdb.js:13:17:13:30 | req.body.title | marsdb.js:12:17:12:18 | {} | provenance | Config | +| marsdb.js:13:17:13:30 | req.body.title | marsdb.js:16:12:16:16 | query | provenance | Config | +| minimongo.js:14:9:14:18 | query | minimongo.js:18:12:18:16 | query | provenance | | +| minimongo.js:14:17:14:18 | {} | minimongo.js:14:9:14:18 | query | provenance | | +| minimongo.js:15:17:15:24 | req.body | minimongo.js:15:17:15:30 | req.body.title | provenance | Config | +| minimongo.js:15:17:15:30 | req.body.title | minimongo.js:14:9:14:18 | query | provenance | Config | +| minimongo.js:15:17:15:30 | req.body.title | minimongo.js:14:17:14:18 | {} | provenance | Config | +| minimongo.js:15:17:15:30 | req.body.title | minimongo.js:18:12:18:16 | query | provenance | Config | +| mongodb.js:12:11:12:20 | query | mongodb.js:13:5:13:9 | query | provenance | | +| mongodb.js:12:19:12:20 | {} | mongodb.js:12:11:12:20 | query | provenance | | +| mongodb.js:13:5:13:9 | query | mongodb.js:18:16:18:20 | query | provenance | | +| mongodb.js:13:19:13:26 | req.body | mongodb.js:13:19:13:32 | req.body.title | provenance | Config | +| mongodb.js:13:19:13:32 | req.body.title | mongodb.js:12:11:12:20 | query | provenance | Config | +| mongodb.js:13:19:13:32 | req.body.title | mongodb.js:12:19:12:20 | {} | provenance | Config | +| mongodb.js:13:19:13:32 | req.body.title | mongodb.js:13:5:13:9 | query | provenance | Config | +| mongodb.js:13:19:13:32 | req.body.title | mongodb.js:18:16:18:20 | query | provenance | Config | +| mongodb.js:26:11:26:32 | title | mongodb.js:32:38:32:42 | title | provenance | | +| mongodb.js:26:19:26:26 | req.body | mongodb.js:26:19:26:32 | req.body.title | provenance | Config | +| mongodb.js:26:19:26:32 | req.body.title | mongodb.js:26:11:26:32 | title | provenance | | +| mongodb.js:32:27:32:43 | JSON.parse(title) | mongodb.js:32:18:32:45 | { title ... itle) } | provenance | Config | +| mongodb.js:32:38:32:42 | title | mongodb.js:32:27:32:43 | JSON.parse(title) | provenance | Config | +| mongodb.js:48:11:48:20 | query | mongodb.js:49:5:49:9 | query | provenance | | +| mongodb.js:48:19:48:20 | {} | mongodb.js:48:11:48:20 | query | provenance | | +| mongodb.js:49:5:49:9 | query | mongodb.js:54:16:54:20 | query | provenance | | +| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:48:11:48:20 | query | provenance | Config | +| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:48:19:48:20 | {} | provenance | Config | +| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:49:5:49:9 | query | provenance | Config | +| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:54:16:54:20 | query | provenance | Config | +| mongodb.js:59:8:59:17 | query | mongodb.js:60:2:60:6 | query | provenance | | +| mongodb.js:59:16:59:17 | {} | mongodb.js:59:8:59:17 | query | provenance | | +| mongodb.js:60:2:60:6 | query | mongodb.js:65:12:65:16 | query | provenance | | +| mongodb.js:60:16:60:30 | req.query.title | mongodb.js:59:8:59:17 | query | provenance | Config | +| mongodb.js:60:16:60:30 | req.query.title | mongodb.js:59:16:59:17 | {} | provenance | Config | +| mongodb.js:60:16:60:30 | req.query.title | mongodb.js:60:2:60:6 | query | provenance | Config | +| mongodb.js:60:16:60:30 | req.query.title | mongodb.js:65:12:65:16 | query | provenance | Config | +| mongodb.js:70:7:70:25 | tag | mongodb.js:77:22:77:24 | tag | provenance | | +| mongodb.js:70:7:70:25 | tag | mongodb.js:85:20:85:22 | tag | provenance | | +| mongodb.js:70:13:70:25 | req.query.tag | mongodb.js:70:7:70:25 | tag | provenance | | +| mongodb.js:77:22:77:24 | tag | mongodb.js:77:14:77:26 | { tags: tag } | provenance | Config | +| mongodb.js:85:20:85:22 | tag | mongodb.js:85:12:85:24 | { tags: tag } | provenance | Config | +| mongodb.js:106:9:106:18 | query | mongodb.js:107:3:107:7 | query | provenance | | +| mongodb.js:106:17:106:18 | {} | mongodb.js:106:9:106:18 | query | provenance | | +| mongodb.js:107:3:107:7 | query | mongodb.js:112:14:112:18 | query | provenance | | +| mongodb.js:107:17:107:29 | queries.title | mongodb.js:106:9:106:18 | query | provenance | Config | +| mongodb.js:107:17:107:29 | queries.title | mongodb.js:106:17:106:18 | {} | provenance | Config | +| mongodb.js:107:17:107:29 | queries.title | mongodb.js:107:3:107:7 | query | provenance | Config | +| mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query | provenance | Config | +| mongodb_bodySafe.js:23:11:23:20 | query | mongodb_bodySafe.js:24:5:24:9 | query | provenance | | +| mongodb_bodySafe.js:23:19:23:20 | {} | mongodb_bodySafe.js:23:11:23:20 | query | provenance | | +| mongodb_bodySafe.js:24:5:24:9 | query | mongodb_bodySafe.js:29:16:29:20 | query | provenance | | +| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:23:11:23:20 | query | provenance | Config | +| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:23:19:23:20 | {} | provenance | Config | +| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:24:5:24:9 | query | provenance | Config | +| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | provenance | Config | +| mongoose.js:20:8:20:17 | query | mongoose.js:21:2:21:6 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:24:22:24:26 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:27:17:27:21 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:30:22:30:26 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:33:21:33:25 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:36:28:36:32 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:39:16:39:20 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:42:19:42:23 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:45:28:45:32 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:48:28:48:32 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:51:28:51:32 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:54:22:54:26 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:57:18:57:22 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:60:22:60:26 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:63:21:63:25 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:65:32:65:36 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:67:27:67:31 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:68:8:68:12 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:71:17:71:21 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:72:10:72:14 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:73:8:73:12 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:74:7:74:11 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:75:16:75:20 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:76:12:76:16 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:77:10:77:14 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:81:37:81:41 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:82:46:82:50 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:83:47:83:51 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:104:21:104:25 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:111:14:111:18 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:113:31:113:35 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:133:38:133:42 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:134:30:134:34 | query | provenance | | +| mongoose.js:20:8:20:17 | query | mongoose.js:136:30:136:34 | query | provenance | | +| mongoose.js:20:16:20:17 | {} | mongoose.js:20:8:20:17 | query | provenance | | +| mongoose.js:21:2:21:6 | query | mongoose.js:24:22:24:26 | query | provenance | | +| mongoose.js:21:16:21:23 | req.body | mongoose.js:21:16:21:29 | req.body.title | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:20:8:20:17 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:20:16:20:17 | {} | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:21:2:21:6 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:24:22:24:26 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:27:17:27:21 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:30:22:30:26 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:33:21:33:25 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:36:28:36:32 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:39:16:39:20 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:42:19:42:23 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:45:28:45:32 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:48:28:48:32 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:51:28:51:32 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:54:22:54:26 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:57:18:57:22 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:60:22:60:26 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:63:21:63:25 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:65:32:65:36 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:67:27:67:31 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:68:8:68:12 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:71:17:71:21 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:72:10:72:14 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:73:8:73:12 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:74:7:74:11 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:75:16:75:20 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:76:12:76:16 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:77:10:77:14 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:81:37:81:41 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:82:46:82:50 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:83:47:83:51 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:85:46:85:50 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:87:51:87:55 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:89:46:89:50 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:92:46:92:50 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:94:51:94:55 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:96:46:96:50 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:104:21:104:25 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:111:14:111:18 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:113:31:113:35 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:133:38:133:42 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:134:30:134:34 | query | provenance | Config | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:136:30:136:34 | query | provenance | Config | +| mongoose.js:24:22:24:26 | query | mongoose.js:24:21:24:27 | [query] | provenance | Config | +| mongoose.js:24:22:24:26 | query | mongoose.js:27:17:27:21 | query | provenance | | +| mongoose.js:27:17:27:21 | query | mongoose.js:30:22:30:26 | query | provenance | | +| mongoose.js:30:22:30:26 | query | mongoose.js:33:21:33:25 | query | provenance | | +| mongoose.js:33:21:33:25 | query | mongoose.js:36:28:36:32 | query | provenance | | +| mongoose.js:36:28:36:32 | query | mongoose.js:39:16:39:20 | query | provenance | | +| mongoose.js:39:16:39:20 | query | mongoose.js:42:19:42:23 | query | provenance | | +| mongoose.js:42:19:42:23 | query | mongoose.js:45:28:45:32 | query | provenance | | +| mongoose.js:45:28:45:32 | query | mongoose.js:48:28:48:32 | query | provenance | | +| mongoose.js:48:28:48:32 | query | mongoose.js:51:28:51:32 | query | provenance | | +| mongoose.js:51:28:51:32 | query | mongoose.js:54:22:54:26 | query | provenance | | +| mongoose.js:54:22:54:26 | query | mongoose.js:57:18:57:22 | query | provenance | | +| mongoose.js:57:18:57:22 | query | mongoose.js:60:22:60:26 | query | provenance | | +| mongoose.js:60:22:60:26 | query | mongoose.js:63:21:63:25 | query | provenance | | +| mongoose.js:63:21:63:25 | query | mongoose.js:65:32:65:36 | query | provenance | | +| mongoose.js:65:32:65:36 | query | mongoose.js:67:27:67:31 | query | provenance | | +| mongoose.js:67:27:67:31 | query | mongoose.js:68:8:68:12 | query | provenance | | +| mongoose.js:68:8:68:12 | query | mongoose.js:71:17:71:21 | query | provenance | | +| mongoose.js:71:17:71:21 | query | mongoose.js:72:10:72:14 | query | provenance | | +| mongoose.js:72:10:72:14 | query | mongoose.js:73:8:73:12 | query | provenance | | +| mongoose.js:73:8:73:12 | query | mongoose.js:74:7:74:11 | query | provenance | | +| mongoose.js:74:7:74:11 | query | mongoose.js:75:16:75:20 | query | provenance | | +| mongoose.js:75:16:75:20 | query | mongoose.js:76:12:76:16 | query | provenance | | +| mongoose.js:76:12:76:16 | query | mongoose.js:77:10:77:14 | query | provenance | | +| mongoose.js:77:10:77:14 | query | mongoose.js:81:37:81:41 | query | provenance | | +| mongoose.js:81:37:81:41 | query | mongoose.js:82:46:82:50 | query | provenance | | +| mongoose.js:82:46:82:50 | query | mongoose.js:83:47:83:51 | query | provenance | | +| mongoose.js:83:47:83:51 | query | mongoose.js:85:46:85:50 | query | provenance | | +| mongoose.js:83:47:83:51 | query | mongoose.js:87:51:87:55 | query | provenance | | +| mongoose.js:83:47:83:51 | query | mongoose.js:89:46:89:50 | query | provenance | | +| mongoose.js:83:47:83:51 | query | mongoose.js:92:46:92:50 | query | provenance | | +| mongoose.js:83:47:83:51 | query | mongoose.js:94:51:94:55 | query | provenance | | +| mongoose.js:83:47:83:51 | query | mongoose.js:96:46:96:50 | query | provenance | | +| mongoose.js:83:47:83:51 | query | mongoose.js:104:21:104:25 | query | provenance | | +| mongoose.js:104:21:104:25 | query | mongoose.js:111:14:111:18 | query | provenance | | +| mongoose.js:111:14:111:18 | query | mongoose.js:113:31:113:35 | query | provenance | | +| mongoose.js:113:31:113:35 | query | mongoose.js:133:38:133:42 | query | provenance | | +| mongoose.js:115:6:115:22 | id | mongoose.js:123:20:123:21 | id | provenance | | +| mongoose.js:115:6:115:22 | id | mongoose.js:130:23:130:24 | id | provenance | | +| mongoose.js:115:11:115:22 | req.query.id | mongoose.js:115:6:115:22 | id | provenance | | +| mongoose.js:115:25:115:45 | cond | mongoose.js:116:22:116:25 | cond | provenance | | +| mongoose.js:115:25:115:45 | cond | mongoose.js:117:21:117:24 | cond | provenance | | +| mongoose.js:115:25:115:45 | cond | mongoose.js:118:21:118:24 | cond | provenance | | +| mongoose.js:115:25:115:45 | cond | mongoose.js:119:18:119:21 | cond | provenance | | +| mongoose.js:115:25:115:45 | cond | mongoose.js:120:22:120:25 | cond | provenance | | +| mongoose.js:115:25:115:45 | cond | mongoose.js:121:16:121:19 | cond | provenance | | +| mongoose.js:115:25:115:45 | cond | mongoose.js:122:19:122:22 | cond | provenance | | +| mongoose.js:115:25:115:45 | cond | mongoose.js:124:28:124:31 | cond | provenance | | +| mongoose.js:115:25:115:45 | cond | mongoose.js:125:28:125:31 | cond | provenance | | +| mongoose.js:115:25:115:45 | cond | mongoose.js:126:28:126:31 | cond | provenance | | +| mongoose.js:115:25:115:45 | cond | mongoose.js:127:18:127:21 | cond | provenance | | +| mongoose.js:115:25:115:45 | cond | mongoose.js:128:22:128:25 | cond | provenance | | +| mongoose.js:115:25:115:45 | cond | mongoose.js:129:21:129:24 | cond | provenance | | +| mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:115:25:115:45 | cond | provenance | | +| mongoose.js:130:23:130:24 | id | mongoose.js:130:16:130:26 | { _id: id } | provenance | Config | +| mongoose.js:133:38:133:42 | query | mongoose.js:134:30:134:34 | query | provenance | | +| mongoose.js:133:38:133:42 | query | mongoose.js:136:30:136:34 | query | provenance | | +| mongooseJsonParse.js:19:11:19:20 | query | mongooseJsonParse.js:23:19:23:23 | query | provenance | | +| mongooseJsonParse.js:19:19:19:20 | {} | mongooseJsonParse.js:19:11:19:20 | query | provenance | | +| mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) | mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | provenance | Config | +| mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | mongooseJsonParse.js:19:11:19:20 | query | provenance | Config | +| mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | mongooseJsonParse.js:19:19:19:20 | {} | provenance | Config | +| mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | mongooseJsonParse.js:23:19:23:23 | query | provenance | Config | +| mongooseJsonParse.js:20:30:20:43 | req.query.data | mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) | provenance | Config | +| mongooseModelClient.js:10:7:10:32 | v | mongooseModelClient.js:11:22:11:22 | v | provenance | | +| mongooseModelClient.js:10:11:10:32 | JSON.pa ... body.x) | mongooseModelClient.js:10:7:10:32 | v | provenance | | +| mongooseModelClient.js:10:22:10:29 | req.body | mongooseModelClient.js:10:22:10:31 | req.body.x | provenance | Config | +| mongooseModelClient.js:10:22:10:31 | req.body.x | mongooseModelClient.js:10:11:10:32 | JSON.pa ... body.x) | provenance | Config | +| mongooseModelClient.js:11:22:11:22 | v | mongooseModelClient.js:11:16:11:24 | { id: v } | provenance | Config | +| mongooseModelClient.js:12:22:12:29 | req.body | mongooseModelClient.js:12:22:12:32 | req.body.id | provenance | Config | +| mongooseModelClient.js:12:22:12:32 | req.body.id | mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | provenance | Config | +| mysql.js:6:9:6:31 | temp | mysql.js:15:62:15:65 | temp | provenance | | +| mysql.js:6:9:6:31 | temp | mysql.js:19:70:19:73 | temp | provenance | | +| mysql.js:6:16:6:31 | req.params.value | mysql.js:6:9:6:31 | temp | provenance | | +| mysql.js:15:62:15:65 | temp | mysql.js:15:18:15:65 | 'SELECT ... + temp | provenance | | +| mysql.js:19:70:19:73 | temp | mysql.js:19:26:19:73 | 'SELECT ... + temp | provenance | | +| pg-promise-types.ts:7:9:7:28 | taint | pg-promise-types.ts:8:17:8:21 | taint | provenance | | +| pg-promise-types.ts:7:17:7:28 | req.params.x | pg-promise-types.ts:7:9:7:28 | taint | provenance | | +| pg-promise.js:6:7:7:55 | query | pg-promise.js:9:10:9:14 | query | provenance | | +| pg-promise.js:6:7:7:55 | query | pg-promise.js:10:11:10:15 | query | provenance | | +| pg-promise.js:6:7:7:55 | query | pg-promise.js:11:17:11:21 | query | provenance | | +| pg-promise.js:6:7:7:55 | query | pg-promise.js:12:10:12:14 | query | provenance | | +| pg-promise.js:6:7:7:55 | query | pg-promise.js:13:12:13:16 | query | provenance | | +| pg-promise.js:6:7:7:55 | query | pg-promise.js:14:18:14:22 | query | provenance | | +| pg-promise.js:6:7:7:55 | query | pg-promise.js:15:11:15:15 | query | provenance | | +| pg-promise.js:6:7:7:55 | query | pg-promise.js:16:10:16:14 | query | provenance | | +| pg-promise.js:6:7:7:55 | query | pg-promise.js:17:16:17:20 | query | provenance | | +| pg-promise.js:6:7:7:55 | query | pg-promise.js:18:12:18:16 | query | provenance | | +| pg-promise.js:6:7:7:55 | query | pg-promise.js:19:13:19:17 | query | provenance | | +| pg-promise.js:6:7:7:55 | query | pg-promise.js:22:11:22:15 | query | provenance | | +| pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:6:7:7:55 | query | provenance | | +| pg-promise.js:9:10:9:14 | query | pg-promise.js:10:11:10:15 | query | provenance | | +| pg-promise.js:10:11:10:15 | query | pg-promise.js:11:17:11:21 | query | provenance | | +| pg-promise.js:11:17:11:21 | query | pg-promise.js:12:10:12:14 | query | provenance | | +| pg-promise.js:12:10:12:14 | query | pg-promise.js:13:12:13:16 | query | provenance | | +| pg-promise.js:13:12:13:16 | query | pg-promise.js:14:18:14:22 | query | provenance | | +| pg-promise.js:14:18:14:22 | query | pg-promise.js:15:11:15:15 | query | provenance | | +| pg-promise.js:15:11:15:15 | query | pg-promise.js:16:10:16:14 | query | provenance | | +| pg-promise.js:16:10:16:14 | query | pg-promise.js:17:16:17:20 | query | provenance | | +| pg-promise.js:17:16:17:20 | query | pg-promise.js:18:12:18:16 | query | provenance | | +| pg-promise.js:18:12:18:16 | query | pg-promise.js:19:13:19:17 | query | provenance | | +| pg-promise.js:19:13:19:17 | query | pg-promise.js:22:11:22:15 | query | provenance | | +| pg-promise.js:22:11:22:15 | query | pg-promise.js:60:20:60:24 | query | provenance | | +| pg-promise.js:22:11:22:15 | query | pg-promise.js:63:23:63:27 | query | provenance | | +| pg-promise.js:22:11:22:15 | query | pg-promise.js:64:16:64:20 | query | provenance | | +| pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | provenance | | +| pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | provenance | | +| pg-promise.js:41:7:41:20 | req.params.foo | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | provenance | | +| redis.js:10:16:10:23 | req.body | redis.js:10:16:10:27 | req.body.key | provenance | Config | +| redis.js:12:9:12:26 | key | redis.js:13:16:13:18 | key | provenance | | +| redis.js:12:9:12:26 | key | redis.js:18:16:18:18 | key | provenance | | +| redis.js:12:9:12:26 | key | redis.js:19:43:19:45 | key | provenance | | +| redis.js:12:9:12:26 | key | redis.js:25:14:25:16 | key | provenance | | +| redis.js:12:9:12:26 | key | redis.js:26:14:26:16 | key | provenance | | +| redis.js:12:9:12:26 | key | redis.js:32:28:32:30 | key | provenance | | +| redis.js:12:15:12:22 | req.body | redis.js:12:15:12:26 | req.body.key | provenance | Config | +| redis.js:12:15:12:26 | req.body.key | redis.js:12:9:12:26 | key | provenance | | +| redis.js:13:16:13:18 | key | redis.js:18:16:18:18 | key | provenance | | +| redis.js:18:16:18:18 | key | redis.js:19:43:19:45 | key | provenance | | +| redis.js:19:43:19:45 | key | redis.js:25:14:25:16 | key | provenance | | +| redis.js:25:14:25:16 | key | redis.js:26:14:26:16 | key | provenance | | +| redis.js:26:14:26:16 | key | redis.js:30:23:30:25 | key | provenance | | +| redis.js:26:14:26:16 | key | redis.js:32:28:32:30 | key | provenance | | +| redis.js:38:11:38:28 | key | redis.js:39:16:39:18 | key | provenance | | +| redis.js:38:11:38:28 | key | redis.js:43:27:43:29 | key | provenance | | +| redis.js:38:11:38:28 | key | redis.js:46:34:46:36 | key | provenance | | +| redis.js:38:17:38:24 | req.body | redis.js:38:17:38:28 | req.body.key | provenance | Config | +| redis.js:38:17:38:28 | req.body.key | redis.js:38:11:38:28 | key | provenance | | +| socketio.js:10:25:10:30 | handle | socketio.js:11:46:11:51 | handle | provenance | | +| socketio.js:11:46:11:51 | handle | socketio.js:11:12:11:53 | `INSERT ... andle}` | provenance | | +| tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" | provenance | | +| tst3.js:7:7:8:55 | query1 | tst3.js:9:14:9:19 | query1 | provenance | | +| tst3.js:8:16:8:34 | req.params.category | tst3.js:7:7:8:55 | query1 | provenance | | +| tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | provenance | | +| tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | provenance | | subpaths #select | graphql.js:10:34:20:5 | `\\n ... }\\n ` | graphql.js:8:16:8:28 | req.params.id | graphql.js:10:34:20:5 | `\\n ... }\\n ` | This query string depends on a $@. | graphql.js:8:16:8:28 | req.params.id | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected b/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected index 973b7da8555..1f3caa8f1ce 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected @@ -1,32 +1,45 @@ edges -| build-leaks.js:4:39:6:1 | [post update] { // NO ... .env)\\n} [process.env] | build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | -| build-leaks.js:5:20:5:46 | JSON.st ... ss.env) | build-leaks.js:4:39:6:1 | [post update] { // NO ... .env)\\n} [process.env] | -| build-leaks.js:5:35:5:45 | process.env | build-leaks.js:5:20:5:46 | JSON.st ... ss.env) | -| build-leaks.js:13:11:19:10 | raw | build-leaks.js:22:36:22:38 | raw | -| build-leaks.js:13:17:19:10 | Object. ... }) | build-leaks.js:13:11:19:10 | raw | -| build-leaks.js:14:18:14:20 | env | build-leaks.js:16:20:16:22 | env | -| build-leaks.js:15:13:15:15 | [post update] env | build-leaks.js:14:18:14:20 | env | -| build-leaks.js:15:13:15:15 | [post update] env | build-leaks.js:17:12:19:9 | [post update] {\\n ... } | -| build-leaks.js:15:24:15:34 | process.env | build-leaks.js:15:13:15:15 | [post update] env | -| build-leaks.js:16:20:16:22 | env | build-leaks.js:13:17:19:10 | Object. ... }) | -| build-leaks.js:17:12:19:9 | [post update] {\\n ... } | build-leaks.js:17:12:19:9 | {\\n ... } | -| build-leaks.js:17:12:19:9 | {\\n ... } | build-leaks.js:13:17:19:10 | Object. ... }) | -| build-leaks.js:21:11:26:5 | stringifed [process.env] | build-leaks.js:30:22:30:31 | stringifed [process.env] | -| build-leaks.js:21:24:26:5 | {\\n ... )\\n } [process.env] | build-leaks.js:21:11:26:5 | stringifed [process.env] | -| build-leaks.js:22:24:25:14 | Object. ... }, {}) | build-leaks.js:21:24:26:5 | {\\n ... )\\n } [process.env] | -| build-leaks.js:22:36:22:38 | raw | build-leaks.js:22:24:25:14 | Object. ... }, {}) | -| build-leaks.js:22:36:22:38 | raw | build-leaks.js:25:12:25:13 | [post update] {} | -| build-leaks.js:25:12:25:13 | [post update] {} | build-leaks.js:25:12:25:13 | {} | -| build-leaks.js:25:12:25:13 | {} | build-leaks.js:22:24:25:14 | Object. ... }, {}) | -| build-leaks.js:28:12:31:5 | {\\n ... d\\n } [stringified, process.env] | build-leaks.js:34:26:34:45 | getEnv('production') [stringified, process.env] | -| build-leaks.js:30:22:30:31 | stringifed [process.env] | build-leaks.js:28:12:31:5 | {\\n ... d\\n } [stringified, process.env] | -| build-leaks.js:34:26:34:45 | getEnv('production') [stringified, process.env] | build-leaks.js:34:26:34:57 | getEnv( ... ngified [process.env] | -| build-leaks.js:34:26:34:57 | getEnv( ... ngified [process.env] | build-leaks.js:34:26:34:57 | getEnv( ... ngified | -| build-leaks.js:40:9:40:60 | pw | build-leaks.js:41:82:41:83 | pw | -| build-leaks.js:40:14:40:60 | url.par ... assword | build-leaks.js:40:9:40:60 | pw | -| build-leaks.js:41:43:41:86 | [post update] { "proc ... y(pw) } [process.env.secret] | build-leaks.js:41:43:41:86 | { "proc ... y(pw) } | -| build-leaks.js:41:67:41:84 | JSON.stringify(pw) | build-leaks.js:41:43:41:86 | [post update] { "proc ... y(pw) } [process.env.secret] | -| build-leaks.js:41:82:41:83 | pw | build-leaks.js:41:67:41:84 | JSON.stringify(pw) | +| build-leaks.js:4:39:6:1 | [post update] { // NO ... .env)\\n} [process.env] | build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | provenance | | +| build-leaks.js:5:20:5:46 | JSON.st ... ss.env) | build-leaks.js:4:39:6:1 | [post update] { // NO ... .env)\\n} [process.env] | provenance | | +| build-leaks.js:5:35:5:45 | process.env | build-leaks.js:5:20:5:46 | JSON.st ... ss.env) | provenance | | +| build-leaks.js:13:11:19:10 | raw | build-leaks.js:22:36:22:38 | raw | provenance | | +| build-leaks.js:13:17:19:10 | Object. ... }) | build-leaks.js:13:11:19:10 | raw | provenance | | +| build-leaks.js:14:18:14:20 | env | build-leaks.js:16:20:16:22 | env | provenance | | +| build-leaks.js:14:18:14:20 | env | build-leaks.js:16:20:16:22 | env | provenance | | +| build-leaks.js:14:18:14:20 | env [Return] | build-leaks.js:17:12:19:9 | [post update] {\\n ... } | provenance | | +| build-leaks.js:15:13:15:15 | [post update] env | build-leaks.js:14:18:14:20 | env | provenance | | +| build-leaks.js:15:13:15:15 | [post update] env | build-leaks.js:14:18:14:20 | env [Return] | provenance | | +| build-leaks.js:15:24:15:34 | process.env | build-leaks.js:15:13:15:15 | [post update] env | provenance | Config | +| build-leaks.js:16:20:16:22 | env | build-leaks.js:13:17:19:10 | Object. ... }) | provenance | | +| build-leaks.js:16:20:16:22 | env | build-leaks.js:14:18:14:20 | env | provenance | | +| build-leaks.js:16:20:16:22 | env | build-leaks.js:22:49:22:51 | env | provenance | | +| build-leaks.js:17:12:19:9 | [post update] {\\n ... } | build-leaks.js:17:12:19:9 | {\\n ... } | provenance | | +| build-leaks.js:17:12:19:9 | {\\n ... } | build-leaks.js:13:17:19:10 | Object. ... }) | provenance | | +| build-leaks.js:17:12:19:9 | {\\n ... } | build-leaks.js:14:18:14:20 | env | provenance | | +| build-leaks.js:21:11:26:5 | stringifed [process.env] | build-leaks.js:30:22:30:31 | stringifed [process.env] | provenance | | +| build-leaks.js:21:24:26:5 | {\\n ... )\\n } [process.env] | build-leaks.js:21:11:26:5 | stringifed [process.env] | provenance | | +| build-leaks.js:22:24:25:14 | Object. ... }, {}) | build-leaks.js:21:24:26:5 | {\\n ... )\\n } [process.env] | provenance | | +| build-leaks.js:22:36:22:38 | raw | build-leaks.js:22:24:25:14 | Object. ... }, {}) | provenance | | +| build-leaks.js:22:36:22:38 | raw | build-leaks.js:22:49:22:51 | env | provenance | Config | +| build-leaks.js:22:36:22:38 | raw | build-leaks.js:23:39:23:41 | raw | provenance | | +| build-leaks.js:22:36:22:38 | raw | build-leaks.js:25:12:25:13 | [post update] {} | provenance | | +| build-leaks.js:22:49:22:51 | env | build-leaks.js:24:20:24:22 | env | provenance | | +| build-leaks.js:22:49:22:51 | env | build-leaks.js:24:20:24:22 | env | provenance | | +| build-leaks.js:23:13:23:15 | [post update] env | build-leaks.js:22:49:22:51 | env | provenance | | +| build-leaks.js:23:13:23:15 | [post update] env | build-leaks.js:22:49:22:51 | env [Return] | provenance | | +| build-leaks.js:23:39:23:41 | raw | build-leaks.js:23:13:23:15 | [post update] env | provenance | Config | +| build-leaks.js:25:12:25:13 | [post update] {} | build-leaks.js:25:12:25:13 | {} | provenance | | +| build-leaks.js:25:12:25:13 | {} | build-leaks.js:22:24:25:14 | Object. ... }, {}) | provenance | | +| build-leaks.js:25:12:25:13 | {} | build-leaks.js:22:49:22:51 | env | provenance | | +| build-leaks.js:28:12:31:5 | {\\n ... d\\n } [stringified, process.env] | build-leaks.js:34:26:34:45 | getEnv('production') [stringified, process.env] | provenance | | +| build-leaks.js:30:22:30:31 | stringifed [process.env] | build-leaks.js:28:12:31:5 | {\\n ... d\\n } [stringified, process.env] | provenance | | +| build-leaks.js:34:26:34:45 | getEnv('production') [stringified, process.env] | build-leaks.js:34:26:34:57 | getEnv( ... ngified [process.env] | provenance | | +| build-leaks.js:34:26:34:57 | getEnv( ... ngified [process.env] | build-leaks.js:34:26:34:57 | getEnv( ... ngified | provenance | | +| build-leaks.js:40:9:40:60 | pw | build-leaks.js:41:82:41:83 | pw | provenance | | +| build-leaks.js:40:14:40:60 | url.par ... assword | build-leaks.js:40:9:40:60 | pw | provenance | | +| build-leaks.js:41:43:41:86 | [post update] { "proc ... y(pw) } [process.env.secret] | build-leaks.js:41:43:41:86 | { "proc ... y(pw) } | provenance | | +| build-leaks.js:41:67:41:84 | JSON.stringify(pw) | build-leaks.js:41:43:41:86 | [post update] { "proc ... y(pw) } [process.env.secret] | provenance | | +| build-leaks.js:41:82:41:83 | pw | build-leaks.js:41:67:41:84 | JSON.stringify(pw) | provenance | | nodes | build-leaks.js:4:39:6:1 | [post update] { // NO ... .env)\\n} [process.env] | semmle.label | [post update] { // NO ... .env)\\n} [process.env] | | build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | semmle.label | { // NO ... .env)\\n} | @@ -35,15 +48,25 @@ nodes | build-leaks.js:13:11:19:10 | raw | semmle.label | raw | | build-leaks.js:13:17:19:10 | Object. ... }) | semmle.label | Object. ... }) | | build-leaks.js:14:18:14:20 | env | semmle.label | env | +| build-leaks.js:14:18:14:20 | env | semmle.label | env | +| build-leaks.js:14:18:14:20 | env [Return] | semmle.label | env [Return] | | build-leaks.js:15:13:15:15 | [post update] env | semmle.label | [post update] env | | build-leaks.js:15:24:15:34 | process.env | semmle.label | process.env | | build-leaks.js:16:20:16:22 | env | semmle.label | env | +| build-leaks.js:16:20:16:22 | env | semmle.label | env | | build-leaks.js:17:12:19:9 | [post update] {\\n ... } | semmle.label | [post update] {\\n ... } | | build-leaks.js:17:12:19:9 | {\\n ... } | semmle.label | {\\n ... } | | build-leaks.js:21:11:26:5 | stringifed [process.env] | semmle.label | stringifed [process.env] | | build-leaks.js:21:24:26:5 | {\\n ... )\\n } [process.env] | semmle.label | {\\n ... )\\n } [process.env] | | build-leaks.js:22:24:25:14 | Object. ... }, {}) | semmle.label | Object. ... }, {}) | | build-leaks.js:22:36:22:38 | raw | semmle.label | raw | +| build-leaks.js:22:49:22:51 | env | semmle.label | env | +| build-leaks.js:22:49:22:51 | env | semmle.label | env | +| build-leaks.js:22:49:22:51 | env [Return] | semmle.label | env [Return] | +| build-leaks.js:23:13:23:15 | [post update] env | semmle.label | [post update] env | +| build-leaks.js:23:39:23:41 | raw | semmle.label | raw | +| build-leaks.js:24:20:24:22 | env | semmle.label | env | +| build-leaks.js:24:20:24:22 | env | semmle.label | env | | build-leaks.js:25:12:25:13 | [post update] {} | semmle.label | [post update] {} | | build-leaks.js:25:12:25:13 | {} | semmle.label | {} | | build-leaks.js:28:12:31:5 | {\\n ... d\\n } [stringified, process.env] | semmle.label | {\\n ... d\\n } [stringified, process.env] | @@ -58,6 +81,10 @@ nodes | build-leaks.js:41:67:41:84 | JSON.stringify(pw) | semmle.label | JSON.stringify(pw) | | build-leaks.js:41:82:41:83 | pw | semmle.label | pw | subpaths +| build-leaks.js:17:12:19:9 | {\\n ... } | build-leaks.js:14:18:14:20 | env | build-leaks.js:16:20:16:22 | env | build-leaks.js:13:17:19:10 | Object. ... }) | +| build-leaks.js:22:36:22:38 | raw | build-leaks.js:23:39:23:41 | raw | build-leaks.js:22:49:22:51 | env [Return] | build-leaks.js:25:12:25:13 | [post update] {} | +| build-leaks.js:22:36:22:38 | raw | build-leaks.js:23:39:23:41 | raw | build-leaks.js:24:20:24:22 | env | build-leaks.js:22:24:25:14 | Object. ... }, {}) | +| build-leaks.js:25:12:25:13 | {} | build-leaks.js:22:49:22:51 | env | build-leaks.js:24:20:24:22 | env | build-leaks.js:22:24:25:14 | Object. ... }, {}) | #select | build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | build-leaks.js:5:35:5:45 | process.env | build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | This creates a build artifact that depends on $@. | build-leaks.js:5:35:5:45 | process.env | sensitive data returned byprocess environment | | build-leaks.js:34:26:34:57 | getEnv( ... ngified | build-leaks.js:15:24:15:34 | process.env | build-leaks.js:34:26:34:57 | getEnv( ... ngified | This creates a build artifact that depends on $@. | build-leaks.js:15:24:15:34 | process.env | sensitive data returned byprocess environment | From 1c730bc66ea11f222adcc4ec97d9026f4fca3646 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 27 Jun 2024 12:47:15 +0200 Subject: [PATCH 220/514] JS: Fix compilation error in DataFlowImplConsistency.qll --- .../javascript/dataflow/internal/DataFlowImplConsistency.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll index a4cf0199930..84f0f3e39b4 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll @@ -4,7 +4,7 @@ private import sharedlib.DataFlowArg private import semmle.javascript.dataflow.internal.DataFlowPrivate private import semmle.javascript.dataflow.internal.DataFlowNode -private module ConsistencyConfig implements InputSig { +private module ConsistencyConfig implements InputSig { private predicate isAmbientNode(DataFlow::Node node) { exists(AstNode n | n.isAmbient() | node = TValueNode(n) or @@ -39,4 +39,4 @@ private module ConsistencyConfig implements InputSig { } } -module Consistency = MakeConsistency; +module Consistency = MakeConsistency; From 14fc790617223f3a97dbcbeef0c25eedfe8516c1 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 28 Jun 2024 13:08:09 +0200 Subject: [PATCH 221/514] Update DataFlowConsistency.expected --- .../FlowSummary/DataFlowConsistency.expected | 23 +------------------ 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected b/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected index 79c66aa0381..5a967f1256e 100644 --- a/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected +++ b/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected @@ -4,28 +4,6 @@ uniqueType uniqueNodeLocation missingLocation uniqueNodeToString -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | -| file://:0:0:0:0 | (no string representation) | Node should have one toString but has 0. | parameterCallable localFlowIsLocal readStepIsLocal @@ -228,3 +206,4 @@ multipleArgumentCall | tst.js:265:3:265:6 | map3 | tst.js:265:3:265:27 | map3.se ... urce()) | Multiple calls for argument node. | | tst.js:266:3:266:6 | map3 | tst.js:266:3:266:14 | map3.forEach (as accessor call) | Multiple calls for argument node. | | tst.js:266:3:266:6 | map3 | tst.js:266:3:266:36 | map3.fo ... value)) | Multiple calls for argument node. | +lambdaCallEnclosingCallableMismatch From e5924c1f8423cd99e2f3423230a9b05f500f8557 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 28 Jun 2024 13:08:32 +0200 Subject: [PATCH 222/514] JS: Another messy test update --- .../TaintTracking/DataFlowTracking.expected | 257 ++++++++++++------ 1 file changed, 181 insertions(+), 76 deletions(-) diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected index 9a7889b6109..de977a8ff92 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected @@ -1,76 +1,181 @@ -ERROR: AccessPathRange must implement toString() (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1053,19-34) -ERROR: Cannot reference parameterised module signatures without arguments. (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll:6,41-49) -ERROR: Class must extend or implement at least one type (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1053,19-34) -ERROR: Could not resolve module AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1053,43-53) -ERROR: Could not resolve module AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1187,7-17) -ERROR: Could not resolve module AccessPathSyntax (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll:28,12-28) -ERROR: Could not resolve module AccessPathSyntax (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll:50,14-30) -ERROR: Could not resolve module AccessPathSyntax (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll:150,24-40) -ERROR: Could not resolve module AccessPathSyntax (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll:189,9-25) -ERROR: Could not resolve module AccessPathSyntax (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:343,10-26) -ERROR: Could not resolve module AccessPathSyntax (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll:358,27-43) -ERROR: Could not resolve module Pass1 (/Users/asger/git/code/ql/shared/dataflow/codeql/dataflow/DataFlow.qll:952,29-34) -ERROR: Could not resolve module Pass2 (/Users/asger/git/code/ql/shared/dataflow/codeql/dataflow/DataFlow.qll:955,48-53) -ERROR: Could not resolve module Pass2 (/Users/asger/git/code/ql/shared/dataflow/codeql/dataflow/DataFlow.qll:958,13-18) -ERROR: Could not resolve module VariableCapture::VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll:63,23-61) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll:48,3-24) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll:169,3-24) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll:266,43-64) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll:267,29-50) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll:269,29-50) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll:271,38-59) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll:275,45-66) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll:277,36-57) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll:279,18-39) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll:282,1-22) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll:294,5-26) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll:294,47-68) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll:296,5-26) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll:813,3-24) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll:877,5-26) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll:922,5-26) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll:952,3-24) -ERROR: Could not resolve module VariableCaptureOutput (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll:1000,5-26) -ERROR: Could not resolve module semmle.javascript.frameworks.data.internal.AccessPathSyntax (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll:2,16-75) -ERROR: Could not resolve module semmle.javascript.frameworks.data.internal.AccessPathSyntax (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll:12,8-67) -ERROR: Could not resolve predicate edges/2 (/Users/asger/git/code/ql/shared/dataflow/codeql/dataflow/DataFlow.qll:939,49-63) -ERROR: Could not resolve predicate edges/2 (/Users/asger/git/code/ql/shared/dataflow/codeql/dataflow/DataFlow.qll:942,7-19) -ERROR: Could not resolve predicate edges/2 (/Users/asger/git/code/ql/shared/dataflow/codeql/dataflow/DataFlow.qll:1013,9-21) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1100,29-39) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1105,37-47) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1117,7-17) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1133,9-19) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1133,28-38) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1142,48-58) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1142,67-77) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1154,16-26) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1154,35-45) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1171,36-46) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1184,37-47) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1200,59-69) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1209,57-67) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1220,7-17) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1258,38-48) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1296,33-43) -ERROR: Could not resolve type AccessPath (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1307,33-43) -ERROR: Could not resolve type AccessPathToken (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1058,26-41) -ERROR: Could not resolve type AccessPathToken (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1064,24-39) -ERROR: Could not resolve type AccessPathToken (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1070,32-47) -ERROR: Could not resolve type AccessPathToken (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1079,49-64) -ERROR: Could not resolve type AccessPathToken (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1184,54-69) -ERROR: Could not resolve type AccessPathToken (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1190,43-58) -ERROR: Could not resolve type AccessPathToken (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1195,44-59) -ERROR: Could not resolve type AccessPathToken (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1232,33-48) -ERROR: Could not resolve type AccessPathToken (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/FlowSummaryImpl.qll:1269,33-48) -ERROR: Could not resolve type Private::AccessPathToken (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll:101,3-27) -ERROR: Could not resolve type Private::AccessPathToken (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll:115,3-27) -ERROR: Could not resolve type Private::AccessPathToken (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll:163,45-69) -ERROR: Default predicate predicate DataFlow::InputSig[DataFlowArg::JSDataFlow]::viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) conflicts with existing declarations: predicate DataFlowPrivate::viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) from DataFlowPrivate.qll:720 (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll:5,30-54) -ERROR: Module PathGraph does not declare edges/4, required by implemented signature PathGraphSig. (/Users/asger/git/code/ql/shared/dataflow/codeql/dataflow/DataFlow.qll:1007,33-55) -ERROR: Predicate getLocation/0 in type BasicBlock in module implementation VariableCaptureConfig of signature InputSig has result type Location, which does not match the expected result type Location (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/Locations.qll:91,12-23) -ERROR: Predicate getLocation/0 in type Callable in module implementation VariableCaptureConfig of signature InputSig has result type Location, which does not match the expected result type Location (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/AST.qll:26,21-32) -ERROR: Predicate getLocation/0 in type CapturedVariable in module implementation VariableCaptureConfig of signature InputSig has result type Location, which does not match the expected result type Location (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll:54,9-25) -ERROR: Predicate getLocation/0 in type Expr in module implementation VariableCaptureConfig of signature InputSig has result type Location, which does not match the expected result type Location (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/AST.qll:26,21-32) -ERROR: Predicate getLocation/0 in type VariableWrite in module implementation VariableCaptureConfig of signature InputSig has result type Location, which does not match the expected result type Location (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll:190,14-25) -ERROR: The predicate DataFlowPrivate::viableImplInCallContext(DataFlowCall call, DataFlowCall ctx), which was brought into scope by this import, conflicts with existing declarations: predicate DataFlow::InputSig[DataFlowArg::JSDataFlow]::viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) from DataFlow.qll:107 (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlowArg.qll:6,3-17) -ERROR: Wrong number of arguments for parameterised module (expected 2 rather than 1). (/Users/asger/git/code/ql/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll:264,32-59) +legacyDataFlowDifference +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:38:8:38:13 | arr[5] | only flow with NEW data flow library | +| bound-function.js:27:8:27:15 | source() | bound-function.js:30:10:30:10 | y | only flow with OLD data flow library | +| call-apply.js:27:14:27:21 | source() | call-apply.js:34:6:34:29 | foo1_ap ... e, ""]) | only flow with NEW data flow library | +| call-apply.js:45:8:45:15 | source() | call-apply.js:55:6:55:13 | foo(obj) | only flow with NEW data flow library | +| callbacks.js:37:17:37:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | +| callbacks.js:37:17:37:24 | source() | callbacks.js:41:10:41:10 | x | only flow with NEW data flow library | +| callbacks.js:44:17:44:24 | source() | callbacks.js:37:37:37:37 | x | only flow with NEW data flow library | +| callbacks.js:44:17:44:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | +| capture-flow.js:89:13:89:20 | source() | capture-flow.js:89:6:89:21 | test3c(source()) | only flow with NEW data flow library | +| capture-flow.js:101:12:101:19 | source() | capture-flow.js:102:6:102:20 | test5("safe")() | only flow with OLD data flow library | +| capture-flow.js:274:33:274:40 | source() | capture-flow.js:272:10:272:17 | this.foo | only flow with OLD data flow library | +| capture-flow.js:274:33:274:40 | source() | capture-flow.js:274:6:274:45 | new Cap ... ()).foo | only flow with OLD data flow library | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:40:8:40:14 | e.taint | only flow with NEW data flow library | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:44:8:44:19 | f_safe.taint | only flow with NEW data flow library | +| constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:39:8:39:14 | e.param | only flow with NEW data flow library | +| exceptions.js:53:14:53:21 | source() | exceptions.js:54:10:54:10 | e | only flow with NEW data flow library | +| getters-and-setters.js:53:21:53:28 | source() | getters-and-setters.js:53:10:53:30 | getX(ne ... rce())) | only flow with NEW data flow library | +| nested-props.js:14:15:14:22 | source() | nested-props.js:15:10:15:16 | obj.x.y | only flow with NEW data flow library | +| nested-props.js:27:18:27:25 | source() | nested-props.js:28:10:28:14 | obj.x | only flow with NEW data flow library | +| nested-props.js:51:22:51:29 | source() | nested-props.js:52:10:52:16 | obj.x.y | only flow with NEW data flow library | +| sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | only flow with NEW data flow library | +| tst.js:2:13:2:20 | source() | tst.js:35:14:35:16 | ary | only flow with NEW data flow library | +| tst.js:2:13:2:20 | source() | tst.js:41:14:41:16 | ary | only flow with NEW data flow library | +flow +| access-path-sanitizer.js:2:18:2:25 | source() | access-path-sanitizer.js:4:8:4:12 | obj.x | +| advanced-callgraph.js:2:13:2:20 | source() | advanced-callgraph.js:6:22:6:22 | v | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:17:8:17:13 | arr[1] | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:22:8:22:13 | arr[6] | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:28:8:28:13 | arr[1] | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:34:8:34:13 | arr[1] | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:38:8:38:13 | arr[5] | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:43:10:43:15 | arr[i] | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:55:10:55:15 | arr[i] | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:61:10:61:13 | item | +| booleanOps.js:2:11:2:18 | source() | booleanOps.js:4:8:4:8 | x | +| booleanOps.js:2:11:2:18 | source() | booleanOps.js:7:10:7:10 | x | +| booleanOps.js:2:11:2:18 | source() | booleanOps.js:10:10:10:10 | x | +| booleanOps.js:2:11:2:18 | source() | booleanOps.js:13:10:13:10 | x | +| booleanOps.js:2:11:2:18 | source() | booleanOps.js:19:10:19:10 | x | +| booleanOps.js:2:11:2:18 | source() | booleanOps.js:22:10:22:10 | x | +| bound-function.js:17:21:17:28 | source() | bound-function.js:5:10:5:16 | y.test2 | +| bound-function.js:19:15:19:22 | source() | bound-function.js:6:10:6:16 | y.test3 | +| bound-function.js:50:10:50:17 | source() | bound-function.js:50:6:50:18 | id3(source()) | +| bound-function.js:54:12:54:19 | source() | bound-function.js:59:6:59:14 | source0() | +| bound-function.js:54:12:54:19 | source() | bound-function.js:60:6:60:14 | source1() | +| call-apply.js:27:14:27:21 | source() | call-apply.js:24:8:24:11 | arg1 | +| call-apply.js:27:14:27:21 | source() | call-apply.js:29:6:29:32 | foo1.ca ... ce, "") | +| call-apply.js:27:14:27:21 | source() | call-apply.js:32:6:32:35 | foo1.ap ... e, ""]) | +| call-apply.js:27:14:27:21 | source() | call-apply.js:34:6:34:29 | foo1_ap ... e, ""]) | +| call-apply.js:27:14:27:21 | source() | call-apply.js:40:6:40:28 | foo1_ca ... e, ""]) | +| call-apply.js:27:14:27:21 | source() | call-apply.js:62:10:62:21 | arguments[0] | +| call-apply.js:45:8:45:15 | source() | call-apply.js:55:6:55:13 | foo(obj) | +| call-apply.js:81:17:81:24 | source() | call-apply.js:78:8:78:11 | this | +| callbacks.js:4:6:4:13 | source() | callbacks.js:34:27:34:27 | x | +| callbacks.js:4:6:4:13 | source() | callbacks.js:35:27:35:27 | x | +| callbacks.js:5:6:5:13 | source() | callbacks.js:34:27:34:27 | x | +| callbacks.js:5:6:5:13 | source() | callbacks.js:35:27:35:27 | x | +| callbacks.js:25:16:25:23 | source() | callbacks.js:47:26:47:26 | x | +| callbacks.js:25:16:25:23 | source() | callbacks.js:48:26:48:26 | x | +| callbacks.js:37:17:37:24 | source() | callbacks.js:37:37:37:37 | x | +| callbacks.js:37:17:37:24 | source() | callbacks.js:38:35:38:35 | x | +| callbacks.js:37:17:37:24 | source() | callbacks.js:41:10:41:10 | x | +| callbacks.js:44:17:44:24 | source() | callbacks.js:37:37:37:37 | x | +| callbacks.js:44:17:44:24 | source() | callbacks.js:38:35:38:35 | x | +| callbacks.js:44:17:44:24 | source() | callbacks.js:41:10:41:10 | x | +| callbacks.js:50:18:50:25 | source() | callbacks.js:30:29:30:29 | y | +| callbacks.js:51:18:51:25 | source() | callbacks.js:30:29:30:29 | y | +| callbacks.js:53:23:53:30 | source() | callbacks.js:58:10:58:10 | x | +| callbacks.js:73:17:73:24 | source() | callbacks.js:73:37:73:37 | x | +| capture-flow.js:9:11:9:18 | source() | capture-flow.js:14:10:14:16 | outer() | +| capture-flow.js:9:11:9:18 | source() | capture-flow.js:19:6:19:16 | outerMost() | +| capture-flow.js:31:14:31:21 | source() | capture-flow.js:31:6:31:22 | confuse(source()) | +| capture-flow.js:45:12:45:19 | source() | capture-flow.js:45:6:45:20 | test3(source()) | +| capture-flow.js:60:13:60:20 | source() | capture-flow.js:60:6:60:21 | test3a(source()) | +| capture-flow.js:76:13:76:20 | source() | capture-flow.js:76:6:76:21 | test3b(source()) | +| capture-flow.js:89:13:89:20 | source() | capture-flow.js:89:6:89:21 | test3c(source()) | +| capture-flow.js:93:13:93:20 | source() | capture-flow.js:96:6:96:14 | test4()() | +| capture-flow.js:101:12:101:19 | source() | capture-flow.js:101:6:101:22 | test5(source())() | +| capture-flow.js:110:12:110:19 | source() | capture-flow.js:106:14:106:14 | x | +| capture-flow.js:118:37:118:44 | source() | capture-flow.js:114:14:114:14 | x | +| capture-flow.js:126:25:126:32 | source() | capture-flow.js:123:14:123:26 | orderingTaint | +| capture-flow.js:126:25:126:32 | source() | capture-flow.js:129:14:129:26 | orderingTaint | +| capture-flow.js:177:26:177:33 | source() | capture-flow.js:173:14:173:14 | x | +| capture-flow.js:187:34:187:41 | source() | capture-flow.js:183:14:183:14 | x | +| capture-flow.js:195:24:195:31 | source() | capture-flow.js:191:14:191:14 | x | +| capture-flow.js:205:24:205:31 | source() | capture-flow.js:200:18:200:18 | x | +| capture-flow.js:225:13:225:20 | source() | capture-flow.js:220:51:220:59 | fileOrDir | +| capture-flow.js:230:9:230:16 | source() | capture-flow.js:233:14:233:14 | x | +| capture-flow.js:259:23:259:30 | source() | capture-flow.js:243:18:243:40 | objectW ... s.field | +| capture-flow.js:259:23:259:30 | source() | capture-flow.js:247:18:247:40 | objectW ... s.field | +| capture-flow.js:259:23:259:30 | source() | capture-flow.js:248:18:248:27 | this.field | +| capture-flow.js:259:23:259:30 | source() | capture-flow.js:252:14:252:36 | objectW ... s.field | +| capture-flow.js:259:23:259:30 | source() | capture-flow.js:253:14:253:23 | this.field | +| capture-flow.js:262:16:262:23 | source() | capture-flow.js:264:14:264:21 | this.foo | +| capture-flow.js:283:34:283:41 | source() | capture-flow.js:283:6:283:46 | new Cap ... ()).foo | +| captured-sanitizer.js:25:3:25:10 | source() | captured-sanitizer.js:15:10:15:10 | x | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:24:8:24:14 | c.taint | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:28:8:28:19 | c_safe.taint | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:40:8:40:14 | e.taint | +| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:44:8:44:19 | f_safe.taint | +| constructor-calls.js:10:16:10:23 | source() | constructor-calls.js:32:8:32:14 | d.taint | +| constructor-calls.js:10:16:10:23 | source() | constructor-calls.js:36:8:36:19 | d_safe.taint | +| constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:23:8:23:14 | c.param | +| constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:31:8:31:14 | d.param | +| constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:39:8:39:14 | e.param | +| exceptions.js:3:15:3:22 | source() | exceptions.js:5:10:5:10 | e | +| exceptions.js:53:14:53:21 | source() | exceptions.js:54:10:54:10 | e | +| exceptions.js:59:24:59:31 | source() | exceptions.js:61:12:61:12 | e | +| exceptions.js:88:6:88:13 | source() | exceptions.js:11:10:11:10 | e | +| exceptions.js:93:11:93:18 | source() | exceptions.js:95:10:95:10 | e | +| exceptions.js:100:13:100:20 | source() | exceptions.js:102:12:102:12 | e | +| exceptions.js:115:21:115:28 | source() | exceptions.js:121:10:121:10 | e | +| exceptions.js:144:9:144:16 | source() | exceptions.js:129:10:129:10 | e | +| exceptions.js:144:9:144:16 | source() | exceptions.js:132:8:132:27 | returnThrownSource() | +| exceptions.js:150:13:150:20 | source() | exceptions.js:153:10:153:10 | e | +| exceptions.js:158:13:158:20 | source() | exceptions.js:161:10:161:10 | e | +| factory-function.js:21:13:21:20 | source() | factory-function.js:7:10:7:12 | obj | +| factory-function.js:22:13:22:20 | source() | factory-function.js:7:10:7:12 | obj | +| factory-function.js:26:7:26:14 | source() | factory-function.js:16:14:16:16 | obj | +| factory-function.js:27:7:27:14 | source() | factory-function.js:16:14:16:16 | obj | +| getters-and-setters.js:6:20:6:27 | source() | getters-and-setters.js:9:10:9:18 | new C().x | +| getters-and-setters.js:6:20:6:27 | source() | getters-and-setters.js:13:18:13:20 | c.x | +| getters-and-setters.js:27:15:27:22 | source() | getters-and-setters.js:23:18:23:18 | v | +| getters-and-setters.js:47:23:47:30 | source() | getters-and-setters.js:45:14:45:16 | c.x | +| getters-and-setters.js:53:21:53:28 | source() | getters-and-setters.js:53:10:53:30 | getX(ne ... rce())) | +| getters-and-setters.js:60:20:60:27 | source() | getters-and-setters.js:66:10:66:14 | obj.x | +| getters-and-setters.js:67:13:67:20 | source() | getters-and-setters.js:63:18:63:22 | value | +| getters-and-setters.js:79:20:79:27 | source() | getters-and-setters.js:88:10:88:18 | new C().x | +| getters-and-setters.js:79:20:79:27 | source() | getters-and-setters.js:92:14:92:16 | c.x | +| getters-and-setters.js:79:20:79:27 | source() | getters-and-setters.js:100:10:100:22 | getX(new C()) | +| getters-and-setters.js:89:17:89:24 | source() | getters-and-setters.js:82:18:82:22 | value | +| implied-receiver.js:4:16:4:23 | source() | implied-receiver.js:7:18:7:25 | this.foo | +| importedReactComponent.jsx:4:40:4:47 | source() | exportedReactComponent.jsx:2:10:2:19 | props.text | +| indexOf.js:4:11:4:18 | source() | indexOf.js:9:10:9:10 | x | +| indexOf.js:4:11:4:18 | source() | indexOf.js:13:10:13:10 | x | +| logical-and.js:2:17:2:24 | source() | logical-and.js:4:10:4:24 | "safe" && taint | +| nested-props.js:4:13:4:20 | source() | nested-props.js:5:10:5:14 | obj.x | +| nested-props.js:9:18:9:25 | source() | nested-props.js:10:10:10:16 | obj.x.y | +| nested-props.js:14:15:14:22 | source() | nested-props.js:15:10:15:16 | obj.x.y | +| nested-props.js:27:18:27:25 | source() | nested-props.js:28:10:28:14 | obj.x | +| nested-props.js:35:13:35:20 | source() | nested-props.js:36:10:36:20 | doLoad(obj) | +| nested-props.js:43:13:43:20 | source() | nested-props.js:44:10:44:18 | id(obj).x | +| nested-props.js:51:22:51:29 | source() | nested-props.js:52:10:52:16 | obj.x.y | +| nested-props.js:67:31:67:38 | source() | nested-props.js:68:10:68:10 | x | +| object-bypass-sanitizer.js:32:21:32:28 | source() | object-bypass-sanitizer.js:15:10:15:24 | sanitizer_id(x) | +| object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:27:10:27:30 | sanitiz ... bj.foo) | +| object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:28:10:28:30 | sanitiz ... bj).foo | +| partialCalls.js:4:17:4:24 | source() | partialCalls.js:17:14:17:14 | x | +| partialCalls.js:4:17:4:24 | source() | partialCalls.js:20:14:20:14 | y | +| partialCalls.js:4:17:4:24 | source() | partialCalls.js:30:14:30:20 | x.value | +| partialCalls.js:4:17:4:24 | source() | partialCalls.js:41:10:41:18 | id(taint) | +| partialCalls.js:4:17:4:24 | source() | partialCalls.js:51:14:51:14 | x | +| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:14:10:14:14 | taint | +| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:17:14:17:18 | taint | +| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:21:14:21:18 | taint | +| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:25:14:25:18 | taint | +| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:33:14:33:18 | taint | +| sanitizer-guards.js:2:11:2:18 | source() | sanitizer-guards.js:4:8:4:8 | x | +| sanitizer-guards.js:13:14:13:21 | source() | sanitizer-guards.js:15:10:15:15 | this.x | +| sanitizer-guards.js:13:14:13:21 | source() | sanitizer-guards.js:21:14:21:19 | this.x | +| sanitizer-guards.js:13:14:13:21 | source() | sanitizer-guards.js:26:9:26:14 | this.x | +| sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:45:8:45:8 | x | +| sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:48:10:48:10 | x | +| sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:52:10:52:10 | x | +| sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | +| sanitizer-guards.js:68:11:68:18 | source() | sanitizer-guards.js:75:8:75:8 | x | +| sanitizer-guards.js:79:11:79:18 | source() | sanitizer-guards.js:81:8:81:8 | x | +| sanitizer-guards.js:79:11:79:18 | source() | sanitizer-guards.js:84:10:84:10 | x | +| sanitizer-guards.js:79:11:79:18 | source() | sanitizer-guards.js:86:9:86:9 | x | +| sanitizer-guards.js:91:11:91:18 | source() | sanitizer-guards.js:93:8:93:8 | x | +| sanitizer-guards.js:91:11:91:18 | source() | sanitizer-guards.js:96:10:96:10 | x | +| sanitizer-guards.js:91:11:91:18 | source() | sanitizer-guards.js:98:7:98:7 | x | +| sanitizer-guards.js:91:11:91:18 | source() | sanitizer-guards.js:102:10:102:10 | x | +| sanitizer-guards.js:91:11:91:18 | source() | sanitizer-guards.js:104:7:104:7 | x | +| thisAssignments.js:4:17:4:24 | source() | thisAssignments.js:5:10:5:18 | obj.field | +| thisAssignments.js:7:19:7:26 | source() | thisAssignments.js:8:10:8:20 | this.field2 | +| tst.js:2:13:2:20 | source() | tst.js:4:10:4:10 | x | +| tst.js:2:13:2:20 | source() | tst.js:35:14:35:16 | ary | +| tst.js:2:13:2:20 | source() | tst.js:41:14:41:16 | ary | +| tst.js:2:13:2:20 | source() | tst.js:54:14:54:19 | unsafe | From 1d267efb6bd068962917d8cd6c13626da8551562 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 28 Jun 2024 14:30:56 +0200 Subject: [PATCH 223/514] JS: Fix missing qldoc --- .../ql/lib/semmle/javascript/dataflow/Configuration.qll | 2 ++ .../ql/lib/semmle/javascript/dataflow/FlowSummary.qll | 5 +++++ .../semmle/javascript/dataflow/internal/BarrierGuards.qll | 2 +- .../semmle/javascript/dataflow/internal/DataFlowNode.qll | 8 +++----- .../javascript/dataflow/internal/sharedlib/DataFlow.qll | 2 ++ .../dataflow/internal/sharedlib/TaintTracking.qll | 2 ++ .../security/dataflow/UnsafeDynamicMethodAccessQuery.qll | 1 + 7 files changed, 16 insertions(+), 6 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index 3c5f57f60a6..981155a5fee 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -1762,7 +1762,9 @@ class MidPathNode extends PathNode, MkMidNode { predicate isHidden() { PathNode::shouldNodeBeHidden(nd) } } +/** Companion module to the `PathNode` class. */ module PathNode { + /** Holds if `nd` should be hidden in data flow paths. */ predicate shouldNodeBeHidden(DataFlow::Node nd) { // Skip phi, refinement, and capture nodes nd.(DataFlow::SsaDefinitionNode).getSsaVariable().getDefinition() instanceof diff --git a/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll b/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll index 51005bf44ca..9f619a3058e 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll @@ -12,6 +12,11 @@ abstract class SummarizedCallable extends LibraryCallable, Impl::Public::Summari SummarizedCallable() { any() } // TODO: rename 'propagatesFlowExt' and/or override 'propagatesFlow' directly + /** + * Holds if data may flow from `input` to `output` through this callable. + * + * `preservesValue` indicates whether this is a value-preserving step or a taint-step. + */ pragma[nomagic] predicate propagatesFlowExt(string input, string output, boolean preservesValue) { none() } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll index 340a7b9694b..1235e05121a 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll @@ -187,7 +187,7 @@ module MakeStateBarrierGuard< abstract predicate blocksExpr(boolean outcome, Expr test, FlowState state); } - class ExplicitBarrierGuard extends BarrierGuard instanceof BaseGuard { + private class ExplicitBarrierGuard extends BarrierGuard instanceof BaseGuard { override predicate blocksExpr(boolean outcome, Expr test, FlowState state) { BaseGuard.super.blocksExpr(outcome, test, state) } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index 5f80355f000..4e10b6b27e1 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -112,11 +112,9 @@ private class TEarlyStageNode = * These module systems must therefore use `EarlyStageNode` instead of `DataFlow::Node`. */ class EarlyStageNode extends TEarlyStageNode { + /** Gets a string representation of this data flow node. */ string toString() { result = this.(DataFlow::Node).toString() } - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - this.(DataFlow::Node).hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } + /** Gets the location of this data flow node. */ + Location getLocation() { result = this.(DataFlow::Node).getLocation() } } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlow.qll index a9148af94ac..d9e711ee07a 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/DataFlow.qll @@ -1,3 +1,5 @@ +/** Provides the instantiation of the shared data flow library. */ + private import semmle.javascript.Locations private import codeql.dataflow.DataFlow private import DataFlowArg diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/TaintTracking.qll index bfa4c4de8c9..e2215a8afc3 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/TaintTracking.qll @@ -1,3 +1,5 @@ +/** Provides the instantiation of the shared taint tracking library. */ + private import semmle.javascript.Locations private import codeql.dataflow.TaintTracking private import DataFlowArg diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccessQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccessQuery.qll index 1d1098f87e1..f73363d1767 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccessQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccessQuery.qll @@ -43,6 +43,7 @@ module UnsafeDynamicMethodAccessConfig implements DataFlow::StateConfigSig { label.isTaint() } + /** An additional flow step for use in both this configuration and the legacy configuration. */ additional predicate additionalFlowStep( DataFlow::Node src, DataFlow::FlowLabel srclabel, DataFlow::Node dst, DataFlow::FlowLabel dstlabel From 1a532dac29d9c3b9f398bde7eea3d64e060b1943 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 2 Aug 2024 12:58:27 +0200 Subject: [PATCH 224/514] JS: Update VariableCapture instantiation after merge --- .../lib/semmle/javascript/dataflow/internal/VariableCapture.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll index f170b99e892..8f95c88d72a 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll @@ -126,6 +126,8 @@ module VariableCaptureConfig implements InputSig { ) } + class ControlFlowNode = js::ControlFlowNode; + class BasicBlock extends js::BasicBlock { Callable getEnclosingCallable() { result = this.getContainer().getFunctionBoundary() } } From 0a143a5f52a17436d5db720e4ed2f5fbfff220df Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 2 Aug 2024 14:17:56 +0200 Subject: [PATCH 225/514] JS: Do not include type in path explanation --- .../semmle/javascript/dataflow/internal/DataFlowPrivate.qll | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 941ce88f3d9..8f9e3ee6f6f 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -301,7 +301,7 @@ newtype TDataFlowType = TAnyType() class DataFlowType extends TDataFlowType { - string toString() { + string toDebugString() { this instanceof TFunctionType and result = "TFunctionType(" + this.asFunction().toString() + ") at line " + @@ -310,6 +310,10 @@ class DataFlowType extends TDataFlowType { this instanceof TAnyType and result = "TAnyType" } + string toString() { + result = "" // Must be the empty string to prevent this from showing up in path explanations + } + Function asFunction() { this = TFunctionType(result) } } From 2d814428d67ca67109843680c598173eed5d6bd8 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 5 Aug 2024 10:44:12 +0200 Subject: [PATCH 226/514] JS: Update expected output with provenance --- .../Security/CWE-079/ExceptionXss/ExceptionXss.expected | 6 +++--- .../query-tests/Security/CWE-312/BuildArtifactLeak.expected | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ExceptionXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ExceptionXss.expected index 67c34650206..798632aabb1 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ExceptionXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ExceptionXss.expected @@ -104,14 +104,14 @@ edges | exception-xss.js:33:19:33:21 | foo | exception-xss.js:33:11:33:22 | ["bar", foo] | provenance | | | exception-xss.js:34:11:34:11 | e | exception-xss.js:35:18:35:18 | e | provenance | | | exception-xss.js:38:16:38:16 | x | exception-xss.js:39:9:39:9 | x | provenance | | -| exception-xss.js:39:9:39:9 | x | exception-xss.js:39:3:39:10 | exceptional return of deep2(x) | provenance | | +| exception-xss.js:39:9:39:9 | x | exception-xss.js:39:3:39:10 | exceptional return of deep2(x) | provenance | Config | | exception-xss.js:39:9:39:9 | x | exception-xss.js:41:17:41:17 | x | provenance | | | exception-xss.js:41:17:41:17 | x | exception-xss.js:42:9:42:9 | x | provenance | | | exception-xss.js:42:9:42:9 | x | exception-xss.js:4:17:4:17 | x | provenance | | | exception-xss.js:42:9:42:9 | x | exception-xss.js:42:3:42:10 | exceptional return of inner(x) | provenance | Config | | exception-xss.js:46:3:46:19 | exceptional return of deep("bar" + foo) | exception-xss.js:47:11:47:11 | e | provenance | | | exception-xss.js:46:8:46:18 | "bar" + foo | exception-xss.js:38:16:38:16 | x | provenance | | -| exception-xss.js:46:8:46:18 | "bar" + foo | exception-xss.js:46:3:46:19 | exceptional return of deep("bar" + foo) | provenance | | +| exception-xss.js:46:8:46:18 | "bar" + foo | exception-xss.js:46:3:46:19 | exceptional return of deep("bar" + foo) | provenance | Config | | exception-xss.js:46:16:46:18 | foo | exception-xss.js:46:8:46:18 | "bar" + foo | provenance | | | exception-xss.js:47:11:47:11 | e | exception-xss.js:48:18:48:18 | e | provenance | | | exception-xss.js:74:28:74:28 | x | exception-xss.js:75:10:75:10 | x | provenance | | @@ -119,7 +119,7 @@ edges | exception-xss.js:75:10:75:10 | x | exception-xss.js:75:4:75:11 | exceptional return of inner(x) | provenance | Config | | exception-xss.js:81:3:81:19 | exceptional return of myWeirdInner(foo) | exception-xss.js:82:11:82:11 | e | provenance | | | exception-xss.js:81:16:81:18 | foo | exception-xss.js:74:28:74:28 | x | provenance | | -| exception-xss.js:81:16:81:18 | foo | exception-xss.js:81:3:81:19 | exceptional return of myWeirdInner(foo) | provenance | | +| exception-xss.js:81:16:81:18 | foo | exception-xss.js:81:3:81:19 | exceptional return of myWeirdInner(foo) | provenance | Config | | exception-xss.js:82:11:82:11 | e | exception-xss.js:83:18:83:18 | e | provenance | | | exception-xss.js:89:11:89:13 | foo | exception-xss.js:89:11:89:26 | foo.match(/foo/) | provenance | | | exception-xss.js:89:11:89:26 | foo.match(/foo/) | exception-xss.js:90:11:90:11 | e | provenance | Config | diff --git a/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected b/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected index 1f3caa8f1ce..c05cb5f53f5 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected @@ -19,10 +19,10 @@ edges | build-leaks.js:21:11:26:5 | stringifed [process.env] | build-leaks.js:30:22:30:31 | stringifed [process.env] | provenance | | | build-leaks.js:21:24:26:5 | {\\n ... )\\n } [process.env] | build-leaks.js:21:11:26:5 | stringifed [process.env] | provenance | | | build-leaks.js:22:24:25:14 | Object. ... }, {}) | build-leaks.js:21:24:26:5 | {\\n ... )\\n } [process.env] | provenance | | -| build-leaks.js:22:36:22:38 | raw | build-leaks.js:22:24:25:14 | Object. ... }, {}) | provenance | | +| build-leaks.js:22:36:22:38 | raw | build-leaks.js:22:24:25:14 | Object. ... }, {}) | provenance | Config | | build-leaks.js:22:36:22:38 | raw | build-leaks.js:22:49:22:51 | env | provenance | Config | | build-leaks.js:22:36:22:38 | raw | build-leaks.js:23:39:23:41 | raw | provenance | | -| build-leaks.js:22:36:22:38 | raw | build-leaks.js:25:12:25:13 | [post update] {} | provenance | | +| build-leaks.js:22:36:22:38 | raw | build-leaks.js:25:12:25:13 | [post update] {} | provenance | Config | | build-leaks.js:22:49:22:51 | env | build-leaks.js:24:20:24:22 | env | provenance | | | build-leaks.js:22:49:22:51 | env | build-leaks.js:24:20:24:22 | env | provenance | | | build-leaks.js:23:13:23:15 | [post update] env | build-leaks.js:22:49:22:51 | env | provenance | | From 423fd045452475d415935987c520cde5329563bf Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 22 Aug 2024 13:17:09 +0200 Subject: [PATCH 227/514] JS: Update new xsjs-specific code to respect TEarlyStageNode --- javascript/ql/lib/semmle/javascript/NodeJS.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/NodeJS.qll b/javascript/ql/lib/semmle/javascript/NodeJS.qll index dec585084c2..cd00e06e722 100644 --- a/javascript/ql/lib/semmle/javascript/NodeJS.qll +++ b/javascript/ql/lib/semmle/javascript/NodeJS.qll @@ -309,10 +309,10 @@ private predicate isRequire(EarlyStageNode nd) { // `$.require('underscore');`. // NPM as supported in [XSJS files](https://www.npmjs.com/package/@sap/async-xsjs#npm-packages-support). exists(MethodCallExpr require | - nd.getFile().getExtension() = ["xsjs", "xsjslib"] and + require.getFile().getExtension() = ["xsjs", "xsjslib"] and require.getCalleeName() = "require" and require.getReceiver().(GlobalVarAccess).getName() = "$" and - nd = require.getCallee().flow() + nd = TValueNode(require.getCallee()) ) } From a2dd47aeb2f339be0ffc3a13bc33da9095db5621 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 22 Aug 2024 13:37:09 +0200 Subject: [PATCH 228/514] JS: Update test output These files conflicted and have been regenerated. --- .../CWE-022/TaintedPath/TaintedPath.expected | 410 +++++++++--------- .../Security/CWE-079/DomBasedXss/Xss.expected | 8 + .../XssWithAdditionalSources.expected | 7 + .../CWE-312/BuildArtifactLeak.expected | 1 + .../Security/CWE-730/RegExpInjection.expected | 18 +- .../CWE-798/HardcodedCredentials.expected | 79 +++- 6 files changed, 303 insertions(+), 220 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected index fcc9e4dd3b2..bfff47f8391 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected @@ -41,103 +41,99 @@ nodes | TaintedPath.js:58:54:58:57 | path | semmle.label | path | | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | semmle.label | pathMod ... h(path) | | TaintedPath.js:60:57:60:60 | path | semmle.label | path | -| TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | semmle.label | Cookie.get("unsafe") | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | semmle.label | require ... eq.url) | -| TaintedPath.js:77:31:77:76 | require ... ).query | semmle.label | require ... ).query | -| TaintedPath.js:77:63:77:69 | req.url | semmle.label | req.url | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | semmle.label | require ... eq.url) | -| TaintedPath.js:78:31:78:74 | require ... ).query | semmle.label | require ... ).query | -| TaintedPath.js:78:61:78:67 | req.url | semmle.label | req.url | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | semmle.label | require ... eq.url) | -| TaintedPath.js:79:31:79:73 | require ... ).query | semmle.label | require ... ).query | -| TaintedPath.js:79:60:79:66 | req.url | semmle.label | req.url | -| TaintedPath.js:87:48:87:60 | req.params[0] | semmle.label | req.params[0] | -| TaintedPath.js:95:30:95:31 | ev | semmle.label | ev | -| TaintedPath.js:96:24:96:25 | ev | semmle.label | ev | -| TaintedPath.js:96:24:96:30 | ev.data | semmle.label | ev.data | -| TaintedPath.js:100:6:100:47 | path | semmle.label | path | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | semmle.label | url.par ... , true) | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | semmle.label | url.par ... ).query | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | semmle.label | url.par ... ry.path | -| TaintedPath.js:100:23:100:29 | req.url | semmle.label | req.url | -| TaintedPath.js:102:28:102:48 | fs.real ... c(path) | semmle.label | fs.real ... c(path) | -| TaintedPath.js:102:44:102:47 | path | semmle.label | path | -| TaintedPath.js:103:14:103:17 | path | semmle.label | path | -| TaintedPath.js:104:32:104:39 | realpath | semmle.label | realpath | -| TaintedPath.js:105:45:105:52 | realpath | semmle.label | realpath | -| TaintedPath.js:136:6:136:47 | path | semmle.label | path | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | semmle.label | url.par ... , true) | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | semmle.label | url.par ... ).query | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | semmle.label | url.par ... ry.path | -| TaintedPath.js:136:23:136:29 | req.url | semmle.label | req.url | -| TaintedPath.js:138:23:138:26 | path | semmle.label | path | -| TaintedPath.js:142:7:142:48 | path | semmle.label | path | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | semmle.label | url.par ... , true) | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | semmle.label | url.par ... ).query | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | -| TaintedPath.js:142:24:142:30 | req.url | semmle.label | req.url | -| TaintedPath.js:144:19:144:22 | path | semmle.label | path | -| TaintedPath.js:146:7:146:29 | split | semmle.label | split | -| TaintedPath.js:146:15:146:18 | path | semmle.label | path | -| TaintedPath.js:146:15:146:29 | path.split("/") | semmle.label | path.split("/") | -| TaintedPath.js:148:19:148:23 | split | semmle.label | split | -| TaintedPath.js:148:19:148:33 | split.join("/") | semmle.label | split.join("/") | -| TaintedPath.js:152:19:152:23 | split | semmle.label | split | -| TaintedPath.js:152:19:152:26 | split[x] | semmle.label | split[x] | -| TaintedPath.js:153:19:153:35 | prefix + split[x] | semmle.label | prefix + split[x] | -| TaintedPath.js:153:28:153:32 | split | semmle.label | split | -| TaintedPath.js:153:28:153:35 | split[x] | semmle.label | split[x] | -| TaintedPath.js:155:7:155:38 | concatted | semmle.label | concatted | -| TaintedPath.js:155:19:155:38 | prefix.concat(split) | semmle.label | prefix.concat(split) | -| TaintedPath.js:155:33:155:37 | split | semmle.label | split | -| TaintedPath.js:156:19:156:27 | concatted | semmle.label | concatted | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | semmle.label | concatted.join("/") | -| TaintedPath.js:158:7:158:39 | concatted2 | semmle.label | concatted2 | -| TaintedPath.js:158:20:158:24 | split | semmle.label | split | -| TaintedPath.js:158:20:158:39 | split.concat(prefix) | semmle.label | split.concat(prefix) | -| TaintedPath.js:159:19:159:28 | concatted2 | semmle.label | concatted2 | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | semmle.label | concatted2.join("/") | -| TaintedPath.js:161:19:161:23 | split | semmle.label | split | -| TaintedPath.js:161:19:161:29 | split.pop() | semmle.label | split.pop() | -| TaintedPath.js:166:7:166:48 | path | semmle.label | path | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | semmle.label | url.par ... , true) | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | semmle.label | url.par ... ).query | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | -| TaintedPath.js:166:24:166:30 | req.url | semmle.label | req.url | -| TaintedPath.js:170:29:170:32 | path | semmle.label | path | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | semmle.label | path.re ... /g, '') | -| TaintedPath.js:176:29:176:32 | path | semmle.label | path | -| TaintedPath.js:176:29:176:52 | path.re ... /g, '') | semmle.label | path.re ... /g, '') | -| TaintedPath.js:177:29:177:32 | path | semmle.label | path | -| TaintedPath.js:177:29:177:53 | path.re ... /g, '') | semmle.label | path.re ... /g, '') | -| TaintedPath.js:178:29:178:32 | path | semmle.label | path | -| TaintedPath.js:178:29:178:51 | path.re ... /g, '') | semmle.label | path.re ... /g, '') | -| TaintedPath.js:179:29:179:32 | path | semmle.label | path | -| TaintedPath.js:179:29:179:57 | path.re ... /g, '') | semmle.label | path.re ... /g, '') | -| TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | semmle.label | "prefix ... +/, '') | -| TaintedPath.js:194:40:194:43 | path | semmle.label | path | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | semmle.label | path.re ... +/, '') | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | semmle.label | pathMod ... e(path) | -| TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | semmle.label | pathMod ... +/, '') | -| TaintedPath.js:195:50:195:53 | path | semmle.label | path | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | semmle.label | qs.parse(req.url) | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | semmle.label | qs.pars ... rl).foo | -| TaintedPath.js:203:38:203:44 | req.url | semmle.label | req.url | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | semmle.label | qs.pars ... q.url)) | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | semmle.label | qs.pars ... l)).foo | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | semmle.label | normali ... eq.url) | -| TaintedPath.js:204:51:204:57 | req.url | semmle.label | req.url | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | semmle.label | parseqs ... eq.url) | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | semmle.label | parseqs ... rl).foo | -| TaintedPath.js:206:44:206:50 | req.url | semmle.label | req.url | -| TaintedPath.js:211:7:211:48 | path | semmle.label | path | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | semmle.label | url.par ... , true) | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | semmle.label | url.par ... ).query | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | -| TaintedPath.js:211:24:211:30 | req.url | semmle.label | req.url | -| TaintedPath.js:212:31:212:34 | path | semmle.label | path | -| TaintedPath.js:213:45:213:48 | path | semmle.label | path | -| TaintedPath.js:214:35:214:38 | path | semmle.label | path | +| TaintedPath.js:65:31:65:70 | require ... eq.url) | semmle.label | require ... eq.url) | +| TaintedPath.js:65:31:65:76 | require ... ).query | semmle.label | require ... ).query | +| TaintedPath.js:65:63:65:69 | req.url | semmle.label | req.url | +| TaintedPath.js:66:31:66:68 | require ... eq.url) | semmle.label | require ... eq.url) | +| TaintedPath.js:66:31:66:74 | require ... ).query | semmle.label | require ... ).query | +| TaintedPath.js:66:61:66:67 | req.url | semmle.label | req.url | +| TaintedPath.js:67:31:67:67 | require ... eq.url) | semmle.label | require ... eq.url) | +| TaintedPath.js:67:31:67:73 | require ... ).query | semmle.label | require ... ).query | +| TaintedPath.js:67:60:67:66 | req.url | semmle.label | req.url | +| TaintedPath.js:75:48:75:60 | req.params[0] | semmle.label | req.params[0] | +| TaintedPath.js:84:6:84:47 | path | semmle.label | path | +| TaintedPath.js:84:13:84:36 | url.par ... , true) | semmle.label | url.par ... , true) | +| TaintedPath.js:84:13:84:42 | url.par ... ).query | semmle.label | url.par ... ).query | +| TaintedPath.js:84:13:84:47 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| TaintedPath.js:84:23:84:29 | req.url | semmle.label | req.url | +| TaintedPath.js:86:28:86:48 | fs.real ... c(path) | semmle.label | fs.real ... c(path) | +| TaintedPath.js:86:44:86:47 | path | semmle.label | path | +| TaintedPath.js:87:14:87:17 | path | semmle.label | path | +| TaintedPath.js:88:32:88:39 | realpath | semmle.label | realpath | +| TaintedPath.js:89:45:89:52 | realpath | semmle.label | realpath | +| TaintedPath.js:120:6:120:47 | path | semmle.label | path | +| TaintedPath.js:120:13:120:36 | url.par ... , true) | semmle.label | url.par ... , true) | +| TaintedPath.js:120:13:120:42 | url.par ... ).query | semmle.label | url.par ... ).query | +| TaintedPath.js:120:13:120:47 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| TaintedPath.js:120:23:120:29 | req.url | semmle.label | req.url | +| TaintedPath.js:122:23:122:26 | path | semmle.label | path | +| TaintedPath.js:126:7:126:48 | path | semmle.label | path | +| TaintedPath.js:126:14:126:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| TaintedPath.js:126:14:126:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| TaintedPath.js:126:14:126:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| TaintedPath.js:126:24:126:30 | req.url | semmle.label | req.url | +| TaintedPath.js:128:19:128:22 | path | semmle.label | path | +| TaintedPath.js:130:7:130:29 | split | semmle.label | split | +| TaintedPath.js:130:15:130:18 | path | semmle.label | path | +| TaintedPath.js:130:15:130:29 | path.split("/") | semmle.label | path.split("/") | +| TaintedPath.js:132:19:132:23 | split | semmle.label | split | +| TaintedPath.js:132:19:132:33 | split.join("/") | semmle.label | split.join("/") | +| TaintedPath.js:136:19:136:23 | split | semmle.label | split | +| TaintedPath.js:136:19:136:26 | split[x] | semmle.label | split[x] | +| TaintedPath.js:137:19:137:35 | prefix + split[x] | semmle.label | prefix + split[x] | +| TaintedPath.js:137:28:137:32 | split | semmle.label | split | +| TaintedPath.js:137:28:137:35 | split[x] | semmle.label | split[x] | +| TaintedPath.js:139:7:139:38 | concatted | semmle.label | concatted | +| TaintedPath.js:139:19:139:38 | prefix.concat(split) | semmle.label | prefix.concat(split) | +| TaintedPath.js:139:33:139:37 | split | semmle.label | split | +| TaintedPath.js:140:19:140:27 | concatted | semmle.label | concatted | +| TaintedPath.js:140:19:140:37 | concatted.join("/") | semmle.label | concatted.join("/") | +| TaintedPath.js:142:7:142:39 | concatted2 | semmle.label | concatted2 | +| TaintedPath.js:142:20:142:24 | split | semmle.label | split | +| TaintedPath.js:142:20:142:39 | split.concat(prefix) | semmle.label | split.concat(prefix) | +| TaintedPath.js:143:19:143:28 | concatted2 | semmle.label | concatted2 | +| TaintedPath.js:143:19:143:38 | concatted2.join("/") | semmle.label | concatted2.join("/") | +| TaintedPath.js:145:19:145:23 | split | semmle.label | split | +| TaintedPath.js:145:19:145:29 | split.pop() | semmle.label | split.pop() | +| TaintedPath.js:150:7:150:48 | path | semmle.label | path | +| TaintedPath.js:150:14:150:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| TaintedPath.js:150:14:150:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| TaintedPath.js:150:14:150:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| TaintedPath.js:150:24:150:30 | req.url | semmle.label | req.url | +| TaintedPath.js:154:29:154:32 | path | semmle.label | path | +| TaintedPath.js:154:29:154:55 | path.re ... /g, '') | semmle.label | path.re ... /g, '') | +| TaintedPath.js:160:29:160:32 | path | semmle.label | path | +| TaintedPath.js:160:29:160:52 | path.re ... /g, '') | semmle.label | path.re ... /g, '') | +| TaintedPath.js:161:29:161:32 | path | semmle.label | path | +| TaintedPath.js:161:29:161:53 | path.re ... /g, '') | semmle.label | path.re ... /g, '') | +| TaintedPath.js:162:29:162:32 | path | semmle.label | path | +| TaintedPath.js:162:29:162:51 | path.re ... /g, '') | semmle.label | path.re ... /g, '') | +| TaintedPath.js:163:29:163:32 | path | semmle.label | path | +| TaintedPath.js:163:29:163:57 | path.re ... /g, '') | semmle.label | path.re ... /g, '') | +| TaintedPath.js:178:29:178:73 | "prefix ... +/, '') | semmle.label | "prefix ... +/, '') | +| TaintedPath.js:178:40:178:43 | path | semmle.label | path | +| TaintedPath.js:178:40:178:73 | path.re ... +/, '') | semmle.label | path.re ... +/, '') | +| TaintedPath.js:179:29:179:54 | pathMod ... e(path) | semmle.label | pathMod ... e(path) | +| TaintedPath.js:179:29:179:84 | pathMod ... +/, '') | semmle.label | pathMod ... +/, '') | +| TaintedPath.js:179:50:179:53 | path | semmle.label | path | +| TaintedPath.js:187:29:187:45 | qs.parse(req.url) | semmle.label | qs.parse(req.url) | +| TaintedPath.js:187:29:187:49 | qs.pars ... rl).foo | semmle.label | qs.pars ... rl).foo | +| TaintedPath.js:187:38:187:44 | req.url | semmle.label | req.url | +| TaintedPath.js:188:29:188:59 | qs.pars ... q.url)) | semmle.label | qs.pars ... q.url)) | +| TaintedPath.js:188:29:188:63 | qs.pars ... l)).foo | semmle.label | qs.pars ... l)).foo | +| TaintedPath.js:188:38:188:58 | normali ... eq.url) | semmle.label | normali ... eq.url) | +| TaintedPath.js:188:51:188:57 | req.url | semmle.label | req.url | +| TaintedPath.js:190:29:190:51 | parseqs ... eq.url) | semmle.label | parseqs ... eq.url) | +| TaintedPath.js:190:29:190:55 | parseqs ... rl).foo | semmle.label | parseqs ... rl).foo | +| TaintedPath.js:190:44:190:50 | req.url | semmle.label | req.url | +| TaintedPath.js:195:7:195:48 | path | semmle.label | path | +| TaintedPath.js:195:14:195:37 | url.par ... , true) | semmle.label | url.par ... , true) | +| TaintedPath.js:195:14:195:43 | url.par ... ).query | semmle.label | url.par ... ).query | +| TaintedPath.js:195:14:195:48 | url.par ... ry.path | semmle.label | url.par ... ry.path | +| TaintedPath.js:195:24:195:30 | req.url | semmle.label | req.url | +| TaintedPath.js:196:31:196:34 | path | semmle.label | path | +| TaintedPath.js:197:45:197:48 | path | semmle.label | path | +| TaintedPath.js:198:35:198:38 | path | semmle.label | path | | examples/TaintedPath.js:8:7:8:52 | filePath | semmle.label | filePath | | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | semmle.label | url.par ... , true) | | examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | semmle.label | url.par ... ).query | @@ -532,90 +528,87 @@ edges | TaintedPath.js:56:48:56:51 | path | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | provenance | Config | | TaintedPath.js:58:54:58:57 | path | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | provenance | Config | | TaintedPath.js:60:57:60:60 | path | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | provenance | Config | -| TaintedPath.js:77:31:77:70 | require ... eq.url) | TaintedPath.js:77:31:77:76 | require ... ).query | provenance | Config | -| TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:70 | require ... eq.url) | provenance | Config | -| TaintedPath.js:78:31:78:68 | require ... eq.url) | TaintedPath.js:78:31:78:74 | require ... ).query | provenance | Config | -| TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:68 | require ... eq.url) | provenance | Config | -| TaintedPath.js:79:31:79:67 | require ... eq.url) | TaintedPath.js:79:31:79:73 | require ... ).query | provenance | Config | -| TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:67 | require ... eq.url) | provenance | Config | -| TaintedPath.js:95:30:95:31 | ev | TaintedPath.js:96:24:96:25 | ev | provenance | | -| TaintedPath.js:96:24:96:25 | ev | TaintedPath.js:96:24:96:30 | ev.data | provenance | Config | -| TaintedPath.js:96:24:96:30 | ev.data | TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | provenance | Config | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:102:44:102:47 | path | provenance | | -| TaintedPath.js:100:6:100:47 | path | TaintedPath.js:103:14:103:17 | path | provenance | | -| TaintedPath.js:100:13:100:36 | url.par ... , true) | TaintedPath.js:100:13:100:42 | url.par ... ).query | provenance | Config | -| TaintedPath.js:100:13:100:42 | url.par ... ).query | TaintedPath.js:100:13:100:47 | url.par ... ry.path | provenance | Config | -| TaintedPath.js:100:13:100:47 | url.par ... ry.path | TaintedPath.js:100:6:100:47 | path | provenance | | -| TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:100:13:100:36 | url.par ... , true) | provenance | Config | -| TaintedPath.js:102:44:102:47 | path | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | provenance | Config | -| TaintedPath.js:103:14:103:17 | path | TaintedPath.js:104:32:104:39 | realpath | provenance | Config | -| TaintedPath.js:104:32:104:39 | realpath | TaintedPath.js:105:45:105:52 | realpath | provenance | | -| TaintedPath.js:136:6:136:47 | path | TaintedPath.js:138:23:138:26 | path | provenance | | -| TaintedPath.js:136:13:136:36 | url.par ... , true) | TaintedPath.js:136:13:136:42 | url.par ... ).query | provenance | Config | -| TaintedPath.js:136:13:136:42 | url.par ... ).query | TaintedPath.js:136:13:136:47 | url.par ... ry.path | provenance | Config | -| TaintedPath.js:136:13:136:47 | url.par ... ry.path | TaintedPath.js:136:6:136:47 | path | provenance | | -| TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:136:13:136:36 | url.par ... , true) | provenance | Config | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:144:19:144:22 | path | provenance | | -| TaintedPath.js:142:7:142:48 | path | TaintedPath.js:146:15:146:18 | path | provenance | | -| TaintedPath.js:142:14:142:37 | url.par ... , true) | TaintedPath.js:142:14:142:43 | url.par ... ).query | provenance | Config | -| TaintedPath.js:142:14:142:43 | url.par ... ).query | TaintedPath.js:142:14:142:48 | url.par ... ry.path | provenance | Config | -| TaintedPath.js:142:14:142:48 | url.par ... ry.path | TaintedPath.js:142:7:142:48 | path | provenance | | -| TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:142:14:142:37 | url.par ... , true) | provenance | Config | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:148:19:148:23 | split | provenance | | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:152:19:152:23 | split | provenance | | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:153:28:153:32 | split | provenance | | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:155:33:155:37 | split | provenance | | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:158:20:158:24 | split | provenance | | -| TaintedPath.js:146:7:146:29 | split | TaintedPath.js:161:19:161:23 | split | provenance | | -| TaintedPath.js:146:15:146:18 | path | TaintedPath.js:146:15:146:29 | path.split("/") | provenance | Config | -| TaintedPath.js:146:15:146:29 | path.split("/") | TaintedPath.js:146:7:146:29 | split | provenance | | -| TaintedPath.js:148:19:148:23 | split | TaintedPath.js:148:19:148:33 | split.join("/") | provenance | Config | -| TaintedPath.js:152:19:152:23 | split | TaintedPath.js:152:19:152:26 | split[x] | provenance | Config | -| TaintedPath.js:153:28:153:32 | split | TaintedPath.js:153:28:153:35 | split[x] | provenance | Config | -| TaintedPath.js:153:28:153:35 | split[x] | TaintedPath.js:153:19:153:35 | prefix + split[x] | provenance | Config | -| TaintedPath.js:155:7:155:38 | concatted | TaintedPath.js:156:19:156:27 | concatted | provenance | | -| TaintedPath.js:155:19:155:38 | prefix.concat(split) | TaintedPath.js:155:7:155:38 | concatted | provenance | | -| TaintedPath.js:155:33:155:37 | split | TaintedPath.js:155:19:155:38 | prefix.concat(split) | provenance | Config | -| TaintedPath.js:156:19:156:27 | concatted | TaintedPath.js:156:19:156:37 | concatted.join("/") | provenance | Config | -| TaintedPath.js:158:7:158:39 | concatted2 | TaintedPath.js:159:19:159:28 | concatted2 | provenance | | -| TaintedPath.js:158:20:158:24 | split | TaintedPath.js:158:20:158:39 | split.concat(prefix) | provenance | Config | -| TaintedPath.js:158:20:158:39 | split.concat(prefix) | TaintedPath.js:158:7:158:39 | concatted2 | provenance | | -| TaintedPath.js:159:19:159:28 | concatted2 | TaintedPath.js:159:19:159:38 | concatted2.join("/") | provenance | Config | -| TaintedPath.js:161:19:161:23 | split | TaintedPath.js:161:19:161:29 | split.pop() | provenance | Config | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:170:29:170:32 | path | provenance | | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:176:29:176:32 | path | provenance | | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:177:29:177:32 | path | provenance | | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:178:29:178:32 | path | provenance | | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:179:29:179:32 | path | provenance | | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:194:40:194:43 | path | provenance | | -| TaintedPath.js:166:7:166:48 | path | TaintedPath.js:195:50:195:53 | path | provenance | | -| TaintedPath.js:166:14:166:37 | url.par ... , true) | TaintedPath.js:166:14:166:43 | url.par ... ).query | provenance | Config | -| TaintedPath.js:166:14:166:43 | url.par ... ).query | TaintedPath.js:166:14:166:48 | url.par ... ry.path | provenance | Config | -| TaintedPath.js:166:14:166:48 | url.par ... ry.path | TaintedPath.js:166:7:166:48 | path | provenance | | -| TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:166:14:166:37 | url.par ... , true) | provenance | Config | -| TaintedPath.js:170:29:170:32 | path | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | provenance | Config | -| TaintedPath.js:176:29:176:32 | path | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | provenance | Config | -| TaintedPath.js:177:29:177:32 | path | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | provenance | Config | -| TaintedPath.js:178:29:178:32 | path | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | provenance | Config | -| TaintedPath.js:179:29:179:32 | path | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | provenance | Config | -| TaintedPath.js:194:40:194:43 | path | TaintedPath.js:194:40:194:73 | path.re ... +/, '') | provenance | Config | -| TaintedPath.js:194:40:194:73 | path.re ... +/, '') | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | provenance | Config | -| TaintedPath.js:195:29:195:54 | pathMod ... e(path) | TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | provenance | Config | -| TaintedPath.js:195:50:195:53 | path | TaintedPath.js:195:29:195:54 | pathMod ... e(path) | provenance | Config | -| TaintedPath.js:203:29:203:45 | qs.parse(req.url) | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | provenance | Config | -| TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:45 | qs.parse(req.url) | provenance | Config | -| TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | provenance | Config | -| TaintedPath.js:204:38:204:58 | normali ... eq.url) | TaintedPath.js:204:29:204:59 | qs.pars ... q.url)) | provenance | Config | -| TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:38:204:58 | normali ... eq.url) | provenance | Config | -| TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | provenance | Config | -| TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:51 | parseqs ... eq.url) | provenance | Config | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:212:31:212:34 | path | provenance | | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:45:213:48 | path | provenance | | -| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:214:35:214:38 | path | provenance | | -| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | provenance | Config | -| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | provenance | Config | -| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | provenance | | -| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | provenance | Config | +| TaintedPath.js:65:31:65:70 | require ... eq.url) | TaintedPath.js:65:31:65:76 | require ... ).query | provenance | Config | +| TaintedPath.js:65:63:65:69 | req.url | TaintedPath.js:65:31:65:70 | require ... eq.url) | provenance | Config | +| TaintedPath.js:66:31:66:68 | require ... eq.url) | TaintedPath.js:66:31:66:74 | require ... ).query | provenance | Config | +| TaintedPath.js:66:61:66:67 | req.url | TaintedPath.js:66:31:66:68 | require ... eq.url) | provenance | Config | +| TaintedPath.js:67:31:67:67 | require ... eq.url) | TaintedPath.js:67:31:67:73 | require ... ).query | provenance | Config | +| TaintedPath.js:67:60:67:66 | req.url | TaintedPath.js:67:31:67:67 | require ... eq.url) | provenance | Config | +| TaintedPath.js:84:6:84:47 | path | TaintedPath.js:86:44:86:47 | path | provenance | | +| TaintedPath.js:84:6:84:47 | path | TaintedPath.js:87:14:87:17 | path | provenance | | +| TaintedPath.js:84:13:84:36 | url.par ... , true) | TaintedPath.js:84:13:84:42 | url.par ... ).query | provenance | Config | +| TaintedPath.js:84:13:84:42 | url.par ... ).query | TaintedPath.js:84:13:84:47 | url.par ... ry.path | provenance | Config | +| TaintedPath.js:84:13:84:47 | url.par ... ry.path | TaintedPath.js:84:6:84:47 | path | provenance | | +| TaintedPath.js:84:23:84:29 | req.url | TaintedPath.js:84:13:84:36 | url.par ... , true) | provenance | Config | +| TaintedPath.js:86:44:86:47 | path | TaintedPath.js:86:28:86:48 | fs.real ... c(path) | provenance | Config | +| TaintedPath.js:87:14:87:17 | path | TaintedPath.js:88:32:88:39 | realpath | provenance | Config | +| TaintedPath.js:88:32:88:39 | realpath | TaintedPath.js:89:45:89:52 | realpath | provenance | | +| TaintedPath.js:120:6:120:47 | path | TaintedPath.js:122:23:122:26 | path | provenance | | +| TaintedPath.js:120:13:120:36 | url.par ... , true) | TaintedPath.js:120:13:120:42 | url.par ... ).query | provenance | Config | +| TaintedPath.js:120:13:120:42 | url.par ... ).query | TaintedPath.js:120:13:120:47 | url.par ... ry.path | provenance | Config | +| TaintedPath.js:120:13:120:47 | url.par ... ry.path | TaintedPath.js:120:6:120:47 | path | provenance | | +| TaintedPath.js:120:23:120:29 | req.url | TaintedPath.js:120:13:120:36 | url.par ... , true) | provenance | Config | +| TaintedPath.js:126:7:126:48 | path | TaintedPath.js:128:19:128:22 | path | provenance | | +| TaintedPath.js:126:7:126:48 | path | TaintedPath.js:130:15:130:18 | path | provenance | | +| TaintedPath.js:126:14:126:37 | url.par ... , true) | TaintedPath.js:126:14:126:43 | url.par ... ).query | provenance | Config | +| TaintedPath.js:126:14:126:43 | url.par ... ).query | TaintedPath.js:126:14:126:48 | url.par ... ry.path | provenance | Config | +| TaintedPath.js:126:14:126:48 | url.par ... ry.path | TaintedPath.js:126:7:126:48 | path | provenance | | +| TaintedPath.js:126:24:126:30 | req.url | TaintedPath.js:126:14:126:37 | url.par ... , true) | provenance | Config | +| TaintedPath.js:130:7:130:29 | split | TaintedPath.js:132:19:132:23 | split | provenance | | +| TaintedPath.js:130:7:130:29 | split | TaintedPath.js:136:19:136:23 | split | provenance | | +| TaintedPath.js:130:7:130:29 | split | TaintedPath.js:137:28:137:32 | split | provenance | | +| TaintedPath.js:130:7:130:29 | split | TaintedPath.js:139:33:139:37 | split | provenance | | +| TaintedPath.js:130:7:130:29 | split | TaintedPath.js:142:20:142:24 | split | provenance | | +| TaintedPath.js:130:7:130:29 | split | TaintedPath.js:145:19:145:23 | split | provenance | | +| TaintedPath.js:130:15:130:18 | path | TaintedPath.js:130:15:130:29 | path.split("/") | provenance | Config | +| TaintedPath.js:130:15:130:29 | path.split("/") | TaintedPath.js:130:7:130:29 | split | provenance | | +| TaintedPath.js:132:19:132:23 | split | TaintedPath.js:132:19:132:33 | split.join("/") | provenance | Config | +| TaintedPath.js:136:19:136:23 | split | TaintedPath.js:136:19:136:26 | split[x] | provenance | Config | +| TaintedPath.js:137:28:137:32 | split | TaintedPath.js:137:28:137:35 | split[x] | provenance | Config | +| TaintedPath.js:137:28:137:35 | split[x] | TaintedPath.js:137:19:137:35 | prefix + split[x] | provenance | Config | +| TaintedPath.js:139:7:139:38 | concatted | TaintedPath.js:140:19:140:27 | concatted | provenance | | +| TaintedPath.js:139:19:139:38 | prefix.concat(split) | TaintedPath.js:139:7:139:38 | concatted | provenance | | +| TaintedPath.js:139:33:139:37 | split | TaintedPath.js:139:19:139:38 | prefix.concat(split) | provenance | Config | +| TaintedPath.js:140:19:140:27 | concatted | TaintedPath.js:140:19:140:37 | concatted.join("/") | provenance | Config | +| TaintedPath.js:142:7:142:39 | concatted2 | TaintedPath.js:143:19:143:28 | concatted2 | provenance | | +| TaintedPath.js:142:20:142:24 | split | TaintedPath.js:142:20:142:39 | split.concat(prefix) | provenance | Config | +| TaintedPath.js:142:20:142:39 | split.concat(prefix) | TaintedPath.js:142:7:142:39 | concatted2 | provenance | | +| TaintedPath.js:143:19:143:28 | concatted2 | TaintedPath.js:143:19:143:38 | concatted2.join("/") | provenance | Config | +| TaintedPath.js:145:19:145:23 | split | TaintedPath.js:145:19:145:29 | split.pop() | provenance | Config | +| TaintedPath.js:150:7:150:48 | path | TaintedPath.js:154:29:154:32 | path | provenance | | +| TaintedPath.js:150:7:150:48 | path | TaintedPath.js:160:29:160:32 | path | provenance | | +| TaintedPath.js:150:7:150:48 | path | TaintedPath.js:161:29:161:32 | path | provenance | | +| TaintedPath.js:150:7:150:48 | path | TaintedPath.js:162:29:162:32 | path | provenance | | +| TaintedPath.js:150:7:150:48 | path | TaintedPath.js:163:29:163:32 | path | provenance | | +| TaintedPath.js:150:7:150:48 | path | TaintedPath.js:178:40:178:43 | path | provenance | | +| TaintedPath.js:150:7:150:48 | path | TaintedPath.js:179:50:179:53 | path | provenance | | +| TaintedPath.js:150:14:150:37 | url.par ... , true) | TaintedPath.js:150:14:150:43 | url.par ... ).query | provenance | Config | +| TaintedPath.js:150:14:150:43 | url.par ... ).query | TaintedPath.js:150:14:150:48 | url.par ... ry.path | provenance | Config | +| TaintedPath.js:150:14:150:48 | url.par ... ry.path | TaintedPath.js:150:7:150:48 | path | provenance | | +| TaintedPath.js:150:24:150:30 | req.url | TaintedPath.js:150:14:150:37 | url.par ... , true) | provenance | Config | +| TaintedPath.js:154:29:154:32 | path | TaintedPath.js:154:29:154:55 | path.re ... /g, '') | provenance | Config | +| TaintedPath.js:160:29:160:32 | path | TaintedPath.js:160:29:160:52 | path.re ... /g, '') | provenance | Config | +| TaintedPath.js:161:29:161:32 | path | TaintedPath.js:161:29:161:53 | path.re ... /g, '') | provenance | Config | +| TaintedPath.js:162:29:162:32 | path | TaintedPath.js:162:29:162:51 | path.re ... /g, '') | provenance | Config | +| TaintedPath.js:163:29:163:32 | path | TaintedPath.js:163:29:163:57 | path.re ... /g, '') | provenance | Config | +| TaintedPath.js:178:40:178:43 | path | TaintedPath.js:178:40:178:73 | path.re ... +/, '') | provenance | Config | +| TaintedPath.js:178:40:178:73 | path.re ... +/, '') | TaintedPath.js:178:29:178:73 | "prefix ... +/, '') | provenance | Config | +| TaintedPath.js:179:29:179:54 | pathMod ... e(path) | TaintedPath.js:179:29:179:84 | pathMod ... +/, '') | provenance | Config | +| TaintedPath.js:179:50:179:53 | path | TaintedPath.js:179:29:179:54 | pathMod ... e(path) | provenance | Config | +| TaintedPath.js:187:29:187:45 | qs.parse(req.url) | TaintedPath.js:187:29:187:49 | qs.pars ... rl).foo | provenance | Config | +| TaintedPath.js:187:38:187:44 | req.url | TaintedPath.js:187:29:187:45 | qs.parse(req.url) | provenance | Config | +| TaintedPath.js:188:29:188:59 | qs.pars ... q.url)) | TaintedPath.js:188:29:188:63 | qs.pars ... l)).foo | provenance | Config | +| TaintedPath.js:188:38:188:58 | normali ... eq.url) | TaintedPath.js:188:29:188:59 | qs.pars ... q.url)) | provenance | Config | +| TaintedPath.js:188:51:188:57 | req.url | TaintedPath.js:188:38:188:58 | normali ... eq.url) | provenance | Config | +| TaintedPath.js:190:29:190:51 | parseqs ... eq.url) | TaintedPath.js:190:29:190:55 | parseqs ... rl).foo | provenance | Config | +| TaintedPath.js:190:44:190:50 | req.url | TaintedPath.js:190:29:190:51 | parseqs ... eq.url) | provenance | Config | +| TaintedPath.js:195:7:195:48 | path | TaintedPath.js:196:31:196:34 | path | provenance | | +| TaintedPath.js:195:7:195:48 | path | TaintedPath.js:197:45:197:48 | path | provenance | | +| TaintedPath.js:195:7:195:48 | path | TaintedPath.js:198:35:198:38 | path | provenance | | +| TaintedPath.js:195:14:195:37 | url.par ... , true) | TaintedPath.js:195:14:195:43 | url.par ... ).query | provenance | Config | +| TaintedPath.js:195:14:195:43 | url.par ... ).query | TaintedPath.js:195:14:195:48 | url.par ... ry.path | provenance | Config | +| TaintedPath.js:195:14:195:48 | url.par ... ry.path | TaintedPath.js:195:7:195:48 | path | provenance | | +| TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:195:14:195:37 | url.par ... , true) | provenance | Config | | examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | provenance | | | examples/TaintedPath.js:8:18:8:41 | url.par ... , true) | examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | provenance | Config | | examples/TaintedPath.js:8:18:8:47 | url.par ... ).query | examples/TaintedPath.js:8:18:8:52 | url.par ... ry.path | provenance | Config | @@ -936,34 +929,33 @@ subpaths | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:56:29:56:52 | pathMod ... e(path) | This path depends on a $@. | TaintedPath.js:38:20:38:26 | req.url | user-provided value | | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | This path depends on a $@. | TaintedPath.js:38:20:38:26 | req.url | user-provided value | | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | TaintedPath.js:38:20:38:26 | req.url | TaintedPath.js:60:29:60:61 | pathMod ... h(path) | This path depends on a $@. | TaintedPath.js:38:20:38:26 | req.url | user-provided value | -| TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | TaintedPath.js:95:30:95:31 | ev | TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | This path depends on a $@. | TaintedPath.js:95:30:95:31 | ev | user-provided value | -| TaintedPath.js:77:31:77:76 | require ... ).query | TaintedPath.js:77:63:77:69 | req.url | TaintedPath.js:77:31:77:76 | require ... ).query | This path depends on a $@. | TaintedPath.js:77:63:77:69 | req.url | user-provided value | -| TaintedPath.js:78:31:78:74 | require ... ).query | TaintedPath.js:78:61:78:67 | req.url | TaintedPath.js:78:31:78:74 | require ... ).query | This path depends on a $@. | TaintedPath.js:78:61:78:67 | req.url | user-provided value | -| TaintedPath.js:79:31:79:73 | require ... ).query | TaintedPath.js:79:60:79:66 | req.url | TaintedPath.js:79:31:79:73 | require ... ).query | This path depends on a $@. | TaintedPath.js:79:60:79:66 | req.url | user-provided value | -| TaintedPath.js:87:48:87:60 | req.params[0] | TaintedPath.js:87:48:87:60 | req.params[0] | TaintedPath.js:87:48:87:60 | req.params[0] | This path depends on a $@. | TaintedPath.js:87:48:87:60 | req.params[0] | user-provided value | -| TaintedPath.js:102:28:102:48 | fs.real ... c(path) | TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:102:28:102:48 | fs.real ... c(path) | This path depends on a $@. | TaintedPath.js:100:23:100:29 | req.url | user-provided value | -| TaintedPath.js:105:45:105:52 | realpath | TaintedPath.js:100:23:100:29 | req.url | TaintedPath.js:105:45:105:52 | realpath | This path depends on a $@. | TaintedPath.js:100:23:100:29 | req.url | user-provided value | -| TaintedPath.js:138:23:138:26 | path | TaintedPath.js:136:23:136:29 | req.url | TaintedPath.js:138:23:138:26 | path | This path depends on a $@. | TaintedPath.js:136:23:136:29 | req.url | user-provided value | -| TaintedPath.js:144:19:144:22 | path | TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:144:19:144:22 | path | This path depends on a $@. | TaintedPath.js:142:24:142:30 | req.url | user-provided value | -| TaintedPath.js:148:19:148:33 | split.join("/") | TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:148:19:148:33 | split.join("/") | This path depends on a $@. | TaintedPath.js:142:24:142:30 | req.url | user-provided value | -| TaintedPath.js:152:19:152:26 | split[x] | TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:152:19:152:26 | split[x] | This path depends on a $@. | TaintedPath.js:142:24:142:30 | req.url | user-provided value | -| TaintedPath.js:153:19:153:35 | prefix + split[x] | TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:153:19:153:35 | prefix + split[x] | This path depends on a $@. | TaintedPath.js:142:24:142:30 | req.url | user-provided value | -| TaintedPath.js:156:19:156:37 | concatted.join("/") | TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:156:19:156:37 | concatted.join("/") | This path depends on a $@. | TaintedPath.js:142:24:142:30 | req.url | user-provided value | -| TaintedPath.js:159:19:159:38 | concatted2.join("/") | TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:159:19:159:38 | concatted2.join("/") | This path depends on a $@. | TaintedPath.js:142:24:142:30 | req.url | user-provided value | -| TaintedPath.js:161:19:161:29 | split.pop() | TaintedPath.js:142:24:142:30 | req.url | TaintedPath.js:161:19:161:29 | split.pop() | This path depends on a $@. | TaintedPath.js:142:24:142:30 | req.url | user-provided value | -| TaintedPath.js:170:29:170:55 | path.re ... /g, '') | TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:170:29:170:55 | path.re ... /g, '') | This path depends on a $@. | TaintedPath.js:166:24:166:30 | req.url | user-provided value | -| TaintedPath.js:176:29:176:52 | path.re ... /g, '') | TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:176:29:176:52 | path.re ... /g, '') | This path depends on a $@. | TaintedPath.js:166:24:166:30 | req.url | user-provided value | -| TaintedPath.js:177:29:177:53 | path.re ... /g, '') | TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:177:29:177:53 | path.re ... /g, '') | This path depends on a $@. | TaintedPath.js:166:24:166:30 | req.url | user-provided value | -| TaintedPath.js:178:29:178:51 | path.re ... /g, '') | TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:178:29:178:51 | path.re ... /g, '') | This path depends on a $@. | TaintedPath.js:166:24:166:30 | req.url | user-provided value | -| TaintedPath.js:179:29:179:57 | path.re ... /g, '') | TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | This path depends on a $@. | TaintedPath.js:166:24:166:30 | req.url | user-provided value | -| TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | This path depends on a $@. | TaintedPath.js:166:24:166:30 | req.url | user-provided value | -| TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | This path depends on a $@. | TaintedPath.js:166:24:166:30 | req.url | user-provided value | -| TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | TaintedPath.js:203:38:203:44 | req.url | TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | This path depends on a $@. | TaintedPath.js:203:38:203:44 | req.url | user-provided value | -| TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | TaintedPath.js:204:51:204:57 | req.url | TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | This path depends on a $@. | TaintedPath.js:204:51:204:57 | req.url | user-provided value | -| TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | TaintedPath.js:206:44:206:50 | req.url | TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | This path depends on a $@. | TaintedPath.js:206:44:206:50 | req.url | user-provided value | -| TaintedPath.js:212:31:212:34 | path | TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:212:31:212:34 | path | This path depends on a $@. | TaintedPath.js:211:24:211:30 | req.url | user-provided value | -| TaintedPath.js:213:45:213:48 | path | TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:213:45:213:48 | path | This path depends on a $@. | TaintedPath.js:211:24:211:30 | req.url | user-provided value | -| TaintedPath.js:214:35:214:38 | path | TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:214:35:214:38 | path | This path depends on a $@. | TaintedPath.js:211:24:211:30 | req.url | user-provided value | +| TaintedPath.js:65:31:65:76 | require ... ).query | TaintedPath.js:65:63:65:69 | req.url | TaintedPath.js:65:31:65:76 | require ... ).query | This path depends on a $@. | TaintedPath.js:65:63:65:69 | req.url | user-provided value | +| TaintedPath.js:66:31:66:74 | require ... ).query | TaintedPath.js:66:61:66:67 | req.url | TaintedPath.js:66:31:66:74 | require ... ).query | This path depends on a $@. | TaintedPath.js:66:61:66:67 | req.url | user-provided value | +| TaintedPath.js:67:31:67:73 | require ... ).query | TaintedPath.js:67:60:67:66 | req.url | TaintedPath.js:67:31:67:73 | require ... ).query | This path depends on a $@. | TaintedPath.js:67:60:67:66 | req.url | user-provided value | +| TaintedPath.js:75:48:75:60 | req.params[0] | TaintedPath.js:75:48:75:60 | req.params[0] | TaintedPath.js:75:48:75:60 | req.params[0] | This path depends on a $@. | TaintedPath.js:75:48:75:60 | req.params[0] | user-provided value | +| TaintedPath.js:86:28:86:48 | fs.real ... c(path) | TaintedPath.js:84:23:84:29 | req.url | TaintedPath.js:86:28:86:48 | fs.real ... c(path) | This path depends on a $@. | TaintedPath.js:84:23:84:29 | req.url | user-provided value | +| TaintedPath.js:89:45:89:52 | realpath | TaintedPath.js:84:23:84:29 | req.url | TaintedPath.js:89:45:89:52 | realpath | This path depends on a $@. | TaintedPath.js:84:23:84:29 | req.url | user-provided value | +| TaintedPath.js:122:23:122:26 | path | TaintedPath.js:120:23:120:29 | req.url | TaintedPath.js:122:23:122:26 | path | This path depends on a $@. | TaintedPath.js:120:23:120:29 | req.url | user-provided value | +| TaintedPath.js:128:19:128:22 | path | TaintedPath.js:126:24:126:30 | req.url | TaintedPath.js:128:19:128:22 | path | This path depends on a $@. | TaintedPath.js:126:24:126:30 | req.url | user-provided value | +| TaintedPath.js:132:19:132:33 | split.join("/") | TaintedPath.js:126:24:126:30 | req.url | TaintedPath.js:132:19:132:33 | split.join("/") | This path depends on a $@. | TaintedPath.js:126:24:126:30 | req.url | user-provided value | +| TaintedPath.js:136:19:136:26 | split[x] | TaintedPath.js:126:24:126:30 | req.url | TaintedPath.js:136:19:136:26 | split[x] | This path depends on a $@. | TaintedPath.js:126:24:126:30 | req.url | user-provided value | +| TaintedPath.js:137:19:137:35 | prefix + split[x] | TaintedPath.js:126:24:126:30 | req.url | TaintedPath.js:137:19:137:35 | prefix + split[x] | This path depends on a $@. | TaintedPath.js:126:24:126:30 | req.url | user-provided value | +| TaintedPath.js:140:19:140:37 | concatted.join("/") | TaintedPath.js:126:24:126:30 | req.url | TaintedPath.js:140:19:140:37 | concatted.join("/") | This path depends on a $@. | TaintedPath.js:126:24:126:30 | req.url | user-provided value | +| TaintedPath.js:143:19:143:38 | concatted2.join("/") | TaintedPath.js:126:24:126:30 | req.url | TaintedPath.js:143:19:143:38 | concatted2.join("/") | This path depends on a $@. | TaintedPath.js:126:24:126:30 | req.url | user-provided value | +| TaintedPath.js:145:19:145:29 | split.pop() | TaintedPath.js:126:24:126:30 | req.url | TaintedPath.js:145:19:145:29 | split.pop() | This path depends on a $@. | TaintedPath.js:126:24:126:30 | req.url | user-provided value | +| TaintedPath.js:154:29:154:55 | path.re ... /g, '') | TaintedPath.js:150:24:150:30 | req.url | TaintedPath.js:154:29:154:55 | path.re ... /g, '') | This path depends on a $@. | TaintedPath.js:150:24:150:30 | req.url | user-provided value | +| TaintedPath.js:160:29:160:52 | path.re ... /g, '') | TaintedPath.js:150:24:150:30 | req.url | TaintedPath.js:160:29:160:52 | path.re ... /g, '') | This path depends on a $@. | TaintedPath.js:150:24:150:30 | req.url | user-provided value | +| TaintedPath.js:161:29:161:53 | path.re ... /g, '') | TaintedPath.js:150:24:150:30 | req.url | TaintedPath.js:161:29:161:53 | path.re ... /g, '') | This path depends on a $@. | TaintedPath.js:150:24:150:30 | req.url | user-provided value | +| TaintedPath.js:162:29:162:51 | path.re ... /g, '') | TaintedPath.js:150:24:150:30 | req.url | TaintedPath.js:162:29:162:51 | path.re ... /g, '') | This path depends on a $@. | TaintedPath.js:150:24:150:30 | req.url | user-provided value | +| TaintedPath.js:163:29:163:57 | path.re ... /g, '') | TaintedPath.js:150:24:150:30 | req.url | TaintedPath.js:163:29:163:57 | path.re ... /g, '') | This path depends on a $@. | TaintedPath.js:150:24:150:30 | req.url | user-provided value | +| TaintedPath.js:178:29:178:73 | "prefix ... +/, '') | TaintedPath.js:150:24:150:30 | req.url | TaintedPath.js:178:29:178:73 | "prefix ... +/, '') | This path depends on a $@. | TaintedPath.js:150:24:150:30 | req.url | user-provided value | +| TaintedPath.js:179:29:179:84 | pathMod ... +/, '') | TaintedPath.js:150:24:150:30 | req.url | TaintedPath.js:179:29:179:84 | pathMod ... +/, '') | This path depends on a $@. | TaintedPath.js:150:24:150:30 | req.url | user-provided value | +| TaintedPath.js:187:29:187:49 | qs.pars ... rl).foo | TaintedPath.js:187:38:187:44 | req.url | TaintedPath.js:187:29:187:49 | qs.pars ... rl).foo | This path depends on a $@. | TaintedPath.js:187:38:187:44 | req.url | user-provided value | +| TaintedPath.js:188:29:188:63 | qs.pars ... l)).foo | TaintedPath.js:188:51:188:57 | req.url | TaintedPath.js:188:29:188:63 | qs.pars ... l)).foo | This path depends on a $@. | TaintedPath.js:188:51:188:57 | req.url | user-provided value | +| TaintedPath.js:190:29:190:55 | parseqs ... rl).foo | TaintedPath.js:190:44:190:50 | req.url | TaintedPath.js:190:29:190:55 | parseqs ... rl).foo | This path depends on a $@. | TaintedPath.js:190:44:190:50 | req.url | user-provided value | +| TaintedPath.js:196:31:196:34 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:196:31:196:34 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value | +| TaintedPath.js:197:45:197:48 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:197:45:197:48 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value | +| TaintedPath.js:198:35:198:38 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:198:35:198:38 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value | | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | This path depends on a $@. | examples/TaintedPath.js:8:28:8:34 | req.url | user-provided value | | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | This path depends on a $@. | express.js:8:20:8:32 | req.query.bar | user-provided value | | handlebars.js:11:32:11:39 | filePath | handlebars.js:29:46:29:60 | req.params.path | handlebars.js:11:32:11:39 | filePath | This path depends on a $@. | handlebars.js:29:46:29:60 | req.params.path | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 46dbe7ac431..db6b8453219 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -27,6 +27,10 @@ nodes | angular2-client.ts:38:44:38:58 | this.router.url | semmle.label | this.router.url | | angular2-client.ts:40:45:40:59 | this.router.url | semmle.label | this.router.url | | angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | semmle.label | routeSn ... ('foo') | +| angular-tempate-url.js:9:26:9:45 | Cookie.get("unsafe") | semmle.label | Cookie.get("unsafe") | +| angular-tempate-url.js:13:30:13:31 | ev | semmle.label | ev | +| angular-tempate-url.js:14:26:14:27 | ev | semmle.label | ev | +| angular-tempate-url.js:14:26:14:32 | ev.data | semmle.label | ev.data | | classnames.js:7:31:7:84 | `` | semmle.label | `` | | classnames.js:7:47:7:69 | classNa ... w.name) | semmle.label | classNa ... w.name) | | classnames.js:7:58:7:68 | window.name | semmle.label | window.name | @@ -636,6 +640,9 @@ edges | angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | provenance | | | angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | provenance | | | angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | provenance | | +| angular-tempate-url.js:13:30:13:31 | ev | angular-tempate-url.js:14:26:14:27 | ev | provenance | | +| angular-tempate-url.js:14:26:14:27 | ev | angular-tempate-url.js:14:26:14:32 | ev.data | provenance | | +| angular-tempate-url.js:14:26:14:32 | ev.data | angular-tempate-url.js:9:26:9:45 | Cookie.get("unsafe") | provenance | | | classnames.js:7:47:7:69 | classNa ... w.name) | classnames.js:7:31:7:84 | `` | provenance | | | classnames.js:7:58:7:68 | window.name | classnames.js:7:47:7:69 | classNa ... w.name) | provenance | | | classnames.js:8:47:8:70 | classNa ... w.name) | classnames.js:8:31:8:85 | `` | provenance | | @@ -1243,6 +1250,7 @@ subpaths | angular2-client.ts:38:44:38:58 | this.router.url | angular2-client.ts:38:44:38:58 | this.router.url | angular2-client.ts:38:44:38:58 | this.router.url | Cross-site scripting vulnerability due to $@. | angular2-client.ts:38:44:38:58 | this.router.url | user-provided value | | angular2-client.ts:40:45:40:59 | this.router.url | angular2-client.ts:40:45:40:59 | this.router.url | angular2-client.ts:40:45:40:59 | this.router.url | Cross-site scripting vulnerability due to $@. | angular2-client.ts:40:45:40:59 | this.router.url | user-provided value | | angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | Cross-site scripting vulnerability due to $@. | angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | user-provided value | +| angular-tempate-url.js:9:26:9:45 | Cookie.get("unsafe") | angular-tempate-url.js:13:30:13:31 | ev | angular-tempate-url.js:9:26:9:45 | Cookie.get("unsafe") | Cross-site scripting vulnerability due to $@. | angular-tempate-url.js:13:30:13:31 | ev | user-provided value | | classnames.js:7:31:7:84 | `` | classnames.js:7:58:7:68 | window.name | classnames.js:7:31:7:84 | `` | Cross-site scripting vulnerability due to $@. | classnames.js:7:58:7:68 | window.name | user-provided value | | classnames.js:8:31:8:85 | `` | classnames.js:8:59:8:69 | window.name | classnames.js:8:31:8:85 | `` | Cross-site scripting vulnerability due to $@. | classnames.js:8:59:8:69 | window.name | user-provided value | | classnames.js:9:31:9:85 | `` | classnames.js:9:59:9:69 | window.name | classnames.js:9:31:9:85 | `` | Cross-site scripting vulnerability due to $@. | classnames.js:9:59:9:69 | window.name | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index d08a55f938c..2cbf440a6b5 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -27,6 +27,10 @@ nodes | angular2-client.ts:38:44:38:58 | this.router.url | semmle.label | this.router.url | | angular2-client.ts:40:45:40:59 | this.router.url | semmle.label | this.router.url | | angular2-client.ts:44:44:44:76 | routeSn ... ('foo') | semmle.label | routeSn ... ('foo') | +| angular-tempate-url.js:9:26:9:45 | Cookie.get("unsafe") | semmle.label | Cookie.get("unsafe") | +| angular-tempate-url.js:13:30:13:31 | ev | semmle.label | ev | +| angular-tempate-url.js:14:26:14:27 | ev | semmle.label | ev | +| angular-tempate-url.js:14:26:14:32 | ev.data | semmle.label | ev.data | | classnames.js:7:31:7:84 | `` | semmle.label | `` | | classnames.js:7:47:7:69 | classNa ... w.name) | semmle.label | classNa ... w.name) | | classnames.js:7:58:7:68 | window.name | semmle.label | window.name | @@ -657,6 +661,9 @@ edges | angular2-client.ts:25:44:25:74 | this.ro ... yParams | angular2-client.ts:25:44:25:78 | this.ro ... ams.foo | provenance | | | angular2-client.ts:34:44:34:80 | this.ro ... ameters | angular2-client.ts:34:44:34:82 | this.ro ... eters.x | provenance | | | angular2-client.ts:36:44:36:89 | this.ro ... .params | angular2-client.ts:36:44:36:91 | this.ro ... arams.x | provenance | | +| angular-tempate-url.js:13:30:13:31 | ev | angular-tempate-url.js:14:26:14:27 | ev | provenance | | +| angular-tempate-url.js:14:26:14:27 | ev | angular-tempate-url.js:14:26:14:32 | ev.data | provenance | | +| angular-tempate-url.js:14:26:14:32 | ev.data | angular-tempate-url.js:9:26:9:45 | Cookie.get("unsafe") | provenance | | | classnames.js:7:47:7:69 | classNa ... w.name) | classnames.js:7:31:7:84 | `` | provenance | | | classnames.js:7:58:7:68 | window.name | classnames.js:7:47:7:69 | classNa ... w.name) | provenance | | | classnames.js:8:47:8:70 | classNa ... w.name) | classnames.js:8:31:8:85 | `` | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected b/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected index c05cb5f53f5..88ce227af45 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected @@ -82,6 +82,7 @@ nodes | build-leaks.js:41:82:41:83 | pw | semmle.label | pw | subpaths | build-leaks.js:17:12:19:9 | {\\n ... } | build-leaks.js:14:18:14:20 | env | build-leaks.js:16:20:16:22 | env | build-leaks.js:13:17:19:10 | Object. ... }) | +| build-leaks.js:22:36:22:38 | raw | build-leaks.js:22:49:22:51 | env | build-leaks.js:24:20:24:22 | env | build-leaks.js:22:24:25:14 | Object. ... }, {}) | | build-leaks.js:22:36:22:38 | raw | build-leaks.js:23:39:23:41 | raw | build-leaks.js:22:49:22:51 | env [Return] | build-leaks.js:25:12:25:13 | [post update] {} | | build-leaks.js:22:36:22:38 | raw | build-leaks.js:23:39:23:41 | raw | build-leaks.js:24:20:24:22 | env | build-leaks.js:22:24:25:14 | Object. ... }, {}) | | build-leaks.js:25:12:25:13 | {} | build-leaks.js:22:49:22:51 | env | build-leaks.js:24:20:24:22 | env | build-leaks.js:22:24:25:14 | Object. ... }, {}) | diff --git a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected index 14a51915162..4a5af8a6e00 100644 --- a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected @@ -39,10 +39,9 @@ edges | RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") | RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | provenance | | | RegExpInjection.js:91:20:91:30 | process.env | RegExpInjection.js:91:16:91:50 | `^${pro ... r.app$` | provenance | | | RegExpInjection.js:93:20:93:31 | process.argv | RegExpInjection.js:93:16:93:49 | `^${pro ... r.app$` | provenance | | -| tst.js:1:46:1:46 | e | tst.js:2:16:2:16 | e | provenance | | -| tst.js:2:9:2:21 | data | tst.js:3:21:3:24 | data | provenance | | -| tst.js:2:16:2:16 | e | tst.js:2:9:2:21 | data | provenance | | -| tst.js:3:21:3:24 | data | tst.js:3:16:3:35 | "^"+ data.name + "$" | provenance | | +| tst.js:5:9:5:29 | data | tst.js:6:21:6:24 | data | provenance | | +| tst.js:5:16:5:29 | req.query.data | tst.js:5:9:5:29 | data | provenance | | +| tst.js:6:21:6:24 | data | tst.js:6:16:6:35 | "^"+ data.name + "$" | provenance | | nodes | RegExpInjection.js:5:7:5:28 | key | semmle.label | key | | RegExpInjection.js:5:13:5:28 | req.param("key") | semmle.label | req.param("key") | @@ -89,11 +88,10 @@ nodes | RegExpInjection.js:91:20:91:30 | process.env | semmle.label | process.env | | RegExpInjection.js:93:16:93:49 | `^${pro ... r.app$` | semmle.label | `^${pro ... r.app$` | | RegExpInjection.js:93:20:93:31 | process.argv | semmle.label | process.argv | -| tst.js:1:46:1:46 | e | semmle.label | e | -| tst.js:2:9:2:21 | data | semmle.label | data | -| tst.js:2:16:2:16 | e | semmle.label | e | -| tst.js:3:16:3:35 | "^"+ data.name + "$" | semmle.label | "^"+ data.name + "$" | -| tst.js:3:21:3:24 | data | semmle.label | data | +| tst.js:5:9:5:29 | data | semmle.label | data | +| tst.js:5:16:5:29 | req.query.data | semmle.label | req.query.data | +| tst.js:6:16:6:35 | "^"+ data.name + "$" | semmle.label | "^"+ data.name + "$" | +| tst.js:6:21:6:24 | data | semmle.label | data | subpaths | RegExpInjection.js:11:26:11:26 | s | RegExpInjection.js:14:18:14:18 | s | RegExpInjection.js:15:12:15:24 | s + "=(.*)\\n" | RegExpInjection.js:11:20:11:27 | wrap2(s) | | RegExpInjection.js:19:19:19:21 | key | RegExpInjection.js:10:17:10:17 | s | RegExpInjection.js:11:12:11:27 | "\\\\b" + wrap2(s) | RegExpInjection.js:19:14:19:22 | wrap(key) | @@ -116,4 +114,4 @@ subpaths | RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | RegExpInjection.js:82:15:82:32 | req.param("input") | RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | This regular expression is constructed from a $@. | RegExpInjection.js:82:15:82:32 | req.param("input") | user-provided value | | RegExpInjection.js:91:16:91:50 | `^${pro ... r.app$` | RegExpInjection.js:91:20:91:30 | process.env | RegExpInjection.js:91:16:91:50 | `^${pro ... r.app$` | This regular expression is constructed from a $@. | RegExpInjection.js:91:20:91:30 | process.env | environment variable | | RegExpInjection.js:93:16:93:49 | `^${pro ... r.app$` | RegExpInjection.js:93:20:93:31 | process.argv | RegExpInjection.js:93:16:93:49 | `^${pro ... r.app$` | This regular expression is constructed from a $@. | RegExpInjection.js:93:20:93:31 | process.argv | command-line argument | -| tst.js:3:16:3:35 | "^"+ data.name + "$" | tst.js:1:46:1:46 | e | tst.js:3:16:3:35 | "^"+ data.name + "$" | This regular expression is constructed from a $@. | tst.js:1:46:1:46 | e | user-provided value | +| tst.js:6:16:6:35 | "^"+ data.name + "$" | tst.js:5:16:5:29 | req.query.data | tst.js:6:16:6:35 | "^"+ data.name + "$" | This regular expression is constructed from a $@. | tst.js:5:16:5:29 | req.query.data | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected index 086af0f7bdf..ed9dd70a890 100644 --- a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected +++ b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected @@ -32,11 +32,38 @@ edges | HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') | provenance | Config | | HardcodedCredentials.js:237:47:237:54 | username | HardcodedCredentials.js:237:47:237:71 | usernam ... assword | provenance | Config | | HardcodedCredentials.js:237:47:237:71 | usernam ... assword | HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) | provenance | Config | +| HardcodedCredentials.js:237:47:237:71 | usernam ... assword | HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | provenance | Config | | HardcodedCredentials.js:245:9:245:44 | privateKey | HardcodedCredentials.js:246:42:246:51 | privateKey | provenance | | | HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:245:9:245:44 | privateKey | provenance | | +| HardcodedCredentials.js:248:9:248:42 | publicKey | HardcodedCredentials.js:249:23:249:31 | publicKey | provenance | | +| HardcodedCredentials.js:248:21:248:42 | "myHard ... licKey" | HardcodedCredentials.js:248:9:248:42 | publicKey | provenance | | | HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | HardcodedCredentials.js:268:30:268:73 | `${foo ... Token}` | provenance | Config | | HardcodedCredentials.js:268:39:268:46 | 'Bearer' | HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | provenance | | | HardcodedCredentials.js:268:50:268:56 | 'OAuth' | HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | provenance | | +| HardcodedCredentials.js:308:9:308:44 | privateKey | HardcodedCredentials.js:309:34:309:43 | privateKey | provenance | | +| HardcodedCredentials.js:308:22:308:44 | "myHard ... ateKey" | HardcodedCredentials.js:308:9:308:44 | privateKey | provenance | | +| HardcodedCredentials.js:316:9:316:44 | privateKey | HardcodedCredentials.js:317:52:317:61 | privateKey | provenance | | +| HardcodedCredentials.js:316:22:316:44 | "myHard ... ateKey" | HardcodedCredentials.js:316:9:316:44 | privateKey | provenance | | +| HardcodedCredentials.js:317:52:317:61 | privateKey | HardcodedCredentials.js:317:27:317:62 | new Tex ... ateKey) | provenance | Config | +| HardcodedCredentials.js:319:11:321:29 | spki | HardcodedCredentials.js:322:43:322:46 | spki | provenance | | +| HardcodedCredentials.js:319:18:321:29 | `-----B ... Y-----` | HardcodedCredentials.js:319:11:321:29 | spki | provenance | | +| HardcodedCredentials.js:322:9:322:56 | publicKey | HardcodedCredentials.js:323:27:323:35 | publicKey | provenance | | +| HardcodedCredentials.js:322:21:322:56 | await j ... RS256') | HardcodedCredentials.js:322:9:322:56 | publicKey | provenance | | +| HardcodedCredentials.js:322:43:322:46 | spki | HardcodedCredentials.js:322:21:322:56 | await j ... RS256') | provenance | Config | +| HardcodedCredentials.js:328:12:328:55 | 'whYOFK ... -6f...' | HardcodedCredentials.js:331:17:331:46 | await j ... k, alg) | provenance | Config | +| HardcodedCredentials.js:331:5:331:46 | publicKey | HardcodedCredentials.js:335:31:335:39 | publicKey | provenance | | +| HardcodedCredentials.js:331:17:331:46 | await j ... k, alg) | HardcodedCredentials.js:331:5:331:46 | publicKey | provenance | | +| HardcodedCredentials.js:344:9:344:43 | secretKey | HardcodedCredentials.js:349:21:349:29 | secretKey | provenance | | +| HardcodedCredentials.js:344:9:344:43 | secretKey | HardcodedCredentials.js:360:33:360:41 | secretKey | provenance | | +| HardcodedCredentials.js:344:21:344:43 | "myHard ... ateKey" | HardcodedCredentials.js:344:9:344:43 | secretKey | provenance | | +| HardcodedCredentials.js:360:33:360:41 | secretKey | HardcodedCredentials.js:360:21:360:52 | Buffer. ... ase64") | provenance | Config | +| HardcodedCredentials.js:375:9:375:43 | secretKey | HardcodedCredentials.js:378:24:378:32 | secretKey | provenance | | +| HardcodedCredentials.js:375:9:375:43 | secretKey | HardcodedCredentials.js:385:31:385:39 | secretKey | provenance | | +| HardcodedCredentials.js:375:21:375:43 | "myHard ... ateKey" | HardcodedCredentials.js:375:9:375:43 | secretKey | provenance | | +| HardcodedCredentials.js:396:9:396:43 | secretKey | HardcodedCredentials.js:399:17:399:25 | secretKey | provenance | | +| HardcodedCredentials.js:396:21:396:43 | "myHard ... ateKey" | HardcodedCredentials.js:396:9:396:43 | secretKey | provenance | | +| HardcodedCredentials.js:414:9:414:43 | secretKey | HardcodedCredentials.js:416:27:416:35 | secretKey | provenance | | +| HardcodedCredentials.js:414:21:414:43 | "myHard ... ateKey" | HardcodedCredentials.js:414:9:414:43 | secretKey | provenance | | nodes | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | semmle.label | 'dbuser' | | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | semmle.label | 'hgfedcba' | @@ -131,6 +158,9 @@ nodes | HardcodedCredentials.js:245:9:245:44 | privateKey | semmle.label | privateKey | | HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | semmle.label | "myHard ... ateKey" | | HardcodedCredentials.js:246:42:246:51 | privateKey | semmle.label | privateKey | +| HardcodedCredentials.js:248:9:248:42 | publicKey | semmle.label | publicKey | +| HardcodedCredentials.js:248:21:248:42 | "myHard ... licKey" | semmle.label | "myHard ... licKey" | +| HardcodedCredentials.js:249:23:249:31 | publicKey | semmle.label | publicKey | | HardcodedCredentials.js:260:30:260:40 | `Basic foo` | semmle.label | `Basic foo` | | HardcodedCredentials.js:268:30:268:73 | `${foo ... Token}` | semmle.label | `${foo ... Token}` | | HardcodedCredentials.js:268:33:268:56 | foo ? ' ... 'OAuth' | semmle.label | foo ? ' ... 'OAuth' | @@ -156,6 +186,40 @@ nodes | HardcodedCredentials.js:300:44:300:56 | 'SampleToken' | semmle.label | 'SampleToken' | | HardcodedCredentials.js:301:44:301:55 | 'MyPassword' | semmle.label | 'MyPassword' | | HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | semmle.label | 'iubfew ... ybgera' | +| HardcodedCredentials.js:308:9:308:44 | privateKey | semmle.label | privateKey | +| HardcodedCredentials.js:308:22:308:44 | "myHard ... ateKey" | semmle.label | "myHard ... ateKey" | +| HardcodedCredentials.js:309:34:309:43 | privateKey | semmle.label | privateKey | +| HardcodedCredentials.js:316:9:316:44 | privateKey | semmle.label | privateKey | +| HardcodedCredentials.js:316:22:316:44 | "myHard ... ateKey" | semmle.label | "myHard ... ateKey" | +| HardcodedCredentials.js:317:27:317:62 | new Tex ... ateKey) | semmle.label | new Tex ... ateKey) | +| HardcodedCredentials.js:317:52:317:61 | privateKey | semmle.label | privateKey | +| HardcodedCredentials.js:319:11:321:29 | spki | semmle.label | spki | +| HardcodedCredentials.js:319:18:321:29 | `-----B ... Y-----` | semmle.label | `-----B ... Y-----` | +| HardcodedCredentials.js:322:9:322:56 | publicKey | semmle.label | publicKey | +| HardcodedCredentials.js:322:21:322:56 | await j ... RS256') | semmle.label | await j ... RS256') | +| HardcodedCredentials.js:322:43:322:46 | spki | semmle.label | spki | +| HardcodedCredentials.js:323:27:323:35 | publicKey | semmle.label | publicKey | +| HardcodedCredentials.js:328:12:328:55 | 'whYOFK ... -6f...' | semmle.label | 'whYOFK ... -6f...' | +| HardcodedCredentials.js:331:5:331:46 | publicKey | semmle.label | publicKey | +| HardcodedCredentials.js:331:17:331:46 | await j ... k, alg) | semmle.label | await j ... k, alg) | +| HardcodedCredentials.js:335:31:335:39 | publicKey | semmle.label | publicKey | +| HardcodedCredentials.js:344:9:344:43 | secretKey | semmle.label | secretKey | +| HardcodedCredentials.js:344:21:344:43 | "myHard ... ateKey" | semmle.label | "myHard ... ateKey" | +| HardcodedCredentials.js:349:21:349:29 | secretKey | semmle.label | secretKey | +| HardcodedCredentials.js:360:21:360:52 | Buffer. ... ase64") | semmle.label | Buffer. ... ase64") | +| HardcodedCredentials.js:360:33:360:41 | secretKey | semmle.label | secretKey | +| HardcodedCredentials.js:375:9:375:43 | secretKey | semmle.label | secretKey | +| HardcodedCredentials.js:375:21:375:43 | "myHard ... ateKey" | semmle.label | "myHard ... ateKey" | +| HardcodedCredentials.js:378:24:378:32 | secretKey | semmle.label | secretKey | +| HardcodedCredentials.js:385:31:385:39 | secretKey | semmle.label | secretKey | +| HardcodedCredentials.js:396:9:396:43 | secretKey | semmle.label | secretKey | +| HardcodedCredentials.js:396:21:396:43 | "myHard ... ateKey" | semmle.label | "myHard ... ateKey" | +| HardcodedCredentials.js:399:17:399:25 | secretKey | semmle.label | secretKey | +| HardcodedCredentials.js:414:9:414:43 | secretKey | semmle.label | secretKey | +| HardcodedCredentials.js:414:21:414:43 | "myHard ... ateKey" | semmle.label | "myHard ... ateKey" | +| HardcodedCredentials.js:416:27:416:35 | secretKey | semmle.label | secretKey | +| __tests__/HardcodedCredentialsDemo.js:5:15:5:22 | 'dbuser' | semmle.label | 'dbuser' | +| __tests__/HardcodedCredentialsDemo.js:8:19:8:28 | 'hgfedcba' | semmle.label | 'hgfedcba' | subpaths #select | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | The hard-coded value "dbuser" is used as $@. | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | user name | @@ -219,7 +283,20 @@ subpaths | HardcodedCredentials.js:214:18:214:25 | 'sdsdag' | HardcodedCredentials.js:214:18:214:25 | 'sdsdag' | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | authorization header | | HardcodedCredentials.js:215:18:215:25 | 'sdsdag' | HardcodedCredentials.js:215:18:215:25 | 'sdsdag' | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | authorization header | | HardcodedCredentials.js:231:22:231:29 | 'sdsdag' | HardcodedCredentials.js:231:22:231:29 | 'sdsdag' | HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') | authorization header | -| HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:246:42:246:51 | privateKey | The hard-coded value "myHardCodedPrivateKey" is used as $@. | HardcodedCredentials.js:246:42:246:51 | privateKey | key | +| HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:246:42:246:51 | privateKey | The hard-coded value "myHardCodedPrivateKey" is used as $@. | HardcodedCredentials.js:246:42:246:51 | privateKey | jwt key | +| HardcodedCredentials.js:248:21:248:42 | "myHard ... licKey" | HardcodedCredentials.js:248:21:248:42 | "myHard ... licKey" | HardcodedCredentials.js:249:23:249:31 | publicKey | The hard-coded value "myHardCodedPublicKey" is used as $@. | HardcodedCredentials.js:249:23:249:31 | publicKey | jwt key | | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | The hard-coded value "Basic sdsdag:sdsdag" is used as $@. | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | authorization header | | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | The hard-coded value "Basic sdsdag:aaaiuogrweuibgbbbbb" is used as $@. | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | authorization header | | HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | The hard-coded value "iubfewiaaweiybgaeuybgera" is used as $@. | HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | key | +| HardcodedCredentials.js:308:22:308:44 | "myHard ... ateKey" | HardcodedCredentials.js:308:22:308:44 | "myHard ... ateKey" | HardcodedCredentials.js:309:34:309:43 | privateKey | The hard-coded value "myHardCodedPrivateKey" is used as $@. | HardcodedCredentials.js:309:34:309:43 | privateKey | jwt key | +| HardcodedCredentials.js:316:22:316:44 | "myHard ... ateKey" | HardcodedCredentials.js:316:22:316:44 | "myHard ... ateKey" | HardcodedCredentials.js:317:27:317:62 | new Tex ... ateKey) | The hard-coded value "myHardCodedPrivateKey" is used as $@. | HardcodedCredentials.js:317:27:317:62 | new Tex ... ateKey) | jwt key | +| HardcodedCredentials.js:319:18:321:29 | `-----B ... Y-----` | HardcodedCredentials.js:319:18:321:29 | `-----B ... Y-----` | HardcodedCredentials.js:323:27:323:35 | publicKey | The hard-coded value "-----BEGIN PUBLIC KEY-----\n MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwhYOFK2Ocbbpb/zVypi9...\n -----END PUBLIC KEY-----" is used as $@. | HardcodedCredentials.js:323:27:323:35 | publicKey | jwt key | +| HardcodedCredentials.js:328:12:328:55 | 'whYOFK ... -6f...' | HardcodedCredentials.js:328:12:328:55 | 'whYOFK ... -6f...' | HardcodedCredentials.js:335:31:335:39 | publicKey | The hard-coded value "whYOFK2Ocbbpb_zVypi9SeKiNUqKQH0zTKN1-6f..." is used as $@. | HardcodedCredentials.js:335:31:335:39 | publicKey | jwt key | +| HardcodedCredentials.js:344:21:344:43 | "myHard ... ateKey" | HardcodedCredentials.js:344:21:344:43 | "myHard ... ateKey" | HardcodedCredentials.js:349:21:349:29 | secretKey | The hard-coded value "myHardCodedPrivateKey" is used as $@. | HardcodedCredentials.js:349:21:349:29 | secretKey | jwt key | +| HardcodedCredentials.js:344:21:344:43 | "myHard ... ateKey" | HardcodedCredentials.js:344:21:344:43 | "myHard ... ateKey" | HardcodedCredentials.js:360:21:360:52 | Buffer. ... ase64") | The hard-coded value "myHardCodedPrivateKey" is used as $@. | HardcodedCredentials.js:360:21:360:52 | Buffer. ... ase64") | jwt key | +| HardcodedCredentials.js:375:21:375:43 | "myHard ... ateKey" | HardcodedCredentials.js:375:21:375:43 | "myHard ... ateKey" | HardcodedCredentials.js:378:24:378:32 | secretKey | The hard-coded value "myHardCodedPrivateKey" is used as $@. | HardcodedCredentials.js:378:24:378:32 | secretKey | jwt key | +| HardcodedCredentials.js:375:21:375:43 | "myHard ... ateKey" | HardcodedCredentials.js:375:21:375:43 | "myHard ... ateKey" | HardcodedCredentials.js:385:31:385:39 | secretKey | The hard-coded value "myHardCodedPrivateKey" is used as $@. | HardcodedCredentials.js:385:31:385:39 | secretKey | jwt key | +| HardcodedCredentials.js:396:21:396:43 | "myHard ... ateKey" | HardcodedCredentials.js:396:21:396:43 | "myHard ... ateKey" | HardcodedCredentials.js:399:17:399:25 | secretKey | The hard-coded value "myHardCodedPrivateKey" is used as $@. | HardcodedCredentials.js:399:17:399:25 | secretKey | jwt key | +| HardcodedCredentials.js:414:21:414:43 | "myHard ... ateKey" | HardcodedCredentials.js:414:21:414:43 | "myHard ... ateKey" | HardcodedCredentials.js:416:27:416:35 | secretKey | The hard-coded value "myHardCodedPrivateKey" is used as $@. | HardcodedCredentials.js:416:27:416:35 | secretKey | jwt key | +| __tests__/HardcodedCredentialsDemo.js:5:15:5:22 | 'dbuser' | __tests__/HardcodedCredentialsDemo.js:5:15:5:22 | 'dbuser' | __tests__/HardcodedCredentialsDemo.js:5:15:5:22 | 'dbuser' | The hard-coded value "dbuser" is used as $@. | __tests__/HardcodedCredentialsDemo.js:5:15:5:22 | 'dbuser' | user name | +| __tests__/HardcodedCredentialsDemo.js:8:19:8:28 | 'hgfedcba' | __tests__/HardcodedCredentialsDemo.js:8:19:8:28 | 'hgfedcba' | __tests__/HardcodedCredentialsDemo.js:8:19:8:28 | 'hgfedcba' | The hard-coded value "hgfedcba" is used as $@. | __tests__/HardcodedCredentialsDemo.js:8:19:8:28 | 'hgfedcba' | password | From 7cfe3dae85a9662c1b474e4d751fe80da30db567 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 20 Aug 2024 15:05:00 +0200 Subject: [PATCH 229/514] JS: Port step for dynamic imports --- .../ql/lib/semmle/javascript/Promises.qll | 1 - .../flow_summaries/AllFlowSummaries.qll | 1 + .../flow_summaries/DynamicImportStep.qll | 39 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 javascript/ql/lib/semmle/javascript/internal/flow_summaries/DynamicImportStep.qll diff --git a/javascript/ql/lib/semmle/javascript/Promises.qll b/javascript/ql/lib/semmle/javascript/Promises.qll index f25fa2bc820..c254128f87b 100644 --- a/javascript/ql/lib/semmle/javascript/Promises.qll +++ b/javascript/ql/lib/semmle/javascript/Promises.qll @@ -705,7 +705,6 @@ private module DynamicImportSteps { */ class DynamicImportStep extends LegacyPreCallGraphStep { override predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { - // TODO: this step needs to be ported to dataflow2 exists(DynamicImportExpr imprt | pred = imprt.getImportedModule().getAnExportedValue("default") and succ = imprt.flow() and diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll index d7eba4852db..6094141cc40 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll @@ -9,3 +9,4 @@ private import Maps private import Promises private import Sets private import Strings +private import DynamicImportStep diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/DynamicImportStep.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/DynamicImportStep.qll new file mode 100644 index 00000000000..2976b467315 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/DynamicImportStep.qll @@ -0,0 +1,39 @@ +/** + * Contains flow steps to model flow from a module into a dynamic `import()` expression. + */ + +private import javascript +private import semmle.javascript.dataflow.internal.DataFlowNode +private import semmle.javascript.dataflow.internal.AdditionalFlowInternal +private import semmle.javascript.dataflow.internal.DataFlowPrivate + +/** + * Flow steps for dynamic import expressions. + * + * The default export of the imported module must be boxed in a promise, so we pass + * it through a synthetic node. + */ +class DynamicImportStep extends AdditionalFlowInternal { + override predicate needsSynthesizedNode(AstNode node, string tag, DataFlowCallable container) { + node instanceof DynamicImportExpr and + tag = "imported-value" and + container.asSourceCallable() = node.getContainer() + } + + override predicate jumpStep(DataFlow::Node pred, DataFlow::Node succ) { + exists(DynamicImportExpr expr | + pred = expr.getImportedModule().getAnExportedValue("default") and + succ = getSynthesizedNode(expr, "imported-value") + ) + } + + override predicate storeStep( + DataFlow::Node pred, DataFlow::ContentSet contents, DataFlow::Node succ + ) { + exists(DynamicImportExpr expr | + pred = getSynthesizedNode(expr, "imported-value") and + contents = DataFlow::ContentSet::promiseValue() and + succ = TValueNode(expr) + ) + } +} From 47c519fc0a0457722006b85b2d542ff4794379bb Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 26 Aug 2024 15:15:49 +0200 Subject: [PATCH 230/514] JS: Add test for flow through dynamic imports --- .../TaintTracking/BasicTaintTracking.expected | 4 ++++ .../TaintTracking/DataFlowTracking.expected | 4 ++++ .../library-tests/TaintTracking/export-taint.js | 4 ++++ .../library-tests/TaintTracking/import-taint.js | 16 ++++++++++++++++ 4 files changed, 28 insertions(+) create mode 100644 javascript/ql/test/library-tests/TaintTracking/export-taint.js create mode 100644 javascript/ql/test/library-tests/TaintTracking/import-taint.js diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 91a7f386516..7fff1f8f963 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -14,6 +14,8 @@ legacyDataFlowDifference | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:44:8:44:19 | f_safe.taint | only flow with NEW data flow library | | constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:39:8:39:14 | e.param | only flow with NEW data flow library | | exceptions.js:53:14:53:21 | source() | exceptions.js:54:10:54:10 | e | only flow with NEW data flow library | +| export-taint.js:3:22:3:29 | source() | import-taint.js:7:10:7:25 | mod.object.taint | only flow with OLD data flow library | +| export-taint.js:3:22:3:29 | source() | import-taint.js:14:14:14:29 | mod.object.taint | only flow with OLD data flow library | | getters-and-setters.js:53:21:53:28 | source() | getters-and-setters.js:53:10:53:30 | getX(ne ... rce())) | only flow with NEW data flow library | | nested-props.js:14:15:14:22 | source() | nested-props.js:15:10:15:16 | obj.x.y | only flow with NEW data flow library | | nested-props.js:27:18:27:25 | source() | nested-props.js:28:10:28:14 | obj.x | only flow with NEW data flow library | @@ -165,6 +167,8 @@ flow | exceptions.js:144:9:144:16 | source() | exceptions.js:132:8:132:27 | returnThrownSource() | | exceptions.js:150:13:150:20 | source() | exceptions.js:153:10:153:10 | e | | exceptions.js:158:13:158:20 | source() | exceptions.js:161:10:161:10 | e | +| export-taint.js:2:12:2:19 | source() | import-taint.js:6:10:6:18 | mod.taint | +| export-taint.js:2:12:2:19 | source() | import-taint.js:13:14:13:22 | mod.taint | | factory-function.js:21:13:21:20 | source() | factory-function.js:7:10:7:12 | obj | | factory-function.js:22:13:22:20 | source() | factory-function.js:7:10:7:12 | obj | | factory-function.js:26:7:26:14 | source() | factory-function.js:16:14:16:16 | obj | diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected index de977a8ff92..fe96a5e3db5 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected @@ -15,6 +15,8 @@ legacyDataFlowDifference | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:44:8:44:19 | f_safe.taint | only flow with NEW data flow library | | constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:39:8:39:14 | e.param | only flow with NEW data flow library | | exceptions.js:53:14:53:21 | source() | exceptions.js:54:10:54:10 | e | only flow with NEW data flow library | +| export-taint.js:3:22:3:29 | source() | import-taint.js:7:10:7:25 | mod.object.taint | only flow with OLD data flow library | +| export-taint.js:3:22:3:29 | source() | import-taint.js:14:14:14:29 | mod.object.taint | only flow with OLD data flow library | | getters-and-setters.js:53:21:53:28 | source() | getters-and-setters.js:53:10:53:30 | getX(ne ... rce())) | only flow with NEW data flow library | | nested-props.js:14:15:14:22 | source() | nested-props.js:15:10:15:16 | obj.x.y | only flow with NEW data flow library | | nested-props.js:27:18:27:25 | source() | nested-props.js:28:10:28:14 | obj.x | only flow with NEW data flow library | @@ -115,6 +117,8 @@ flow | exceptions.js:144:9:144:16 | source() | exceptions.js:132:8:132:27 | returnThrownSource() | | exceptions.js:150:13:150:20 | source() | exceptions.js:153:10:153:10 | e | | exceptions.js:158:13:158:20 | source() | exceptions.js:161:10:161:10 | e | +| export-taint.js:2:12:2:19 | source() | import-taint.js:6:10:6:18 | mod.taint | +| export-taint.js:2:12:2:19 | source() | import-taint.js:13:14:13:22 | mod.taint | | factory-function.js:21:13:21:20 | source() | factory-function.js:7:10:7:12 | obj | | factory-function.js:22:13:22:20 | source() | factory-function.js:7:10:7:12 | obj | | factory-function.js:26:7:26:14 | source() | factory-function.js:16:14:16:16 | obj | diff --git a/javascript/ql/test/library-tests/TaintTracking/export-taint.js b/javascript/ql/test/library-tests/TaintTracking/export-taint.js new file mode 100644 index 00000000000..aa27847b64d --- /dev/null +++ b/javascript/ql/test/library-tests/TaintTracking/export-taint.js @@ -0,0 +1,4 @@ +export default { + taint: source(), + object: { taint: source() } +}; diff --git a/javascript/ql/test/library-tests/TaintTracking/import-taint.js b/javascript/ql/test/library-tests/TaintTracking/import-taint.js new file mode 100644 index 00000000000..3b4e0fff59f --- /dev/null +++ b/javascript/ql/test/library-tests/TaintTracking/import-taint.js @@ -0,0 +1,16 @@ +import 'dummy'; + +async function test1() { + let mod = await import("./export-taint"); + sink(mod); // OK + sink(mod.taint); // NOT OK + sink(mod.object.taint); // NOT OK [INCONSISTENCY] - blocked by access path limit +} + +function test2() { + import("./export-taint").then(mod => { + sink(mod); // OK + sink(mod.taint); // NOT OK + sink(mod.object.taint); // NOT OK [INCONSISTENCY] - blocked by access path limit + }); +} From 4cdaccd22e96f38822684451ed921d65f316c9b6 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 7 Aug 2024 14:03:25 +0200 Subject: [PATCH 231/514] JS: Add InlineFlowTest --- .../ql/test/testUtilities/InlineFlowTest.qll | 25 +++++++++++++++++++ .../test/testUtilities/InlineFlowTestUtil.qll | 21 ++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 javascript/ql/test/testUtilities/InlineFlowTest.qll create mode 100644 javascript/ql/test/testUtilities/InlineFlowTestUtil.qll diff --git a/javascript/ql/test/testUtilities/InlineFlowTest.qll b/javascript/ql/test/testUtilities/InlineFlowTest.qll new file mode 100644 index 00000000000..787f5f1540b --- /dev/null +++ b/javascript/ql/test/testUtilities/InlineFlowTest.qll @@ -0,0 +1,25 @@ +/** + * Inline flow tests for JavaScript. + * See `shared/util/codeql/dataflow/test/InlineFlowTest.qll` + */ + +private import javascript +private import semmle.javascript.Locations +private import codeql.dataflow.test.InlineFlowTest +private import semmle.javascript.dataflow.internal.sharedlib.DataFlowArg +private import semmle.javascript.frameworks.data.internal.ApiGraphModelsExtensions as ApiGraphModelsExtensions +private import internal.InlineExpectationsTestImpl + +private module FlowTestImpl implements InputSig { + import testUtilities.InlineFlowTestUtil + + bindingset[src, sink] + string getArgString(DataFlow::Node src, DataFlow::Node sink) { + (if exists(getSourceArgString(src)) then result = getSourceArgString(src) else result = "") and + exists(sink) + } + + predicate interpretModelForTest = ApiGraphModelsExtensions::interpretModelForTest/2; +} + +import InlineFlowTestMake diff --git a/javascript/ql/test/testUtilities/InlineFlowTestUtil.qll b/javascript/ql/test/testUtilities/InlineFlowTestUtil.qll new file mode 100644 index 00000000000..4072e4dd9e6 --- /dev/null +++ b/javascript/ql/test/testUtilities/InlineFlowTestUtil.qll @@ -0,0 +1,21 @@ +/** + * Defines the default source and sink recognition for `InlineFlowTest.qll`. + * + * We reuse these predicates in some type-tracking tests that don't wish to bring in the + * test configuration from `InlineFlowTest`. + */ + +private import javascript + +predicate defaultSource(DataFlow::Node src) { src.(DataFlow::CallNode).getCalleeName() = "source" } + +predicate defaultSink(DataFlow::Node sink) { + exists(DataFlow::CallNode call | call.getCalleeName() = "sink" | sink = call.getAnArgument()) +} + +bindingset[src] +string getSourceArgString(DataFlow::Node src) { + src.(DataFlow::CallNode).getAnArgument().getStringValue() = result + or + src.(DataFlow::ParameterNode).getName() = result +} From 5d77c336fcf7ee4ada7a3ee7865a9ad7f9dd5e5c Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 8 Aug 2024 20:04:11 +0200 Subject: [PATCH 232/514] Test case for spread and rest args/params --- .../library-tests/TripleDot/test.expected | 61 ++++++++++ .../ql/test/library-tests/TripleDot/test.ql | 3 + .../ql/test/library-tests/TripleDot/tst.js | 114 ++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 javascript/ql/test/library-tests/TripleDot/test.expected create mode 100644 javascript/ql/test/library-tests/TripleDot/test.ql create mode 100644 javascript/ql/test/library-tests/TripleDot/tst.js diff --git a/javascript/ql/test/library-tests/TripleDot/test.expected b/javascript/ql/test/library-tests/TripleDot/test.expected new file mode 100644 index 00000000000..046eb06471d --- /dev/null +++ b/javascript/ql/test/library-tests/TripleDot/test.expected @@ -0,0 +1,61 @@ +| tst.js:5:14:5:20 | rest[0] | Unexpected result: hasTaintFlow=t1.1 | +| tst.js:5:24:5:45 | // $ ha ... ow=t1.1 | Missing result:hasValueFlow=t1.1 | +| tst.js:6:14:6:20 | rest[1] | Unexpected result: hasTaintFlow=t1.1 | +| tst.js:6:24:6:45 | // $ ha ... ow=t1.2 | Missing result:hasValueFlow=t1.2 | +| tst.js:7:31:7:70 | // $ ha ... ow=t1.2 | Missing result:hasTaintFlow=t1.2 | +| tst.js:15:31:15:70 | // $ ha ... ow=t2.3 | Missing result:hasTaintFlow=t2.3 | +| tst.js:22:14:22:14 | x | Unexpected result: hasTaintFlow=t3.1 | +| tst.js:22:18:22:39 | // $ ha ... ow=t3.1 | Missing result:hasValueFlow=t3.1 | +| tst.js:23:14:23:14 | y | Unexpected result: hasTaintFlow=t3.1 | +| tst.js:23:18:23:39 | // $ ha ... ow=t3.2 | Missing result:hasValueFlow=t3.2 | +| tst.js:24:14:24:14 | z | Unexpected result: hasTaintFlow=t3.1 | +| tst.js:24:18:24:39 | // $ ha ... ow=t3.3 | Missing result:hasValueFlow=t3.3 | +| tst.js:34:14:34:14 | w | Unexpected result: hasTaintFlow=t4.1 | +| tst.js:35:14:35:14 | x | Unexpected result: hasTaintFlow=t4.1 | +| tst.js:35:18:35:39 | // $ ha ... ow=t4.1 | Missing result:hasValueFlow=t4.1 | +| tst.js:36:14:36:14 | y | Unexpected result: hasTaintFlow=t4.1 | +| tst.js:36:18:36:39 | // $ ha ... ow=t4.2 | Missing result:hasValueFlow=t4.2 | +| tst.js:37:14:37:14 | z | Unexpected result: hasTaintFlow=t4.1 | +| tst.js:37:18:37:39 | // $ ha ... ow=t4.3 | Missing result:hasValueFlow=t4.3 | +| tst.js:47:14:47:14 | w | Unexpected result: hasTaintFlow=t5.2 | +| tst.js:47:14:47:14 | w | Unexpected result: hasTaintFlow=t5.3 | +| tst.js:47:14:47:14 | w | Unexpected result: hasValueFlow=t5.1 | +| tst.js:48:14:48:14 | x | Unexpected result: hasTaintFlow=t5.1 | +| tst.js:48:14:48:14 | x | Unexpected result: hasTaintFlow=t5.3 | +| tst.js:48:14:48:14 | x | Unexpected result: hasValueFlow=t5.2 | +| tst.js:48:18:48:39 | // $ ha ... ow=t5.1 | Missing result:hasValueFlow=t5.1 | +| tst.js:49:14:49:14 | y | Unexpected result: hasTaintFlow=t5.1 | +| tst.js:49:14:49:14 | y | Unexpected result: hasTaintFlow=t5.2 | +| tst.js:49:14:49:14 | y | Unexpected result: hasValueFlow=t5.3 | +| tst.js:49:18:49:39 | // $ ha ... ow=t5.2 | Missing result:hasValueFlow=t5.2 | +| tst.js:50:14:50:14 | z | Unexpected result: hasTaintFlow=t5.1 | +| tst.js:50:14:50:14 | z | Unexpected result: hasTaintFlow=t5.2 | +| tst.js:50:14:50:14 | z | Unexpected result: hasTaintFlow=t5.3 | +| tst.js:50:18:50:39 | // $ ha ... ow=t5.3 | Missing result:hasValueFlow=t5.3 | +| tst.js:61:28:61:49 | // $ ha ... ow=t6.1 | Missing result:hasValueFlow=t6.1 | +| tst.js:62:28:62:49 | // $ ha ... ow=t6.2 | Missing result:hasValueFlow=t6.2 | +| tst.js:63:28:63:49 | // $ ha ... ow=t6.3 | Missing result:hasValueFlow=t6.3 | +| tst.js:70:18:70:39 | // $ ha ... ow=t7.1 | Missing result:hasValueFlow=t7.1 | +| tst.js:71:18:71:39 | // $ ha ... ow=t7.2 | Missing result:hasValueFlow=t7.2 | +| tst.js:72:18:72:39 | // $ ha ... ow=t7.3 | Missing result:hasValueFlow=t7.3 | +| tst.js:82:14:82:14 | x | Unexpected result: hasTaintFlow=t8.2 | +| tst.js:82:14:82:14 | x | Unexpected result: hasTaintFlow=t8.4 | +| tst.js:83:14:83:14 | y | Unexpected result: hasTaintFlow=t8.1 | +| tst.js:83:14:83:14 | y | Unexpected result: hasTaintFlow=t8.3 | +| tst.js:83:18:83:85 | // $ ha ... ow=t8.4 | Fixed spurious result:hasValueFlow=t8.3 | +| tst.js:84:14:84:14 | z | Unexpected result: hasTaintFlow=t8.1 | +| tst.js:84:14:84:14 | z | Unexpected result: hasTaintFlow=t8.2 | +| tst.js:84:14:84:14 | z | Unexpected result: hasTaintFlow=t8.3 | +| tst.js:84:14:84:14 | z | Unexpected result: hasTaintFlow=t8.4 | +| tst.js:84:18:84:85 | // $ ha ... ow=t8.4 | Fixed spurious result:hasValueFlow=t8.3 | +| tst.js:84:18:84:85 | // $ ha ... ow=t8.4 | Fixed spurious result:hasValueFlow=t8.4 | +| tst.js:84:18:84:85 | // $ ha ... ow=t8.4 | Missing result:hasValueFlow=t8.3 | +| tst.js:94:18:94:39 | // $ ha ... ow=t9.1 | Missing result:hasValueFlow=t9.1 | +| tst.js:95:18:95:39 | // $ ha ... ow=t9.2 | Missing result:hasValueFlow=t9.2 | +| tst.js:96:18:96:39 | // $ ha ... ow=t9.3 | Missing result:hasValueFlow=t9.3 | +| tst.js:106:14:106:14 | x | Unexpected result: hasTaintFlow=t10.1 | +| tst.js:106:18:106:40 | // $ ha ... w=t10.1 | Missing result:hasValueFlow=t10.1 | +| tst.js:107:14:107:14 | y | Unexpected result: hasTaintFlow=t10.1 | +| tst.js:107:18:107:40 | // $ ha ... w=t10.2 | Missing result:hasValueFlow=t10.2 | +| tst.js:108:14:108:14 | z | Unexpected result: hasTaintFlow=t10.1 | +| tst.js:108:18:108:40 | // $ ha ... w=t10.3 | Missing result:hasValueFlow=t10.3 | diff --git a/javascript/ql/test/library-tests/TripleDot/test.ql b/javascript/ql/test/library-tests/TripleDot/test.ql new file mode 100644 index 00000000000..222c24dbbea --- /dev/null +++ b/javascript/ql/test/library-tests/TripleDot/test.ql @@ -0,0 +1,3 @@ +import javascript +import testUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/javascript/ql/test/library-tests/TripleDot/tst.js b/javascript/ql/test/library-tests/TripleDot/tst.js new file mode 100644 index 00000000000..3613857d455 --- /dev/null +++ b/javascript/ql/test/library-tests/TripleDot/tst.js @@ -0,0 +1,114 @@ +import 'dummy'; + +function t1() { + function target(...rest) { + sink(rest[0]); // $ hasValueFlow=t1.1 + sink(rest[1]); // $ hasValueFlow=t1.2 + sink(rest.join(',')); // $ hasTaintFlow=t1.1 hasTaintFlow=t1.2 + } + target(source('t1.1'), source('t1.2')); +} + +function t2() { + function target(x, ...rest) { + sink(x); // $ hasValueFlow=t2.1 + sink(rest.join(',')); // $ hasTaintFlow=t2.2 hasTaintFlow=t2.3 + } + target(source('t2.1'), source('t2.2'), source('t2.3')); +} + +function t3() { + function finalTarget(x, y, z) { + sink(x); // $ hasValueFlow=t3.1 + sink(y); // $ hasValueFlow=t3.2 + sink(z); // $ hasValueFlow=t3.3 + } + function target(...rest) { + finalTarget(...rest); + } + target(source('t3.1'), source('t3.2'), source('t3.3')); +} + +function t4() { + function finalTarget(w, x, y, z) { + sink(w); // $ hasValueFlow=t4.0 + sink(x); // $ hasValueFlow=t4.1 + sink(y); // $ hasValueFlow=t4.2 + sink(z); // $ hasValueFlow=t4.3 + } + function target(...rest) { + finalTarget(source('t4.0'), ...rest); + } + target(source('t4.1'), source('t4.2'), source('t4.3')); +} + +function t5() { + function finalTarget(w, x, y, z) { + sink(w); // $ hasValueFlow=t5.0 + sink(x); // $ hasValueFlow=t5.1 + sink(y); // $ hasValueFlow=t5.2 + sink(z); // $ hasValueFlow=t5.3 + } + function target(array) { + finalTarget(source('t5.0'), ...array); + } + target([source('t5.1'), source('t5.2'), source('t5.3')]); +} + +function t6() { + function target(x) { + sink(x); // $ hasValueFlow=t6.1 + sink(arguments[0]);// $ hasValueFlow=t6.1 + sink(arguments[1]);// $ hasValueFlow=t6.2 + sink(arguments[2]);// $ hasValueFlow=t6.3 + } + target(source('t6.1'), source('t6.2'), source('t6.3')); +} + +function t7() { + function finalTarget(x, y, z) { + sink(x); // $ hasValueFlow=t7.1 + sink(y); // $ hasValueFlow=t7.2 + sink(z); // $ hasValueFlow=t7.3 + } + function target() { + finalTarget(...arguments); + } + target(source('t7.1'), source('t7.2'), source('t7.3')); +} + +function t8() { + function finalTarget(x, y, z) { + sink(x); // $ hasValueFlow=t8.1 SPURIOUS: hasValueFlow=t8.3 + sink(y); // $ hasValueFlow=t8.2 SPURIOUS: hasValueFlow=t8.3 hasValueFlow=t8.4 + sink(z); // $ hasValueFlow=t8.3 SPURIOUS: hasValueFlow=t8.3 hasValueFlow=t8.4 + } + function target(array1, array2) { + finalTarget(...array1, ...array2); + } + target([source('t8.1'), source('t8.2')], [source('t8.3'), source('t8.4')]); +} + +function t9() { + function finalTarget(x, y, z) { + sink(x); // $ hasValueFlow=t9.1 + sink(y); // $ hasValueFlow=t9.2 + sink(z); // $ hasValueFlow=t9.3 + } + function target() { + finalTarget.apply(undefined, arguments); + } + target(source('t9.1'), source('t9.2'), source('t9.3')); +} + +function t10() { + function finalTarget(x, y, z) { + sink(x); // $ hasValueFlow=t10.1 + sink(y); // $ hasValueFlow=t10.2 + sink(z); // $ hasValueFlow=t10.3 + } + function target(...rest) { + finalTarget.apply(undefined, rest); + } + target(source('t10.1'), source('t10.2'), source('t10.3')); +} From 6c7d745a2bc774744c0cde31b5dfa49c36e9fc90 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 9 Aug 2024 10:08:45 +0200 Subject: [PATCH 233/514] JS: Add nodes for static/dynamic argument/parameter arrays --- .../dataflow/internal/DataFlowNode.qll | 6 ++ .../dataflow/internal/DataFlowPrivate.qll | 67 +++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index 4e10b6b27e1..2499e92b7db 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -33,6 +33,12 @@ private module Cached { } or TThisNode(StmtContainer f) { f.(Function).getThisBinder() = f or f instanceof TopLevel } or TFunctionSelfReferenceNode(Function f) or + TStaticArgumentArrayNode(InvokeExpr node) or + TDynamicArgumentArrayNode(InvokeExpr node) { node.isSpreadArgument(_) } or + TStaticParameterArrayNode(Function f) { + f.getAParameter().isRestParameter() or f.usesArgumentsObject() + } or + TDynamicParameterArrayNode(Function f) or TDestructuredModuleImportNode(ImportDeclaration decl) { exists(decl.getASpecifier().getImportedName()) } or diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 8f9e3ee6f6f..ac508e0e9e7 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -81,6 +81,73 @@ class GenericSynthesizedNode extends DataFlow::Node, TGenericSynthesizedNode { string getTag() { result = tag } } +/** + * An argument containing an array of all positional arguments with an obvious index, i.e. not affected by a spread argument. + */ +class StaticArgumentArrayNode extends DataFlow::Node, TStaticArgumentArrayNode { + private InvokeExpr invoke; + + StaticArgumentArrayNode() { this = TStaticArgumentArrayNode(invoke) } + + override StmtContainer getContainer() { result = invoke.getContainer() } + + override string toString() { result = "[static argument array]" } + + override Location getLocation() { result = invoke.getLocation() } +} + +/** + * An argument containing an array of all positional arguments with non-obvious index, i.e. affected by a spread argument. + * + * Only exists for call sites with a spread argument. + */ +class DynamicArgumentArrayNode extends DataFlow::Node, TDynamicArgumentArrayNode { + private InvokeExpr invoke; + + DynamicArgumentArrayNode() { this = TDynamicArgumentArrayNode(invoke) } + + override StmtContainer getContainer() { result = invoke.getContainer() } + + override string toString() { result = "[dynamic argument array]" } + + override Location getLocation() { result = invoke.getLocation() } +} + +/** + * A parameter containing an array of all positional arguments with an obvious index, i.e. not affected by spread or `.apply()`. + * + * These are read and stored in the function's rest parameter and `arguments` array. + * The node only exists for functions with a rest parameter or which uses the `arguments` array. + */ +class StaticParameterArrayNode extends DataFlow::Node, TStaticParameterArrayNode { + private Function function; + + StaticParameterArrayNode() { this = TStaticParameterArrayNode(function) } + + override StmtContainer getContainer() { result = function } + + override string toString() { result = "[static parameter array]" } + + override Location getLocation() { result = function.getLocation() } +} + +/** + * A parameter containing an array of all positional argument values with non-obvious index, i.e. affected by spread or `.apply()`. + * + * These are read and assigned into regular positional parameters and stored into rest parameters and the `arguments` array. + */ +class DynamicParameterArrayNode extends DataFlow::Node, TDynamicParameterArrayNode { + private Function function; + + DynamicParameterArrayNode() { this = TDynamicParameterArrayNode(function) } + + override StmtContainer getContainer() { result = function } + + override string toString() { result = "[dynamic parameter array]" } + + override Location getLocation() { result = function.getLocation() } +} + cached newtype TReturnKind = MkNormalReturnKind() or From a72f79576a1527d1e42bd738a9fd1409f76a970e Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 9 Aug 2024 10:24:02 +0200 Subject: [PATCH 234/514] JS: Add corresponding argument positions --- .../dataflow/internal/DataFlowPrivate.qll | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index ac508e0e9e7..d25c53cb786 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -293,7 +293,11 @@ private predicate isParameterNodeImpl(Node p, DataFlowCallable c, ParameterPosit or pos.isFunctionSelfReference() and p = TFunctionSelfReferenceNode(c.asSourceCallable()) or - pos.isArgumentsArray() and p = TReflectiveParametersNode(c.asSourceCallable()) + pos.isArgumentsArray() and p = TReflectiveParametersNode(c.asSourceCallable()) // TODO: remove + or + pos.isStaticArgumentArray() and p = TStaticParameterArrayNode(c.asSourceCallable()) + or + pos.isDynamicArgumentArray() and p = TDynamicParameterArrayNode(c.asSourceCallable()) or exists(FlowSummaryNode summaryNode | summaryNode = p and @@ -347,6 +351,14 @@ private predicate isArgumentNodeImpl(Node n, DataFlowCall call, ArgumentPosition or FlowSummaryImpl::Private::summaryArgumentNode(call.(SummaryCall).getReceiver(), n.(FlowSummaryNode).getSummaryNode(), pos) + or + exists(InvokeExpr invoke | call.asOrdinaryCall() = TValueNode(invoke) | + n = TStaticArgumentArrayNode(invoke) and + pos.isStaticArgumentArray() + or + n = TDynamicArgumentArrayNode(invoke) and + pos.isDynamicArgumentArray() + ) } predicate isArgumentNode(ArgumentNode n, DataFlowCall call, ArgumentPosition pos) { @@ -738,7 +750,9 @@ newtype TParameterPosition = MkPositionalLowerBound(int n) { n = [0 .. getMaxArity()] } or MkThisParameter() or MkFunctionSelfReferenceParameter() or - MkArgumentsArrayParameter() + MkArgumentsArrayParameter() or // TODO: remove + MkStaticArgumentArray() or + MkDynamicArgumentArray() class ParameterPosition extends TParameterPosition { predicate isPositionalExact() { this instanceof MkPositionalParameter } @@ -755,7 +769,11 @@ class ParameterPosition extends TParameterPosition { predicate isFunctionSelfReference() { this = MkFunctionSelfReferenceParameter() } - predicate isArgumentsArray() { this = MkArgumentsArrayParameter() } + predicate isArgumentsArray() { this = MkArgumentsArrayParameter() } // TODO: remove + + predicate isStaticArgumentArray() { this = MkStaticArgumentArray() } + + predicate isDynamicArgumentArray() { this = MkDynamicArgumentArray() } string toString() { result = this.asPositional().toString() @@ -766,7 +784,11 @@ class ParameterPosition extends TParameterPosition { or this.isFunctionSelfReference() and result = "function" or - this.isArgumentsArray() and result = "arguments-array" + this = MkArgumentsArrayParameter() and result = "deprecated-arguments-array" + or + this.isStaticArgumentArray() and result = "static-argument-array" + or + this.isDynamicArgumentArray() and result = "dynamic-argument-array" } } From 623dbda77ddd4a092bb3c8beedcfb0001fc4c7a2 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 12 Aug 2024 13:18:58 +0200 Subject: [PATCH 235/514] Do not pass regular positional args into the rest parameter --- .../semmle/javascript/dataflow/internal/DataFlowPrivate.qll | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index d25c53cb786..1b08b63f897 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -287,7 +287,11 @@ abstract class LibraryCallable extends string { } private predicate isParameterNodeImpl(Node p, DataFlowCallable c, ParameterPosition pos) { - p = c.asSourceCallable().(Function).getParameter(pos.asPositional()).flow() + exists(Parameter parameter | + parameter = c.asSourceCallable().(Function).getParameter(pos.asPositional()) and + not parameter.isRestParameter() and + p = TValueNode(parameter) + ) or pos.isThis() and p = TThisNode(c.asSourceCallable().(Function)) or From fa7ad0306848966ba61d9de90c089f02e8a4ea98 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 9 Aug 2024 11:17:35 +0200 Subject: [PATCH 236/514] JS: Add store/load steps for the new argument arrays --- .../semmle/javascript/dataflow/DataFlow.qll | 5 +- .../dataflow/internal/DataFlowNode.qll | 18 ++- .../dataflow/internal/DataFlowPrivate.qll | 144 +++++++++++++++++- .../library-tests/TripleDot/test.expected | 61 -------- .../ql/test/library-tests/TripleDot/tst.js | 2 +- 5 files changed, 158 insertions(+), 72 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index a80b2e79ff9..433cf286c34 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -1780,8 +1780,7 @@ module DataFlow { ) } - /** A load step from a reflective parameter node to each parameter. */ - private class ReflectiveParamsStep extends PreCallGraphStep { + private class ReflectiveParamsStep extends LegacyPreCallGraphStep { override predicate loadStep(DataFlow::Node obj, DataFlow::Node element, string prop) { exists(DataFlow::ReflectiveParametersNode params, DataFlow::FunctionNode f, int i | f.getFunction() = params.getFunction() and @@ -1793,7 +1792,7 @@ module DataFlow { } /** A taint step from the reflective parameters node to any parameter. */ - private class ReflectiveParamsTaintStep extends TaintTracking::SharedTaintStep { + private class ReflectiveParamsTaintStep extends TaintTracking::LegacyTaintStep { override predicate step(DataFlow::Node obj, DataFlow::Node element) { exists(DataFlow::ReflectiveParametersNode params, DataFlow::FunctionNode f | f.getFunction() = params.getFunction() and diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index 2499e92b7db..ab152e34f9d 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -15,6 +15,12 @@ private import semmle.javascript.dataflow.internal.VariableCapture as VariableCa cached private module Cached { + private Content dynamicArgumentsContent() { + result.asArrayIndex() = [0 .. 10] + or + result.isUnknownArrayElement() + } + /** * The raw data type underlying `DataFlow::Node`. */ @@ -39,6 +45,16 @@ private module Cached { f.getAParameter().isRestParameter() or f.usesArgumentsObject() } or TDynamicParameterArrayNode(Function f) or + /** Data about to be stored in the rest parameter object. Needed for shifting array indices. */ + TRestParameterStoreNode(Function f, Content storeContent) { + f.getRestParameter().getIndex() > 0 and + storeContent = dynamicArgumentsContent() + } or + /** Data about to be stored in the dynamic argument array of an invocation. Needed for shifting array indices. */ + TDynamicArgumentStoreNode(InvokeExpr invoke, Content storeContent) { + invoke.isSpreadArgument(_) and + storeContent = dynamicArgumentsContent() + } or TDestructuredModuleImportNode(ImportDeclaration decl) { exists(decl.getASpecifier().getImportedName()) } or @@ -49,7 +65,7 @@ private module Cached { TExceptionalInvocationReturnNode(InvokeExpr e) or TGlobalAccessPathRoot() or TTemplatePlaceholderTag(Templating::TemplatePlaceholderTag tag) or - TReflectiveParametersNode(Function f) or + TReflectiveParametersNode(Function f) { f.usesArgumentsObject() } or TExprPostUpdateNode(AST::ValueNode e) { e = any(InvokeExpr invoke).getAnArgument() or e = any(PropAccess access).getBase() or diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 1b08b63f897..c4b1ee8d6ea 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -113,6 +113,42 @@ class DynamicArgumentArrayNode extends DataFlow::Node, TDynamicArgumentArrayNode override Location getLocation() { result = invoke.getLocation() } } +/** + * Intermediate node with data that will be stored in `DyanmicArgumentArrayNode`. + */ +class DynamicArgumentStoreNode extends DataFlow::Node, TDynamicArgumentStoreNode { + private InvokeExpr invoke; + private Content content; + + DynamicArgumentStoreNode() { this = TDynamicArgumentStoreNode(invoke, content) } + + override StmtContainer getContainer() { result = invoke.getContainer() } + + override string toString() { result = "[dynamic argument store node] content=" + content } + + override Location getLocation() { result = invoke.getLocation() } +} + +/** + * Intermediate node with data that will be stored in the function's rest parameter node. + */ +class RestParameterStoreNode extends DataFlow::Node, TRestParameterStoreNode { + private Function function; + private Content content; + + RestParameterStoreNode() { this = TRestParameterStoreNode(function, content) } + + override StmtContainer getContainer() { result = function } + + override string toString() { + result = + "[rest parameter store node] '..." + function.getRestParameter().getName() + "' content=" + + content + } + + override Location getLocation() { result = function.getRestParameter().getLocation() } +} + /** * A parameter containing an array of all positional arguments with an obvious index, i.e. not affected by spread or `.apply()`. * @@ -297,8 +333,6 @@ private predicate isParameterNodeImpl(Node p, DataFlowCallable c, ParameterPosit or pos.isFunctionSelfReference() and p = TFunctionSelfReferenceNode(c.asSourceCallable()) or - pos.isArgumentsArray() and p = TReflectiveParametersNode(c.asSourceCallable()) // TODO: remove - or pos.isStaticArgumentArray() and p = TStaticParameterArrayNode(c.asSourceCallable()) or pos.isDynamicArgumentArray() and p = TDynamicParameterArrayNode(c.asSourceCallable()) @@ -317,6 +351,12 @@ predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition private predicate isArgumentNodeImpl(Node n, DataFlowCall call, ArgumentPosition pos) { n = call.asOrdinaryCall().getArgument(pos.asPositional()) or + exists(InvokeExpr invoke | + call.asOrdinaryCall() = TReflectiveCallNode(invoke, "apply") and + pos.isDynamicArgumentArray() and + n = TValueNode(invoke.getArgument(1)) + ) + or pos.isThis() and n = call.asOrdinaryCall().(DataFlow::CallNode).getReceiver() or exists(DataFlow::PartialInvokeNode invoke, DataFlow::Node callback | @@ -343,10 +383,6 @@ private predicate isArgumentNodeImpl(Node n, DataFlowCall call, ArgumentPosition or pos.isThis() and n = TConstructorThisArgumentNode(call.asOrdinaryCall().asExpr()) or - // For now, treat all spread argument as flowing into the 'arguments' array, regardless of preceding arguments - n = call.asOrdinaryCall().getASpreadArgument() and - pos.isArgumentsArray() - or // receiver of accessor call pos.isThis() and n = call.asAccessorCall().getBase() or @@ -953,6 +989,39 @@ predicate simpleLocalFlowStep(Node node1, Node node2) { or // NOTE: For consistency with readStep/storeStep, we do not translate these steps to jump steps automatically. DataFlow::AdditionalFlowStep::step(node1, node2) + or + exists(InvokeExpr invoke | + // When the first argument is a spread argument, flow into the argument array as a local flow step + // to ensure we preserve knowledge about array indices + node1 = TValueNode(invoke.getArgument(0).stripParens().(SpreadElement).getOperand()) and + node2 = TDynamicArgumentArrayNode(invoke) + ) + or + exists(Function f | + // When the first parameter is a rest parameter, flow into the rest parameter as a local flow step + // to ensure we preserve knowledge about array indices + (node1 = TStaticParameterArrayNode(f) or node1 = TDynamicParameterArrayNode(f)) + | + // rest parameter at initial position + exists(Parameter rest | + rest = f.getParameter(0) and + rest.isRestParameter() and + node2 = TValueNode(rest) + ) + or + // 'arguments' array + node2 = TReflectiveParametersNode(f) + ) + or + // Prepare to store non-spread arguments after a spread into the dynamic arguments array + exists(InvokeExpr invoke, int n, Expr argument, Content storeContent | + invoke.getArgument(n) = argument and + not argument instanceof SpreadElement and + n > firstSpreadArgumentIndex(invoke) and + node1 = TValueNode(argument) and + node2 = TDynamicArgumentStoreNode(invoke, storeContent) and + storeContent.isUnknownArrayElement() + ) } predicate localMustFlowStep(Node node1, Node node2) { node1 = node2.getImmediatePredecessor() } @@ -1018,6 +1087,42 @@ predicate readStep(Node node1, ContentSet c, Node node2) { ) or DataFlow::AdditionalFlowStep::readStep(node1, c, node2) + or + // Pass dynamic arguments into plain parameters + exists(Function function, Parameter param, int n | + param = function.getParameter(n) and + not param.isRestParameter() and + node1 = TDynamicParameterArrayNode(function) and + node2 = TValueNode(param) and + c = ContentSet::arrayElementFromInt(n) + ) + or + // Prepare to store dynamic and static arguments into the rest parameter array when it isn't the first parameter + exists(Function function, Content content, int restIndex | + restIndex = function.getRestParameter().getIndex() and + restIndex > 0 and + (node1 = TStaticParameterArrayNode(function) or node1 = TDynamicParameterArrayNode(function)) and + node2 = TRestParameterStoreNode(function, content) + | + // shift known array indices + c.asArrayIndex() = content.asArrayIndex() + restIndex + or + content.isUnknownArrayElement() and // TODO: don't read unknown array elements from static array + c = ContentSet::arrayElementUnknown() + ) + or + // Prepare to store spread arguments into the dynamic arguments array, when it isn't the initial spread argument + exists(InvokeExpr invoke, int n, Expr argument, Content storeContent | + invoke.getArgument(n).stripParens().(SpreadElement).getOperand() = argument and + n > 0 and // n=0 is handled as a value step + node1 = TValueNode(argument) and + node2 = TDynamicArgumentStoreNode(invoke, storeContent) and + if n > firstSpreadArgumentIndex(invoke) + then + c = ContentSet::arrayElement() and // unknown start index when not the first spread operator + storeContent.isUnknownArrayElement() + else storeContent.asArrayIndex() = n + c.asArrayIndex() + ) } /** Gets the post-update node for which `node` is the corresponding pre-update node. */ @@ -1032,6 +1137,11 @@ private Node tryGetPostUpdate(Node node) { result = node } +pragma[nomagic] +private int firstSpreadArgumentIndex(InvokeExpr expr) { + result = min(int i | expr.isSpreadArgument(i)) +} + /** * Holds if data can flow from `node1` to `node2` via a store into `c`. Thus, * `node2` references an object with a content `c.getAStoreContent()` that @@ -1063,6 +1173,25 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { ) or DataFlow::AdditionalFlowStep::storeStep(node1, c, node2) + or + exists(Function f, Content storeContent | + node1 = TRestParameterStoreNode(f, storeContent) and + node2 = TValueNode(f.getRestParameter()) and + c.asSingleton() = storeContent + ) + or + exists(InvokeExpr invoke, Content storeContent | + node1 = TDynamicArgumentStoreNode(invoke, storeContent) and + node2 = TDynamicArgumentArrayNode(invoke) and + c.asSingleton() = storeContent + ) + or + exists(InvokeExpr invoke, int n | + node1 = TValueNode(invoke.getArgument(n)) and + node2 = TStaticArgumentArrayNode(invoke) and + c.asArrayIndex() = n and + not n >= firstSpreadArgumentIndex(invoke) + ) } /** @@ -1112,6 +1241,9 @@ predicate expectsContent(Node n, ContentSet c) { c = MkPromiseFilter() or any(AdditionalFlowInternal flow).expectsContent(n, c) + or + c = ContentSet::arrayElement() and + n instanceof TDynamicParameterArrayNode } abstract class NodeRegion extends Unit { diff --git a/javascript/ql/test/library-tests/TripleDot/test.expected b/javascript/ql/test/library-tests/TripleDot/test.expected index 046eb06471d..e69de29bb2d 100644 --- a/javascript/ql/test/library-tests/TripleDot/test.expected +++ b/javascript/ql/test/library-tests/TripleDot/test.expected @@ -1,61 +0,0 @@ -| tst.js:5:14:5:20 | rest[0] | Unexpected result: hasTaintFlow=t1.1 | -| tst.js:5:24:5:45 | // $ ha ... ow=t1.1 | Missing result:hasValueFlow=t1.1 | -| tst.js:6:14:6:20 | rest[1] | Unexpected result: hasTaintFlow=t1.1 | -| tst.js:6:24:6:45 | // $ ha ... ow=t1.2 | Missing result:hasValueFlow=t1.2 | -| tst.js:7:31:7:70 | // $ ha ... ow=t1.2 | Missing result:hasTaintFlow=t1.2 | -| tst.js:15:31:15:70 | // $ ha ... ow=t2.3 | Missing result:hasTaintFlow=t2.3 | -| tst.js:22:14:22:14 | x | Unexpected result: hasTaintFlow=t3.1 | -| tst.js:22:18:22:39 | // $ ha ... ow=t3.1 | Missing result:hasValueFlow=t3.1 | -| tst.js:23:14:23:14 | y | Unexpected result: hasTaintFlow=t3.1 | -| tst.js:23:18:23:39 | // $ ha ... ow=t3.2 | Missing result:hasValueFlow=t3.2 | -| tst.js:24:14:24:14 | z | Unexpected result: hasTaintFlow=t3.1 | -| tst.js:24:18:24:39 | // $ ha ... ow=t3.3 | Missing result:hasValueFlow=t3.3 | -| tst.js:34:14:34:14 | w | Unexpected result: hasTaintFlow=t4.1 | -| tst.js:35:14:35:14 | x | Unexpected result: hasTaintFlow=t4.1 | -| tst.js:35:18:35:39 | // $ ha ... ow=t4.1 | Missing result:hasValueFlow=t4.1 | -| tst.js:36:14:36:14 | y | Unexpected result: hasTaintFlow=t4.1 | -| tst.js:36:18:36:39 | // $ ha ... ow=t4.2 | Missing result:hasValueFlow=t4.2 | -| tst.js:37:14:37:14 | z | Unexpected result: hasTaintFlow=t4.1 | -| tst.js:37:18:37:39 | // $ ha ... ow=t4.3 | Missing result:hasValueFlow=t4.3 | -| tst.js:47:14:47:14 | w | Unexpected result: hasTaintFlow=t5.2 | -| tst.js:47:14:47:14 | w | Unexpected result: hasTaintFlow=t5.3 | -| tst.js:47:14:47:14 | w | Unexpected result: hasValueFlow=t5.1 | -| tst.js:48:14:48:14 | x | Unexpected result: hasTaintFlow=t5.1 | -| tst.js:48:14:48:14 | x | Unexpected result: hasTaintFlow=t5.3 | -| tst.js:48:14:48:14 | x | Unexpected result: hasValueFlow=t5.2 | -| tst.js:48:18:48:39 | // $ ha ... ow=t5.1 | Missing result:hasValueFlow=t5.1 | -| tst.js:49:14:49:14 | y | Unexpected result: hasTaintFlow=t5.1 | -| tst.js:49:14:49:14 | y | Unexpected result: hasTaintFlow=t5.2 | -| tst.js:49:14:49:14 | y | Unexpected result: hasValueFlow=t5.3 | -| tst.js:49:18:49:39 | // $ ha ... ow=t5.2 | Missing result:hasValueFlow=t5.2 | -| tst.js:50:14:50:14 | z | Unexpected result: hasTaintFlow=t5.1 | -| tst.js:50:14:50:14 | z | Unexpected result: hasTaintFlow=t5.2 | -| tst.js:50:14:50:14 | z | Unexpected result: hasTaintFlow=t5.3 | -| tst.js:50:18:50:39 | // $ ha ... ow=t5.3 | Missing result:hasValueFlow=t5.3 | -| tst.js:61:28:61:49 | // $ ha ... ow=t6.1 | Missing result:hasValueFlow=t6.1 | -| tst.js:62:28:62:49 | // $ ha ... ow=t6.2 | Missing result:hasValueFlow=t6.2 | -| tst.js:63:28:63:49 | // $ ha ... ow=t6.3 | Missing result:hasValueFlow=t6.3 | -| tst.js:70:18:70:39 | // $ ha ... ow=t7.1 | Missing result:hasValueFlow=t7.1 | -| tst.js:71:18:71:39 | // $ ha ... ow=t7.2 | Missing result:hasValueFlow=t7.2 | -| tst.js:72:18:72:39 | // $ ha ... ow=t7.3 | Missing result:hasValueFlow=t7.3 | -| tst.js:82:14:82:14 | x | Unexpected result: hasTaintFlow=t8.2 | -| tst.js:82:14:82:14 | x | Unexpected result: hasTaintFlow=t8.4 | -| tst.js:83:14:83:14 | y | Unexpected result: hasTaintFlow=t8.1 | -| tst.js:83:14:83:14 | y | Unexpected result: hasTaintFlow=t8.3 | -| tst.js:83:18:83:85 | // $ ha ... ow=t8.4 | Fixed spurious result:hasValueFlow=t8.3 | -| tst.js:84:14:84:14 | z | Unexpected result: hasTaintFlow=t8.1 | -| tst.js:84:14:84:14 | z | Unexpected result: hasTaintFlow=t8.2 | -| tst.js:84:14:84:14 | z | Unexpected result: hasTaintFlow=t8.3 | -| tst.js:84:14:84:14 | z | Unexpected result: hasTaintFlow=t8.4 | -| tst.js:84:18:84:85 | // $ ha ... ow=t8.4 | Fixed spurious result:hasValueFlow=t8.3 | -| tst.js:84:18:84:85 | // $ ha ... ow=t8.4 | Fixed spurious result:hasValueFlow=t8.4 | -| tst.js:84:18:84:85 | // $ ha ... ow=t8.4 | Missing result:hasValueFlow=t8.3 | -| tst.js:94:18:94:39 | // $ ha ... ow=t9.1 | Missing result:hasValueFlow=t9.1 | -| tst.js:95:18:95:39 | // $ ha ... ow=t9.2 | Missing result:hasValueFlow=t9.2 | -| tst.js:96:18:96:39 | // $ ha ... ow=t9.3 | Missing result:hasValueFlow=t9.3 | -| tst.js:106:14:106:14 | x | Unexpected result: hasTaintFlow=t10.1 | -| tst.js:106:18:106:40 | // $ ha ... w=t10.1 | Missing result:hasValueFlow=t10.1 | -| tst.js:107:14:107:14 | y | Unexpected result: hasTaintFlow=t10.1 | -| tst.js:107:18:107:40 | // $ ha ... w=t10.2 | Missing result:hasValueFlow=t10.2 | -| tst.js:108:14:108:14 | z | Unexpected result: hasTaintFlow=t10.1 | -| tst.js:108:18:108:40 | // $ ha ... w=t10.3 | Missing result:hasValueFlow=t10.3 | diff --git a/javascript/ql/test/library-tests/TripleDot/tst.js b/javascript/ql/test/library-tests/TripleDot/tst.js index 3613857d455..3206ad657d0 100644 --- a/javascript/ql/test/library-tests/TripleDot/tst.js +++ b/javascript/ql/test/library-tests/TripleDot/tst.js @@ -79,7 +79,7 @@ function t7() { function t8() { function finalTarget(x, y, z) { - sink(x); // $ hasValueFlow=t8.1 SPURIOUS: hasValueFlow=t8.3 + sink(x); // $ hasValueFlow=t8.1 SPURIOUS: hasValueFlow=t8.3 hasValueFlow=t8.4 sink(y); // $ hasValueFlow=t8.2 SPURIOUS: hasValueFlow=t8.3 hasValueFlow=t8.4 sink(z); // $ hasValueFlow=t8.3 SPURIOUS: hasValueFlow=t8.3 hasValueFlow=t8.4 } From ed33a6e91bda710a2687a8d1bd6b6fe91bc0ffc0 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 12 Aug 2024 13:14:18 +0200 Subject: [PATCH 237/514] JS: Add explicit model of .join() --- .../internal/flow_summaries/Arrays.qll | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll index 054e617721e..8ab74e217b1 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll @@ -1,7 +1,7 @@ /** - * Contains a summary for relevant methods on arrays, except Array.prototype.join which is currently special-cased in StringConcatenation.qll. + * Contains a summary for relevant methods on arrays. * - * Note that some of Array methods are modelled in `AmbiguousCoreMethods.qll`, and `join` and `toString` are special-cased elsewhere. + * Note that some of Array methods are modelled in `AmbiguousCoreMethods.qll`, and `toString` is special-cased elsewhere. */ private import javascript @@ -116,6 +116,26 @@ class ArrayConstructorSummary extends SummarizedCallable { } } +/** + * A call to `join` with a separator argument. + * + * Calls without separators are modelled in `StringConcatenation.qll`. + */ +class Join extends SummarizedCallable { + Join() { this = "Array#join" } + + override InstanceCall getACallSimple() { + result.getMethodName() = "join" and + result.getNumArgument() = [0, 1] + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = false and + input = "Argument[this].ArrayElement" and + output = "ReturnValue" + } +} + class CopyWithin extends SummarizedCallable { CopyWithin() { this = "Array#copyWithin" } From bbb1c8c374c1b6a35ad5401f44809178aa9951f0 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 12 Aug 2024 13:58:42 +0200 Subject: [PATCH 238/514] Remove old arguments-array position --- .../semmle/javascript/dataflow/internal/DataFlowPrivate.qll | 5 ----- .../javascript/dataflow/internal/FlowSummaryPrivate.qll | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index c4b1ee8d6ea..99929776e71 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -790,7 +790,6 @@ newtype TParameterPosition = MkPositionalLowerBound(int n) { n = [0 .. getMaxArity()] } or MkThisParameter() or MkFunctionSelfReferenceParameter() or - MkArgumentsArrayParameter() or // TODO: remove MkStaticArgumentArray() or MkDynamicArgumentArray() @@ -809,8 +808,6 @@ class ParameterPosition extends TParameterPosition { predicate isFunctionSelfReference() { this = MkFunctionSelfReferenceParameter() } - predicate isArgumentsArray() { this = MkArgumentsArrayParameter() } // TODO: remove - predicate isStaticArgumentArray() { this = MkStaticArgumentArray() } predicate isDynamicArgumentArray() { this = MkDynamicArgumentArray() } @@ -824,8 +821,6 @@ class ParameterPosition extends TParameterPosition { or this.isFunctionSelfReference() and result = "function" or - this = MkArgumentsArrayParameter() and result = "deprecated-arguments-array" - or this.isStaticArgumentArray() and result = "static-argument-array" or this.isDynamicArgumentArray() and result = "dynamic-argument-array" diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index d978f81fb8a..ca38d30e901 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -35,7 +35,7 @@ private predicate positionName(ParameterPosition pos, string operand) { or pos.isFunctionSelfReference() and operand = "function" or - pos.isArgumentsArray() and operand = "arguments-array" + pos.isDynamicArgumentArray() and operand = "arguments-array" // TODO: remove and handle automatically or operand = pos.asPositionalLowerBound() + ".." } From 60c3d077b2fe813c07d36fcd27b032b57657a38e Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 12 Aug 2024 14:08:07 +0200 Subject: [PATCH 239/514] Update DataFlowImplConsistency.qll --- .../dataflow/internal/DataFlowImplConsistency.qll | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll index 84f0f3e39b4..5b166b89119 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll @@ -37,6 +37,12 @@ private module ConsistencyConfig implements InputSig { isAmbientNode(call.asOrdinaryCall()) or isAmbientNode(call.asAccessorCall()) } + + predicate argHasPostUpdateExclude(ArgumentNode node) { + // Side-effects directly on these can't propagate back to the caller, and for longer access paths it's too imprecise + node instanceof TStaticArgumentArrayNode or + node instanceof TDynamicArgumentArrayNode + } } module Consistency = MakeConsistency; From c04f0beb8a41cce5bb89eb1a8d453043075e8658 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 12 Aug 2024 14:08:23 +0200 Subject: [PATCH 240/514] Update DataFlowConsistency.expected --- .../library-tests/FlowSummary/DataFlowConsistency.expected | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected b/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected index 5a967f1256e..892f306f30e 100644 --- a/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected +++ b/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected @@ -16,10 +16,9 @@ postHasUniquePre uniquePostUpdate postIsInSameCallable reverseRead -| tst.js:109:11:113:3 | 'arguments' object of anonymous function | Origin of readStep is missing a PostUpdateNode. | +| tst.js:109:11:113:3 | [dynamic parameter array] | Origin of readStep is missing a PostUpdateNode. | | tst.js:267:28:267:31 | map3 | Origin of readStep is missing a PostUpdateNode. | argHasPostUpdate -| tst.js:219:18:219:27 | [source()] | ArgumentNode is missing PostUpdateNode. | postWithInFlow | file://:0:0:0:0 | [summary] to write: Argument[1] in Array method with flow into callback | PostUpdateNode should not be the target of local flow. | | file://:0:0:0:0 | [summary] to write: Argument[1] in Array#filter | PostUpdateNode should not be the target of local flow. | From 5c7e623c472380dd3c1662ba74a29b1b7ec071e0 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 12 Aug 2024 14:08:43 +0200 Subject: [PATCH 241/514] JS: Add some tests for missing handling of dynamic args in flow summaries --- .../library-tests/FlowSummary/test.expected | 7 ++++++ .../ql/test/library-tests/FlowSummary/tst.js | 23 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/javascript/ql/test/library-tests/FlowSummary/test.expected b/javascript/ql/test/library-tests/FlowSummary/test.expected index e69de29bb2d..28b528767d8 100644 --- a/javascript/ql/test/library-tests/FlowSummary/test.expected +++ b/javascript/ql/test/library-tests/FlowSummary/test.expected @@ -0,0 +1,7 @@ +| library-tests/FlowSummary/tst.js:278 | expected an alert, but found none | NOT OK | ConsistencyConfig | +| library-tests/FlowSummary/tst.js:282 | expected an alert, but found none | NOT OK | ConsistencyConfig | +| library-tests/FlowSummary/tst.js:283 | expected an alert, but found none | NOT OK | ConsistencyConfig | +| library-tests/FlowSummary/tst.js:286 | expected an alert, but found none | NOT OK | ConsistencyConfig | +| library-tests/FlowSummary/tst.js:287 | expected an alert, but found none | NOT OK | ConsistencyConfig | +| library-tests/FlowSummary/tst.js:290 | expected an alert, but found none | NOT OK | ConsistencyConfig | +| library-tests/FlowSummary/tst.js:291 | expected an alert, but found none | NOT OK | ConsistencyConfig | diff --git a/javascript/ql/test/library-tests/FlowSummary/tst.js b/javascript/ql/test/library-tests/FlowSummary/tst.js index aea6cf4f6fa..ac0ffb0003e 100644 --- a/javascript/ql/test/library-tests/FlowSummary/tst.js +++ b/javascript/ql/test/library-tests/FlowSummary/tst.js @@ -268,3 +268,26 @@ function m17() { sink(value); // NOT OK } } + +function m18() { + const staticParam0 = mkSummary("Argument[0]", "ReturnValue"); + const staticParam1 = mkSummary("Argument[1]", "ReturnValue"); + const dynamicParam0 = mkSummary("Argument[0..]", "ReturnValue"); + const dynamicParam1 = mkSummary("Argument[1..]", "ReturnValue"); + + sink(staticParam0(...source())); // NOT OK + sink(staticParam0("safe", ...source())); // OK + sink(staticParam0(source(), ...["safe"])); // NOT OK + + sink(staticParam1(...source())); // NOT OK + sink(staticParam1("safe", ...source())); // NOT OK + sink(staticParam1(source(), ...["safe"])); // OK + + sink(dynamicParam0(...source())); // NOT OK + sink(dynamicParam0("safe", ...source())); // NOT OK + sink(dynamicParam0(source(), ...["safe"])); // NOT OK + + sink(dynamicParam1(...source())); // NOT OK + sink(dynamicParam1("safe", ...source())); // NOT OK + sink(dynamicParam1(source(), ...["safe"])); // OK +} From 53a2a66dd0e7496e6cbf234c6723555efed95b18 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 12 Aug 2024 14:13:28 +0200 Subject: [PATCH 242/514] Add new nodes to early stage --- .../lib/semmle/javascript/dataflow/internal/DataFlowNode.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index ab152e34f9d..7db6e3a3c71 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -118,7 +118,8 @@ private class TEarlyStageNode = TFunctionSelfReferenceNode or TDestructuredModuleImportNode or THtmlAttributeNode or TFunctionReturnNode or TExceptionalFunctionReturnNode or TExceptionalInvocationReturnNode or TGlobalAccessPathRoot or TTemplatePlaceholderTag or TReflectiveParametersNode or - TExprPostUpdateNode or TConstructorThisArgumentNode; + TExprPostUpdateNode or TConstructorThisArgumentNode or TStaticArgumentArrayNode or + TDynamicArgumentArrayNode or TStaticParameterArrayNode or TDynamicParameterArrayNode; /** * A data-flow node that is not a flow summary node. From acdc896c043dd31398f1d456b50c6b51b7e1c4fa Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 12 Aug 2024 14:38:19 +0200 Subject: [PATCH 243/514] JS: Support for dynamic args to flow summaries --- .../internal/DataFlowImplConsistency.qll | 6 ++++ .../dataflow/internal/DataFlowNode.qll | 1 + .../dataflow/internal/DataFlowPrivate.qll | 32 +++++++++++++++++++ .../dataflow/internal/FlowSummaryPrivate.qll | 2 -- .../internal/flow_summaries/Arrays.qll | 15 +++------ .../library-tests/FlowSummary/test.expected | 7 ---- .../ql/test/library-tests/FlowSummary/tst.js | 24 +++++++++----- 7 files changed, 59 insertions(+), 28 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll index 5b166b89119..aa892c810db 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll @@ -24,6 +24,8 @@ private module ConsistencyConfig implements InputSig { or n instanceof FlowSummaryIntermediateAwaitStoreNode or + n instanceof FlowSummaryDynamicParameterArrayNode + or n instanceof GenericSynthesizedNode or n = DataFlow::globalAccessPathRootPseudoNode() @@ -43,6 +45,10 @@ private module ConsistencyConfig implements InputSig { node instanceof TStaticArgumentArrayNode or node instanceof TDynamicArgumentArrayNode } + + predicate reverseReadExclude(DataFlow::Node node) { + node instanceof FlowSummaryDynamicParameterArrayNode + } } module Consistency = MakeConsistency; diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index 7db6e3a3c71..59e0b65e58f 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -80,6 +80,7 @@ private module Cached { TConstructorThisArgumentNode(InvokeExpr e) { e instanceof NewExpr or e instanceof SuperCall } or TConstructorThisPostUpdate(Constructor ctor) or TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or + TFlowSummaryDynamicParameterArrayNode(FlowSummaryImpl::Public::SummarizedCallable callable) or TFlowSummaryIntermediateAwaitStoreNode(FlowSummaryImpl::Private::SummaryNode sn) { // NOTE: This dependency goes through the 'Steps' module whose instantiation depends on the call graph, // but the specific predicate we're referering to does not use that information. diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 99929776e71..fe7027fe705 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -30,6 +30,19 @@ class FlowSummaryNode extends DataFlow::Node, TFlowSummaryNode { override string toString() { result = this.getSummaryNode().toString() } } +class FlowSummaryDynamicParameterArrayNode extends DataFlow::Node, + TFlowSummaryDynamicParameterArrayNode +{ + private FlowSummaryImpl::Public::SummarizedCallable callable; + + FlowSummaryDynamicParameterArrayNode() { this = TFlowSummaryDynamicParameterArrayNode(callable) } + + FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() { result = callable } + + cached + override string toString() { result = "[dynamic parameter array] " + callable } +} + class FlowSummaryIntermediateAwaitStoreNode extends DataFlow::Node, TFlowSummaryIntermediateAwaitStoreNode { @@ -342,6 +355,12 @@ private predicate isParameterNodeImpl(Node p, DataFlowCallable c, ParameterPosit FlowSummaryImpl::Private::summaryParameterNode(summaryNode.getSummaryNode(), pos) and c.asLibraryCallable() = summaryNode.getSummarizedCallable() ) + or + exists(FlowSummaryImpl::Public::SummarizedCallable callable | + c.asLibraryCallable() = callable and + pos.isDynamicArgumentArray() and + p = TFlowSummaryDynamicParameterArrayNode(callable) + ) } predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) { @@ -410,6 +429,8 @@ DataFlowCallable nodeGetEnclosingCallable(Node node) { or result.asLibraryCallable() = node.(FlowSummaryNode).getSummarizedCallable() or + result.asLibraryCallable() = node.(FlowSummaryDynamicParameterArrayNode).getSummarizedCallable() + or result.asLibraryCallable() = node.(FlowSummaryIntermediateAwaitStoreNode).getSummarizedCallable() or node = TGenericSynthesizedNode(_, _, result) @@ -1118,6 +1139,17 @@ predicate readStep(Node node1, ContentSet c, Node node2) { storeContent.isUnknownArrayElement() else storeContent.asArrayIndex() = n + c.asArrayIndex() ) + or + exists(FlowSummaryNode parameter, ParameterPosition pos | + FlowSummaryImpl::Private::summaryParameterNode(parameter.getSummaryNode(), pos) and + node1 = TFlowSummaryDynamicParameterArrayNode(parameter.getSummarizedCallable()) and + node2 = parameter and + ( + c.asArrayIndex() = pos.asPositional() + or + c = ContentSet::arrayElementLowerBound(pos.asPositionalLowerBound()) + ) + ) } /** Gets the post-update node for which `node` is the corresponding pre-update node. */ diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index ca38d30e901..3611d34667e 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -35,8 +35,6 @@ private predicate positionName(ParameterPosition pos, string operand) { or pos.isFunctionSelfReference() and operand = "function" or - pos.isDynamicArgumentArray() and operand = "arguments-array" // TODO: remove and handle automatically - or operand = pos.asPositionalLowerBound() + ".." } diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll index 8ab74e217b1..0723cbf3767 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll @@ -101,17 +101,11 @@ class ArrayConstructorSummary extends SummarizedCallable { override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { preservesValue = true and - ( - input = "Argument[0..]" and - output = "ReturnValue.ArrayElement" - or - input = "Argument[arguments-array].WithArrayElement" and - output = "ReturnValue" - ) + input = "Argument[0..]" and + output = "ReturnValue.ArrayElement" or - // TODO: workaround for WithArrayElement not being converted to a taint step preservesValue = false and - input = "Argument[arguments-array]" and + input = "Argument[0..]" and output = "ReturnValue" } } @@ -437,8 +431,7 @@ class PushLike extends SummarizedCallable { override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { preservesValue = true and - // TODO: make it so `arguments-array` is handled without needing to reference it explicitly in every flow-summary - input = ["Argument[0..]", "Argument[arguments-array].ArrayElement"] and + input = "Argument[0..]" and output = "Argument[this].ArrayElement" } } diff --git a/javascript/ql/test/library-tests/FlowSummary/test.expected b/javascript/ql/test/library-tests/FlowSummary/test.expected index 28b528767d8..e69de29bb2d 100644 --- a/javascript/ql/test/library-tests/FlowSummary/test.expected +++ b/javascript/ql/test/library-tests/FlowSummary/test.expected @@ -1,7 +0,0 @@ -| library-tests/FlowSummary/tst.js:278 | expected an alert, but found none | NOT OK | ConsistencyConfig | -| library-tests/FlowSummary/tst.js:282 | expected an alert, but found none | NOT OK | ConsistencyConfig | -| library-tests/FlowSummary/tst.js:283 | expected an alert, but found none | NOT OK | ConsistencyConfig | -| library-tests/FlowSummary/tst.js:286 | expected an alert, but found none | NOT OK | ConsistencyConfig | -| library-tests/FlowSummary/tst.js:287 | expected an alert, but found none | NOT OK | ConsistencyConfig | -| library-tests/FlowSummary/tst.js:290 | expected an alert, but found none | NOT OK | ConsistencyConfig | -| library-tests/FlowSummary/tst.js:291 | expected an alert, but found none | NOT OK | ConsistencyConfig | diff --git a/javascript/ql/test/library-tests/FlowSummary/tst.js b/javascript/ql/test/library-tests/FlowSummary/tst.js index ac0ffb0003e..264c304f0f3 100644 --- a/javascript/ql/test/library-tests/FlowSummary/tst.js +++ b/javascript/ql/test/library-tests/FlowSummary/tst.js @@ -275,19 +275,27 @@ function m18() { const dynamicParam0 = mkSummary("Argument[0..]", "ReturnValue"); const dynamicParam1 = mkSummary("Argument[1..]", "ReturnValue"); - sink(staticParam0(...source())); // NOT OK - sink(staticParam0("safe", ...source())); // OK + sink(staticParam0(...[source()])); // NOT OK + sink(staticParam0(...["safe", source()])); // OK + sink(staticParam0(...[source(), "safe", ])); // NOT OK + sink(staticParam0("safe", ...[source()])); // OK sink(staticParam0(source(), ...["safe"])); // NOT OK - sink(staticParam1(...source())); // NOT OK - sink(staticParam1("safe", ...source())); // NOT OK + sink(staticParam1(...[source()])); // OK + sink(staticParam1(...["safe", source()])); // NOT OK + sink(staticParam1(...[source(), "safe", ])); // OK + sink(staticParam1("safe", ...[source()])); // NOT OK sink(staticParam1(source(), ...["safe"])); // OK - sink(dynamicParam0(...source())); // NOT OK - sink(dynamicParam0("safe", ...source())); // NOT OK + sink(dynamicParam0(...[source()])); // NOT OK + sink(dynamicParam0(...["safe", source()])); // NOT OK + sink(dynamicParam0(...[source(), "safe", ])); // NOT OK + sink(dynamicParam0("safe", ...[source()])); // NOT OK sink(dynamicParam0(source(), ...["safe"])); // NOT OK - sink(dynamicParam1(...source())); // NOT OK - sink(dynamicParam1("safe", ...source())); // NOT OK + sink(dynamicParam1(...[source()])); // OK + sink(dynamicParam1(...["safe", source()])); // NOT OK + sink(dynamicParam1(...[source(), "safe", ])); // OK + sink(dynamicParam1("safe", ...[source()])); // NOT OK sink(dynamicParam1(source(), ...["safe"])); // OK } From 6a083136d77746c0e91f4059db6501ed3b817565 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 12 Aug 2024 14:52:00 +0200 Subject: [PATCH 244/514] JS: Hide some nodes --- .../dataflow/internal/DataFlowPrivate.qll | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index fe7027fe705..d7791c0f59e 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -487,6 +487,8 @@ predicate nodeIsHidden(Node node) { or node instanceof FlowSummaryNode or + node instanceof FlowSummaryDynamicParameterArrayNode + or node instanceof FlowSummaryIntermediateAwaitStoreNode or node instanceof CaptureNode @@ -499,6 +501,18 @@ predicate nodeIsHidden(Node node) { node.(DataFlow::ExprPostUpdateNode).getExpr() instanceof Function or node instanceof GenericSynthesizedNode + or + node instanceof StaticArgumentArrayNode + or + node instanceof DynamicArgumentArrayNode + or + node instanceof DynamicArgumentStoreNode + or + node instanceof StaticParameterArrayNode + or + node instanceof DynamicParameterArrayNode + or + node instanceof RestParameterStoreNode } predicate neverSkipInPathGraph(Node node) { From 079a622cf99c7341a2d39efcfe04356fc58e2cd9 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 14 Aug 2024 12:02:58 +0200 Subject: [PATCH 245/514] JS: Add tests showing missing taint flow When the spread argument itself is tained and not inside any content, the read steps currently fail to propagate the data. --- .../ql/test/library-tests/TripleDot/tst.js | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/javascript/ql/test/library-tests/TripleDot/tst.js b/javascript/ql/test/library-tests/TripleDot/tst.js index 3206ad657d0..aa53a49bb8e 100644 --- a/javascript/ql/test/library-tests/TripleDot/tst.js +++ b/javascript/ql/test/library-tests/TripleDot/tst.js @@ -112,3 +112,29 @@ function t10() { } target(source('t10.1'), source('t10.2'), source('t10.3')); } + +function t11() { + function target(x, y) { + sink(x); // $ MISSING: hasTaintFlow=t11.1 + sink(y); // $ MISSING: hasTaintFlow=t11.1 + } + target(...source('t11.1')); +} + +function t12() { + function target(x, y) { + sink(x); + sink(y); // $ MISSING: hasTaintFlow=t12.1 + } + target("safe", ...source('t12.1')); +} + +function t13() { + function target(x, y, ...rest) { + sink(x); + sink(y); // $ MISSING: hasTaintFlow=t13.1 + sink(rest); // $ MISSING: hasTaintFlow=t13.1 + sink(rest[0]); // $ MISSING: hasTaintFlow=t13.1 + } + target("safe", ...source('t13.1')); +} From 895cb872ada8427a856a104207b86df85d40081a Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 14 Aug 2024 13:13:58 +0200 Subject: [PATCH 246/514] JS: Add taint into dynamic argument array --- .../dataflow/internal/TaintTrackingPrivate.qll | 8 ++++++++ javascript/ql/test/library-tests/TripleDot/tst.js | 12 ++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index 7b4d8a8e94b..400640f6945 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -1,5 +1,6 @@ private import javascript private import semmle.javascript.dataflow.internal.DataFlowPrivate +private import semmle.javascript.dataflow.internal.DataFlowNode private import semmle.javascript.dataflow.internal.Contents::Public private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as FlowSummaryImpl private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate @@ -18,6 +19,13 @@ predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) or FlowSummaryPrivate::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), ContentSet::arrayElement(), node2.(FlowSummaryNode).getSummaryNode()) + or + // If the spread argument itself is tainted (not inside a content), store it into the dynamic argument array. + exists(InvokeExpr invoke, Content c | + node1 = TValueNode(invoke.getAnArgument().stripParens().(SpreadElement).getOperand()) and + node2 = TDynamicArgumentStoreNode(invoke, c) and + c.isUnknownArrayElement() + ) } predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2, string model) { diff --git a/javascript/ql/test/library-tests/TripleDot/tst.js b/javascript/ql/test/library-tests/TripleDot/tst.js index aa53a49bb8e..1a0f000fd50 100644 --- a/javascript/ql/test/library-tests/TripleDot/tst.js +++ b/javascript/ql/test/library-tests/TripleDot/tst.js @@ -115,24 +115,24 @@ function t10() { function t11() { function target(x, y) { - sink(x); // $ MISSING: hasTaintFlow=t11.1 - sink(y); // $ MISSING: hasTaintFlow=t11.1 + sink(x); // $ hasTaintFlow=t11.1 + sink(y); // $ hasTaintFlow=t11.1 } target(...source('t11.1')); } function t12() { function target(x, y) { - sink(x); - sink(y); // $ MISSING: hasTaintFlow=t12.1 + sink(x); // $ SPURIOUS: hasTaintFlow=t12.1 + sink(y); // $ hasTaintFlow=t12.1 } target("safe", ...source('t12.1')); } function t13() { function target(x, y, ...rest) { - sink(x); - sink(y); // $ MISSING: hasTaintFlow=t13.1 + sink(x); // $ SPURIOUS: hasTaintFlow=t13.1 + sink(y); // $ hasTaintFlow=t13.1 sink(rest); // $ MISSING: hasTaintFlow=t13.1 sink(rest[0]); // $ MISSING: hasTaintFlow=t13.1 } From 5084d0260f822aefbe2ebbf1fc9a7365e16a4a29 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 14 Aug 2024 14:02:56 +0200 Subject: [PATCH 247/514] Update tests.expected The 'arguments' node is only materialised for functions that use 'arguments --- .../library-tests/DataFlow/tests.expected | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/javascript/ql/test/library-tests/DataFlow/tests.expected b/javascript/ql/test/library-tests/DataFlow/tests.expected index 3b127d2dfa0..8d333f1b9e0 100644 --- a/javascript/ql/test/library-tests/DataFlow/tests.expected +++ b/javascript/ql/test/library-tests/DataFlow/tests.expected @@ -15,7 +15,6 @@ basicBlock | arguments.js:1:1:12:4 | (functi ... );\\n})() | arguments.js:1:1:1:0 | entry node of | | arguments.js:1:1:12:4 | exceptional return of (functi ... );\\n})() | arguments.js:1:1:1:0 | entry node of | | arguments.js:1:2:1:1 | this | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} | -| arguments.js:1:2:12:1 | 'arguments' object of anonymous function | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} | | arguments.js:1:2:12:1 | [function self-reference] functio ... , 3);\\n} | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} | | arguments.js:1:2:12:1 | exceptional return of anonymous function | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} | | arguments.js:1:2:12:1 | functio ... , 3);\\n} | arguments.js:1:1:1:0 | entry node of | @@ -70,7 +69,6 @@ basicBlock | arguments.js:11:13:11:13 | 3 | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} | | eval.js:1:1:1:0 | this | eval.js:1:1:1:0 | entry node of | | eval.js:1:1:1:0 | this | eval.js:1:1:1:0 | entry node of functio ... eval`\\n} | -| eval.js:1:1:5:1 | 'arguments' object of function k | eval.js:1:1:1:0 | entry node of functio ... eval`\\n} | | eval.js:1:1:5:1 | [function self-reference] functio ... eval`\\n} | eval.js:1:1:1:0 | entry node of functio ... eval`\\n} | | eval.js:1:1:5:1 | exceptional return of function k | eval.js:1:1:1:0 | entry node of functio ... eval`\\n} | | eval.js:1:1:5:1 | functio ... eval`\\n} | eval.js:1:1:1:0 | entry node of | @@ -91,7 +89,6 @@ basicBlock | sources.js:1:5:1:12 | (x => x) | sources.js:1:1:1:0 | entry node of | | sources.js:1:6:1:6 | x | sources.js:1:6:1:5 | entry node of x => x | | sources.js:1:6:1:6 | x | sources.js:1:6:1:5 | entry node of x => x | -| sources.js:1:6:1:11 | 'arguments' object of anonymous function | sources.js:1:6:1:5 | entry node of x => x | | sources.js:1:6:1:11 | [function self-reference] x => x | sources.js:1:6:1:5 | entry node of x => x | | sources.js:1:6:1:11 | exceptional return of anonymous function | sources.js:1:6:1:5 | entry node of x => x | | sources.js:1:6:1:11 | return of anonymous function | sources.js:1:6:1:5 | entry node of x => x | @@ -101,7 +98,6 @@ basicBlock | sources.js:3:1:5:6 | (functi ... \\n})(23) | sources.js:1:1:1:0 | entry node of | | sources.js:3:1:5:6 | exceptional return of (functi ... \\n})(23) | sources.js:1:1:1:0 | entry node of | | sources.js:3:2:3:1 | this | sources.js:3:2:3:1 | entry node of functio ... x+19;\\n} | -| sources.js:3:2:5:1 | 'arguments' object of anonymous function | sources.js:3:2:3:1 | entry node of functio ... x+19;\\n} | | sources.js:3:2:5:1 | [function self-reference] functio ... x+19;\\n} | sources.js:3:2:3:1 | entry node of functio ... x+19;\\n} | | sources.js:3:2:5:1 | exceptional return of anonymous function | sources.js:3:2:3:1 | entry node of functio ... x+19;\\n} | | sources.js:3:2:5:1 | functio ... x+19;\\n} | sources.js:1:1:1:0 | entry node of | @@ -114,7 +110,6 @@ basicBlock | sources.js:5:4:5:5 | 23 | sources.js:1:1:1:0 | entry node of | | sources.js:7:1:7:3 | /x/ | sources.js:1:1:1:0 | entry node of | | sources.js:9:1:9:0 | this | sources.js:9:1:9:0 | entry node of functio ... ey; }\\n} | -| sources.js:9:1:12:1 | 'arguments' object of function foo | sources.js:9:1:9:0 | entry node of functio ... ey; }\\n} | | sources.js:9:1:12:1 | [function self-reference] functio ... ey; }\\n} | sources.js:9:1:9:0 | entry node of functio ... ey; }\\n} | | sources.js:9:1:12:1 | exceptional return of function foo | sources.js:12:2:12:1 | exit node of functio ... ey; }\\n} | | sources.js:9:1:12:1 | functio ... ey; }\\n} | sources.js:1:1:1:0 | entry node of | @@ -152,7 +147,6 @@ basicBlock | tst2.ts:4:3:4:3 | x | tst2.ts:1:1:1:0 | entry node of | | tst2.ts:7:1:7:0 | A | tst2.ts:7:1:7:0 | entry node of functio ... = 23;\\n} | | tst2.ts:7:1:7:0 | this | tst2.ts:7:1:7:0 | entry node of functio ... = 23;\\n} | -| tst2.ts:7:1:9:1 | 'arguments' object of function setX | tst2.ts:7:1:7:0 | entry node of functio ... = 23;\\n} | | tst2.ts:7:1:9:1 | [function self-reference] functio ... = 23;\\n} | tst2.ts:7:1:7:0 | entry node of functio ... = 23;\\n} | | tst2.ts:7:1:9:1 | exceptional return of function setX | tst2.ts:7:1:7:0 | entry node of functio ... = 23;\\n} | | tst2.ts:7:1:9:1 | functio ... = 23;\\n} | tst2.ts:1:1:1:0 | entry node of | @@ -174,7 +168,6 @@ basicBlock | tst2.ts:13:7:13:16 | StringList | tst2.ts:1:1:1:0 | entry node of | | tst2.ts:13:26:13:29 | List | tst2.ts:1:1:1:0 | entry node of | | tst2.ts:13:26:13:37 | List | tst2.ts:1:1:1:0 | entry node of | -| tst2.ts:13:39:13:38 | 'arguments' object of default constructor of class StringList | tst2.ts:13:39:13:38 | entry node of (...arg ... rgs); } | | tst2.ts:13:39:13:38 | (...arg ... rgs); } | tst2.ts:1:1:1:0 | entry node of | | tst2.ts:13:39:13:38 | ...args | tst2.ts:13:39:13:38 | entry node of (...arg ... rgs); } | | tst2.ts:13:39:13:38 | [function self-reference] (...arg ... rgs); } | tst2.ts:13:39:13:38 | entry node of (...arg ... rgs); } | @@ -243,7 +236,6 @@ basicBlock | tst.js:16:1:20:9 | (functi ... ("arg") | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:16:1:20:9 | exceptional return of (functi ... ("arg") | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:16:2:16:1 | this | tst.js:16:2:16:1 | entry node of functio ... n "";\\n} | -| tst.js:16:2:20:1 | 'arguments' object of function f | tst.js:16:2:16:1 | entry node of functio ... n "";\\n} | | tst.js:16:2:20:1 | [function self-reference] functio ... n "";\\n} | tst.js:16:2:16:1 | entry node of functio ... n "";\\n} | | tst.js:16:2:20:1 | exceptional return of function f | tst.js:20:2:20:1 | exit node of functio ... n "";\\n} | | tst.js:16:2:20:1 | functio ... n "";\\n} | tst.js:16:1:20:10 | (functi ... "arg"); | @@ -278,7 +270,6 @@ basicBlock | tst.js:28:1:30:3 | (() =>\\n ... les\\n)() | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:28:1:30:3 | exceptional return of (() =>\\n ... les\\n)() | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:28:2:28:1 | x | tst.js:28:2:28:1 | entry node of () =>\\n x | -| tst.js:28:2:29:3 | 'arguments' object of anonymous function | tst.js:28:2:28:1 | entry node of () =>\\n x | | tst.js:28:2:29:3 | () =>\\n x | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:28:2:29:3 | [function self-reference] () =>\\n x | tst.js:28:2:28:1 | entry node of () =>\\n x | | tst.js:28:2:29:3 | exceptional return of anonymous function | tst.js:28:2:28:1 | entry node of () =>\\n x | @@ -286,7 +277,6 @@ basicBlock | tst.js:29:3:29:3 | x | tst.js:28:2:28:1 | entry node of () =>\\n x | | tst.js:32:1:32:0 | this | tst.js:32:1:32:0 | entry node of functio ... ables\\n} | | tst.js:32:1:32:0 | x | tst.js:32:1:32:0 | entry node of functio ... ables\\n} | -| tst.js:32:1:34:1 | 'arguments' object of function g | tst.js:32:1:32:0 | entry node of functio ... ables\\n} | | tst.js:32:1:34:1 | [function self-reference] functio ... ables\\n} | tst.js:32:1:32:0 | entry node of functio ... ables\\n} | | tst.js:32:1:34:1 | exceptional return of function g | tst.js:32:1:32:0 | entry node of functio ... ables\\n} | | tst.js:32:1:34:1 | functio ... ables\\n} | tst.js:16:1:20:10 | (functi ... "arg"); | @@ -311,7 +301,6 @@ basicBlock | tst.js:39:3:41:3 | m() {\\n this;\\n } | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:39:3:41:3 | m() {\\n this;\\n } | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:39:4:39:3 | this | tst.js:39:4:39:3 | entry node of () {\\n this;\\n } | -| tst.js:39:4:41:3 | 'arguments' object of method m | tst.js:39:4:39:3 | entry node of () {\\n this;\\n } | | tst.js:39:4:41:3 | () {\\n this;\\n } | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:39:4:41:3 | [function self-reference] () {\\n this;\\n } | tst.js:39:4:39:3 | entry node of () {\\n this;\\n } | | tst.js:39:4:41:3 | exceptional return of method m | tst.js:39:4:39:3 | entry node of () {\\n this;\\n } | @@ -337,7 +326,6 @@ basicBlock | tst.js:50:3:53:3 | constru ... et`\\n } | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:50:3:53:3 | constru ... et`\\n } | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:50:14:50:13 | this | tst.js:50:14:50:13 | entry node of () {\\n ... et`\\n } | -| tst.js:50:14:53:3 | 'arguments' object of constructor of class A | tst.js:50:14:50:13 | entry node of () {\\n ... et`\\n } | | tst.js:50:14:53:3 | () {\\n ... et`\\n } | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:50:14:53:3 | [function self-reference] () {\\n ... et`\\n } | tst.js:50:14:50:13 | entry node of () {\\n ... et`\\n } | | tst.js:50:14:53:3 | exceptional return of constructor of class A | tst.js:50:14:50:13 | entry node of () {\\n ... et`\\n } | @@ -365,7 +353,6 @@ basicBlock | tst.js:62:1:62:4 | o::g | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:62:4:62:4 | g | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:64:1:64:0 | this | tst.js:64:1:64:0 | entry node of functio ... lysed\\n} | -| tst.js:64:1:67:1 | 'arguments' object of function h | tst.js:64:1:64:0 | entry node of functio ... lysed\\n} | | tst.js:64:1:67:1 | [function self-reference] functio ... lysed\\n} | tst.js:64:1:64:0 | entry node of functio ... lysed\\n} | | tst.js:64:1:67:1 | exceptional return of function h | tst.js:64:1:64:0 | entry node of functio ... lysed\\n} | | tst.js:64:1:67:1 | functio ... lysed\\n} | tst.js:16:1:20:10 | (functi ... "arg"); | @@ -390,7 +377,6 @@ basicBlock | tst.js:69:6:69:9 | next | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:69:11:69:12 | 23 | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:71:1:71:0 | this | tst.js:71:1:71:0 | entry node of async f ... lysed\\n} | -| tst.js:71:1:73:1 | 'arguments' object of function k | tst.js:71:1:71:0 | entry node of async f ... lysed\\n} | | tst.js:71:1:73:1 | [function self-reference] async f ... lysed\\n} | tst.js:71:1:71:0 | entry node of async f ... lysed\\n} | | tst.js:71:1:73:1 | async f ... lysed\\n} | tst.js:16:1:20:10 | (functi ... "arg"); | | tst.js:71:1:73:1 | exceptional return of function k | tst.js:71:1:71:0 | entry node of async f ... lysed\\n} | @@ -434,7 +420,6 @@ basicBlock | tst.js:87:1:96:2 | (functi ... r: 0\\n}) | tst.js:85:5:85:28 | vs2 = ( ... o) v ) | | tst.js:87:1:96:2 | exceptional return of (functi ... r: 0\\n}) | tst.js:85:5:85:28 | vs2 = ( ... o) v ) | | tst.js:87:2:87:1 | this | tst.js:87:2:87:1 | entry node of functio ... + z;\\n} | -| tst.js:87:2:92:1 | 'arguments' object of anonymous function | tst.js:87:2:87:1 | entry node of functio ... + z;\\n} | | tst.js:87:2:92:1 | [function self-reference] functio ... + z;\\n} | tst.js:87:2:87:1 | entry node of functio ... + z;\\n} | | tst.js:87:2:92:1 | exceptional return of anonymous function | tst.js:87:2:87:1 | entry node of functio ... + z;\\n} | | tst.js:87:2:92:1 | functio ... + z;\\n} | tst.js:85:5:85:28 | vs2 = ( ... o) v ) | @@ -489,7 +474,6 @@ basicBlock | tst.js:98:1:103:17 | (functi ... 3, 0 ]) | tst.js:85:5:85:28 | vs2 = ( ... o) v ) | | tst.js:98:1:103:17 | exceptional return of (functi ... 3, 0 ]) | tst.js:85:5:85:28 | vs2 = ( ... o) v ) | | tst.js:98:2:98:1 | this | tst.js:98:2:98:1 | entry node of functio ... + z;\\n} | -| tst.js:98:2:103:1 | 'arguments' object of anonymous function | tst.js:98:2:98:1 | entry node of functio ... + z;\\n} | | tst.js:98:2:103:1 | [function self-reference] functio ... + z;\\n} | tst.js:98:2:98:1 | entry node of functio ... + z;\\n} | | tst.js:98:2:103:1 | exceptional return of anonymous function | tst.js:98:2:98:1 | entry node of functio ... + z;\\n} | | tst.js:98:2:103:1 | functio ... + z;\\n} | tst.js:85:5:85:28 | vs2 = ( ... o) v ) | @@ -532,7 +516,6 @@ basicBlock | tst.js:105:6:105:6 | y | tst.js:105:6:105:6 | y | | tst.js:107:1:113:2 | (functi ... v2c;\\n}) | tst.js:107:1:113:3 | (functi ... 2c;\\n}); | | tst.js:107:2:107:1 | this | tst.js:107:2:107:1 | entry node of functio ... v2c;\\n} | -| tst.js:107:2:113:1 | 'arguments' object of anonymous function | tst.js:107:2:107:1 | entry node of functio ... v2c;\\n} | | tst.js:107:2:113:1 | [function self-reference] functio ... v2c;\\n} | tst.js:107:2:107:1 | entry node of functio ... v2c;\\n} | | tst.js:107:2:113:1 | exceptional return of anonymous function | tst.js:107:2:107:1 | entry node of functio ... v2c;\\n} | | tst.js:107:2:113:1 | functio ... v2c;\\n} | tst.js:107:1:113:3 | (functi ... 2c;\\n}); | @@ -1479,7 +1462,6 @@ sources | arguments.js:1:1:1:0 | this | | arguments.js:1:1:12:4 | (functi ... );\\n})() | | arguments.js:1:2:1:1 | this | -| arguments.js:1:2:12:1 | 'arguments' object of anonymous function | | arguments.js:1:2:12:1 | functio ... , 3);\\n} | | arguments.js:1:2:12:1 | return of anonymous function | | arguments.js:2:5:2:4 | this | @@ -1495,7 +1477,6 @@ sources | arguments.js:11:5:11:14 | f(1, 2, 3) | | eval.js:1:1:1:0 | this | | eval.js:1:1:1:0 | this | -| eval.js:1:1:5:1 | 'arguments' object of function k | | eval.js:1:1:5:1 | functio ... eval`\\n} | | eval.js:1:1:5:1 | return of function k | | eval.js:3:3:3:6 | eval | @@ -1505,18 +1486,15 @@ sources | sources.js:1:1:1:0 | this | | sources.js:1:1:1:12 | new (x => x) | | sources.js:1:6:1:6 | x | -| sources.js:1:6:1:11 | 'arguments' object of anonymous function | | sources.js:1:6:1:11 | return of anonymous function | | sources.js:1:6:1:11 | x => x | | sources.js:3:1:5:6 | (functi ... \\n})(23) | | sources.js:3:2:3:1 | this | -| sources.js:3:2:5:1 | 'arguments' object of anonymous function | | sources.js:3:2:5:1 | functio ... x+19;\\n} | | sources.js:3:2:5:1 | return of anonymous function | | sources.js:3:11:3:11 | x | | sources.js:7:1:7:3 | /x/ | | sources.js:9:1:9:0 | this | -| sources.js:9:1:12:1 | 'arguments' object of function foo | | sources.js:9:1:12:1 | functio ... ey; }\\n} | | sources.js:9:1:12:1 | return of function foo | | sources.js:9:14:9:18 | array | @@ -1526,14 +1504,12 @@ sources | tst2.ts:1:1:1:0 | this | | tst2.ts:3:3:3:8 | setX() | | tst2.ts:7:1:7:0 | this | -| tst2.ts:7:1:9:1 | 'arguments' object of function setX | | tst2.ts:7:1:9:1 | functio ... = 23;\\n} | | tst2.ts:7:1:9:1 | return of function setX | | tst2.ts:8:3:8:5 | A.x | | tst2.ts:11:11:11:13 | A.x | | tst2.ts:13:1:13:40 | class S ... ing> {} | | tst2.ts:13:26:13:29 | List | -| tst2.ts:13:39:13:38 | 'arguments' object of default constructor of class StringList | | tst2.ts:13:39:13:38 | (...arg ... rgs); } | | tst2.ts:13:39:13:38 | args | | tst2.ts:13:39:13:38 | return of default constructor of class StringList | @@ -1547,7 +1523,6 @@ sources | tst.js:4:9:4:12 | "hi" | | tst.js:16:1:20:9 | (functi ... ("arg") | | tst.js:16:2:16:1 | this | -| tst.js:16:2:20:1 | 'arguments' object of function f | | tst.js:16:2:20:1 | functio ... n "";\\n} | | tst.js:16:2:20:1 | return of function f | | tst.js:16:13:16:13 | a | @@ -1558,18 +1533,15 @@ sources | tst.js:20:4:20:8 | "arg" | | tst.js:22:7:22:18 | readFileSync | | tst.js:28:1:30:3 | (() =>\\n ... les\\n)() | -| tst.js:28:2:29:3 | 'arguments' object of anonymous function | | tst.js:28:2:29:3 | () =>\\n x | | tst.js:28:2:29:3 | return of anonymous function | | tst.js:32:1:32:0 | this | -| tst.js:32:1:34:1 | 'arguments' object of function g | | tst.js:32:1:34:1 | functio ... ables\\n} | | tst.js:32:1:34:1 | return of function g | | tst.js:32:12:32:12 | b | | tst.js:35:1:35:7 | g(true) | | tst.js:37:9:42:1 | {\\n x: ... ;\\n }\\n} | | tst.js:39:4:39:3 | this | -| tst.js:39:4:41:3 | 'arguments' object of method m | | tst.js:39:4:41:3 | () {\\n this;\\n } | | tst.js:39:4:41:3 | return of method m | | tst.js:43:1:43:3 | o.x | @@ -1581,7 +1553,6 @@ sources | tst.js:49:1:54:1 | class A ... `\\n }\\n} | | tst.js:49:17:49:17 | B | | tst.js:50:14:50:13 | this | -| tst.js:50:14:53:3 | 'arguments' object of constructor of class A | | tst.js:50:14:53:3 | () {\\n ... et`\\n } | | tst.js:50:14:53:3 | return of constructor of class A | | tst.js:51:5:51:13 | super(42) | @@ -1591,7 +1562,6 @@ sources | tst.js:61:3:61:5 | o.m | | tst.js:62:1:62:4 | o::g | | tst.js:64:1:64:0 | this | -| tst.js:64:1:67:1 | 'arguments' object of function h | | tst.js:64:1:67:1 | functio ... lysed\\n} | | tst.js:64:1:67:1 | return of function h | | tst.js:65:3:65:10 | yield 42 | @@ -1600,7 +1570,6 @@ sources | tst.js:69:1:69:9 | iter.next | | tst.js:69:1:69:13 | iter.next(23) | | tst.js:71:1:71:0 | this | -| tst.js:71:1:73:1 | 'arguments' object of function k | | tst.js:71:1:73:1 | async f ... lysed\\n} | | tst.js:71:1:73:1 | return of function k | | tst.js:72:3:72:11 | await p() | @@ -1613,7 +1582,6 @@ sources | tst.js:85:11:85:28 | ( for (v of o) v ) | | tst.js:87:1:96:2 | (functi ... r: 0\\n}) | | tst.js:87:2:87:1 | this | -| tst.js:87:2:92:1 | 'arguments' object of anonymous function | | tst.js:87:2:92:1 | functio ... + z;\\n} | | tst.js:87:2:92:1 | return of anonymous function | | tst.js:87:11:87:24 | { p: x, ...o } | @@ -1624,7 +1592,6 @@ sources | tst.js:92:4:96:1 | {\\n p: ... r: 0\\n} | | tst.js:98:1:103:17 | (functi ... 3, 0 ]) | | tst.js:98:2:98:1 | this | -| tst.js:98:2:103:1 | 'arguments' object of anonymous function | | tst.js:98:2:103:1 | functio ... + z;\\n} | | tst.js:98:2:103:1 | return of anonymous function | | tst.js:98:11:98:24 | [ x, ...rest ] | @@ -1634,7 +1601,6 @@ sources | tst.js:101:7:101:7 | z | | tst.js:103:4:103:16 | [ 19, 23, 0 ] | | tst.js:107:2:107:1 | this | -| tst.js:107:2:113:1 | 'arguments' object of anonymous function | | tst.js:107:2:113:1 | functio ... v2c;\\n} | | tst.js:107:2:113:1 | return of anonymous function | | tst.js:108:7:108:9 | v1a | From ac1dd1850e39ee45954e9990dd28dc37692c57c8 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 14 Aug 2024 14:33:52 +0200 Subject: [PATCH 248/514] JS: Remove taint step from array element to whole array --- .../javascript/dataflow/TaintTracking.qll | 12 ++++++---- .../TaintTracking/BasicTaintTracking.expected | 22 ++++++++++--------- .../TaintTracking/DataFlowTracking.expected | 2 ++ .../TaintTracking/arrays-init.js | 10 ++++----- .../library-tests/TaintTracking/call-apply.js | 6 ++--- 5 files changed, 30 insertions(+), 22 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 2574660fbeb..e6eccf6097d 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -260,6 +260,14 @@ module TaintTracking { ) } + private class HeapLegacyTaintStep extends LegacyTaintStep { + override predicate heapStep(DataFlow::Node pred, DataFlow::Node succ) { + // arrays with tainted elements are tainted (in old data flow) + succ.(DataFlow::ArrayCreationNode).getAnElement() = pred and + not any(PromiseAllCreation call).getArrayNode() = succ + } + } + /** * A taint propagating data flow edge through object or array elements and * promises. @@ -274,10 +282,6 @@ module TaintTracking { // spreading a tainted value into an array literal gives a tainted array succ.(DataFlow::ArrayCreationNode).getASpreadArgument() = pred or - // arrays with tainted elements and objects with tainted property names are tainted - succ.(DataFlow::ArrayCreationNode).getAnElement() = pred and - not any(PromiseAllCreation call).getArrayNode() = succ - or // reading from a tainted object yields a tainted result succ.(DataFlow::PropRead).getBase() = pred and not ( diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 91a7f386516..57699721a37 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -1,5 +1,17 @@ legacyDataFlowDifference +| array-mutation.js:31:33:31:40 | source() | array-mutation.js:32:8:32:8 | h | only flow with OLD data flow library | +| array-mutation.js:35:36:35:43 | source() | array-mutation.js:36:8:36:8 | i | only flow with OLD data flow library | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:27:8:27:13 | arr[0] | only flow with OLD data flow library | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:33:8:33:13 | arr[0] | only flow with OLD data flow library | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:35:8:35:13 | arr[2] | only flow with OLD data flow library | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:36:8:36:13 | arr[3] | only flow with OLD data flow library | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:37:8:37:13 | arr[4] | only flow with OLD data flow library | | bound-function.js:27:8:27:15 | source() | bound-function.js:30:10:30:10 | y | only flow with OLD data flow library | +| call-apply.js:27:14:27:21 | source() | call-apply.js:24:8:24:11 | arg1 | only flow with NEW data flow library | +| call-apply.js:27:14:27:21 | source() | call-apply.js:32:6:32:35 | foo1.ap ... e, ""]) | only flow with NEW data flow library | +| call-apply.js:27:14:27:21 | source() | call-apply.js:34:6:34:29 | foo1_ap ... e, ""]) | only flow with NEW data flow library | +| call-apply.js:27:14:27:21 | source() | call-apply.js:41:6:41:28 | foo1_ca ... ource]) | only flow with OLD data flow library | +| call-apply.js:27:14:27:21 | source() | call-apply.js:59:10:59:21 | arguments[1] | only flow with OLD data flow library | | call-apply.js:45:8:45:15 | source() | call-apply.js:55:6:55:13 | foo(obj) | only flow with NEW data flow library | | callbacks.js:37:17:37:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | | callbacks.js:37:17:37:24 | source() | callbacks.js:41:10:41:10 | x | only flow with NEW data flow library | @@ -35,18 +47,11 @@ flow | array-mutation.js:19:18:19:25 | source() | array-mutation.js:20:8:20:8 | e | | array-mutation.js:23:13:23:20 | source() | array-mutation.js:24:8:24:8 | f | | array-mutation.js:27:16:27:23 | source() | array-mutation.js:28:8:28:8 | g | -| array-mutation.js:31:33:31:40 | source() | array-mutation.js:32:8:32:8 | h | -| array-mutation.js:35:36:35:43 | source() | array-mutation.js:36:8:36:8 | i | | array-mutation.js:39:17:39:24 | source() | array-mutation.js:40:8:40:8 | j | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:17:8:17:13 | arr[1] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:22:8:22:13 | arr[6] | -| arrays-init.js:2:16:2:23 | source() | arrays-init.js:27:8:27:13 | arr[0] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:28:8:28:13 | arr[1] | -| arrays-init.js:2:16:2:23 | source() | arrays-init.js:33:8:33:13 | arr[0] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:34:8:34:13 | arr[1] | -| arrays-init.js:2:16:2:23 | source() | arrays-init.js:35:8:35:13 | arr[2] | -| arrays-init.js:2:16:2:23 | source() | arrays-init.js:36:8:36:13 | arr[3] | -| arrays-init.js:2:16:2:23 | source() | arrays-init.js:37:8:37:13 | arr[4] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:38:8:38:13 | arr[5] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:43:10:43:15 | arr[i] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:55:10:55:15 | arr[i] | @@ -69,11 +74,8 @@ flow | call-apply.js:27:14:27:21 | source() | call-apply.js:24:8:24:11 | arg1 | | call-apply.js:27:14:27:21 | source() | call-apply.js:29:6:29:32 | foo1.ca ... ce, "") | | call-apply.js:27:14:27:21 | source() | call-apply.js:32:6:32:35 | foo1.ap ... e, ""]) | -| call-apply.js:27:14:27:21 | source() | call-apply.js:33:6:33:35 | foo2.ap ... e, ""]) | | call-apply.js:27:14:27:21 | source() | call-apply.js:34:6:34:29 | foo1_ap ... e, ""]) | | call-apply.js:27:14:27:21 | source() | call-apply.js:40:6:40:28 | foo1_ca ... e, ""]) | -| call-apply.js:27:14:27:21 | source() | call-apply.js:41:6:41:28 | foo1_ca ... ource]) | -| call-apply.js:27:14:27:21 | source() | call-apply.js:59:10:59:21 | arguments[1] | | call-apply.js:27:14:27:21 | source() | call-apply.js:62:10:62:21 | arguments[0] | | call-apply.js:45:8:45:15 | source() | call-apply.js:55:6:55:13 | foo(obj) | | call-apply.js:81:17:81:24 | source() | call-apply.js:78:8:78:11 | this | diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected index de977a8ff92..18ff982fa1e 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected @@ -1,6 +1,8 @@ legacyDataFlowDifference | arrays-init.js:2:16:2:23 | source() | arrays-init.js:38:8:38:13 | arr[5] | only flow with NEW data flow library | | bound-function.js:27:8:27:15 | source() | bound-function.js:30:10:30:10 | y | only flow with OLD data flow library | +| call-apply.js:27:14:27:21 | source() | call-apply.js:24:8:24:11 | arg1 | only flow with NEW data flow library | +| call-apply.js:27:14:27:21 | source() | call-apply.js:32:6:32:35 | foo1.ap ... e, ""]) | only flow with NEW data flow library | | call-apply.js:27:14:27:21 | source() | call-apply.js:34:6:34:29 | foo1_ap ... e, ""]) | only flow with NEW data flow library | | call-apply.js:45:8:45:15 | source() | call-apply.js:55:6:55:13 | foo(obj) | only flow with NEW data flow library | | callbacks.js:37:17:37:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | diff --git a/javascript/ql/test/library-tests/TaintTracking/arrays-init.js b/javascript/ql/test/library-tests/TaintTracking/arrays-init.js index a0f3839d275..7db1eaf682d 100644 --- a/javascript/ql/test/library-tests/TaintTracking/arrays-init.js +++ b/javascript/ql/test/library-tests/TaintTracking/arrays-init.js @@ -24,17 +24,17 @@ console.log("=== access by index (init by [...]) ==="); var arr = [str, source]; - sink(arr[0]); // OK [INCONSISTENCY] + sink(arr[0]); // OK sink(arr[1]); // NOT OK sink(str); // OK console.log("=== access by index (init by [...], array.lenght > 5) ==="); var arr = [str, source, 'b', 'c', 'd', source]; - sink(arr[0]); // OK [INCONSISTENCY] + sink(arr[0]); // OK sink(arr[1]); // NOT OK - sink(arr[2]); // OK [INCONSISTENCY] - sink(arr[3]); // OK [INCONSISTENCY] - sink(arr[4]); // OK [INCONSISTENCY] + sink(arr[2]); // OK + sink(arr[3]); // OK + sink(arr[4]); // OK sink(arr[5]); // NOT OK console.log("=== access in for (init by [...]) ==="); diff --git a/javascript/ql/test/library-tests/TaintTracking/call-apply.js b/javascript/ql/test/library-tests/TaintTracking/call-apply.js index 0782ad71bab..4ed1bba7b71 100644 --- a/javascript/ql/test/library-tests/TaintTracking/call-apply.js +++ b/javascript/ql/test/library-tests/TaintTracking/call-apply.js @@ -30,7 +30,7 @@ sink(foo1.call(null, source, "")); // NOT OK sink(foo2.call(null, source, "")); // OK sink(foo1.apply(null, [source, ""])); // NOT OK -sink(foo2.apply(null, [source, ""])); // OK [INCONSISTENCY] +sink(foo2.apply(null, [source, ""])); // OK sink(foo1_apply([source, ""])); // NOT OK foo1_apply_sink([source, ""]); // This works, because we don't need a return after a call (the sink is inside the called function). @@ -38,7 +38,7 @@ foo1_apply_sink([source, ""]); // This works, because we don't need a return aft sink(foo1_apply.apply(["", source])); // OK sink(foo1_call([source, ""])); // NOT OK -sink(foo1_call(["", source])); // OK [INCONSISTENCY] +sink(foo1_call(["", source])); // OK var obj = { @@ -56,7 +56,7 @@ sink(foo(obj)); // NOT OK function argumentsObject() { function sinkArguments1() { - sink(arguments[1]); // OK [INCONSISTENCY] + sink(arguments[1]); // OK } function sinkArguments0() { sink(arguments[0]); // NOT OK From 34e6864fa3bcb4bd4d5eee5623e9389598cc7b62 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 14 Aug 2024 14:34:55 +0200 Subject: [PATCH 249/514] JS: Note issue with .apply() calls --- .../javascript/dataflow/internal/TaintTrackingPrivate.qll | 1 + .../ql/test/library-tests/TaintTracking/array-mutation.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index 400640f6945..66c4fa2c60b 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -25,6 +25,7 @@ predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) node1 = TValueNode(invoke.getAnArgument().stripParens().(SpreadElement).getOperand()) and node2 = TDynamicArgumentStoreNode(invoke, c) and c.isUnknownArrayElement() + // TODO: we need a similar case for .apply() calls ) } diff --git a/javascript/ql/test/library-tests/TaintTracking/array-mutation.js b/javascript/ql/test/library-tests/TaintTracking/array-mutation.js index cc581d34a25..e58b6fd99a9 100644 --- a/javascript/ql/test/library-tests/TaintTracking/array-mutation.js +++ b/javascript/ql/test/library-tests/TaintTracking/array-mutation.js @@ -29,11 +29,11 @@ function test(x, y) { let h = []; Array.prototype.push.apply(h, source()); - sink(h); // NOT OK + sink(h); // NOT OK [INCONSISTENCY] let i = []; Array.prototype.unshift.apply(i, source()); - sink(i); // NOT OK + sink(i); // NOT OK [INCONSISTENCY] let j = []; j[j.length] = source(); From 4389b5c999638c3a6999d44da9898efe9c1bec5c Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 14 Aug 2024 14:51:22 +0200 Subject: [PATCH 250/514] JS: Fix issue for .apply() calls --- .../dataflow/internal/DataFlowNode.qll | 3 ++ .../dataflow/internal/DataFlowPrivate.qll | 28 +++++++++++++++++++ .../internal/TaintTrackingPrivate.qll | 7 ++++- .../TaintTracking/BasicTaintTracking.expected | 4 +-- .../TaintTracking/array-mutation.js | 4 +-- 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index 59e0b65e58f..cd027d00862 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -55,6 +55,9 @@ private module Cached { invoke.isSpreadArgument(_) and storeContent = dynamicArgumentsContent() } or + TApplyCallTaintNode(MethodCallExpr node) { + node.getMethodName() = "apply" and exists(node.getArgument(1)) + } or TDestructuredModuleImportNode(ImportDeclaration decl) { exists(decl.getASpecifier().getImportedName()) } or diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index d7791c0f59e..25fa75e0e71 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -197,6 +197,28 @@ class DynamicParameterArrayNode extends DataFlow::Node, TDynamicParameterArrayNo override Location getLocation() { result = function.getLocation() } } +/** + * Node with taint input from the second argument of `.apply()` and with a store edge back into that same argument. + * + * This ensures that if `.apply()` is called with a tainted value (not inside a content) the taint is + * boxed in an `ArrayElement` content. This is necessary for the target function to propagate the taint. + */ +class ApplyCallTaintNode extends DataFlow::Node, TApplyCallTaintNode { + private MethodCallExpr apply; + + ApplyCallTaintNode() { this = TApplyCallTaintNode(apply) } + + override StmtContainer getContainer() { result = apply.getContainer() } + + override string toString() { result = "[apply call taint node]" } + + override Location getLocation() { result = apply.getArgument(1).getLocation() } + + MethodCallExpr getMethodCallExpr() { result = apply } + + DataFlow::Node getArrayNode() { result = apply.getArgument(1).flow() } +} + cached newtype TReturnKind = MkNormalReturnKind() or @@ -1233,6 +1255,12 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { c.asArrayIndex() = n and not n >= firstSpreadArgumentIndex(invoke) ) + or + exists(ApplyCallTaintNode taintNode | + node1 = taintNode and + node2 = taintNode.getArrayNode() and + c = ContentSet::arrayElementUnknown() + ) } /** diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index 66c4fa2c60b..9d17da244c5 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -25,7 +25,12 @@ predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) node1 = TValueNode(invoke.getAnArgument().stripParens().(SpreadElement).getOperand()) and node2 = TDynamicArgumentStoreNode(invoke, c) and c.isUnknownArrayElement() - // TODO: we need a similar case for .apply() calls + ) + or + // If the array in an .apply() call is tainted (not inside a content), box it in an array element (similar to the case above). + exists(ApplyCallTaintNode taintNode | + node1 = taintNode.getArrayNode() and + node2 = taintNode ) } diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 57699721a37..fd2fb8bbc09 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -1,6 +1,4 @@ legacyDataFlowDifference -| array-mutation.js:31:33:31:40 | source() | array-mutation.js:32:8:32:8 | h | only flow with OLD data flow library | -| array-mutation.js:35:36:35:43 | source() | array-mutation.js:36:8:36:8 | i | only flow with OLD data flow library | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:27:8:27:13 | arr[0] | only flow with OLD data flow library | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:33:8:33:13 | arr[0] | only flow with OLD data flow library | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:35:8:35:13 | arr[2] | only flow with OLD data flow library | @@ -47,6 +45,8 @@ flow | array-mutation.js:19:18:19:25 | source() | array-mutation.js:20:8:20:8 | e | | array-mutation.js:23:13:23:20 | source() | array-mutation.js:24:8:24:8 | f | | array-mutation.js:27:16:27:23 | source() | array-mutation.js:28:8:28:8 | g | +| array-mutation.js:31:33:31:40 | source() | array-mutation.js:32:8:32:8 | h | +| array-mutation.js:35:36:35:43 | source() | array-mutation.js:36:8:36:8 | i | | array-mutation.js:39:17:39:24 | source() | array-mutation.js:40:8:40:8 | j | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:17:8:17:13 | arr[1] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:22:8:22:13 | arr[6] | diff --git a/javascript/ql/test/library-tests/TaintTracking/array-mutation.js b/javascript/ql/test/library-tests/TaintTracking/array-mutation.js index e58b6fd99a9..cc581d34a25 100644 --- a/javascript/ql/test/library-tests/TaintTracking/array-mutation.js +++ b/javascript/ql/test/library-tests/TaintTracking/array-mutation.js @@ -29,11 +29,11 @@ function test(x, y) { let h = []; Array.prototype.push.apply(h, source()); - sink(h); // NOT OK [INCONSISTENCY] + sink(h); // NOT OK let i = []; Array.prototype.unshift.apply(i, source()); - sink(i); // NOT OK [INCONSISTENCY] + sink(i); // NOT OK let j = []; j[j.length] = source(); From 4e7bd9ddd84353bb6a15f8a24384a3fa9f3bdfa3 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 19 Aug 2024 11:42:30 +0200 Subject: [PATCH 251/514] JS: Update Arrays test now that array elements do not taint the whole array --- .../library-tests/Arrays/DataFlow.expected | 2 + .../library-tests/Arrays/TaintFlow.expected | 7 +- .../ql/test/library-tests/Arrays/arrays.js | 6 +- .../library-tests/Arrays/printAst.expected | 372 ++++++++++-------- 4 files changed, 214 insertions(+), 173 deletions(-) diff --git a/javascript/ql/test/library-tests/Arrays/DataFlow.expected b/javascript/ql/test/library-tests/Arrays/DataFlow.expected index 340f5dbe230..21671a19464 100644 --- a/javascript/ql/test/library-tests/Arrays/DataFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/DataFlow.expected @@ -24,3 +24,5 @@ flow | arrays.js:29:21:29:28 | "source" | arrays.js:50:8:50:17 | arr6.pop() | | arrays.js:33:37:33:44 | "source" | arrays.js:35:8:35:25 | arr4_variant.pop() | | arrays.js:53:4:53:11 | "source" | arrays.js:54:10:54:18 | ary.pop() | +| arrays.js:96:9:96:16 | "source" | arrays.js:96:8:96:40 | ["sourc ... ).pop() | +| arrays.js:97:9:97:16 | "source" | arrays.js:97:8:97:42 | ["sourc ... ).pop() | diff --git a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected index 0f246a750bc..70f5b29403d 100644 --- a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected @@ -1,11 +1,11 @@ legacyDataFlowDifference -| arrays.js:2:16:2:23 | "source" | arrays.js:39:8:39:24 | arr4_spread.pop() | only flow with OLD data flow library | flow | arrays.js:2:16:2:23 | "source" | arrays.js:5:8:5:14 | obj.foo | | arrays.js:2:16:2:23 | "source" | arrays.js:11:10:11:15 | arr[i] | | arrays.js:2:16:2:23 | "source" | arrays.js:15:27:15:27 | e | | arrays.js:2:16:2:23 | "source" | arrays.js:16:23:16:23 | e | | arrays.js:2:16:2:23 | "source" | arrays.js:20:8:20:16 | arr.pop() | +| arrays.js:2:16:2:23 | "source" | arrays.js:39:8:39:24 | arr4_spread.pop() | | arrays.js:2:16:2:23 | "source" | arrays.js:58:8:58:13 | arr[0] | | arrays.js:2:16:2:23 | "source" | arrays.js:61:10:61:10 | x | | arrays.js:2:16:2:23 | "source" | arrays.js:65:10:65:10 | x | @@ -26,5 +26,6 @@ flow | arrays.js:33:37:33:44 | "source" | arrays.js:35:8:35:25 | arr4_variant.pop() | | arrays.js:53:4:53:11 | "source" | arrays.js:54:10:54:18 | ary.pop() | | arrays.js:53:4:53:11 | "source" | arrays.js:55:10:55:12 | ary | -| arrays.js:95:9:95:16 | "source" | arrays.js:95:8:95:34 | ["sourc ... ) => x) | -| arrays.js:96:9:96:16 | "source" | arrays.js:96:8:96:36 | ["sourc ... => !!x) | +| arrays.js:95:9:95:16 | "source" | arrays.js:95:8:95:17 | ["source"] | +| arrays.js:96:9:96:16 | "source" | arrays.js:96:8:96:40 | ["sourc ... ).pop() | +| arrays.js:97:9:97:16 | "source" | arrays.js:97:8:97:42 | ["sourc ... ).pop() | diff --git a/javascript/ql/test/library-tests/Arrays/arrays.js b/javascript/ql/test/library-tests/Arrays/arrays.js index 9806ec2e395..8c981a33a1f 100644 --- a/javascript/ql/test/library-tests/Arrays/arrays.js +++ b/javascript/ql/test/library-tests/Arrays/arrays.js @@ -92,6 +92,8 @@ sink(arr.at(-1)); // NOT OK - sink(["source"].filter((x) => x)); // NOT OK - sink(["source"].filter((x) => !!x)); // NOT OK + sink(["source"]); // OK - for now, array element do not taint the entire array + sink(["source"].filter((x) => x).pop()); // NOT OK + sink(["source"].filter((x) => !!x).pop()); // NOT OK + }); diff --git a/javascript/ql/test/library-tests/Arrays/printAst.expected b/javascript/ql/test/library-tests/Arrays/printAst.expected index 2d0fdb45863..dbbeccd38a8 100644 --- a/javascript/ql/test/library-tests/Arrays/printAst.expected +++ b/javascript/ql/test/library-tests/Arrays/printAst.expected @@ -1,9 +1,9 @@ nodes -| arrays.js:1:1:97:2 | [ParExpr] (functi ... T OK }) | semmle.label | [ParExpr] (functi ... T OK }) | -| arrays.js:1:1:97:3 | [ExprStmt] (functi ... OK }); | semmle.label | [ExprStmt] (functi ... OK }); | -| arrays.js:1:1:97:3 | [ExprStmt] (functi ... OK }); | semmle.order | 1 | -| arrays.js:1:2:97:1 | [FunctionExpr] functio ... OT OK } | semmle.label | [FunctionExpr] functio ... OT OK } | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | semmle.label | [BlockStmt] { let ... OT OK } | +| arrays.js:1:1:99:2 | [ParExpr] (functi ... OK }) | semmle.label | [ParExpr] (functi ... OK }) | +| arrays.js:1:1:99:3 | [ExprStmt] (functi ... OK }); | semmle.label | [ExprStmt] (functi ... OK }); | +| arrays.js:1:1:99:3 | [ExprStmt] (functi ... OK }); | semmle.order | 1 | +| arrays.js:1:2:99:1 | [FunctionExpr] functio ... T OK } | semmle.label | [FunctionExpr] functio ... T OK } | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | semmle.label | [BlockStmt] { let ... T OK } | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | [DeclStmt] let source = ... | | arrays.js:2:7:2:12 | [VarDecl] source | semmle.label | [VarDecl] source | | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.label | [VariableDeclarator] source = "source" | @@ -394,29 +394,41 @@ nodes | arrays.js:93:15:93:16 | [UnaryExpr] -1 | semmle.label | [UnaryExpr] -1 | | arrays.js:93:16:93:16 | [Literal] 1 | semmle.label | [Literal] 1 | | arrays.js:95:3:95:6 | [VarRef] sink | semmle.label | [VarRef] sink | -| arrays.js:95:3:95:35 | [CallExpr] sink([" ... => x)) | semmle.label | [CallExpr] sink([" ... => x)) | -| arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.label | [ExprStmt] sink([" ... => x)); | +| arrays.js:95:3:95:18 | [CallExpr] sink(["source"]) | semmle.label | [CallExpr] sink(["source"]) | +| arrays.js:95:3:95:19 | [ExprStmt] sink(["source"]); | semmle.label | [ExprStmt] sink(["source"]); | | arrays.js:95:8:95:17 | [ArrayExpr] ["source"] | semmle.label | [ArrayExpr] ["source"] | -| arrays.js:95:8:95:24 | [DotExpr] ["source"].filter | semmle.label | [DotExpr] ["source"].filter | -| arrays.js:95:8:95:34 | [MethodCallExpr] ["sourc ... ) => x) | semmle.label | [MethodCallExpr] ["sourc ... ) => x) | | arrays.js:95:9:95:16 | [Literal] "source" | semmle.label | [Literal] "source" | -| arrays.js:95:19:95:24 | [Label] filter | semmle.label | [Label] filter | -| arrays.js:95:26:95:33 | [ArrowFunctionExpr] (x) => x | semmle.label | [ArrowFunctionExpr] (x) => x | -| arrays.js:95:27:95:27 | [SimpleParameter] x | semmle.label | [SimpleParameter] x | -| arrays.js:95:33:95:33 | [VarRef] x | semmle.label | [VarRef] x | | arrays.js:96:3:96:6 | [VarRef] sink | semmle.label | [VarRef] sink | -| arrays.js:96:3:96:37 | [CallExpr] sink([" ... > !!x)) | semmle.label | [CallExpr] sink([" ... > !!x)) | -| arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.label | [ExprStmt] sink([" ... !!x)); | +| arrays.js:96:3:96:41 | [CallExpr] sink([" ... .pop()) | semmle.label | [CallExpr] sink([" ... .pop()) | +| arrays.js:96:3:96:42 | [ExprStmt] sink([" ... pop()); | semmle.label | [ExprStmt] sink([" ... pop()); | | arrays.js:96:8:96:17 | [ArrayExpr] ["source"] | semmle.label | [ArrayExpr] ["source"] | | arrays.js:96:8:96:24 | [DotExpr] ["source"].filter | semmle.label | [DotExpr] ["source"].filter | -| arrays.js:96:8:96:36 | [MethodCallExpr] ["sourc ... => !!x) | semmle.label | [MethodCallExpr] ["sourc ... => !!x) | +| arrays.js:96:8:96:34 | [MethodCallExpr] ["sourc ... ) => x) | semmle.label | [MethodCallExpr] ["sourc ... ) => x) | +| arrays.js:96:8:96:38 | [DotExpr] ["sourc ... x).pop | semmle.label | [DotExpr] ["sourc ... x).pop | +| arrays.js:96:8:96:40 | [MethodCallExpr] ["sourc ... ).pop() | semmle.label | [MethodCallExpr] ["sourc ... ).pop() | | arrays.js:96:9:96:16 | [Literal] "source" | semmle.label | [Literal] "source" | | arrays.js:96:19:96:24 | [Label] filter | semmle.label | [Label] filter | -| arrays.js:96:26:96:35 | [ArrowFunctionExpr] (x) => !!x | semmle.label | [ArrowFunctionExpr] (x) => !!x | +| arrays.js:96:26:96:33 | [ArrowFunctionExpr] (x) => x | semmle.label | [ArrowFunctionExpr] (x) => x | | arrays.js:96:27:96:27 | [SimpleParameter] x | semmle.label | [SimpleParameter] x | -| arrays.js:96:33:96:35 | [UnaryExpr] !!x | semmle.label | [UnaryExpr] !!x | -| arrays.js:96:34:96:35 | [UnaryExpr] !x | semmle.label | [UnaryExpr] !x | -| arrays.js:96:35:96:35 | [VarRef] x | semmle.label | [VarRef] x | +| arrays.js:96:33:96:33 | [VarRef] x | semmle.label | [VarRef] x | +| arrays.js:96:36:96:38 | [Label] pop | semmle.label | [Label] pop | +| arrays.js:97:3:97:6 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:97:3:97:43 | [CallExpr] sink([" ... .pop()) | semmle.label | [CallExpr] sink([" ... .pop()) | +| arrays.js:97:3:97:44 | [ExprStmt] sink([" ... pop()); | semmle.label | [ExprStmt] sink([" ... pop()); | +| arrays.js:97:8:97:17 | [ArrayExpr] ["source"] | semmle.label | [ArrayExpr] ["source"] | +| arrays.js:97:8:97:24 | [DotExpr] ["source"].filter | semmle.label | [DotExpr] ["source"].filter | +| arrays.js:97:8:97:36 | [MethodCallExpr] ["sourc ... => !!x) | semmle.label | [MethodCallExpr] ["sourc ... => !!x) | +| arrays.js:97:8:97:40 | [DotExpr] ["sourc ... !x).pop | semmle.label | [DotExpr] ["sourc ... !x).pop | +| arrays.js:97:8:97:42 | [MethodCallExpr] ["sourc ... ).pop() | semmle.label | [MethodCallExpr] ["sourc ... ).pop() | +| arrays.js:97:9:97:16 | [Literal] "source" | semmle.label | [Literal] "source" | +| arrays.js:97:19:97:24 | [Label] filter | semmle.label | [Label] filter | +| arrays.js:97:26:97:35 | [ArrowFunctionExpr] (x) => !!x | semmle.label | [ArrowFunctionExpr] (x) => !!x | +| arrays.js:97:27:97:27 | [SimpleParameter] x | semmle.label | [SimpleParameter] x | +| arrays.js:97:33:97:35 | [UnaryExpr] !!x | semmle.label | [UnaryExpr] !!x | +| arrays.js:97:34:97:35 | [UnaryExpr] !x | semmle.label | [UnaryExpr] !x | +| arrays.js:97:35:97:35 | [VarRef] x | semmle.label | [VarRef] x | +| arrays.js:97:38:97:40 | [Label] pop | semmle.label | [Label] pop | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | @@ -476,108 +488,110 @@ nodes | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | edges -| arrays.js:1:1:97:2 | [ParExpr] (functi ... T OK }) | arrays.js:1:2:97:1 | [FunctionExpr] functio ... OT OK } | semmle.label | 1 | -| arrays.js:1:1:97:2 | [ParExpr] (functi ... T OK }) | arrays.js:1:2:97:1 | [FunctionExpr] functio ... OT OK } | semmle.order | 1 | -| arrays.js:1:1:97:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:97:2 | [ParExpr] (functi ... T OK }) | semmle.label | 1 | -| arrays.js:1:1:97:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:97:2 | [ParExpr] (functi ... T OK }) | semmle.order | 1 | -| arrays.js:1:2:97:1 | [FunctionExpr] functio ... OT OK } | arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | semmle.label | 5 | -| arrays.js:1:2:97:1 | [FunctionExpr] functio ... OT OK } | arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | semmle.order | 5 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | 1 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.order | 1 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.label | 2 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.order | 2 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.label | 3 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.order | 3 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.label | 4 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.order | 4 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.label | 5 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.order | 5 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.label | 6 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.order | 6 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.label | 7 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.order | 7 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.label | 8 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.order | 8 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.label | 9 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.order | 9 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.label | 10 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.order | 10 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.label | 11 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.order | 11 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.label | 12 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.order | 12 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.label | 13 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.order | 13 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.label | 14 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.order | 14 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.label | 15 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.order | 15 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.label | 16 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.order | 16 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.label | 17 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.order | 17 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.label | 18 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.order | 18 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.label | 19 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.order | 19 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.label | 20 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.order | 20 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 21 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 21 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.label | 22 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.order | 22 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.label | 23 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.order | 23 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 24 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 24 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.label | 25 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.order | 25 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.label | 26 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.order | 26 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.label | 27 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.order | 27 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.label | 28 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.order | 28 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.label | 29 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.order | 29 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.label | 30 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.order | 30 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.label | 31 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.order | 31 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.label | 32 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.order | 32 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.label | 33 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.order | 33 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.label | 34 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.order | 34 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.label | 35 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.order | 35 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.label | 36 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.order | 36 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.label | 37 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.order | 37 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.label | 38 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.order | 38 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.label | 39 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.order | 39 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.label | 40 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.order | 40 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.label | 41 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.order | 41 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.label | 42 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.order | 42 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.label | 43 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.order | 43 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.label | 44 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.order | 44 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.label | 45 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.order | 45 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.label | 46 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.order | 46 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.label | 47 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.order | 47 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.label | 48 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.order | 48 | +| arrays.js:1:1:99:2 | [ParExpr] (functi ... OK }) | arrays.js:1:2:99:1 | [FunctionExpr] functio ... T OK } | semmle.label | 1 | +| arrays.js:1:1:99:2 | [ParExpr] (functi ... OK }) | arrays.js:1:2:99:1 | [FunctionExpr] functio ... T OK } | semmle.order | 1 | +| arrays.js:1:1:99:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:99:2 | [ParExpr] (functi ... OK }) | semmle.label | 1 | +| arrays.js:1:1:99:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:99:2 | [ParExpr] (functi ... OK }) | semmle.order | 1 | +| arrays.js:1:2:99:1 | [FunctionExpr] functio ... T OK } | arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | semmle.label | 5 | +| arrays.js:1:2:99:1 | [FunctionExpr] functio ... T OK } | arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | semmle.order | 5 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | 1 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.order | 1 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.label | 2 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.order | 2 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.label | 3 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.order | 3 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.label | 4 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.order | 4 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.label | 5 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.order | 5 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.label | 6 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.order | 6 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.label | 7 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.order | 7 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.label | 8 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.order | 8 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.label | 9 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.order | 9 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.label | 10 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.order | 10 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.label | 11 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.order | 11 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.label | 12 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.order | 12 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.label | 13 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.order | 13 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.label | 14 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.order | 14 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.label | 15 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.order | 15 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.label | 16 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.order | 16 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.label | 17 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.order | 17 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.label | 18 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.order | 18 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.label | 19 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.order | 19 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.label | 20 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.order | 20 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 21 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 21 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.label | 22 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.order | 22 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.label | 23 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.order | 23 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 24 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 24 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.label | 25 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.order | 25 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.label | 26 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.order | 26 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.label | 27 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.order | 27 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.label | 28 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.order | 28 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.label | 29 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.order | 29 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.label | 30 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.order | 30 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.label | 31 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.order | 31 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.label | 32 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.order | 32 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.label | 33 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.order | 33 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.label | 34 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.order | 34 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.label | 35 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.order | 35 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.label | 36 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.order | 36 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.label | 37 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.order | 37 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.label | 38 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.order | 38 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.label | 39 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.order | 39 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.label | 40 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.order | 40 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.label | 41 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.order | 41 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.label | 42 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.order | 42 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.label | 43 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.order | 43 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.label | 44 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.order | 44 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.label | 45 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.order | 45 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.label | 46 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.order | 46 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:95:3:95:19 | [ExprStmt] sink(["source"]); | semmle.label | 47 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:95:3:95:19 | [ExprStmt] sink(["source"]); | semmle.order | 47 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:96:3:96:42 | [ExprStmt] sink([" ... pop()); | semmle.label | 48 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:96:3:96:42 | [ExprStmt] sink([" ... pop()); | semmle.order | 48 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:97:3:97:44 | [ExprStmt] sink([" ... pop()); | semmle.label | 49 | +| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:97:3:97:44 | [ExprStmt] sink([" ... pop()); | semmle.order | 49 | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.label | 1 | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.order | 1 | | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | arrays.js:2:7:2:12 | [VarDecl] source | semmle.label | 1 | @@ -1244,50 +1258,70 @@ edges | arrays.js:93:8:93:17 | [MethodCallExpr] arr.at(-1) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | | arrays.js:93:15:93:16 | [UnaryExpr] -1 | arrays.js:93:16:93:16 | [Literal] 1 | semmle.label | 1 | | arrays.js:93:15:93:16 | [UnaryExpr] -1 | arrays.js:93:16:93:16 | [Literal] 1 | semmle.order | 1 | -| arrays.js:95:3:95:35 | [CallExpr] sink([" ... => x)) | arrays.js:95:3:95:6 | [VarRef] sink | semmle.label | 0 | -| arrays.js:95:3:95:35 | [CallExpr] sink([" ... => x)) | arrays.js:95:3:95:6 | [VarRef] sink | semmle.order | 0 | -| arrays.js:95:3:95:35 | [CallExpr] sink([" ... => x)) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | -| arrays.js:95:3:95:35 | [CallExpr] sink([" ... => x)) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | -| arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | arrays.js:95:3:95:35 | [CallExpr] sink([" ... => x)) | semmle.label | 1 | -| arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | arrays.js:95:3:95:35 | [CallExpr] sink([" ... => x)) | semmle.order | 1 | +| arrays.js:95:3:95:18 | [CallExpr] sink(["source"]) | arrays.js:95:3:95:6 | [VarRef] sink | semmle.label | 0 | +| arrays.js:95:3:95:18 | [CallExpr] sink(["source"]) | arrays.js:95:3:95:6 | [VarRef] sink | semmle.order | 0 | +| arrays.js:95:3:95:18 | [CallExpr] sink(["source"]) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:95:3:95:18 | [CallExpr] sink(["source"]) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:95:3:95:19 | [ExprStmt] sink(["source"]); | arrays.js:95:3:95:18 | [CallExpr] sink(["source"]) | semmle.label | 1 | +| arrays.js:95:3:95:19 | [ExprStmt] sink(["source"]); | arrays.js:95:3:95:18 | [CallExpr] sink(["source"]) | semmle.order | 1 | | arrays.js:95:8:95:17 | [ArrayExpr] ["source"] | arrays.js:95:9:95:16 | [Literal] "source" | semmle.label | 1 | | arrays.js:95:8:95:17 | [ArrayExpr] ["source"] | arrays.js:95:9:95:16 | [Literal] "source" | semmle.order | 1 | -| arrays.js:95:8:95:24 | [DotExpr] ["source"].filter | arrays.js:95:8:95:17 | [ArrayExpr] ["source"] | semmle.label | 1 | -| arrays.js:95:8:95:24 | [DotExpr] ["source"].filter | arrays.js:95:8:95:17 | [ArrayExpr] ["source"] | semmle.order | 1 | -| arrays.js:95:8:95:24 | [DotExpr] ["source"].filter | arrays.js:95:19:95:24 | [Label] filter | semmle.label | 2 | -| arrays.js:95:8:95:24 | [DotExpr] ["source"].filter | arrays.js:95:19:95:24 | [Label] filter | semmle.order | 2 | -| arrays.js:95:8:95:34 | [MethodCallExpr] ["sourc ... ) => x) | arrays.js:95:8:95:24 | [DotExpr] ["source"].filter | semmle.label | 0 | -| arrays.js:95:8:95:34 | [MethodCallExpr] ["sourc ... ) => x) | arrays.js:95:8:95:24 | [DotExpr] ["source"].filter | semmle.order | 0 | -| arrays.js:95:8:95:34 | [MethodCallExpr] ["sourc ... ) => x) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | -| arrays.js:95:8:95:34 | [MethodCallExpr] ["sourc ... ) => x) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | -| arrays.js:95:26:95:33 | [ArrowFunctionExpr] (x) => x | arrays.js:95:33:95:33 | [VarRef] x | semmle.label | 5 | -| arrays.js:95:26:95:33 | [ArrowFunctionExpr] (x) => x | arrays.js:95:33:95:33 | [VarRef] x | semmle.order | 5 | -| arrays.js:95:26:95:33 | [ArrowFunctionExpr] (x) => x | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | -| arrays.js:95:26:95:33 | [ArrowFunctionExpr] (x) => x | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | -| arrays.js:96:3:96:37 | [CallExpr] sink([" ... > !!x)) | arrays.js:96:3:96:6 | [VarRef] sink | semmle.label | 0 | -| arrays.js:96:3:96:37 | [CallExpr] sink([" ... > !!x)) | arrays.js:96:3:96:6 | [VarRef] sink | semmle.order | 0 | -| arrays.js:96:3:96:37 | [CallExpr] sink([" ... > !!x)) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | -| arrays.js:96:3:96:37 | [CallExpr] sink([" ... > !!x)) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | -| arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | arrays.js:96:3:96:37 | [CallExpr] sink([" ... > !!x)) | semmle.label | 1 | -| arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | arrays.js:96:3:96:37 | [CallExpr] sink([" ... > !!x)) | semmle.order | 1 | +| arrays.js:96:3:96:41 | [CallExpr] sink([" ... .pop()) | arrays.js:96:3:96:6 | [VarRef] sink | semmle.label | 0 | +| arrays.js:96:3:96:41 | [CallExpr] sink([" ... .pop()) | arrays.js:96:3:96:6 | [VarRef] sink | semmle.order | 0 | +| arrays.js:96:3:96:41 | [CallExpr] sink([" ... .pop()) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:96:3:96:41 | [CallExpr] sink([" ... .pop()) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:96:3:96:42 | [ExprStmt] sink([" ... pop()); | arrays.js:96:3:96:41 | [CallExpr] sink([" ... .pop()) | semmle.label | 1 | +| arrays.js:96:3:96:42 | [ExprStmt] sink([" ... pop()); | arrays.js:96:3:96:41 | [CallExpr] sink([" ... .pop()) | semmle.order | 1 | | arrays.js:96:8:96:17 | [ArrayExpr] ["source"] | arrays.js:96:9:96:16 | [Literal] "source" | semmle.label | 1 | | arrays.js:96:8:96:17 | [ArrayExpr] ["source"] | arrays.js:96:9:96:16 | [Literal] "source" | semmle.order | 1 | | arrays.js:96:8:96:24 | [DotExpr] ["source"].filter | arrays.js:96:8:96:17 | [ArrayExpr] ["source"] | semmle.label | 1 | | arrays.js:96:8:96:24 | [DotExpr] ["source"].filter | arrays.js:96:8:96:17 | [ArrayExpr] ["source"] | semmle.order | 1 | | arrays.js:96:8:96:24 | [DotExpr] ["source"].filter | arrays.js:96:19:96:24 | [Label] filter | semmle.label | 2 | | arrays.js:96:8:96:24 | [DotExpr] ["source"].filter | arrays.js:96:19:96:24 | [Label] filter | semmle.order | 2 | -| arrays.js:96:8:96:36 | [MethodCallExpr] ["sourc ... => !!x) | arrays.js:96:8:96:24 | [DotExpr] ["source"].filter | semmle.label | 0 | -| arrays.js:96:8:96:36 | [MethodCallExpr] ["sourc ... => !!x) | arrays.js:96:8:96:24 | [DotExpr] ["source"].filter | semmle.order | 0 | -| arrays.js:96:8:96:36 | [MethodCallExpr] ["sourc ... => !!x) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | -| arrays.js:96:8:96:36 | [MethodCallExpr] ["sourc ... => !!x) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | -| arrays.js:96:26:96:35 | [ArrowFunctionExpr] (x) => !!x | arrays.js:96:33:96:35 | [UnaryExpr] !!x | semmle.label | 5 | -| arrays.js:96:26:96:35 | [ArrowFunctionExpr] (x) => !!x | arrays.js:96:33:96:35 | [UnaryExpr] !!x | semmle.order | 5 | -| arrays.js:96:26:96:35 | [ArrowFunctionExpr] (x) => !!x | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | -| arrays.js:96:26:96:35 | [ArrowFunctionExpr] (x) => !!x | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | -| arrays.js:96:33:96:35 | [UnaryExpr] !!x | arrays.js:96:34:96:35 | [UnaryExpr] !x | semmle.label | 1 | -| arrays.js:96:33:96:35 | [UnaryExpr] !!x | arrays.js:96:34:96:35 | [UnaryExpr] !x | semmle.order | 1 | -| arrays.js:96:34:96:35 | [UnaryExpr] !x | arrays.js:96:35:96:35 | [VarRef] x | semmle.label | 1 | -| arrays.js:96:34:96:35 | [UnaryExpr] !x | arrays.js:96:35:96:35 | [VarRef] x | semmle.order | 1 | +| arrays.js:96:8:96:34 | [MethodCallExpr] ["sourc ... ) => x) | arrays.js:96:8:96:24 | [DotExpr] ["source"].filter | semmle.label | 0 | +| arrays.js:96:8:96:34 | [MethodCallExpr] ["sourc ... ) => x) | arrays.js:96:8:96:24 | [DotExpr] ["source"].filter | semmle.order | 0 | +| arrays.js:96:8:96:34 | [MethodCallExpr] ["sourc ... ) => x) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:96:8:96:34 | [MethodCallExpr] ["sourc ... ) => x) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:96:8:96:38 | [DotExpr] ["sourc ... x).pop | arrays.js:96:8:96:34 | [MethodCallExpr] ["sourc ... ) => x) | semmle.label | 1 | +| arrays.js:96:8:96:38 | [DotExpr] ["sourc ... x).pop | arrays.js:96:8:96:34 | [MethodCallExpr] ["sourc ... ) => x) | semmle.order | 1 | +| arrays.js:96:8:96:38 | [DotExpr] ["sourc ... x).pop | arrays.js:96:36:96:38 | [Label] pop | semmle.label | 2 | +| arrays.js:96:8:96:38 | [DotExpr] ["sourc ... x).pop | arrays.js:96:36:96:38 | [Label] pop | semmle.order | 2 | +| arrays.js:96:8:96:40 | [MethodCallExpr] ["sourc ... ).pop() | arrays.js:96:8:96:38 | [DotExpr] ["sourc ... x).pop | semmle.label | 0 | +| arrays.js:96:8:96:40 | [MethodCallExpr] ["sourc ... ).pop() | arrays.js:96:8:96:38 | [DotExpr] ["sourc ... x).pop | semmle.order | 0 | +| arrays.js:96:26:96:33 | [ArrowFunctionExpr] (x) => x | arrays.js:96:33:96:33 | [VarRef] x | semmle.label | 5 | +| arrays.js:96:26:96:33 | [ArrowFunctionExpr] (x) => x | arrays.js:96:33:96:33 | [VarRef] x | semmle.order | 5 | +| arrays.js:96:26:96:33 | [ArrowFunctionExpr] (x) => x | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| arrays.js:96:26:96:33 | [ArrowFunctionExpr] (x) => x | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| arrays.js:97:3:97:43 | [CallExpr] sink([" ... .pop()) | arrays.js:97:3:97:6 | [VarRef] sink | semmle.label | 0 | +| arrays.js:97:3:97:43 | [CallExpr] sink([" ... .pop()) | arrays.js:97:3:97:6 | [VarRef] sink | semmle.order | 0 | +| arrays.js:97:3:97:43 | [CallExpr] sink([" ... .pop()) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:97:3:97:43 | [CallExpr] sink([" ... .pop()) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:97:3:97:44 | [ExprStmt] sink([" ... pop()); | arrays.js:97:3:97:43 | [CallExpr] sink([" ... .pop()) | semmle.label | 1 | +| arrays.js:97:3:97:44 | [ExprStmt] sink([" ... pop()); | arrays.js:97:3:97:43 | [CallExpr] sink([" ... .pop()) | semmle.order | 1 | +| arrays.js:97:8:97:17 | [ArrayExpr] ["source"] | arrays.js:97:9:97:16 | [Literal] "source" | semmle.label | 1 | +| arrays.js:97:8:97:17 | [ArrayExpr] ["source"] | arrays.js:97:9:97:16 | [Literal] "source" | semmle.order | 1 | +| arrays.js:97:8:97:24 | [DotExpr] ["source"].filter | arrays.js:97:8:97:17 | [ArrayExpr] ["source"] | semmle.label | 1 | +| arrays.js:97:8:97:24 | [DotExpr] ["source"].filter | arrays.js:97:8:97:17 | [ArrayExpr] ["source"] | semmle.order | 1 | +| arrays.js:97:8:97:24 | [DotExpr] ["source"].filter | arrays.js:97:19:97:24 | [Label] filter | semmle.label | 2 | +| arrays.js:97:8:97:24 | [DotExpr] ["source"].filter | arrays.js:97:19:97:24 | [Label] filter | semmle.order | 2 | +| arrays.js:97:8:97:36 | [MethodCallExpr] ["sourc ... => !!x) | arrays.js:97:8:97:24 | [DotExpr] ["source"].filter | semmle.label | 0 | +| arrays.js:97:8:97:36 | [MethodCallExpr] ["sourc ... => !!x) | arrays.js:97:8:97:24 | [DotExpr] ["source"].filter | semmle.order | 0 | +| arrays.js:97:8:97:36 | [MethodCallExpr] ["sourc ... => !!x) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:97:8:97:36 | [MethodCallExpr] ["sourc ... => !!x) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:97:8:97:40 | [DotExpr] ["sourc ... !x).pop | arrays.js:97:8:97:36 | [MethodCallExpr] ["sourc ... => !!x) | semmle.label | 1 | +| arrays.js:97:8:97:40 | [DotExpr] ["sourc ... !x).pop | arrays.js:97:8:97:36 | [MethodCallExpr] ["sourc ... => !!x) | semmle.order | 1 | +| arrays.js:97:8:97:40 | [DotExpr] ["sourc ... !x).pop | arrays.js:97:38:97:40 | [Label] pop | semmle.label | 2 | +| arrays.js:97:8:97:40 | [DotExpr] ["sourc ... !x).pop | arrays.js:97:38:97:40 | [Label] pop | semmle.order | 2 | +| arrays.js:97:8:97:42 | [MethodCallExpr] ["sourc ... ).pop() | arrays.js:97:8:97:40 | [DotExpr] ["sourc ... !x).pop | semmle.label | 0 | +| arrays.js:97:8:97:42 | [MethodCallExpr] ["sourc ... ).pop() | arrays.js:97:8:97:40 | [DotExpr] ["sourc ... !x).pop | semmle.order | 0 | +| arrays.js:97:26:97:35 | [ArrowFunctionExpr] (x) => !!x | arrays.js:97:33:97:35 | [UnaryExpr] !!x | semmle.label | 5 | +| arrays.js:97:26:97:35 | [ArrowFunctionExpr] (x) => !!x | arrays.js:97:33:97:35 | [UnaryExpr] !!x | semmle.order | 5 | +| arrays.js:97:26:97:35 | [ArrowFunctionExpr] (x) => !!x | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| arrays.js:97:26:97:35 | [ArrowFunctionExpr] (x) => !!x | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| arrays.js:97:33:97:35 | [UnaryExpr] !!x | arrays.js:97:34:97:35 | [UnaryExpr] !x | semmle.label | 1 | +| arrays.js:97:33:97:35 | [UnaryExpr] !!x | arrays.js:97:34:97:35 | [UnaryExpr] !x | semmle.order | 1 | +| arrays.js:97:34:97:35 | [UnaryExpr] !x | arrays.js:97:35:97:35 | [VarRef] x | semmle.label | 1 | +| arrays.js:97:34:97:35 | [UnaryExpr] !x | arrays.js:97:35:97:35 | [VarRef] x | semmle.order | 1 | | file://:0:0:0:0 | (Arguments) | arrays.js:5:8:5:14 | [DotExpr] obj.foo | semmle.label | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:5:8:5:14 | [DotExpr] obj.foo | semmle.order | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:8:12:8:17 | [VarRef] source | semmle.label | 0 | @@ -1398,14 +1432,16 @@ edges | file://:0:0:0:0 | (Arguments) | arrays.js:93:8:93:17 | [MethodCallExpr] arr.at(-1) | semmle.order | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:93:15:93:16 | [UnaryExpr] -1 | semmle.label | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:93:15:93:16 | [UnaryExpr] -1 | semmle.order | 0 | -| file://:0:0:0:0 | (Arguments) | arrays.js:95:8:95:34 | [MethodCallExpr] ["sourc ... ) => x) | semmle.label | 0 | -| file://:0:0:0:0 | (Arguments) | arrays.js:95:8:95:34 | [MethodCallExpr] ["sourc ... ) => x) | semmle.order | 0 | -| file://:0:0:0:0 | (Arguments) | arrays.js:95:26:95:33 | [ArrowFunctionExpr] (x) => x | semmle.label | 0 | -| file://:0:0:0:0 | (Arguments) | arrays.js:95:26:95:33 | [ArrowFunctionExpr] (x) => x | semmle.order | 0 | -| file://:0:0:0:0 | (Arguments) | arrays.js:96:8:96:36 | [MethodCallExpr] ["sourc ... => !!x) | semmle.label | 0 | -| file://:0:0:0:0 | (Arguments) | arrays.js:96:8:96:36 | [MethodCallExpr] ["sourc ... => !!x) | semmle.order | 0 | -| file://:0:0:0:0 | (Arguments) | arrays.js:96:26:96:35 | [ArrowFunctionExpr] (x) => !!x | semmle.label | 0 | -| file://:0:0:0:0 | (Arguments) | arrays.js:96:26:96:35 | [ArrowFunctionExpr] (x) => !!x | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:95:8:95:17 | [ArrayExpr] ["source"] | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:95:8:95:17 | [ArrayExpr] ["source"] | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:96:8:96:40 | [MethodCallExpr] ["sourc ... ).pop() | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:96:8:96:40 | [MethodCallExpr] ["sourc ... ).pop() | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:96:26:96:33 | [ArrowFunctionExpr] (x) => x | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:96:26:96:33 | [ArrowFunctionExpr] (x) => x | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:97:8:97:42 | [MethodCallExpr] ["sourc ... ).pop() | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:97:8:97:42 | [MethodCallExpr] ["sourc ... ).pop() | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:97:26:97:35 | [ArrowFunctionExpr] (x) => !!x | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:97:26:97:35 | [ArrowFunctionExpr] (x) => !!x | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:15:16:15:16 | [SimpleParameter] e | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:15:16:15:16 | [SimpleParameter] e | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:16:12:16:12 | [SimpleParameter] e | semmle.label | 0 | @@ -1420,9 +1456,9 @@ edges | file://:0:0:0:0 | (Parameters) | arrays.js:53:26:53:26 | [SimpleParameter] i | semmle.order | 1 | | file://:0:0:0:0 | (Parameters) | arrays.js:53:29:53:31 | [SimpleParameter] ary | semmle.label | 2 | | file://:0:0:0:0 | (Parameters) | arrays.js:53:29:53:31 | [SimpleParameter] ary | semmle.order | 2 | -| file://:0:0:0:0 | (Parameters) | arrays.js:95:27:95:27 | [SimpleParameter] x | semmle.label | 0 | -| file://:0:0:0:0 | (Parameters) | arrays.js:95:27:95:27 | [SimpleParameter] x | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:96:27:96:27 | [SimpleParameter] x | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:96:27:96:27 | [SimpleParameter] x | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | arrays.js:97:27:97:27 | [SimpleParameter] x | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | arrays.js:97:27:97:27 | [SimpleParameter] x | semmle.order | 0 | graphProperties | semmle.graphKind | tree | From df42e7c5271e28d08454035dc464a2ec21073ec9 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 19 Aug 2024 12:01:41 +0200 Subject: [PATCH 252/514] JS: Add test showing lack of implicit reads for ArrayElement --- .../TaintTracking/BasicTaintTracking.expected | 3 +++ .../TaintTracking/DataFlowTracking.expected | 2 ++ .../use-use-after-implicit-read.js | 17 +++++++++++++++++ 3 files changed, 22 insertions(+) create mode 100644 javascript/ql/test/library-tests/TaintTracking/use-use-after-implicit-read.js diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index fd2fb8bbc09..a48580ba6e3 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -32,6 +32,8 @@ legacyDataFlowDifference | object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:28:10:28:30 | sanitiz ... bj).foo | only flow with OLD data flow library | | promise.js:12:20:12:27 | source() | promise.js:13:8:13:23 | resolver.promise | only flow with OLD data flow library | | sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | only flow with NEW data flow library | +| use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:8:10:8:17 | captured | only flow with OLD data flow library | +| use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:15:10:15:10 | x | only flow with NEW data flow library | consistencyIssue | library-tests/TaintTracking/nested-props.js:20 | expected an alert, but found none | NOT OK - but not found | Consistency | | library-tests/TaintTracking/stringification-read-steps.js:17 | expected an alert, but found none | NOT OK | Consistency | @@ -289,6 +291,7 @@ flow | 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) | | tst.js:2:13:2:20 | source() | tst.js:54:14:54:19 | unsafe | +| use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:15:10:15:10 | 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 | diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected index 18ff982fa1e..a90bae10999 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected @@ -24,6 +24,7 @@ legacyDataFlowDifference | sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | only flow with NEW data flow library | | tst.js:2:13:2:20 | source() | tst.js:35:14:35:16 | ary | only flow with NEW data flow library | | tst.js:2:13:2:20 | source() | tst.js:41:14:41:16 | ary | only flow with NEW data flow library | +| use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:15:10:15:10 | x | only flow with NEW data flow library | flow | access-path-sanitizer.js:2:18:2:25 | source() | access-path-sanitizer.js:4:8:4:12 | obj.x | | advanced-callgraph.js:2:13:2:20 | source() | advanced-callgraph.js:6:22:6:22 | v | @@ -181,3 +182,4 @@ flow | tst.js:2:13:2:20 | source() | tst.js:35:14:35:16 | ary | | tst.js:2:13:2:20 | source() | tst.js:41:14:41:16 | ary | | tst.js:2:13:2:20 | source() | tst.js:54:14:54:19 | unsafe | +| use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:15:10:15:10 | x | diff --git a/javascript/ql/test/library-tests/TaintTracking/use-use-after-implicit-read.js b/javascript/ql/test/library-tests/TaintTracking/use-use-after-implicit-read.js new file mode 100644 index 00000000000..43ce5fc99fe --- /dev/null +++ b/javascript/ql/test/library-tests/TaintTracking/use-use-after-implicit-read.js @@ -0,0 +1,17 @@ +import 'dummy'; + +function f(x) { + let captured; + function inner() { captured; captured = "sdf"; } + + captured = [source(), "safe", x]; + sink(captured); // NOT OK [INCONSISTENCY] - no implicit read of ArrayElement + g.apply(undefined, captured); // with use-use flow the output of an implicit read might flow here + + return captured; +} + +function g(x, y) { + sink(x); // NOT OK + sink(y); // OK +} From 371f7ef551b5fcc7e009e50a6f9797d358a8852d Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 19 Aug 2024 14:15:02 +0200 Subject: [PATCH 253/514] JS: Add implicit taint read of array elements --- .../javascript/dataflow/internal/TaintTrackingPrivate.qll | 2 +- .../library-tests/TaintTracking/BasicTaintTracking.expected | 4 +++- .../TaintTracking/use-use-after-implicit-read.js | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index 9d17da244c5..69d275a74dc 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -61,5 +61,5 @@ predicate defaultTaintSanitizer(DataFlow::Node node) { bindingset[node] predicate defaultImplicitTaintRead(DataFlow::Node node, ContentSet c) { exists(node) and - c = ContentSet::promiseValue() + c = [ContentSet::promiseValue(), ContentSet::arrayElement()] } diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index a48580ba6e3..7f249cc675d 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -32,8 +32,8 @@ legacyDataFlowDifference | object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:28:10:28:30 | sanitiz ... bj).foo | only flow with OLD data flow library | | promise.js:12:20:12:27 | source() | promise.js:13:8:13:23 | resolver.promise | only flow with OLD data flow library | | sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | only flow with NEW data flow library | -| use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:8:10:8:17 | captured | only flow with OLD data flow library | | use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:15:10:15:10 | x | only flow with NEW data flow library | +| use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:16:10:16:10 | y | only flow with NEW data flow library | consistencyIssue | library-tests/TaintTracking/nested-props.js:20 | expected an alert, but found none | NOT OK - but not found | Consistency | | library-tests/TaintTracking/stringification-read-steps.js:17 | expected an alert, but found none | NOT OK | Consistency | @@ -291,7 +291,9 @@ flow | 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) | | tst.js:2:13:2:20 | source() | tst.js:54:14:54:19 | unsafe | +| use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:8:10:8:17 | captured | | use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:15:10:15:10 | x | +| use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:16:10:16:10 | y | | 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 | diff --git a/javascript/ql/test/library-tests/TaintTracking/use-use-after-implicit-read.js b/javascript/ql/test/library-tests/TaintTracking/use-use-after-implicit-read.js index 43ce5fc99fe..17c11b6a505 100644 --- a/javascript/ql/test/library-tests/TaintTracking/use-use-after-implicit-read.js +++ b/javascript/ql/test/library-tests/TaintTracking/use-use-after-implicit-read.js @@ -5,7 +5,7 @@ function f(x) { function inner() { captured; captured = "sdf"; } captured = [source(), "safe", x]; - sink(captured); // NOT OK [INCONSISTENCY] - no implicit read of ArrayElement + sink(captured); // NOT OK - implicit read of ArrayElement g.apply(undefined, captured); // with use-use flow the output of an implicit read might flow here return captured; @@ -13,5 +13,5 @@ function f(x) { function g(x, y) { sink(x); // NOT OK - sink(y); // OK + sink(y); // OK [INCONSISTENCY] - implicit read confuses array index } From aa8bd332bf351ae58a5dbe2cf1487bf43d25ceac Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 22 Aug 2024 11:43:29 +0200 Subject: [PATCH 254/514] JS: Add a few more tests --- .../TaintTracking/BasicTaintTracking.expected | 12 ++++++++---- .../TaintTracking/DataFlowTracking.expected | 4 ++++ .../library-tests/TaintTracking/spread.js | 19 ++++++++++++++++++- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 7f249cc675d..2a1ca5c57f6 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -32,6 +32,8 @@ legacyDataFlowDifference | object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:28:10:28:30 | sanitiz ... bj).foo | only flow with OLD data flow library | | promise.js:12:20:12:27 | source() | promise.js:13:8:13:23 | resolver.promise | only flow with OLD data flow library | | sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | only flow with NEW data flow library | +| spread.js:4:15:4:22 | source() | spread.js:18:8:18:8 | y | only flow with NEW data flow library | +| spread.js:4:15:4:22 | source() | spread.js:24:8:24:8 | y | only flow with NEW data flow library | | use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:15:10:15:10 | x | only flow with NEW data flow library | | use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:16:10:16:10 | y | only flow with NEW data flow library | consistencyIssue @@ -250,10 +252,12 @@ flow | sanitizer-guards.js:91:11:91:18 | source() | sanitizer-guards.js:93:8:93:8 | x | | sanitizer-guards.js:91:11:91:18 | source() | sanitizer-guards.js:98:7:98:7 | x | | sanitizer-guards.js:91:11:91:18 | source() | sanitizer-guards.js:104:7:104:7 | x | -| spread.js:2:15:2:22 | source() | spread.js:4:8:4:19 | { ...taint } | -| spread.js:2:15:2:22 | source() | spread.js:5:8:5:43 | { f: 'h ... orld' } | -| spread.js:2:15:2:22 | source() | spread.js:7:8:7:19 | [ ...taint ] | -| spread.js:2:15:2:22 | source() | spread.js:8:8:8:28 | [ 1, 2, ... nt, 3 ] | +| spread.js:4:15:4:22 | source() | spread.js:6:8:6:19 | { ...taint } | +| spread.js:4:15:4:22 | source() | spread.js:7:8:7:43 | { f: 'h ... orld' } | +| spread.js:4:15:4:22 | source() | spread.js:9:8:9:19 | [ ...taint ] | +| spread.js:4:15:4:22 | source() | spread.js:10:8:10:28 | [ 1, 2, ... nt, 3 ] | +| spread.js:4:15:4:22 | source() | spread.js:18:8:18:8 | y | +| spread.js:4:15:4:22 | source() | spread.js:24:8:24:8 | y | | static-capture-groups.js:2:17:2:24 | source() | static-capture-groups.js:5:14:5:22 | RegExp.$1 | | static-capture-groups.js:2:17:2:24 | source() | static-capture-groups.js:15:14:15:22 | RegExp.$1 | | static-capture-groups.js:2:17:2:24 | source() | static-capture-groups.js:17:14:17:22 | RegExp.$1 | diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected index a90bae10999..b4b3458cb8e 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected @@ -22,6 +22,8 @@ legacyDataFlowDifference | nested-props.js:27:18:27:25 | source() | nested-props.js:28:10:28:14 | obj.x | only flow with NEW data flow library | | nested-props.js:51:22:51:29 | source() | nested-props.js:52:10:52:16 | obj.x.y | only flow with NEW data flow library | | sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | only flow with NEW data flow library | +| spread.js:4:15:4:22 | source() | spread.js:18:8:18:8 | y | only flow with NEW data flow library | +| spread.js:4:15:4:22 | source() | spread.js:24:8:24:8 | y | only flow with NEW data flow library | | tst.js:2:13:2:20 | source() | tst.js:35:14:35:16 | ary | only flow with NEW data flow library | | tst.js:2:13:2:20 | source() | tst.js:41:14:41:16 | ary | only flow with NEW data flow library | | use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:15:10:15:10 | x | only flow with NEW data flow library | @@ -176,6 +178,8 @@ flow | sanitizer-guards.js:91:11:91:18 | source() | sanitizer-guards.js:98:7:98:7 | x | | sanitizer-guards.js:91:11:91:18 | source() | sanitizer-guards.js:102:10:102:10 | x | | sanitizer-guards.js:91:11:91:18 | source() | sanitizer-guards.js:104:7:104:7 | x | +| spread.js:4:15:4:22 | source() | spread.js:18:8:18:8 | y | +| spread.js:4:15:4:22 | source() | spread.js:24:8:24:8 | y | | thisAssignments.js:4:17:4:24 | source() | thisAssignments.js:5:10:5:18 | obj.field | | thisAssignments.js:7:19:7:26 | source() | thisAssignments.js:8:10:8:20 | this.field2 | | tst.js:2:13:2:20 | source() | tst.js:4:10:4:10 | x | diff --git a/javascript/ql/test/library-tests/TaintTracking/spread.js b/javascript/ql/test/library-tests/TaintTracking/spread.js index 1a2939b6f1d..34bbb943253 100644 --- a/javascript/ql/test/library-tests/TaintTracking/spread.js +++ b/javascript/ql/test/library-tests/TaintTracking/spread.js @@ -1,9 +1,26 @@ +import 'dummy'; + function test() { let taint = source(); - + sink({ ...taint }); // NOT OK sink({ f: 'hello', ...taint, g: 'world' }); // NOT OK sink([ ...taint ]); // NOT OK sink([ 1, 2, ...taint, 3 ]); // NOT OK + + fn1(...['x', taint, 'z']); + fn2.apply(undefined, ['x', taint, 'z']); +} + +function fn1(x, y, z) { + sink(x); + sink(y); // NOT OK + sink(z); +} + +function fn2(x, y, z) { + sink(x); + sink(y); // NOT OK + sink(z); } From 3e196f83f1c1e4acb7ca0cd494fe46dd7f474a35 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 23 Aug 2024 13:43:25 +0200 Subject: [PATCH 255/514] JS: Update Promises/flow2 test --- javascript/ql/test/library-tests/Promises/flow2.js | 2 +- javascript/ql/test/library-tests/Promises/tests.expected | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/javascript/ql/test/library-tests/Promises/flow2.js b/javascript/ql/test/library-tests/Promises/flow2.js index 87994bd8245..0a29ed35f8e 100644 --- a/javascript/ql/test/library-tests/Promises/flow2.js +++ b/javascript/ql/test/library-tests/Promises/flow2.js @@ -2,7 +2,7 @@ var source = "source"; Promise.all([source, "clean"]).then((arr) => { - sink(arr); // OK + sink(arr); // NOT OK - implicit read of array element sink(arr[0]); // NOT OK sink(arr[1]); // OK }) diff --git a/javascript/ql/test/library-tests/Promises/tests.expected b/javascript/ql/test/library-tests/Promises/tests.expected index 1b0d5466281..52c00a11d50 100644 --- a/javascript/ql/test/library-tests/Promises/tests.expected +++ b/javascript/ql/test/library-tests/Promises/tests.expected @@ -274,6 +274,7 @@ flow | flow.js:136:15:136:22 | "source" | flow.js:142:7:142:19 | await async() | | flow.js:136:15:136:22 | "source" | flow.js:155:9:155:9 | e | exclusiveTaintFlow +| flow2.js:2:15:2:22 | "source" | flow2.js:5:8:5:10 | arr | | flow.js:136:15:136:22 | "source" | flow.js:141:7:141:13 | async() | | flow.js:160:15:160:22 | "source" | flow.js:164:39:164:39 | x | | flow.js:160:15:160:22 | "source" | flow.js:167:7:167:9 | foo | @@ -466,3 +467,4 @@ typetrack valueFlowDifference | flow2.js:2:15:2:22 | "source" | flow2.js:20:7:20:14 | tainted3 | only flow with NEW data flow library | taintFlowDifference +| flow2.js:2:15:2:22 | "source" | flow2.js:5:8:5:10 | arr | only flow with NEW data flow library | From 2e2181be2c7b6334509990158216873ef4f16cde Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 27 Aug 2024 11:30:53 +0200 Subject: [PATCH 256/514] JS: Update test output that only affects nodes/edges/subpaths --- .../UntrustedDataToExternalAPI.expected | 1 - .../CommandInjection.expected | 37 ++++++++------- .../IndirectCommandInjection.expected | 20 ++++++++ .../UnsafeShellCommandConstruction.expected | 29 ++++++++++-- .../Security/CWE-079/DomBasedXss/Xss.expected | 24 +++++++++- .../XssWithAdditionalSources.expected | 24 +++++++++- .../ExceptionXss/ExceptionXss.expected | 12 ++--- .../CWE-079/StoredXss/StoredXss.expected | 15 ++++++ .../CWE-089/untyped/SqlInjection.expected | 19 ++++++-- .../ImproperCodeSanitization.expected | 7 +++ .../CWE-312/CleartextLogging.expected | 21 +++++++++ .../CWE-400/ReDoS/PolynomialReDoS.expected | 8 ++-- .../ServerSideUrlRedirect.expected | 13 +++++ .../Security/CWE-730/RegExpInjection.expected | 5 ++ .../PrototypePollutingFunction.expected | 47 +++++++++++++++++++ 15 files changed, 244 insertions(+), 38 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected b/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected index d7e0636b554..35daa024535 100644 --- a/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected +++ b/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected @@ -14,7 +14,6 @@ edges | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:44:8:44:16 | untrusted | provenance | | | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | provenance | | | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] [1] | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | provenance | | -| tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | provenance | | | tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] [1] | provenance | | | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } [y, z] | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } | provenance | | | tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } [z] | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } [y, z] | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected index 82521f20efa..f4a573e957c 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected @@ -16,6 +16,7 @@ edges | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:39:26:39:28 | cmd | provenance | | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:43:15:43:17 | cmd | provenance | | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:48:15:48:17 | cmd | provenance | | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:48:15:48:17 | cmd | provenance | | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:53:15:53:17 | cmd | provenance | | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:56:54:56:56 | cmd | provenance | | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:56:54:56:56 | cmd | provenance | | @@ -26,12 +27,18 @@ edges | child_process-test.js:6:15:6:49 | url.par ... ry.path | child_process-test.js:6:9:6:49 | cmd | provenance | | | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:6:15:6:38 | url.par ... , true) | provenance | | | child_process-test.js:25:21:25:23 | cmd | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | provenance | | -| child_process-test.js:56:46:56:57 | ["bar", cmd] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | provenance | | +| child_process-test.js:46:9:46:17 | args [1] | child_process-test.js:49:15:49:18 | args [1] | provenance | | +| child_process-test.js:48:5:48:8 | [post update] args [1] | child_process-test.js:46:9:46:17 | args [1] | provenance | | +| child_process-test.js:48:15:48:17 | cmd | child_process-test.js:48:5:48:8 | [post update] args [1] | provenance | | +| child_process-test.js:49:15:49:18 | args [1] | child_process-test.js:66:19:66:22 | args [1] | provenance | | +| child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) [ArrayElement] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | provenance | | | child_process-test.js:56:46:56:57 | ["bar", cmd] [1] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | provenance | | -| child_process-test.js:56:54:56:56 | cmd | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | provenance | | -| child_process-test.js:56:54:56:56 | cmd | child_process-test.js:56:46:56:57 | ["bar", cmd] | provenance | | +| child_process-test.js:56:46:56:57 | ["bar", cmd] [1] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) [ArrayElement] | provenance | | | child_process-test.js:56:54:56:56 | cmd | child_process-test.js:56:46:56:57 | ["bar", cmd] [1] | provenance | | +| child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) [ArrayElement] | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) | provenance | | | child_process-test.js:57:46:57:48 | cmd | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) | provenance | | +| child_process-test.js:57:46:57:48 | cmd | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) [ArrayElement] | provenance | | +| child_process-test.js:66:19:66:22 | args [1] | child_process-test.js:66:19:66:22 | args | provenance | | | child_process-test.js:73:9:73:49 | cmd | child_process-test.js:75:29:75:31 | cmd | provenance | | | child_process-test.js:73:15:73:38 | url.par ... , true) | child_process-test.js:73:9:73:49 | cmd | provenance | | | child_process-test.js:73:25:73:31 | req.url | child_process-test.js:73:15:73:38 | url.par ... , true) | provenance | | @@ -46,26 +53,18 @@ edges | exec-sh.js:19:15:19:38 | url.par ... , true) | exec-sh.js:19:9:19:49 | cmd | provenance | | | exec-sh.js:19:25:19:31 | req.url | exec-sh.js:19:15:19:38 | url.par ... , true) | provenance | | | exec-sh.js:20:12:20:14 | cmd | exec-sh.js:13:17:13:23 | command | provenance | | -| execSeries.js:3:20:3:22 | arr | execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr] | provenance | | -| execSeries.js:3:20:3:22 | arr | execSeries.js:6:14:6:16 | arr | provenance | | | execSeries.js:3:20:3:22 | arr [0] | execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr, 0] | provenance | | | execSeries.js:3:20:3:22 | arr [0] | execSeries.js:6:14:6:16 | arr [0] | provenance | | | execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr, 0] | execSeries.js:6:14:6:16 | arr [0] | provenance | | -| execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr] | execSeries.js:6:14:6:16 | arr | provenance | | -| execSeries.js:6:14:6:16 | arr | execSeries.js:6:14:6:21 | arr[i++] | provenance | | | execSeries.js:6:14:6:16 | arr [0] | execSeries.js:6:14:6:21 | arr[i++] | provenance | | | execSeries.js:6:14:6:21 | arr[i++] | execSeries.js:14:24:14:30 | command | provenance | | -| execSeries.js:13:19:13:26 | commands | execSeries.js:14:13:14:20 | commands | provenance | | | execSeries.js:13:19:13:26 | commands [0] | execSeries.js:14:13:14:20 | commands [0] | provenance | | -| execSeries.js:14:13:14:20 | commands | execSeries.js:3:20:3:22 | arr | provenance | | | execSeries.js:14:13:14:20 | commands [0] | execSeries.js:3:20:3:22 | arr [0] | provenance | | | execSeries.js:14:24:14:30 | command | execSeries.js:14:41:14:47 | command | provenance | | | execSeries.js:18:7:18:58 | cmd | execSeries.js:19:13:19:15 | cmd | provenance | | | execSeries.js:18:13:18:47 | require ... , true) | execSeries.js:18:7:18:58 | cmd | provenance | | | execSeries.js:18:34:18:40 | req.url | execSeries.js:18:13:18:47 | require ... , true) | provenance | | -| execSeries.js:19:12:19:16 | [cmd] | execSeries.js:13:19:13:26 | commands | provenance | | | execSeries.js:19:12:19:16 | [cmd] [0] | execSeries.js:13:19:13:26 | commands [0] | provenance | | -| execSeries.js:19:13:19:15 | cmd | execSeries.js:19:12:19:16 | [cmd] | provenance | | | execSeries.js:19:13:19:15 | cmd | execSeries.js:19:12:19:16 | [cmd] [0] | provenance | | | form-parsers.js:9:19:9:26 | req.file | form-parsers.js:9:8:9:39 | "touch ... nalname | provenance | | | form-parsers.js:13:3:13:11 | req.files | form-parsers.js:13:21:13:24 | file | provenance | | @@ -127,15 +126,22 @@ nodes | child_process-test.js:25:21:25:23 | cmd | semmle.label | cmd | | child_process-test.js:39:26:39:28 | cmd | semmle.label | cmd | | child_process-test.js:43:15:43:17 | cmd | semmle.label | cmd | +| child_process-test.js:46:9:46:17 | args [1] | semmle.label | args [1] | +| child_process-test.js:48:5:48:8 | [post update] args [1] | semmle.label | [post update] args [1] | | child_process-test.js:48:15:48:17 | cmd | semmle.label | cmd | +| child_process-test.js:48:15:48:17 | cmd | semmle.label | cmd | +| child_process-test.js:49:15:49:18 | args [1] | semmle.label | args [1] | | child_process-test.js:53:15:53:17 | cmd | semmle.label | cmd | | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | semmle.label | ['/C', ... , cmd]) | -| child_process-test.js:56:46:56:57 | ["bar", cmd] | semmle.label | ["bar", cmd] | +| child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) [ArrayElement] | semmle.label | ['/C', ... , cmd]) [ArrayElement] | | child_process-test.js:56:46:56:57 | ["bar", cmd] [1] | semmle.label | ["bar", cmd] [1] | | child_process-test.js:56:54:56:56 | cmd | semmle.label | cmd | | child_process-test.js:56:54:56:56 | cmd | semmle.label | cmd | | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) | semmle.label | ['/C', ... at(cmd) | +| child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) [ArrayElement] | semmle.label | ['/C', ... at(cmd) [ArrayElement] | | child_process-test.js:57:46:57:48 | cmd | semmle.label | cmd | +| child_process-test.js:66:19:66:22 | args | semmle.label | args | +| child_process-test.js:66:19:66:22 | args [1] | semmle.label | args [1] | | child_process-test.js:73:9:73:49 | cmd | semmle.label | cmd | | child_process-test.js:73:15:73:38 | url.par ... , true) | semmle.label | url.par ... , true) | | child_process-test.js:73:25:73:31 | req.url | semmle.label | req.url | @@ -155,23 +161,17 @@ nodes | exec-sh.js:19:15:19:38 | url.par ... , true) | semmle.label | url.par ... , true) | | exec-sh.js:19:25:19:31 | req.url | semmle.label | req.url | | exec-sh.js:20:12:20:14 | cmd | semmle.label | cmd | -| execSeries.js:3:20:3:22 | arr | semmle.label | arr | | execSeries.js:3:20:3:22 | arr [0] | semmle.label | arr [0] | | execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr, 0] | semmle.label | (functi ... );\\n }) [arr, 0] | -| execSeries.js:5:3:10:4 | (functi ... );\\n }) [arr] | semmle.label | (functi ... );\\n }) [arr] | -| execSeries.js:6:14:6:16 | arr | semmle.label | arr | | execSeries.js:6:14:6:16 | arr [0] | semmle.label | arr [0] | | execSeries.js:6:14:6:21 | arr[i++] | semmle.label | arr[i++] | -| execSeries.js:13:19:13:26 | commands | semmle.label | commands | | execSeries.js:13:19:13:26 | commands [0] | semmle.label | commands [0] | -| execSeries.js:14:13:14:20 | commands | semmle.label | commands | | execSeries.js:14:13:14:20 | commands [0] | semmle.label | commands [0] | | execSeries.js:14:24:14:30 | command | semmle.label | command | | execSeries.js:14:41:14:47 | command | semmle.label | command | | execSeries.js:18:7:18:58 | cmd | semmle.label | cmd | | execSeries.js:18:13:18:47 | require ... , true) | semmle.label | require ... , true) | | execSeries.js:18:34:18:40 | req.url | semmle.label | req.url | -| execSeries.js:19:12:19:16 | [cmd] | semmle.label | [cmd] | | execSeries.js:19:12:19:16 | [cmd] [0] | semmle.label | [cmd] [0] | | execSeries.js:19:13:19:15 | cmd | semmle.label | cmd | | form-parsers.js:9:8:9:39 | "touch ... nalname | semmle.label | "touch ... nalname | @@ -239,6 +239,7 @@ subpaths | child_process-test.js:57:5:57:50 | cp.spaw ... t(cmd)) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) | This command line depends on a $@. | child_process-test.js:6:25:6:31 | req.url | user-provided value | | child_process-test.js:62:5:62:39 | cp.exec ... , args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:53:15:53:17 | cmd | This command line depends on a $@. | child_process-test.js:6:25:6:31 | req.url | user-provided value | | child_process-test.js:67:3:67:21 | cp.spawn(cmd, args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:48:15:48:17 | cmd | This command line depends on a $@. | child_process-test.js:6:25:6:31 | req.url | user-provided value | +| child_process-test.js:67:3:67:21 | cp.spawn(cmd, args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:66:19:66:22 | args | This command line depends on a $@. | child_process-test.js:6:25:6:31 | req.url | user-provided value | | child_process-test.js:75:29:75:31 | cmd | child_process-test.js:73:25:73:31 | req.url | child_process-test.js:75:29:75:31 | cmd | This command line depends on a $@. | child_process-test.js:73:25:73:31 | req.url | user-provided value | | child_process-test.js:83:19:83:36 | req.query.fileName | child_process-test.js:83:19:83:36 | req.query.fileName | child_process-test.js:83:19:83:36 | req.query.fileName | This command line depends on a $@. | child_process-test.js:83:19:83:36 | req.query.fileName | user-provided value | | child_process-test.js:94:11:94:35 | "ping " ... ms.host | child_process-test.js:94:21:94:30 | ctx.params | child_process-test.js:94:11:94:35 | "ping " ... ms.host | This command line depends on a $@. | child_process-test.js:94:21:94:30 | ctx.params | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected index 26416731806..a6b90c01ff1 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected @@ -28,10 +28,14 @@ edges | command-line-parameter-command-injection.js:20:26:20:29 | arg0 | command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | provenance | | | command-line-parameter-command-injection.js:24:8:24:35 | args | command-line-parameter-command-injection.js:26:32:26:35 | args | provenance | | | command-line-parameter-command-injection.js:24:8:24:35 | args | command-line-parameter-command-injection.js:27:32:27:35 | args | provenance | | +| command-line-parameter-command-injection.js:24:8:24:35 | args [ArrayElement] | command-line-parameter-command-injection.js:27:32:27:35 | args [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:24:15:24:26 | process.argv | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | provenance | | +| command-line-parameter-command-injection.js:24:15:24:26 | process.argv | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | command-line-parameter-command-injection.js:24:8:24:35 | args | provenance | | +| command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) [ArrayElement] | command-line-parameter-command-injection.js:24:8:24:35 | args [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:26:32:26:35 | args | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | provenance | | | command-line-parameter-command-injection.js:27:32:27:35 | args | command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | provenance | | +| command-line-parameter-command-injection.js:27:32:27:35 | args [ArrayElement] | command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | provenance | | | command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | provenance | | | command-line-parameter-command-injection.js:30:21:30:46 | require ... rgs")() | command-line-parameter-command-injection.js:30:9:30:50 | "cmd.sh ... )().foo | provenance | | | command-line-parameter-command-injection.js:32:21:32:41 | require ... ").argv | command-line-parameter-command-injection.js:32:9:32:45 | "cmd.sh ... rgv.foo | provenance | | @@ -71,16 +75,24 @@ edges | command-line-parameter-command-injection.js:71:20:71:40 | require ... ').argv | command-line-parameter-command-injection.js:71:6:71:16 | [...taint4] | provenance | | | command-line-parameter-command-injection.js:72:22:72:27 | taint4 | command-line-parameter-command-injection.js:72:10:72:27 | "cmd.sh " + taint4 | provenance | | | command-line-parameter-command-injection.js:76:8:76:35 | argv | command-line-parameter-command-injection.js:79:31:79:34 | argv | provenance | | +| command-line-parameter-command-injection.js:76:8:76:35 | argv [ArrayElement] | command-line-parameter-command-injection.js:79:31:79:34 | argv [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:76:15:76:26 | process.argv | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | provenance | | +| command-line-parameter-command-injection.js:76:15:76:26 | process.argv | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | command-line-parameter-command-injection.js:76:8:76:35 | argv | provenance | | +| command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) [ArrayElement] | command-line-parameter-command-injection.js:76:8:76:35 | argv [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | command-line-parameter-command-injection.js:79:10:79:39 | "cmd.sh ... gv).foo | provenance | | | command-line-parameter-command-injection.js:79:31:79:34 | argv | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | provenance | Config | +| command-line-parameter-command-injection.js:79:31:79:34 | argv [ArrayElement] | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | provenance | Config | | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | command-line-parameter-command-injection.js:82:10:82:54 | "cmd.sh ... 2)).foo | provenance | | | command-line-parameter-command-injection.js:82:29:82:40 | process.argv | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | provenance | | +| command-line-parameter-command-injection.js:82:29:82:40 | process.argv | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | provenance | Config | +| command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) [ArrayElement] | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | provenance | Config | | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | command-line-parameter-command-injection.js:85:10:85:59 | "cmd.sh ... 2)).foo | provenance | | | command-line-parameter-command-injection.js:85:34:85:45 | process.argv | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | provenance | | +| command-line-parameter-command-injection.js:85:34:85:45 | process.argv | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | provenance | Config | +| command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) [ArrayElement] | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | provenance | Config | | command-line-parameter-command-injection.js:88:6:88:37 | flags | command-line-parameter-command-injection.js:89:22:89:26 | flags | provenance | | | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | command-line-parameter-command-injection.js:88:6:88:37 | flags | provenance | | | command-line-parameter-command-injection.js:88:25:88:36 | process.argv | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | provenance | Config | @@ -144,12 +156,15 @@ nodes | command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | semmle.label | "cmd.sh " + arg0 | | command-line-parameter-command-injection.js:20:26:20:29 | arg0 | semmle.label | arg0 | | command-line-parameter-command-injection.js:24:8:24:35 | args | semmle.label | args | +| command-line-parameter-command-injection.js:24:8:24:35 | args [ArrayElement] | semmle.label | args [ArrayElement] | | command-line-parameter-command-injection.js:24:15:24:26 | process.argv | semmle.label | process.argv | | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | semmle.label | process ... lice(2) | +| command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) [ArrayElement] | semmle.label | process ... lice(2) [ArrayElement] | | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | semmle.label | `node $ ... ption"` | | command-line-parameter-command-injection.js:26:32:26:35 | args | semmle.label | args | | command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | semmle.label | `node $ ... ption"` | | command-line-parameter-command-injection.js:27:32:27:35 | args | semmle.label | args | +| command-line-parameter-command-injection.js:27:32:27:35 | args [ArrayElement] | semmle.label | args [ArrayElement] | | command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | semmle.label | args.join(' ') | | command-line-parameter-command-injection.js:30:9:30:50 | "cmd.sh ... )().foo | semmle.label | "cmd.sh ... )().foo | | command-line-parameter-command-injection.js:30:21:30:46 | require ... rgs")() | semmle.label | require ... rgs")() | @@ -199,19 +214,24 @@ nodes | command-line-parameter-command-injection.js:72:10:72:27 | "cmd.sh " + taint4 | semmle.label | "cmd.sh " + taint4 | | command-line-parameter-command-injection.js:72:22:72:27 | taint4 | semmle.label | taint4 | | command-line-parameter-command-injection.js:76:8:76:35 | argv | semmle.label | argv | +| command-line-parameter-command-injection.js:76:8:76:35 | argv [ArrayElement] | semmle.label | argv [ArrayElement] | | command-line-parameter-command-injection.js:76:15:76:26 | process.argv | semmle.label | process.argv | | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | semmle.label | process ... lice(2) | +| command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) [ArrayElement] | semmle.label | process ... lice(2) [ArrayElement] | | command-line-parameter-command-injection.js:79:10:79:39 | "cmd.sh ... gv).foo | semmle.label | "cmd.sh ... gv).foo | | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | semmle.label | minimist(argv) | | command-line-parameter-command-injection.js:79:31:79:34 | argv | semmle.label | argv | +| command-line-parameter-command-injection.js:79:31:79:34 | argv [ArrayElement] | semmle.label | argv [ArrayElement] | | command-line-parameter-command-injection.js:82:10:82:54 | "cmd.sh ... 2)).foo | semmle.label | "cmd.sh ... 2)).foo | | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | semmle.label | subarg( ... ice(2)) | | command-line-parameter-command-injection.js:82:29:82:40 | process.argv | semmle.label | process.argv | | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | semmle.label | process ... lice(2) | +| command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) [ArrayElement] | semmle.label | process ... lice(2) [ArrayElement] | | command-line-parameter-command-injection.js:85:10:85:59 | "cmd.sh ... 2)).foo | semmle.label | "cmd.sh ... 2)).foo | | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | semmle.label | yargsPa ... ice(2)) | | command-line-parameter-command-injection.js:85:34:85:45 | process.argv | semmle.label | process.argv | | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | semmle.label | process ... lice(2) | +| command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) [ArrayElement] | semmle.label | process ... lice(2) [ArrayElement] | | command-line-parameter-command-injection.js:88:6:88:37 | flags | semmle.label | flags | | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | semmle.label | args.pa ... s.argv) | | command-line-parameter-command-injection.js:88:25:88:36 | process.argv | semmle.label | process.argv | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected index cf74ed30547..2f91b5e8c76 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected @@ -90,16 +90,25 @@ edges | lib/lib.js:414:40:414:43 | name | lib/lib.js:426:11:426:14 | name | provenance | | | lib/lib.js:414:40:414:43 | name | lib/lib.js:428:36:428:39 | name | provenance | | | lib/lib.js:425:6:425:13 | arr | lib/lib.js:427:14:427:16 | arr | provenance | | +| lib/lib.js:425:6:425:13 | arr [ArrayElement] | lib/lib.js:427:14:427:16 | arr [ArrayElement] | provenance | | | lib/lib.js:426:2:426:4 | [post update] arr | lib/lib.js:425:6:425:13 | arr | provenance | | +| lib/lib.js:426:2:426:4 | [post update] arr [ArrayElement] | lib/lib.js:425:6:425:13 | arr [ArrayElement] | provenance | | | lib/lib.js:426:11:426:14 | name | lib/lib.js:426:2:426:4 | [post update] arr | provenance | | +| lib/lib.js:426:11:426:14 | name | lib/lib.js:426:2:426:4 | [post update] arr [ArrayElement] | provenance | | +| lib/lib.js:427:14:427:16 | arr [ArrayElement] | lib/lib.js:427:14:427:16 | arr | provenance | | +| lib/lib.js:428:14:428:58 | build(" ... + '-') [ArrayElement] | lib/lib.js:428:14:428:58 | build(" ... + '-') | provenance | | | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:428:14:428:58 | build(" ... + '-') | provenance | | +| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:428:14:428:58 | build(" ... + '-') [ArrayElement] | provenance | | | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:431:23:431:26 | last | provenance | | | lib/lib.js:428:36:428:39 | name | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | provenance | | | lib/lib.js:431:23:431:26 | last | lib/lib.js:436:19:436:22 | last | provenance | | | lib/lib.js:431:23:431:26 | last | lib/lib.js:436:19:436:22 | last | provenance | | | lib/lib.js:432:6:432:13 | arr | lib/lib.js:437:9:437:11 | arr | provenance | | +| lib/lib.js:432:6:432:13 | arr [ArrayElement] | lib/lib.js:437:9:437:11 | arr [ArrayElement] | provenance | | | lib/lib.js:436:10:436:12 | [post update] arr | lib/lib.js:432:6:432:13 | arr | provenance | | +| lib/lib.js:436:10:436:12 | [post update] arr [ArrayElement] | lib/lib.js:432:6:432:13 | arr [ArrayElement] | provenance | | | lib/lib.js:436:19:436:22 | last | lib/lib.js:436:10:436:12 | [post update] arr | provenance | | +| lib/lib.js:436:19:436:22 | last | lib/lib.js:436:10:436:12 | [post update] arr [ArrayElement] | provenance | | | lib/lib.js:441:39:441:42 | name | lib/lib.js:442:24:442:27 | name | provenance | | | lib/lib.js:446:20:446:23 | name | lib/lib.js:447:25:447:28 | name | provenance | | | lib/lib.js:477:33:477:38 | config | lib/lib.js:478:27:478:32 | config | provenance | | @@ -116,9 +125,10 @@ edges | lib/lib.js:509:39:509:42 | name | lib/lib.js:545:23:545:26 | name | provenance | | | lib/lib.js:550:39:550:42 | name | lib/lib.js:555:33:555:36 | name | provenance | | | lib/lib.js:550:39:550:42 | name | lib/lib.js:555:33:555:36 | name | provenance | | -| lib/lib.js:551:33:551:36 | args | lib/lib.js:552:23:552:26 | args | provenance | | -| lib/lib.js:555:25:555:37 | ["-rf", name] | lib/lib.js:551:33:551:36 | args | provenance | | -| lib/lib.js:555:33:555:36 | name | lib/lib.js:555:25:555:37 | ["-rf", name] | provenance | | +| lib/lib.js:551:33:551:36 | args [1] | lib/lib.js:552:23:552:26 | args [1] | provenance | | +| lib/lib.js:552:23:552:26 | args [1] | lib/lib.js:552:23:552:26 | args | provenance | | +| lib/lib.js:555:25:555:37 | ["-rf", name] [1] | lib/lib.js:551:33:551:36 | args [1] | provenance | | +| lib/lib.js:555:33:555:36 | name | lib/lib.js:555:25:555:37 | ["-rf", name] [1] | provenance | | | lib/lib.js:558:41:558:44 | name | lib/lib.js:560:26:560:29 | name | provenance | | | lib/lib.js:558:41:558:44 | name | lib/lib.js:562:26:562:29 | name | provenance | | | lib/lib.js:558:41:558:44 | name | lib/lib.js:566:26:566:29 | name | provenance | | @@ -267,19 +277,26 @@ nodes | lib/lib.js:420:29:420:32 | name | semmle.label | name | | lib/lib.js:424:24:424:27 | name | semmle.label | name | | lib/lib.js:425:6:425:13 | arr | semmle.label | arr | +| lib/lib.js:425:6:425:13 | arr [ArrayElement] | semmle.label | arr [ArrayElement] | | lib/lib.js:426:2:426:4 | [post update] arr | semmle.label | [post update] arr | +| lib/lib.js:426:2:426:4 | [post update] arr [ArrayElement] | semmle.label | [post update] arr [ArrayElement] | | lib/lib.js:426:11:426:14 | name | semmle.label | name | | lib/lib.js:426:11:426:14 | name | semmle.label | name | | lib/lib.js:427:14:427:16 | arr | semmle.label | arr | +| lib/lib.js:427:14:427:16 | arr [ArrayElement] | semmle.label | arr [ArrayElement] | | lib/lib.js:428:14:428:58 | build(" ... + '-') | semmle.label | build(" ... + '-') | +| lib/lib.js:428:14:428:58 | build(" ... + '-') [ArrayElement] | semmle.label | build(" ... + '-') [ArrayElement] | | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | semmle.label | (name ? ... ) + '-' | | lib/lib.js:428:36:428:39 | name | semmle.label | name | | lib/lib.js:431:23:431:26 | last | semmle.label | last | | lib/lib.js:432:6:432:13 | arr | semmle.label | arr | +| lib/lib.js:432:6:432:13 | arr [ArrayElement] | semmle.label | arr [ArrayElement] | | lib/lib.js:436:10:436:12 | [post update] arr | semmle.label | [post update] arr | +| lib/lib.js:436:10:436:12 | [post update] arr [ArrayElement] | semmle.label | [post update] arr [ArrayElement] | | lib/lib.js:436:19:436:22 | last | semmle.label | last | | lib/lib.js:436:19:436:22 | last | semmle.label | last | | lib/lib.js:437:9:437:11 | arr | semmle.label | arr | +| lib/lib.js:437:9:437:11 | arr [ArrayElement] | semmle.label | arr [ArrayElement] | | lib/lib.js:441:39:441:42 | name | semmle.label | name | | lib/lib.js:442:24:442:27 | name | semmle.label | name | | lib/lib.js:446:20:446:23 | name | semmle.label | name | @@ -301,9 +318,10 @@ nodes | lib/lib.js:543:23:543:26 | name | semmle.label | name | | lib/lib.js:545:23:545:26 | name | semmle.label | name | | lib/lib.js:550:39:550:42 | name | semmle.label | name | -| lib/lib.js:551:33:551:36 | args | semmle.label | args | +| lib/lib.js:551:33:551:36 | args [1] | semmle.label | args [1] | | lib/lib.js:552:23:552:26 | args | semmle.label | args | -| lib/lib.js:555:25:555:37 | ["-rf", name] | semmle.label | ["-rf", name] | +| lib/lib.js:552:23:552:26 | args [1] | semmle.label | args [1] | +| lib/lib.js:555:25:555:37 | ["-rf", name] [1] | semmle.label | ["-rf", name] [1] | | lib/lib.js:555:33:555:36 | name | semmle.label | name | | lib/lib.js:555:33:555:36 | name | semmle.label | name | | lib/lib.js:558:41:558:44 | name | semmle.label | name | @@ -341,6 +359,7 @@ subpaths | lib/lib.js:251:27:251:30 | name | lib/lib.js:239:28:239:28 | s | lib/lib.js:245:9:245:9 | s | lib/lib.js:251:16:251:31 | cleanInput(name) | | lib/lib.js:340:25:340:25 | n | lib/lib.js:329:13:329:13 | x | lib/lib.js:330:9:330:9 | x | lib/lib.js:340:22:340:26 | id(n) | | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:431:23:431:26 | last | lib/lib.js:437:9:437:11 | arr | lib/lib.js:428:14:428:58 | build(" ... + '-') | +| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:431:23:431:26 | last | lib/lib.js:437:9:437:11 | arr [ArrayElement] | lib/lib.js:428:14:428:58 | build(" ... + '-') [ArrayElement] | #select | lib/isImported.js:6:10:6:25 | "rm -rf " + name | lib/isImported.js:5:49:5:52 | name | lib/isImported.js:6:22:6:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/isImported.js:5:49:5:52 | name | library input | lib/isImported.js:6:2:6:26 | cp.exec ... + name) | shell command | | lib/lib2.js:4:10:4:25 | "rm -rf " + name | lib/lib2.js:3:28:3:31 | name | lib/lib2.js:4:22:4:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib2.js:3:28:3:31 | name | library input | lib/lib2.js:4:2:4:26 | cp.exec ... + name) | shell command | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index db6b8453219..99fd4461775 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -265,7 +265,9 @@ nodes | react-use-router.js:11:24:11:35 | router.query | semmle.label | router.query | | react-use-router.js:11:24:11:42 | router.query.foobar | semmle.label | router.query.foobar | | react-use-router.js:23:31:23:36 | [post update] router | semmle.label | [post update] router | +| react-use-router.js:23:31:23:36 | [post update] router [ArrayElement] | semmle.label | [post update] router [ArrayElement] | | react-use-router.js:23:43:23:48 | router | semmle.label | router | +| react-use-router.js:23:43:23:48 | router [ArrayElement] | semmle.label | router [ArrayElement] | | react-use-router.js:23:43:23:54 | router.query | semmle.label | router.query | | react-use-router.js:23:43:23:61 | router.query.foobar | semmle.label | router.query.foobar | | react-use-router.js:33:21:33:32 | router.query | semmle.label | router.query | @@ -540,6 +542,7 @@ nodes | tst.js:421:20:421:27 | match[1] | semmle.label | match[1] | | tst.js:424:18:424:37 | window.location.hash | semmle.label | window.location.hash | | tst.js:424:18:424:48 | window. ... it('#') | semmle.label | window. ... it('#') | +| tst.js:424:18:424:48 | window. ... it('#') [ArrayElement] | semmle.label | window. ... it('#') [ArrayElement] | | tst.js:424:18:424:51 | window. ... '#')[1] | semmle.label | window. ... '#')[1] | | tst.js:428:7:428:39 | target | semmle.label | target | | tst.js:428:16:428:39 | documen ... .search | semmle.label | documen ... .search | @@ -590,6 +593,7 @@ nodes | various-concat-obfuscations.js:5:12:5:18 | tainted | semmle.label | tainted | | various-concat-obfuscations.js:6:4:6:26 | "
    " ... ainted) | semmle.label | "
    " ... ainted) | | various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") | semmle.label | "
    " ... /div>") | +| various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") [ArrayElement] | semmle.label | "
    " ... /div>") [ArrayElement] | | various-concat-obfuscations.js:6:19:6:25 | tainted | semmle.label | tainted | | various-concat-obfuscations.js:7:4:7:31 | ["
    ... /div>"] | semmle.label | ["
    ... /div>"] | | various-concat-obfuscations.js:7:4:7:38 | ["
    ... .join() | semmle.label | ["
    ... .join() | @@ -600,6 +604,7 @@ nodes | various-concat-obfuscations.js:10:16:10:22 | tainted | semmle.label | tainted | | various-concat-obfuscations.js:11:4:11:31 | "
    ") | semmle.label | "
    ") | +| various-concat-obfuscations.js:11:4:11:44 | "
    ") [ArrayElement] | semmle.label | "
    ") [ArrayElement] | | various-concat-obfuscations.js:11:24:11:30 | tainted | semmle.label | tainted | | various-concat-obfuscations.js:12:4:12:34 | ["
    "] | semmle.label | ["
    "] | | various-concat-obfuscations.js:12:4:12:41 | ["
    ') | semmle.label | '
    ') | +| various-concat-obfuscations.js:18:10:18:105 | '
    ') [ArrayElement] | semmle.label | '
    ') [ArrayElement] | | various-concat-obfuscations.js:18:32:18:36 | attrs | semmle.label | attrs | | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | semmle.label | attrs.defaultattr | | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | semmle.label | attrs.d ... 'left' | @@ -621,6 +627,7 @@ nodes | various-concat-obfuscations.js:20:17:20:40 | documen ... .search | semmle.label | documen ... .search | | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | semmle.label | documen ... h.attrs | | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | semmle.label | indirec ... .attrs) | +| various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) [ArrayElement] | semmle.label | indirec ... .attrs) [ArrayElement] | | various-concat-obfuscations.js:21:17:21:40 | documen ... .search | semmle.label | documen ... .search | | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | semmle.label | documen ... h.attrs | | winjs.js:2:7:2:53 | tainted | semmle.label | tainted | @@ -882,9 +889,12 @@ edges | react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | provenance | | | react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | provenance | | | react-use-router.js:23:31:23:36 | [post update] router | react-use-router.js:23:43:23:48 | router | provenance | | +| react-use-router.js:23:31:23:36 | [post update] router [ArrayElement] | react-use-router.js:23:43:23:48 | router [ArrayElement] | provenance | | | react-use-router.js:23:43:23:48 | router | react-use-router.js:23:43:23:54 | router.query | provenance | | +| react-use-router.js:23:43:23:48 | router [ArrayElement] | react-use-router.js:23:43:23:54 | router.query | provenance | | | react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | provenance | | | react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:31:23:36 | [post update] router | provenance | | +| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:31:23:36 | [post update] router [ArrayElement] | provenance | | | react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | provenance | | | react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | provenance | | | react-use-state.js:4:10:4:14 | state | react-use-state.js:4:9:4:49 | state | provenance | | @@ -1026,7 +1036,7 @@ edges | tst.js:70:1:70:27 | [,docum ... search] | tst.js:70:46:70:46 | x | provenance | | | tst.js:70:1:70:27 | [,docum ... search] | tst.js:70:46:70:46 | x | provenance | Config | | tst.js:70:1:70:27 | [,docum ... search] [1] | tst.js:70:46:70:46 | x | provenance | | -| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] | provenance | | +| tst.js:70:1:70:27 | [,docum ... search] [1] | tst.js:70:46:70:46 | x | provenance | Config | | tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] | provenance | Config | | tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] [1] | provenance | | | tst.js:70:46:70:46 | x | tst.js:73:20:73:20 | x | provenance | | @@ -1134,8 +1144,11 @@ edges | tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | provenance | Config | | tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | provenance | | | tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | provenance | Config | +| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') [ArrayElement] | provenance | | | tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | | tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | Config | +| tst.js:424:18:424:48 | window. ... it('#') [ArrayElement] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | +| tst.js:424:18:424:48 | window. ... it('#') [ArrayElement] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | Config | | tst.js:428:7:428:39 | target | tst.js:430:18:430:23 | target | provenance | | | tst.js:428:16:428:39 | documen ... .search | tst.js:428:7:428:39 | target | provenance | | | tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | provenance | | @@ -1184,12 +1197,16 @@ edges | various-concat-obfuscations.js:4:14:4:20 | tainted | various-concat-obfuscations.js:4:4:4:31 | "
    " ...
    " | provenance | Config | | various-concat-obfuscations.js:5:12:5:18 | tainted | various-concat-obfuscations.js:5:4:5:26 | `
    $ ...
    ` | provenance | Config | | various-concat-obfuscations.js:6:4:6:26 | "
    " ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") | provenance | | +| various-concat-obfuscations.js:6:4:6:26 | "
    " ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") [ArrayElement] | provenance | | +| various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") [ArrayElement] | various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") | provenance | | | various-concat-obfuscations.js:6:19:6:25 | tainted | various-concat-obfuscations.js:6:4:6:26 | "
    " ... ainted) | provenance | Config | | various-concat-obfuscations.js:7:4:7:31 | ["
    ... /div>"] | various-concat-obfuscations.js:7:4:7:38 | ["
    ... .join() | provenance | | | various-concat-obfuscations.js:7:14:7:20 | tainted | various-concat-obfuscations.js:7:4:7:31 | ["
    ... /div>"] | provenance | Config | | various-concat-obfuscations.js:9:19:9:25 | tainted | various-concat-obfuscations.js:9:4:9:34 | "
    " | provenance | Config | | various-concat-obfuscations.js:10:16:10:22 | tainted | various-concat-obfuscations.js:10:4:10:27 | `
    ` | provenance | Config | | various-concat-obfuscations.js:11:4:11:31 | "
    ") | provenance | | +| various-concat-obfuscations.js:11:4:11:31 | "
    ") [ArrayElement] | provenance | | +| various-concat-obfuscations.js:11:4:11:44 | "
    ") [ArrayElement] | various-concat-obfuscations.js:11:4:11:44 | "
    ") | provenance | | | various-concat-obfuscations.js:11:24:11:30 | tainted | various-concat-obfuscations.js:11:4:11:31 | "
    "] | various-concat-obfuscations.js:12:4:12:41 | ["
    "] | provenance | Config | @@ -1202,7 +1219,9 @@ edges | various-concat-obfuscations.js:18:10:18:59 | '
    ') | provenance | | +| various-concat-obfuscations.js:18:10:18:88 | '
    ') [ArrayElement] | provenance | | | various-concat-obfuscations.js:18:10:18:88 | '
    ') | provenance | | +| various-concat-obfuscations.js:18:10:18:88 | '
    ') [ArrayElement] | provenance | | | various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | provenance | | | various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | provenance | Config | | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | provenance | | @@ -1211,10 +1230,12 @@ edges | various-concat-obfuscations.js:20:17:20:40 | documen ... .search | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | provenance | Config | | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:14:24:14:28 | attrs | provenance | | | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) | provenance | Config | +| various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) [ArrayElement] | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | provenance | | | various-concat-obfuscations.js:21:17:21:40 | documen ... .search | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | provenance | | | various-concat-obfuscations.js:21:17:21:40 | documen ... .search | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | provenance | Config | | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | provenance | | | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | provenance | Config | +| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) [ArrayElement] | provenance | Config | | winjs.js:2:7:2:53 | tainted | winjs.js:3:43:3:49 | tainted | provenance | | | winjs.js:2:7:2:53 | tainted | winjs.js:4:43:4:49 | tainted | provenance | | | winjs.js:2:17:2:40 | documen ... .search | winjs.js:2:17:2:53 | documen ... ring(1) | provenance | | @@ -1232,6 +1253,7 @@ subpaths | tst.js:58:26:58:30 | bar() | tst.js:48:15:48:15 | s | tst.js:50:12:50:22 | s.substr(1) | tst.js:58:21:58:31 | chop(bar()) | | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:14:24:14:28 | attrs | various-concat-obfuscations.js:15:10:15:83 | '
    ' | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) | | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:10:18:105 | '
    ') | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | +| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:10:18:105 | '
    ') [ArrayElement] | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) [ArrayElement] | #select | addEventListener.js:2:20:2:29 | event.data | addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:29 | event.data | Cross-site scripting vulnerability due to $@. | addEventListener.js:1:43:1:47 | event | user-provided value | | addEventListener.js:6:20:6:23 | data | addEventListener.js:5:43:5:48 | {data} | addEventListener.js:6:20:6:23 | data | Cross-site scripting vulnerability due to $@. | addEventListener.js:5:43:5:48 | {data} | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index 2cbf440a6b5..afd5effb4c3 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -270,7 +270,9 @@ nodes | react-use-router.js:11:24:11:35 | router.query | semmle.label | router.query | | react-use-router.js:11:24:11:42 | router.query.foobar | semmle.label | router.query.foobar | | react-use-router.js:23:31:23:36 | [post update] router | semmle.label | [post update] router | +| react-use-router.js:23:31:23:36 | [post update] router [ArrayElement] | semmle.label | [post update] router [ArrayElement] | | react-use-router.js:23:43:23:48 | router | semmle.label | router | +| react-use-router.js:23:43:23:48 | router [ArrayElement] | semmle.label | router [ArrayElement] | | react-use-router.js:23:43:23:54 | router.query | semmle.label | router.query | | react-use-router.js:23:43:23:61 | router.query.foobar | semmle.label | router.query.foobar | | react-use-router.js:33:21:33:32 | router.query | semmle.label | router.query | @@ -545,6 +547,7 @@ nodes | tst.js:421:20:421:27 | match[1] | semmle.label | match[1] | | tst.js:424:18:424:37 | window.location.hash | semmle.label | window.location.hash | | tst.js:424:18:424:48 | window. ... it('#') | semmle.label | window. ... it('#') | +| tst.js:424:18:424:48 | window. ... it('#') [ArrayElement] | semmle.label | window. ... it('#') [ArrayElement] | | tst.js:424:18:424:51 | window. ... '#')[1] | semmle.label | window. ... '#')[1] | | tst.js:428:7:428:39 | target | semmle.label | target | | tst.js:428:16:428:39 | documen ... .search | semmle.label | documen ... .search | @@ -597,6 +600,7 @@ nodes | various-concat-obfuscations.js:5:12:5:18 | tainted | semmle.label | tainted | | various-concat-obfuscations.js:6:4:6:26 | "
    " ... ainted) | semmle.label | "
    " ... ainted) | | various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") | semmle.label | "
    " ... /div>") | +| various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") [ArrayElement] | semmle.label | "
    " ... /div>") [ArrayElement] | | various-concat-obfuscations.js:6:19:6:25 | tainted | semmle.label | tainted | | various-concat-obfuscations.js:7:4:7:31 | ["
    ... /div>"] | semmle.label | ["
    ... /div>"] | | various-concat-obfuscations.js:7:4:7:38 | ["
    ... .join() | semmle.label | ["
    ... .join() | @@ -607,6 +611,7 @@ nodes | various-concat-obfuscations.js:10:16:10:22 | tainted | semmle.label | tainted | | various-concat-obfuscations.js:11:4:11:31 | "
    ") | semmle.label | "
    ") | +| various-concat-obfuscations.js:11:4:11:44 | "
    ") [ArrayElement] | semmle.label | "
    ") [ArrayElement] | | various-concat-obfuscations.js:11:24:11:30 | tainted | semmle.label | tainted | | various-concat-obfuscations.js:12:4:12:34 | ["
    "] | semmle.label | ["
    "] | | various-concat-obfuscations.js:12:4:12:41 | ["
    ') | semmle.label | '
    ') | +| various-concat-obfuscations.js:18:10:18:105 | '
    ') [ArrayElement] | semmle.label | '
    ') [ArrayElement] | | various-concat-obfuscations.js:18:32:18:36 | attrs | semmle.label | attrs | | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | semmle.label | attrs.defaultattr | | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | semmle.label | attrs.d ... 'left' | @@ -628,6 +634,7 @@ nodes | various-concat-obfuscations.js:20:17:20:40 | documen ... .search | semmle.label | documen ... .search | | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | semmle.label | documen ... h.attrs | | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | semmle.label | indirec ... .attrs) | +| various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) [ArrayElement] | semmle.label | indirec ... .attrs) [ArrayElement] | | various-concat-obfuscations.js:21:17:21:40 | documen ... .search | semmle.label | documen ... .search | | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | semmle.label | documen ... h.attrs | | winjs.js:2:7:2:53 | tainted | semmle.label | tainted | @@ -907,9 +914,12 @@ edges | react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | provenance | | | react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | provenance | | | react-use-router.js:23:31:23:36 | [post update] router | react-use-router.js:23:43:23:48 | router | provenance | | +| react-use-router.js:23:31:23:36 | [post update] router [ArrayElement] | react-use-router.js:23:43:23:48 | router [ArrayElement] | provenance | | | react-use-router.js:23:43:23:48 | router | react-use-router.js:23:43:23:54 | router.query | provenance | | +| react-use-router.js:23:43:23:48 | router [ArrayElement] | react-use-router.js:23:43:23:54 | router.query | provenance | | | react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | provenance | | | react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:31:23:36 | [post update] router | provenance | | +| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:31:23:36 | [post update] router [ArrayElement] | provenance | | | react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | provenance | | | react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | provenance | | | react-use-state.js:4:10:4:14 | state | react-use-state.js:4:9:4:49 | state | provenance | | @@ -1051,7 +1061,7 @@ edges | tst.js:70:1:70:27 | [,docum ... search] | tst.js:70:46:70:46 | x | provenance | | | tst.js:70:1:70:27 | [,docum ... search] | tst.js:70:46:70:46 | x | provenance | Config | | tst.js:70:1:70:27 | [,docum ... search] [1] | tst.js:70:46:70:46 | x | provenance | | -| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] | provenance | | +| tst.js:70:1:70:27 | [,docum ... search] [1] | tst.js:70:46:70:46 | x | provenance | Config | | tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] | provenance | Config | | tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] [1] | provenance | | | tst.js:70:46:70:46 | x | tst.js:73:20:73:20 | x | provenance | | @@ -1159,8 +1169,11 @@ edges | tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | provenance | Config | | tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | provenance | | | tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | provenance | Config | +| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') [ArrayElement] | provenance | | | tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | | tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | Config | +| tst.js:424:18:424:48 | window. ... it('#') [ArrayElement] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | +| tst.js:424:18:424:48 | window. ... it('#') [ArrayElement] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | Config | | tst.js:428:7:428:39 | target | tst.js:430:18:430:23 | target | provenance | | | tst.js:428:16:428:39 | documen ... .search | tst.js:428:7:428:39 | target | provenance | | | tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | provenance | | @@ -1210,12 +1223,16 @@ edges | various-concat-obfuscations.js:4:14:4:20 | tainted | various-concat-obfuscations.js:4:4:4:31 | "
    " ...
    " | provenance | Config | | various-concat-obfuscations.js:5:12:5:18 | tainted | various-concat-obfuscations.js:5:4:5:26 | `
    $ ...
    ` | provenance | Config | | various-concat-obfuscations.js:6:4:6:26 | "
    " ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") | provenance | | +| various-concat-obfuscations.js:6:4:6:26 | "
    " ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") [ArrayElement] | provenance | | +| various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") [ArrayElement] | various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") | provenance | | | various-concat-obfuscations.js:6:19:6:25 | tainted | various-concat-obfuscations.js:6:4:6:26 | "
    " ... ainted) | provenance | Config | | various-concat-obfuscations.js:7:4:7:31 | ["
    ... /div>"] | various-concat-obfuscations.js:7:4:7:38 | ["
    ... .join() | provenance | | | various-concat-obfuscations.js:7:14:7:20 | tainted | various-concat-obfuscations.js:7:4:7:31 | ["
    ... /div>"] | provenance | Config | | various-concat-obfuscations.js:9:19:9:25 | tainted | various-concat-obfuscations.js:9:4:9:34 | "
    " | provenance | Config | | various-concat-obfuscations.js:10:16:10:22 | tainted | various-concat-obfuscations.js:10:4:10:27 | `
    ` | provenance | Config | | various-concat-obfuscations.js:11:4:11:31 | "
    ") | provenance | | +| various-concat-obfuscations.js:11:4:11:31 | "
    ") [ArrayElement] | provenance | | +| various-concat-obfuscations.js:11:4:11:44 | "
    ") [ArrayElement] | various-concat-obfuscations.js:11:4:11:44 | "
    ") | provenance | | | various-concat-obfuscations.js:11:24:11:30 | tainted | various-concat-obfuscations.js:11:4:11:31 | "
    "] | various-concat-obfuscations.js:12:4:12:41 | ["
    "] | provenance | Config | @@ -1228,7 +1245,9 @@ edges | various-concat-obfuscations.js:18:10:18:59 | '
    ') | provenance | | +| various-concat-obfuscations.js:18:10:18:88 | '
    ') [ArrayElement] | provenance | | | various-concat-obfuscations.js:18:10:18:88 | '
    ') | provenance | | +| various-concat-obfuscations.js:18:10:18:88 | '
    ') [ArrayElement] | provenance | | | various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | provenance | | | various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | provenance | Config | | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | provenance | | @@ -1237,10 +1256,12 @@ edges | various-concat-obfuscations.js:20:17:20:40 | documen ... .search | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | provenance | Config | | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:14:24:14:28 | attrs | provenance | | | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) | provenance | Config | +| various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) [ArrayElement] | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | provenance | | | various-concat-obfuscations.js:21:17:21:40 | documen ... .search | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | provenance | | | various-concat-obfuscations.js:21:17:21:40 | documen ... .search | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | provenance | Config | | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | provenance | | | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | provenance | Config | +| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) [ArrayElement] | provenance | Config | | winjs.js:2:7:2:53 | tainted | winjs.js:3:43:3:49 | tainted | provenance | | | winjs.js:2:7:2:53 | tainted | winjs.js:4:43:4:49 | tainted | provenance | | | winjs.js:2:17:2:40 | documen ... .search | winjs.js:2:17:2:53 | documen ... ring(1) | provenance | | @@ -1270,6 +1291,7 @@ subpaths | tst.js:58:26:58:30 | bar() | tst.js:48:15:48:15 | s | tst.js:50:12:50:22 | s.substr(1) | tst.js:58:21:58:31 | chop(bar()) | | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:14:24:14:28 | attrs | various-concat-obfuscations.js:15:10:15:83 | '
    ' | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) | | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:10:18:105 | '
    ') | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | +| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:10:18:105 | '
    ') [ArrayElement] | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) [ArrayElement] | #select | jwt.js:6:14:6:20 | decoded | jwt.js:4:36:4:39 | data | jwt.js:6:14:6:20 | decoded | Cross-site scripting vulnerability due to $@. | jwt.js:4:36:4:39 | data | user-provided value | | typeahead.js:10:16:10:18 | loc | typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | Cross-site scripting vulnerability due to $@. | typeahead.js:9:28:9:30 | loc | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ExceptionXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ExceptionXss.expected index 798632aabb1..a862c47907c 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ExceptionXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ExceptionXss.expected @@ -16,7 +16,7 @@ nodes | exception-xss.js:21:11:21:21 | foo + "bar" | semmle.label | foo + "bar" | | exception-xss.js:22:11:22:11 | e | semmle.label | e | | exception-xss.js:23:18:23:18 | e | semmle.label | e | -| exception-xss.js:33:11:33:22 | ["bar", foo] | semmle.label | ["bar", foo] | +| exception-xss.js:33:11:33:22 | ["bar", foo] [1] | semmle.label | ["bar", foo] [1] | | exception-xss.js:33:19:33:21 | foo | semmle.label | foo | | exception-xss.js:34:11:34:11 | e | semmle.label | e | | exception-xss.js:35:18:35:18 | e | semmle.label | e | @@ -42,7 +42,7 @@ nodes | exception-xss.js:89:11:89:26 | foo.match(/foo/) | semmle.label | foo.match(/foo/) | | exception-xss.js:90:11:90:11 | e | semmle.label | e | | exception-xss.js:91:18:91:18 | e | semmle.label | e | -| exception-xss.js:95:11:95:22 | [foo, "bar"] | semmle.label | [foo, "bar"] | +| exception-xss.js:95:11:95:22 | [foo, "bar"] [0] | semmle.label | [foo, "bar"] [0] | | exception-xss.js:95:12:95:14 | foo | semmle.label | foo | | exception-xss.js:96:11:96:11 | e | semmle.label | e | | exception-xss.js:97:18:97:18 | e | semmle.label | e | @@ -100,8 +100,8 @@ edges | exception-xss.js:21:11:21:13 | foo | exception-xss.js:21:11:21:21 | foo + "bar" | provenance | | | exception-xss.js:21:11:21:21 | foo + "bar" | exception-xss.js:22:11:22:11 | e | provenance | Config | | exception-xss.js:22:11:22:11 | e | exception-xss.js:23:18:23:18 | e | provenance | | -| exception-xss.js:33:11:33:22 | ["bar", foo] | exception-xss.js:34:11:34:11 | e | provenance | Config | -| exception-xss.js:33:19:33:21 | foo | exception-xss.js:33:11:33:22 | ["bar", foo] | provenance | | +| exception-xss.js:33:11:33:22 | ["bar", foo] [1] | exception-xss.js:34:11:34:11 | e | provenance | Config | +| exception-xss.js:33:19:33:21 | foo | exception-xss.js:33:11:33:22 | ["bar", foo] [1] | provenance | | | exception-xss.js:34:11:34:11 | e | exception-xss.js:35:18:35:18 | e | provenance | | | exception-xss.js:38:16:38:16 | x | exception-xss.js:39:9:39:9 | x | provenance | | | exception-xss.js:39:9:39:9 | x | exception-xss.js:39:3:39:10 | exceptional return of deep2(x) | provenance | Config | @@ -124,8 +124,8 @@ edges | exception-xss.js:89:11:89:13 | foo | exception-xss.js:89:11:89:26 | foo.match(/foo/) | provenance | | | exception-xss.js:89:11:89:26 | foo.match(/foo/) | exception-xss.js:90:11:90:11 | e | provenance | Config | | exception-xss.js:90:11:90:11 | e | exception-xss.js:91:18:91:18 | e | provenance | | -| exception-xss.js:95:11:95:22 | [foo, "bar"] | exception-xss.js:96:11:96:11 | e | provenance | Config | -| exception-xss.js:95:12:95:14 | foo | exception-xss.js:95:11:95:22 | [foo, "bar"] | provenance | | +| exception-xss.js:95:11:95:22 | [foo, "bar"] [0] | exception-xss.js:96:11:96:11 | e | provenance | Config | +| exception-xss.js:95:12:95:14 | foo | exception-xss.js:95:11:95:22 | [foo, "bar"] [0] | provenance | | | exception-xss.js:96:11:96:11 | e | exception-xss.js:97:18:97:18 | e | provenance | | | exception-xss.js:102:12:102:14 | foo | exception-xss.js:106:11:106:11 | e | provenance | Config | | exception-xss.js:106:11:106:11 | e | exception-xss.js:107:18:107:18 | e | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected index 3b3b0501e19..33b967f346c 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected @@ -10,15 +10,22 @@ edges | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:19:45:19:48 | file | provenance | | | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:22:16:22:21 | files3 | provenance | | | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:22:16:22:21 | files3 | provenance | | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:22:16:22:21 | files3 [ArrayElement] | provenance | | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:22:16:22:21 | files3 [ArrayElement] | provenance | | | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:19:45:19:48 | file | provenance | | | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:19:45:19:48 | file | provenance | | | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 | provenance | | | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 | provenance | | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 [ArrayElement] | provenance | | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 [ArrayElement] | provenance | | | xss-through-filenames.js:19:45:19:48 | file | xss-through-filenames.js:20:34:20:37 | file | provenance | | | xss-through-filenames.js:20:25:20:47 | '
  • ' ... '
  • ' | xss-through-filenames.js:20:13:20:18 | [post update] files3 | provenance | | +| xss-through-filenames.js:20:25:20:47 | '
  • ' ... '
  • ' | xss-through-filenames.js:20:13:20:18 | [post update] files3 [ArrayElement] | provenance | | | xss-through-filenames.js:20:34:20:37 | file | xss-through-filenames.js:20:25:20:47 | '
  • ' ... '
  • ' | provenance | | | xss-through-filenames.js:22:16:22:21 | files3 | xss-through-filenames.js:22:16:22:30 | files3.join('') | provenance | | | xss-through-filenames.js:22:16:22:21 | files3 | xss-through-filenames.js:22:16:22:30 | files3.join('') | provenance | | +| xss-through-filenames.js:22:16:22:21 | files3 [ArrayElement] | xss-through-filenames.js:22:16:22:30 | files3.join('') | provenance | | +| xss-through-filenames.js:22:16:22:21 | files3 [ArrayElement] | xss-through-filenames.js:22:16:22:30 | files3.join('') | provenance | | | xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 | provenance | | | xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:30:9:30:14 | files1 | provenance | | | xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:30:34:30:37 | file | provenance | | @@ -29,6 +36,7 @@ edges | xss-through-filenames.js:31:25:31:28 | file | xss-through-filenames.js:31:13:31:18 | [post update] files2 | provenance | | | xss-through-filenames.js:31:25:31:28 | file | xss-through-filenames.js:31:13:31:18 | [post update] files2 [ArrayElement] | provenance | | | xss-through-filenames.js:33:19:33:24 | files2 | xss-through-filenames.js:35:29:35:34 | files2 | provenance | | +| xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | xss-through-filenames.js:33:19:33:24 | files2 | provenance | | | xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | provenance | | | xss-through-filenames.js:35:13:35:35 | files3 | xss-through-filenames.js:37:19:37:24 | files3 | provenance | | | xss-through-filenames.js:35:22:35:35 | format(files2) | xss-through-filenames.js:35:13:35:35 | files3 | provenance | | @@ -51,10 +59,13 @@ nodes | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | semmle.label | files2.sort(sort) [ArrayElement] | | xss-through-filenames.js:19:45:19:48 | file | semmle.label | file | | xss-through-filenames.js:20:13:20:18 | [post update] files3 | semmle.label | [post update] files3 | +| xss-through-filenames.js:20:13:20:18 | [post update] files3 [ArrayElement] | semmle.label | [post update] files3 [ArrayElement] | | xss-through-filenames.js:20:25:20:47 | '
  • ' ... '
  • ' | semmle.label | '
  • ' ... '
  • ' | | xss-through-filenames.js:20:34:20:37 | file | semmle.label | file | | xss-through-filenames.js:22:16:22:21 | files3 | semmle.label | files3 | | xss-through-filenames.js:22:16:22:21 | files3 | semmle.label | files3 | +| xss-through-filenames.js:22:16:22:21 | files3 [ArrayElement] | semmle.label | files3 [ArrayElement] | +| xss-through-filenames.js:22:16:22:21 | files3 [ArrayElement] | semmle.label | files3 [ArrayElement] | | xss-through-filenames.js:22:16:22:30 | files3.join('') | semmle.label | files3.join('') | | xss-through-filenames.js:22:16:22:30 | files3.join('') | semmle.label | files3.join('') | | xss-through-filenames.js:25:43:25:48 | files1 | semmle.label | files1 | @@ -78,8 +89,12 @@ nodes subpaths | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:19:45:19:48 | file | xss-through-filenames.js:20:13:20:18 | [post update] files3 | xss-through-filenames.js:22:16:22:21 | files3 | | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:19:45:19:48 | file | xss-through-filenames.js:20:13:20:18 | [post update] files3 | xss-through-filenames.js:22:16:22:21 | files3 | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:19:45:19:48 | file | xss-through-filenames.js:20:13:20:18 | [post update] files3 [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 [ArrayElement] | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:19:45:19:48 | file | xss-through-filenames.js:20:13:20:18 | [post update] files3 [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 [ArrayElement] | | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:19:45:19:48 | file | xss-through-filenames.js:20:13:20:18 | [post update] files3 | xss-through-filenames.js:22:16:22:21 | files3 | | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:19:45:19:48 | file | xss-through-filenames.js:20:13:20:18 | [post update] files3 | xss-through-filenames.js:22:16:22:21 | files3 | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:19:45:19:48 | file | xss-through-filenames.js:20:13:20:18 | [post update] files3 [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 [ArrayElement] | +| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:19:45:19:48 | file | xss-through-filenames.js:20:13:20:18 | [post update] files3 [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 [ArrayElement] | | xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:30:34:30:37 | file | xss-through-filenames.js:31:13:31:18 | [post update] files2 | xss-through-filenames.js:33:19:33:24 | files2 | | xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:30:34:30:37 | file | xss-through-filenames.js:31:13:31:18 | [post update] files2 | xss-through-filenames.js:33:19:33:24 | files2 | | xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:30:34:30:37 | file | xss-through-filenames.js:31:13:31:18 | [post update] files2 [ArrayElement] | xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected index b70b13b4c1b..6c1a83cc421 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected @@ -53,11 +53,14 @@ nodes | koarouter.js:5:11:5:33 | version | semmle.label | version | | koarouter.js:5:13:5:19 | version | semmle.label | version | | koarouter.js:11:11:11:28 | conditions | semmle.label | conditions | +| koarouter.js:11:11:11:28 | conditions [ArrayElement] | semmle.label | conditions [ArrayElement] | | koarouter.js:14:9:14:18 | [post update] conditions | semmle.label | [post update] conditions | +| koarouter.js:14:9:14:18 | [post update] conditions [ArrayElement] | semmle.label | [post update] conditions [ArrayElement] | | koarouter.js:14:25:14:46 | `versio ... rsion}` | semmle.label | `versio ... rsion}` | | koarouter.js:14:38:14:44 | version | semmle.label | version | | koarouter.js:17:27:17:77 | `SELECT ... nd ')}` | semmle.label | `SELECT ... nd ')}` | | koarouter.js:17:52:17:61 | conditions | semmle.label | conditions | +| koarouter.js:17:52:17:61 | conditions [ArrayElement] | semmle.label | conditions [ArrayElement] | | koarouter.js:17:52:17:75 | conditi ... and ') | semmle.label | conditi ... and ') | | ldap.js:20:7:20:34 | q | semmle.label | q | | ldap.js:20:11:20:34 | url.par ... , true) | semmle.label | url.par ... , true) | @@ -240,6 +243,9 @@ nodes | pg-promise.js:30:13:30:25 | req.params.id | semmle.label | req.params.id | | pg-promise.js:34:13:34:25 | req.params.id | semmle.label | req.params.id | | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | semmle.label | [\\n ... n\\n ] | +| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [0] | semmle.label | [\\n ... n\\n ] [0] | +| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [1] | semmle.label | [\\n ... n\\n ] [1] | +| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [2] | semmle.label | [\\n ... n\\n ] [2] | | pg-promise.js:39:7:39:19 | req.params.id | semmle.label | req.params.id | | pg-promise.js:40:7:40:21 | req.params.name | semmle.label | req.params.name | | pg-promise.js:41:7:41:20 | req.params.foo | semmle.label | req.params.foo | @@ -325,10 +331,14 @@ edges | koarouter.js:5:11:5:33 | version | koarouter.js:14:38:14:44 | version | provenance | | | koarouter.js:5:13:5:19 | version | koarouter.js:5:11:5:33 | version | provenance | | | koarouter.js:11:11:11:28 | conditions | koarouter.js:17:52:17:61 | conditions | provenance | | +| koarouter.js:11:11:11:28 | conditions [ArrayElement] | koarouter.js:17:52:17:61 | conditions [ArrayElement] | provenance | | | koarouter.js:14:9:14:18 | [post update] conditions | koarouter.js:11:11:11:28 | conditions | provenance | | +| koarouter.js:14:9:14:18 | [post update] conditions [ArrayElement] | koarouter.js:11:11:11:28 | conditions [ArrayElement] | provenance | | | koarouter.js:14:25:14:46 | `versio ... rsion}` | koarouter.js:14:9:14:18 | [post update] conditions | provenance | | +| koarouter.js:14:25:14:46 | `versio ... rsion}` | koarouter.js:14:9:14:18 | [post update] conditions [ArrayElement] | provenance | | | koarouter.js:14:38:14:44 | version | koarouter.js:14:25:14:46 | `versio ... rsion}` | provenance | | | koarouter.js:17:52:17:61 | conditions | koarouter.js:17:52:17:75 | conditi ... and ') | provenance | | +| koarouter.js:17:52:17:61 | conditions [ArrayElement] | koarouter.js:17:52:17:75 | conditi ... and ') | provenance | | | koarouter.js:17:52:17:75 | conditi ... and ') | koarouter.js:17:27:17:77 | `SELECT ... nd ')}` | provenance | | | ldap.js:20:7:20:34 | q | ldap.js:22:18:22:18 | q | provenance | | | ldap.js:20:11:20:34 | url.par ... , true) | ldap.js:20:7:20:34 | q | provenance | | @@ -602,9 +612,12 @@ edges | pg-promise.js:22:11:22:15 | query | pg-promise.js:60:20:60:24 | query | provenance | | | pg-promise.js:22:11:22:15 | query | pg-promise.js:63:23:63:27 | query | provenance | | | pg-promise.js:22:11:22:15 | query | pg-promise.js:64:16:64:20 | query | provenance | | -| pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | provenance | | -| pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | provenance | | -| pg-promise.js:41:7:41:20 | req.params.foo | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | provenance | | +| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [0] | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | provenance | | +| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [1] | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | provenance | | +| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [2] | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | provenance | | +| pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [0] | provenance | | +| pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [1] | provenance | | +| pg-promise.js:41:7:41:20 | req.params.foo | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [2] | provenance | | | redis.js:10:16:10:23 | req.body | redis.js:10:16:10:27 | req.body.key | provenance | Config | | redis.js:12:9:12:26 | key | redis.js:13:16:13:18 | key | provenance | | | redis.js:12:9:12:26 | key | redis.js:18:16:18:18 | key | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/ImproperCodeSanitization.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/ImproperCodeSanitization.expected index 6e8db046097..1600e99b12f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/ImproperCodeSanitization.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/ImproperCodeSanitization.expected @@ -2,20 +2,27 @@ edges | bad-code-sanitization.js:2:12:2:90 | /^[_$a- ... key)}]` | bad-code-sanitization.js:7:31:7:43 | safeProp(key) | provenance | | | bad-code-sanitization.js:2:69:2:87 | JSON.stringify(key) | bad-code-sanitization.js:2:12:2:90 | /^[_$a- ... key)}]` | provenance | | | bad-code-sanitization.js:6:11:6:25 | statements | bad-code-sanitization.js:8:27:8:36 | statements | provenance | | +| bad-code-sanitization.js:6:11:6:25 | statements [ArrayElement] | bad-code-sanitization.js:8:27:8:36 | statements [ArrayElement] | provenance | | | bad-code-sanitization.js:7:5:7:14 | [post update] statements | bad-code-sanitization.js:6:11:6:25 | statements | provenance | | +| bad-code-sanitization.js:7:5:7:14 | [post update] statements [ArrayElement] | bad-code-sanitization.js:6:11:6:25 | statements [ArrayElement] | provenance | | | bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | bad-code-sanitization.js:7:5:7:14 | [post update] statements | provenance | | +| bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | bad-code-sanitization.js:7:5:7:14 | [post update] statements [ArrayElement] | provenance | | | bad-code-sanitization.js:7:31:7:43 | safeProp(key) | bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | provenance | | | bad-code-sanitization.js:8:27:8:36 | statements | bad-code-sanitization.js:8:27:8:46 | statements.join(';') | provenance | | +| bad-code-sanitization.js:8:27:8:36 | statements [ArrayElement] | bad-code-sanitization.js:8:27:8:46 | statements.join(';') | provenance | | | bad-code-sanitization.js:63:11:63:55 | assignment | bad-code-sanitization.js:64:27:64:36 | assignment | provenance | | | bad-code-sanitization.js:63:31:63:49 | JSON.stringify(key) | bad-code-sanitization.js:63:11:63:55 | assignment | provenance | | nodes | bad-code-sanitization.js:2:12:2:90 | /^[_$a- ... key)}]` | semmle.label | /^[_$a- ... key)}]` | | bad-code-sanitization.js:2:69:2:87 | JSON.stringify(key) | semmle.label | JSON.stringify(key) | | bad-code-sanitization.js:6:11:6:25 | statements | semmle.label | statements | +| bad-code-sanitization.js:6:11:6:25 | statements [ArrayElement] | semmle.label | statements [ArrayElement] | | bad-code-sanitization.js:7:5:7:14 | [post update] statements | semmle.label | [post update] statements | +| bad-code-sanitization.js:7:5:7:14 | [post update] statements [ArrayElement] | semmle.label | [post update] statements [ArrayElement] | | bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | semmle.label | `${name ... key])}` | | bad-code-sanitization.js:7:31:7:43 | safeProp(key) | semmle.label | safeProp(key) | | bad-code-sanitization.js:8:27:8:36 | statements | semmle.label | statements | +| bad-code-sanitization.js:8:27:8:36 | statements [ArrayElement] | semmle.label | statements [ArrayElement] | | bad-code-sanitization.js:8:27:8:46 | statements.join(';') | semmle.label | statements.join(';') | | bad-code-sanitization.js:15:44:15:63 | htmlescape(pathname) | semmle.label | htmlescape(pathname) | | bad-code-sanitization.js:19:27:19:47 | JSON.st ... (input) | semmle.label | JSON.st ... (input) | diff --git a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index 8e50d05362e..b18ece7460a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -48,17 +48,32 @@ edges | passwords.js:135:17:135:22 | config [y] | passwords.js:135:17:135:22 | config | provenance | | | passwords.js:136:17:136:22 | config [x] | passwords.js:136:17:136:24 | config.x | provenance | | | passwords.js:137:17:137:22 | config [y] | passwords.js:137:17:137:24 | config.y | provenance | | +| passwords.js:142:26:142:34 | [apply call taint node] | passwords.js:142:26:142:34 | arguments [ArrayElement] | provenance | | +| passwords.js:142:26:142:34 | [apply call taint node] | passwords.js:142:26:142:34 | arguments [ArrayElement] | provenance | | +| passwords.js:142:26:142:34 | arguments | passwords.js:142:26:142:34 | [apply call taint node] | provenance | | +| passwords.js:142:26:142:34 | arguments [0] | passwords.js:142:26:142:34 | [apply call taint node] | provenance | | +| passwords.js:142:26:142:34 | arguments [0] | passwords.js:142:26:142:34 | arguments | provenance | | +| passwords.js:142:26:142:34 | arguments [ArrayElement] | passwords.js:142:26:142:34 | [apply call taint node] | provenance | | +| passwords.js:142:26:142:34 | arguments [ArrayElement] | passwords.js:142:26:142:34 | [apply call taint node] | provenance | | +| passwords.js:142:26:142:34 | arguments [ArrayElement] | passwords.js:142:26:142:34 | arguments | provenance | | +| passwords.js:142:26:142:34 | arguments [ArrayElement] | passwords.js:142:26:142:34 | arguments | provenance | | | passwords.js:146:9:148:5 | config [x] | passwords.js:149:21:149:26 | config [x] | provenance | | | passwords.js:146:18:148:5 | {\\n ... d\\n } [x] | passwords.js:146:9:148:5 | config [x] | provenance | | | passwords.js:147:12:147:19 | password | passwords.js:146:18:148:5 | {\\n ... d\\n } [x] | provenance | | | passwords.js:149:21:149:26 | config [x] | passwords.js:149:21:149:28 | config.x | provenance | | | passwords.js:149:21:149:28 | config.x | passwords.js:142:26:142:34 | arguments | provenance | Config | +| passwords.js:149:21:149:28 | config.x | passwords.js:142:26:142:34 | arguments | provenance | Config | +| passwords.js:149:21:149:28 | config.x | passwords.js:142:26:142:34 | arguments [0] | provenance | | | passwords.js:150:21:150:31 | process.env | passwords.js:142:26:142:34 | arguments | provenance | Config | +| passwords.js:150:21:150:31 | process.env | passwords.js:142:26:142:34 | arguments | provenance | Config | +| passwords.js:150:21:150:31 | process.env | passwords.js:142:26:142:34 | arguments [0] | provenance | | | passwords.js:152:9:152:63 | procdesc | passwords.js:154:21:154:28 | procdesc | provenance | | | passwords.js:152:20:152:44 | Util.in ... ss.env) | passwords.js:152:20:152:63 | Util.in ... /g, '') | provenance | | | passwords.js:152:20:152:63 | Util.in ... /g, '') | passwords.js:152:9:152:63 | procdesc | provenance | | | passwords.js:152:33:152:43 | process.env | passwords.js:152:20:152:44 | Util.in ... ss.env) | provenance | | | passwords.js:154:21:154:28 | procdesc | passwords.js:142:26:142:34 | arguments | provenance | Config | +| passwords.js:154:21:154:28 | procdesc | passwords.js:142:26:142:34 | arguments | provenance | Config | +| passwords.js:154:21:154:28 | procdesc | passwords.js:142:26:142:34 | arguments [0] | provenance | | | passwords.js:163:14:163:21 | password | passwords.js:163:14:163:41 | passwor ... g, "*") | provenance | | | passwords.js:164:14:164:21 | password | passwords.js:164:14:164:42 | passwor ... g, "*") | provenance | | | passwords.js:169:17:169:24 | password | passwords.js:169:17:169:45 | passwor ... g, "*") | provenance | | @@ -137,7 +152,13 @@ nodes | passwords.js:136:17:136:24 | config.x | semmle.label | config.x | | passwords.js:137:17:137:22 | config [y] | semmle.label | config [y] | | passwords.js:137:17:137:24 | config.y | semmle.label | config.y | +| passwords.js:142:26:142:34 | [apply call taint node] | semmle.label | [apply call taint node] | +| passwords.js:142:26:142:34 | [apply call taint node] | semmle.label | [apply call taint node] | | passwords.js:142:26:142:34 | arguments | semmle.label | arguments | +| passwords.js:142:26:142:34 | arguments | semmle.label | arguments | +| passwords.js:142:26:142:34 | arguments [0] | semmle.label | arguments [0] | +| passwords.js:142:26:142:34 | arguments [ArrayElement] | semmle.label | arguments [ArrayElement] | +| passwords.js:142:26:142:34 | arguments [ArrayElement] | semmle.label | arguments [ArrayElement] | | passwords.js:146:9:148:5 | config [x] | semmle.label | config [x] | | passwords.js:146:18:148:5 | {\\n ... d\\n } [x] | semmle.label | {\\n ... d\\n } [x] | | passwords.js:147:12:147:19 | password | semmle.label | password | diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected index 2d21c332482..da41dd5354d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected @@ -3,8 +3,9 @@ edges | lib/indirect.js:1:32:1:32 | x | lib/indirect.js:2:16:2:16 | x | provenance | | | lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name | provenance | | | lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name | provenance | | -| lib/lib.js:32:32:32:40 | arguments | lib/lib.js:35:1:37:1 | 'arguments' object of function usedWithArguments | provenance | | -| lib/lib.js:35:1:37:1 | 'arguments' object of function usedWithArguments | lib/lib.js:35:28:35:31 | name | provenance | | +| lib/lib.js:32:32:32:40 | [apply call taint node] | lib/lib.js:32:32:32:40 | arguments [ArrayElement] | provenance | | +| lib/lib.js:32:32:32:40 | arguments | lib/lib.js:32:32:32:40 | [apply call taint node] | provenance | | +| lib/lib.js:32:32:32:40 | arguments [ArrayElement] | lib/lib.js:35:28:35:31 | name | provenance | | | lib/lib.js:35:28:35:31 | name | lib/lib.js:36:13:36:16 | name | provenance | | | lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | provenance | | | lib/lib.js:41:32:41:35 | name | lib/lib.js:44:12:44:15 | name | provenance | | @@ -359,8 +360,9 @@ nodes | lib/lib.js:4:14:4:17 | name | semmle.label | name | | lib/lib.js:7:19:7:22 | name | semmle.label | name | | lib/lib.js:8:13:8:16 | name | semmle.label | name | +| lib/lib.js:32:32:32:40 | [apply call taint node] | semmle.label | [apply call taint node] | | lib/lib.js:32:32:32:40 | arguments | semmle.label | arguments | -| lib/lib.js:35:1:37:1 | 'arguments' object of function usedWithArguments | semmle.label | 'arguments' object of function usedWithArguments | +| lib/lib.js:32:32:32:40 | arguments [ArrayElement] | semmle.label | arguments [ArrayElement] | | lib/lib.js:35:28:35:31 | name | semmle.label | name | | lib/lib.js:36:13:36:16 | name | semmle.label | name | | lib/lib.js:41:32:41:35 | name | semmle.label | name | diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected b/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected index ac29a57bf83..aa992b9c707 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected +++ b/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected @@ -10,6 +10,10 @@ edges | express.js:83:7:83:34 | target | express.js:90:18:90:23 | target | provenance | | | express.js:83:7:83:34 | target | express.js:97:16:97:21 | target | provenance | | | express.js:83:16:83:34 | req.param("target") | express.js:83:7:83:34 | target | provenance | | +| express.js:118:16:118:63 | [req.qu ... ection] | express.js:118:16:118:72 | [req.qu ... oin('') | provenance | | +| express.js:118:16:118:63 | [req.qu ... ection] [0] | express.js:118:16:118:72 | [req.qu ... oin('') | provenance | | +| express.js:118:17:118:30 | req.query.page | express.js:118:16:118:63 | [req.qu ... ection] | provenance | | +| express.js:118:17:118:30 | req.query.page | express.js:118:16:118:63 | [req.qu ... ection] [0] | provenance | | | express.js:118:17:118:30 | req.query.page | express.js:118:16:118:72 | [req.qu ... oin('') | provenance | | | express.js:134:22:134:36 | req.params.user | express.js:134:16:134:36 | '/' + r ... ms.user | provenance | | | express.js:135:23:135:37 | req.params.user | express.js:135:16:135:37 | '//' + ... ms.user | provenance | | @@ -18,9 +22,13 @@ edges | express.js:150:7:150:34 | target | express.js:160:18:160:23 | target | provenance | | | express.js:150:16:150:34 | req.param("target") | express.js:150:7:150:34 | target | provenance | | | express.js:164:7:164:54 | myThing | express.js:165:16:165:22 | myThing | provenance | | +| express.js:164:7:164:54 | myThing [ArrayElement] | express.js:165:16:165:22 | myThing [ArrayElement] | provenance | | | express.js:164:17:164:41 | JSON.st ... .query) | express.js:164:17:164:54 | JSON.st ... (1, -1) | provenance | | +| express.js:164:17:164:41 | JSON.st ... .query) | express.js:164:17:164:54 | JSON.st ... (1, -1) [ArrayElement] | provenance | | | express.js:164:17:164:54 | JSON.st ... (1, -1) | express.js:164:7:164:54 | myThing | provenance | | +| express.js:164:17:164:54 | JSON.st ... (1, -1) [ArrayElement] | express.js:164:7:164:54 | myThing [ArrayElement] | provenance | | | express.js:164:32:164:40 | req.query | express.js:164:17:164:41 | JSON.st ... .query) | provenance | | +| express.js:165:16:165:22 | myThing [ArrayElement] | express.js:165:16:165:22 | myThing | provenance | | | koa.js:6:6:6:27 | url | koa.js:7:15:7:17 | url | provenance | | | koa.js:6:6:6:27 | url | koa.js:8:18:8:20 | url | provenance | | | koa.js:6:6:6:27 | url | koa.js:14:16:14:18 | url | provenance | | @@ -62,6 +70,8 @@ nodes | express.js:83:16:83:34 | req.param("target") | semmle.label | req.param("target") | | express.js:90:18:90:23 | target | semmle.label | target | | express.js:97:16:97:21 | target | semmle.label | target | +| express.js:118:16:118:63 | [req.qu ... ection] | semmle.label | [req.qu ... ection] | +| express.js:118:16:118:63 | [req.qu ... ection] [0] | semmle.label | [req.qu ... ection] [0] | | express.js:118:16:118:72 | [req.qu ... oin('') | semmle.label | [req.qu ... oin('') | | express.js:118:17:118:30 | req.query.page | semmle.label | req.query.page | | express.js:134:16:134:36 | '/' + r ... ms.user | semmle.label | '/' + r ... ms.user | @@ -77,10 +87,13 @@ nodes | express.js:155:18:155:23 | target | semmle.label | target | | express.js:160:18:160:23 | target | semmle.label | target | | express.js:164:7:164:54 | myThing | semmle.label | myThing | +| express.js:164:7:164:54 | myThing [ArrayElement] | semmle.label | myThing [ArrayElement] | | express.js:164:17:164:41 | JSON.st ... .query) | semmle.label | JSON.st ... .query) | | express.js:164:17:164:54 | JSON.st ... (1, -1) | semmle.label | JSON.st ... (1, -1) | +| express.js:164:17:164:54 | JSON.st ... (1, -1) [ArrayElement] | semmle.label | JSON.st ... (1, -1) [ArrayElement] | | express.js:164:32:164:40 | req.query | semmle.label | req.query | | express.js:165:16:165:22 | myThing | semmle.label | myThing | +| express.js:165:16:165:22 | myThing [ArrayElement] | semmle.label | myThing [ArrayElement] | | koa.js:6:6:6:27 | url | semmle.label | url | | koa.js:6:12:6:27 | ctx.query.target | semmle.label | ctx.query.target | | koa.js:7:15:7:17 | url | semmle.label | url | diff --git a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected index 4a5af8a6e00..b6622ba3dbc 100644 --- a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected @@ -29,8 +29,11 @@ edges | RegExpInjection.js:33:12:33:14 | key | RegExpInjection.js:29:21:29:21 | s | provenance | | | RegExpInjection.js:34:12:34:19 | getKey() | RegExpInjection.js:29:21:29:21 | s | provenance | | | RegExpInjection.js:54:14:54:16 | key | RegExpInjection.js:54:14:54:27 | key.split(".") | provenance | | +| RegExpInjection.js:54:14:54:16 | key | RegExpInjection.js:54:14:54:27 | key.split(".") [ArrayElement] | provenance | | | RegExpInjection.js:54:14:54:27 | key.split(".") | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | provenance | | +| RegExpInjection.js:54:14:54:27 | key.split(".") [ArrayElement] | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) [ArrayElement] | provenance | | | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | provenance | | +| RegExpInjection.js:54:14:54:42 | key.spl ... x => x) [ArrayElement] | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | provenance | | | RegExpInjection.js:60:31:60:56 | input | RegExpInjection.js:64:14:64:18 | input | provenance | | | RegExpInjection.js:60:39:60:56 | req.param("input") | RegExpInjection.js:60:31:60:56 | input | provenance | | | RegExpInjection.js:82:7:82:32 | input | RegExpInjection.js:87:25:87:29 | input | provenance | | @@ -74,7 +77,9 @@ nodes | RegExpInjection.js:47:26:47:30 | input | semmle.label | input | | RegExpInjection.js:54:14:54:16 | key | semmle.label | key | | RegExpInjection.js:54:14:54:27 | key.split(".") | semmle.label | key.split(".") | +| RegExpInjection.js:54:14:54:27 | key.split(".") [ArrayElement] | semmle.label | key.split(".") [ArrayElement] | | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | semmle.label | key.spl ... x => x) | +| RegExpInjection.js:54:14:54:42 | key.spl ... x => x) [ArrayElement] | semmle.label | key.spl ... x => x) [ArrayElement] | | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | semmle.label | key.spl ... in("-") | | RegExpInjection.js:60:31:60:56 | input | semmle.label | input | | RegExpInjection.js:60:39:60:56 | req.param("input") | semmle.label | req.param("input") | diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/PrototypePollutingFunction.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/PrototypePollutingFunction.expected index 1c21a699533..77719fd65c7 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/PrototypePollutingFunction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingFunction/PrototypePollutingFunction.expected @@ -97,8 +97,12 @@ nodes | tests.js:18:24:18:31 | src[key] | semmle.label | src[key] | | tests.js:18:28:18:30 | key | semmle.label | key | | tests.js:23:19:23:21 | dst | semmle.label | dst | +| tests.js:23:27:23:33 | sources [0] | semmle.label | sources [0] | +| tests.js:24:14:24:19 | source | semmle.label | source | +| tests.js:24:24:24:30 | sources [0] | semmle.label | sources [0] | | tests.js:25:18:25:20 | key | semmle.label | key | | tests.js:26:25:26:27 | dst | semmle.label | dst | +| tests.js:26:30:26:35 | source | semmle.label | source | | tests.js:26:30:26:40 | source[key] | semmle.label | source[key] | | tests.js:26:37:26:39 | key | semmle.label | key | | tests.js:26:43:26:45 | key | semmle.label | key | @@ -110,6 +114,7 @@ nodes | tests.js:32:20:32:27 | dst[key] | semmle.label | dst[key] | | tests.js:32:24:32:26 | key | semmle.label | key | | tests.js:34:18:34:25 | dstValue | semmle.label | dstValue | +| tests.js:34:28:34:32 | value | semmle.label | value | | tests.js:36:9:36:11 | dst | semmle.label | dst | | tests.js:36:13:36:15 | key | semmle.label | key | | tests.js:36:20:36:24 | value | semmle.label | value | @@ -567,8 +572,24 @@ nodes | tests.js:516:36:516:38 | key | semmle.label | key | | tests.js:517:35:517:37 | dst | semmle.label | dst | | tests.js:517:40:517:42 | key | semmle.label | key | +| tests.js:522:35:522:38 | args [0] | semmle.label | args [0] | +| tests.js:522:35:522:38 | args [1] | semmle.label | args [1] | +| tests.js:523:11:523:23 | dst | semmle.label | dst | +| tests.js:523:17:523:20 | args [0] | semmle.label | args [0] | +| tests.js:523:17:523:23 | args[0] | semmle.label | args[0] | +| tests.js:524:11:524:23 | src | semmle.label | src | +| tests.js:524:17:524:20 | args [1] | semmle.label | args [1] | +| tests.js:524:17:524:23 | args[1] | semmle.label | args[1] | | tests.js:525:14:525:16 | key | semmle.label | key | +| tests.js:527:35:527:37 | dst | semmle.label | dst | +| tests.js:527:35:527:42 | dst[key] | semmle.label | dst[key] | +| tests.js:527:39:527:41 | key | semmle.label | key | +| tests.js:527:45:527:47 | src | semmle.label | src | +| tests.js:527:45:527:52 | src[key] | semmle.label | src[key] | +| tests.js:527:49:527:51 | key | semmle.label | key | +| tests.js:529:13:529:15 | dst | semmle.label | dst | | tests.js:529:17:529:19 | key | semmle.label | key | +| tests.js:529:24:529:26 | src | semmle.label | src | | tests.js:529:24:529:31 | src[key] | semmle.label | src[key] | | tests.js:529:28:529:30 | key | semmle.label | key | | tests.js:534:31:534:33 | obj | semmle.label | obj | @@ -735,14 +756,19 @@ edges | tests.js:18:24:18:26 | src | tests.js:18:24:18:31 | src[key] | provenance | Config | | tests.js:18:28:18:30 | key | tests.js:18:24:18:31 | src[key] | provenance | Config | | tests.js:23:19:23:21 | dst | tests.js:26:25:26:27 | dst | provenance | | +| tests.js:23:27:23:33 | sources [0] | tests.js:24:24:24:30 | sources [0] | provenance | | +| tests.js:24:14:24:19 | source | tests.js:26:30:26:35 | source | provenance | | +| tests.js:24:24:24:30 | sources [0] | tests.js:24:14:24:19 | source | provenance | | | tests.js:25:18:25:20 | key | tests.js:26:37:26:39 | key | provenance | | | tests.js:25:18:25:20 | key | tests.js:26:43:26:45 | key | provenance | | | tests.js:26:25:26:27 | dst | tests.js:31:22:31:24 | dst | provenance | | +| tests.js:26:30:26:35 | source | tests.js:26:30:26:40 | source[key] | provenance | Config | | tests.js:26:30:26:40 | source[key] | tests.js:31:27:31:31 | value | provenance | | | tests.js:26:37:26:39 | key | tests.js:26:30:26:40 | source[key] | provenance | Config | | tests.js:26:43:26:45 | key | tests.js:31:34:31:36 | key | provenance | | | tests.js:31:22:31:24 | dst | tests.js:32:20:32:22 | dst | provenance | | | tests.js:31:22:31:24 | dst | tests.js:36:9:36:11 | dst | provenance | | +| tests.js:31:27:31:31 | value | tests.js:34:28:34:32 | value | provenance | | | tests.js:31:27:31:31 | value | tests.js:36:20:36:24 | value | provenance | | | tests.js:31:34:31:36 | key | tests.js:32:24:32:26 | key | provenance | | | tests.js:31:34:31:36 | key | tests.js:36:13:36:15 | key | provenance | | @@ -751,6 +777,7 @@ edges | tests.js:32:20:32:27 | dst[key] | tests.js:32:9:32:27 | dstValue | provenance | | | tests.js:32:24:32:26 | key | tests.js:32:20:32:27 | dst[key] | provenance | Config | | tests.js:34:18:34:25 | dstValue | tests.js:23:19:23:21 | dst | provenance | | +| tests.js:34:28:34:32 | value | tests.js:23:27:23:33 | sources [0] | provenance | | | tests.js:40:27:40:29 | dst | tests.js:44:30:44:32 | dst | provenance | | | tests.js:40:27:40:29 | dst | tests.js:46:13:46:15 | dst | provenance | | | tests.js:40:32:40:34 | src | tests.js:44:40:44:42 | src | provenance | | @@ -1257,8 +1284,27 @@ edges | tests.js:513:47:513:49 | key | tests.js:513:43:513:50 | src[key] | provenance | Config | | tests.js:516:32:516:34 | src | tests.js:516:32:516:39 | src[key] | provenance | Config | | tests.js:516:36:516:38 | key | tests.js:516:32:516:39 | src[key] | provenance | Config | +| tests.js:522:35:522:38 | args [0] | tests.js:523:17:523:20 | args [0] | provenance | | +| tests.js:522:35:522:38 | args [1] | tests.js:524:17:524:20 | args [1] | provenance | | +| tests.js:523:11:523:23 | dst | tests.js:527:35:527:37 | dst | provenance | | +| tests.js:523:11:523:23 | dst | tests.js:529:13:529:15 | dst | provenance | | +| tests.js:523:17:523:20 | args [0] | tests.js:523:17:523:23 | args[0] | provenance | | +| tests.js:523:17:523:23 | args[0] | tests.js:523:11:523:23 | dst | provenance | | +| tests.js:524:11:524:23 | src | tests.js:527:45:527:47 | src | provenance | | +| tests.js:524:11:524:23 | src | tests.js:529:24:529:26 | src | provenance | | +| tests.js:524:17:524:20 | args [1] | tests.js:524:17:524:23 | args[1] | provenance | | +| tests.js:524:17:524:23 | args[1] | tests.js:524:11:524:23 | src | provenance | | +| tests.js:525:14:525:16 | key | tests.js:527:39:527:41 | key | provenance | | +| tests.js:525:14:525:16 | key | tests.js:527:49:527:51 | key | provenance | | | tests.js:525:14:525:16 | key | tests.js:529:17:529:19 | key | provenance | | | tests.js:525:14:525:16 | key | tests.js:529:28:529:30 | key | provenance | | +| tests.js:527:35:527:37 | dst | tests.js:527:35:527:42 | dst[key] | provenance | Config | +| tests.js:527:35:527:42 | dst[key] | tests.js:522:35:522:38 | args [0] | provenance | | +| tests.js:527:39:527:41 | key | tests.js:527:35:527:42 | dst[key] | provenance | Config | +| tests.js:527:45:527:47 | src | tests.js:527:45:527:52 | src[key] | provenance | Config | +| tests.js:527:45:527:52 | src[key] | tests.js:522:35:522:38 | args [1] | provenance | | +| tests.js:527:49:527:51 | key | tests.js:527:45:527:52 | src[key] | provenance | Config | +| tests.js:529:24:529:26 | src | tests.js:529:24:529:31 | src[key] | provenance | Config | | tests.js:529:28:529:30 | key | tests.js:529:24:529:31 | src[key] | provenance | Config | | tests.js:534:31:534:33 | obj | tests.js:538:27:538:29 | obj | provenance | | | tests.js:534:36:534:43 | callback [dst] | tests.js:538:9:538:16 | callback [dst] | provenance | | @@ -1371,5 +1417,6 @@ subpaths | tests.js:477:13:477:15 | dst | tests.js:473:25:473:27 | key | tests.js:477:13:477:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:473:12:473:14 | src | src | tests.js:477:13:477:15 | dst | dst | | tests.js:489:13:489:15 | dst | tests.js:484:14:484:16 | key | tests.js:489:13:489:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:484:21:484:23 | src | src | tests.js:489:13:489:15 | dst | dst | | tests.js:517:35:517:37 | dst | tests.js:511:19:511:25 | keys[i] | tests.js:517:35:517:37 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:509:28:509:30 | src | src | tests.js:517:35:517:37 | dst | dst | +| tests.js:529:13:529:15 | dst | tests.js:525:14:525:16 | key | tests.js:529:13:529:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:525:21:525:23 | src | src | tests.js:529:13:529:15 | dst | dst | | tests.js:547:13:547:15 | dst | tests.js:538:18:538:24 | keys[i] | tests.js:547:13:547:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:535:30:535:32 | obj | obj | tests.js:547:13:547:15 | dst | dst | | tests.js:605:13:605:16 | dest | tests.js:601:16:601:18 | key | tests.js:605:13:605:16 | dest | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:601:35:601:40 | source | source | tests.js:605:13:605:16 | dest | dest | From 837a8be1b8de3ff08a799534d21ab70a3304956f Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 27 Aug 2024 11:31:02 +0200 Subject: [PATCH 257/514] JS: Update test output and add related TODO in 'markdown-table' model --- .../semmle/javascript/frameworks/Markdown.qll | 1 + .../ReflectedXss/ReflectedXss.expected | 36 ++++++++++++++----- .../CWE-079/ReflectedXss/ReflectedXss.js | 2 +- .../ReflectedXssWithCustomSanitizer.expected | 1 - 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Markdown.qll b/javascript/ql/lib/semmle/javascript/frameworks/Markdown.qll index fa8fd4da565..04f3c9f7db7 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Markdown.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Markdown.qll @@ -52,6 +52,7 @@ module Markdown { private class MarkdownTableStep extends MarkdownStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { exists(DataFlow::CallNode call | call = DataFlow::moduleImport("markdown-table").getACall() | + // TODO: needs a flow summary to ensure ArrayElement content is unfolded succ = call and pred = call.getArgument(0) ) diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected index c8e90d80737..ac9d399bd96 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected @@ -2,9 +2,6 @@ edges | ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | provenance | | | ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | provenance | | | ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) | provenance | | -| ReflectedXss.js:30:7:33:4 | mytable | ReflectedXss.js:34:12:34:18 | mytable | provenance | | -| ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | ReflectedXss.js:30:7:33:4 | mytable | provenance | | -| ReflectedXss.js:32:14:32:21 | req.body | ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | provenance | | | ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) | provenance | | | ReflectedXss.js:64:14:64:21 | req.body | ReflectedXss.js:64:39:64:42 | file | provenance | | | ReflectedXss.js:64:39:64:42 | file | ReflectedXss.js:65:16:65:19 | file | provenance | | @@ -26,12 +23,18 @@ edges | ReflectedXss.js:116:18:116:26 | queryKeys | ReflectedXss.js:116:11:116:45 | keys | provenance | | | ReflectedXss.js:116:31:116:45 | paramKeys?.keys | ReflectedXss.js:116:11:116:45 | keys | provenance | | | ReflectedXss.js:118:11:118:61 | keyArray | ReflectedXss.js:119:25:119:32 | keyArray | provenance | | -| ReflectedXss.js:118:50:118:53 | keys | ReflectedXss.js:118:11:118:61 | keyArray | provenance | | +| ReflectedXss.js:118:11:118:61 | keyArray [0] | ReflectedXss.js:119:25:119:32 | keyArray [0] | provenance | | +| ReflectedXss.js:118:49:118:54 | [keys] [0] | ReflectedXss.js:118:11:118:61 | keyArray [0] | provenance | | +| ReflectedXss.js:118:50:118:53 | keys | ReflectedXss.js:118:49:118:54 | [keys] [0] | provenance | | | ReflectedXss.js:118:58:118:61 | keys | ReflectedXss.js:118:11:118:61 | keyArray | provenance | | | ReflectedXss.js:119:11:119:72 | invalidKeys | ReflectedXss.js:122:33:122:43 | invalidKeys | provenance | | +| ReflectedXss.js:119:11:119:72 | invalidKeys [0] | ReflectedXss.js:122:33:122:43 | invalidKeys [0] | provenance | | | ReflectedXss.js:119:25:119:32 | keyArray | ReflectedXss.js:119:25:119:72 | keyArra ... s(key)) | provenance | | +| ReflectedXss.js:119:25:119:32 | keyArray [0] | ReflectedXss.js:119:25:119:72 | keyArra ... s(key)) [0] | provenance | | | ReflectedXss.js:119:25:119:72 | keyArra ... s(key)) | ReflectedXss.js:119:11:119:72 | invalidKeys | provenance | | +| ReflectedXss.js:119:25:119:72 | keyArra ... s(key)) [0] | ReflectedXss.js:119:11:119:72 | invalidKeys [0] | provenance | | | ReflectedXss.js:122:33:122:43 | invalidKeys | ReflectedXss.js:122:33:122:54 | invalid ... n(', ') | provenance | | +| ReflectedXss.js:122:33:122:43 | invalidKeys [0] | ReflectedXss.js:122:33:122:54 | invalid ... n(', ') | provenance | | | ReflectedXss.js:122:33:122:54 | invalid ... n(', ') | ReflectedXss.js:122:30:122:73 | `${inva ... telist` | provenance | | | ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | provenance | | | ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | provenance | | @@ -40,14 +43,22 @@ edges | ReflectedXssGood3.js:68:22:68:26 | value | ReflectedXssGood3.js:77:16:77:20 | value | provenance | | | ReflectedXssGood3.js:68:22:68:26 | value | ReflectedXssGood3.js:105:18:105:22 | value | provenance | | | ReflectedXssGood3.js:77:7:77:37 | parts | ReflectedXssGood3.js:108:10:108:14 | parts | provenance | | +| ReflectedXssGood3.js:77:7:77:37 | parts [0] | ReflectedXssGood3.js:108:10:108:14 | parts [0] | provenance | | +| ReflectedXssGood3.js:77:7:77:37 | parts [ArrayElement] | ReflectedXssGood3.js:108:10:108:14 | parts [ArrayElement] | provenance | | +| ReflectedXssGood3.js:77:15:77:37 | [value. ... (0, i)] [0] | ReflectedXssGood3.js:77:7:77:37 | parts [0] | provenance | | | ReflectedXssGood3.js:77:16:77:20 | value | ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | provenance | | | ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | ReflectedXssGood3.js:77:7:77:37 | parts | provenance | | +| ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | ReflectedXssGood3.js:77:15:77:37 | [value. ... (0, i)] [0] | provenance | | | ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | provenance | | | ReflectedXssGood3.js:105:7:105:11 | [post update] parts | ReflectedXssGood3.js:77:7:77:37 | parts | provenance | | | ReflectedXssGood3.js:105:7:105:11 | [post update] parts | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | provenance | | +| ReflectedXssGood3.js:105:7:105:11 | [post update] parts [ArrayElement] | ReflectedXssGood3.js:77:7:77:37 | parts [ArrayElement] | provenance | | | ReflectedXssGood3.js:105:18:105:22 | value | ReflectedXssGood3.js:105:18:105:38 | value.s ... g(j, i) | provenance | | | ReflectedXssGood3.js:105:18:105:38 | value.s ... g(j, i) | ReflectedXssGood3.js:105:7:105:11 | [post update] parts | provenance | | +| ReflectedXssGood3.js:105:18:105:38 | value.s ... g(j, i) | ReflectedXssGood3.js:105:7:105:11 | [post update] parts [ArrayElement] | provenance | | | ReflectedXssGood3.js:108:10:108:14 | parts | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | provenance | | +| ReflectedXssGood3.js:108:10:108:14 | parts [0] | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | provenance | | +| ReflectedXssGood3.js:108:10:108:14 | parts [ArrayElement] | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | provenance | | | ReflectedXssGood3.js:135:9:135:27 | url | ReflectedXssGood3.js:139:24:139:26 | url | provenance | | | ReflectedXssGood3.js:135:15:135:27 | req.params.id | ReflectedXssGood3.js:135:9:135:27 | url | provenance | | | ReflectedXssGood3.js:139:24:139:26 | url | ReflectedXssGood3.js:68:22:68:26 | value | provenance | | @@ -149,10 +160,6 @@ nodes | ReflectedXss.js:23:12:23:27 | marked(req.body) | semmle.label | marked(req.body) | | ReflectedXss.js:23:19:23:26 | req.body | semmle.label | req.body | | ReflectedXss.js:29:12:29:19 | req.body | semmle.label | req.body | -| ReflectedXss.js:30:7:33:4 | mytable | semmle.label | mytable | -| ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | semmle.label | table([ ... y]\\n ]) | -| ReflectedXss.js:32:14:32:21 | req.body | semmle.label | req.body | -| ReflectedXss.js:34:12:34:18 | mytable | semmle.label | mytable | | ReflectedXss.js:41:12:41:19 | req.body | semmle.label | req.body | | ReflectedXss.js:42:12:42:39 | convert ... q.body) | semmle.label | convert ... q.body) | | ReflectedXss.js:42:31:42:38 | req.body | semmle.label | req.body | @@ -188,13 +195,19 @@ nodes | ReflectedXss.js:116:18:116:26 | queryKeys | semmle.label | queryKeys | | ReflectedXss.js:116:31:116:45 | paramKeys?.keys | semmle.label | paramKeys?.keys | | ReflectedXss.js:118:11:118:61 | keyArray | semmle.label | keyArray | +| ReflectedXss.js:118:11:118:61 | keyArray [0] | semmle.label | keyArray [0] | +| ReflectedXss.js:118:49:118:54 | [keys] [0] | semmle.label | [keys] [0] | | ReflectedXss.js:118:50:118:53 | keys | semmle.label | keys | | ReflectedXss.js:118:58:118:61 | keys | semmle.label | keys | | ReflectedXss.js:119:11:119:72 | invalidKeys | semmle.label | invalidKeys | +| ReflectedXss.js:119:11:119:72 | invalidKeys [0] | semmle.label | invalidKeys [0] | | ReflectedXss.js:119:25:119:32 | keyArray | semmle.label | keyArray | +| ReflectedXss.js:119:25:119:32 | keyArray [0] | semmle.label | keyArray [0] | | ReflectedXss.js:119:25:119:72 | keyArra ... s(key)) | semmle.label | keyArra ... s(key)) | +| ReflectedXss.js:119:25:119:72 | keyArra ... s(key)) [0] | semmle.label | keyArra ... s(key)) [0] | | ReflectedXss.js:122:30:122:73 | `${inva ... telist` | semmle.label | `${inva ... telist` | | ReflectedXss.js:122:33:122:43 | invalidKeys | semmle.label | invalidKeys | +| ReflectedXss.js:122:33:122:43 | invalidKeys [0] | semmle.label | invalidKeys [0] | | ReflectedXss.js:122:33:122:54 | invalid ... n(', ') | semmle.label | invalid ... n(', ') | | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | semmle.label | "FOO: " ... rams.id | | ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | semmle.label | req.params.id | @@ -206,12 +219,18 @@ nodes | ReflectedXssContentTypes.js:70:22:70:34 | req.params.id | semmle.label | req.params.id | | ReflectedXssGood3.js:68:22:68:26 | value | semmle.label | value | | ReflectedXssGood3.js:77:7:77:37 | parts | semmle.label | parts | +| ReflectedXssGood3.js:77:7:77:37 | parts [0] | semmle.label | parts [0] | +| ReflectedXssGood3.js:77:7:77:37 | parts [ArrayElement] | semmle.label | parts [ArrayElement] | +| ReflectedXssGood3.js:77:15:77:37 | [value. ... (0, i)] [0] | semmle.label | [value. ... (0, i)] [0] | | ReflectedXssGood3.js:77:16:77:20 | value | semmle.label | value | | ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | semmle.label | value.s ... g(0, i) | | ReflectedXssGood3.js:105:7:105:11 | [post update] parts | semmle.label | [post update] parts | +| ReflectedXssGood3.js:105:7:105:11 | [post update] parts [ArrayElement] | semmle.label | [post update] parts [ArrayElement] | | ReflectedXssGood3.js:105:18:105:22 | value | semmle.label | value | | ReflectedXssGood3.js:105:18:105:38 | value.s ... g(j, i) | semmle.label | value.s ... g(j, i) | | ReflectedXssGood3.js:108:10:108:14 | parts | semmle.label | parts | +| ReflectedXssGood3.js:108:10:108:14 | parts [0] | semmle.label | parts [0] | +| ReflectedXssGood3.js:108:10:108:14 | parts [ArrayElement] | semmle.label | parts [ArrayElement] | | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | semmle.label | parts.join('') | | ReflectedXssGood3.js:135:9:135:27 | url | semmle.label | url | | ReflectedXssGood3.js:135:15:135:27 | req.params.id | semmle.label | req.params.id | @@ -335,7 +354,6 @@ subpaths | ReflectedXss.js:22:12:22:19 | req.body | ReflectedXss.js:22:12:22:19 | req.body | ReflectedXss.js:22:12:22:19 | req.body | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:22:12:22:19 | req.body | user-provided value | | ReflectedXss.js:23:12:23:27 | marked(req.body) | ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:23:19:23:26 | req.body | user-provided value | | ReflectedXss.js:29:12:29:19 | req.body | ReflectedXss.js:29:12:29:19 | req.body | ReflectedXss.js:29:12:29:19 | req.body | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:29:12:29:19 | req.body | user-provided value | -| ReflectedXss.js:34:12:34:18 | mytable | ReflectedXss.js:32:14:32:21 | req.body | ReflectedXss.js:34:12:34:18 | mytable | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:32:14:32:21 | req.body | user-provided value | | ReflectedXss.js:41:12:41:19 | req.body | ReflectedXss.js:41:12:41:19 | req.body | ReflectedXss.js:41:12:41:19 | req.body | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:41:12:41:19 | req.body | user-provided value | | ReflectedXss.js:42:12:42:39 | convert ... q.body) | ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:42:31:42:38 | req.body | user-provided value | | ReflectedXss.js:56:12:56:19 | req.body | ReflectedXss.js:56:12:56:19 | req.body | ReflectedXss.js:56:12:56:19 | req.body | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:56:12:56:19 | req.body | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.js b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.js index fc2e1abb888..c3b1cbc2da8 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.js @@ -31,7 +31,7 @@ app.get('/user/:id', function(req, res) { ['Name', 'Content'], ['body', req.body] ]); - res.send(mytable); // NOT OK + res.send(mytable); // NOT OK - FIXME: only works in OLD dataflow, add implicit reads before library-contributed taint steps }); var showdown = require('showdown'); diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.expected b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.expected index a367f07307a..d29b35203b8 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.expected @@ -3,7 +3,6 @@ | ReflectedXss.js:22:12:22:19 | req.body | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:22:12:22:19 | req.body | user-provided value | | ReflectedXss.js:23:12:23:27 | marked(req.body) | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:23:19:23:26 | req.body | user-provided value | | ReflectedXss.js:29:12:29:19 | req.body | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:29:12:29:19 | req.body | user-provided value | -| ReflectedXss.js:34:12:34:18 | mytable | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:32:14:32:21 | req.body | user-provided value | | ReflectedXss.js:41:12:41:19 | req.body | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:41:12:41:19 | req.body | user-provided value | | ReflectedXss.js:42:12:42:39 | convert ... q.body) | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:42:31:42:38 | req.body | user-provided value | | ReflectedXss.js:56:12:56:19 | req.body | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:56:12:56:19 | req.body | user-provided value | From a2d53c261bfbda691978aed9c62cccd2345816ec Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 26 Aug 2024 14:02:07 +0200 Subject: [PATCH 258/514] JS: Update test output and add related TODO in model of 'async' --- .../ql/lib/semmle/javascript/frameworks/AsyncPackage.qll | 2 +- .../frameworks/AsyncPackage/AsyncTaintTracking.expected | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/AsyncPackage.qll b/javascript/ql/lib/semmle/javascript/frameworks/AsyncPackage.qll index 26f5570bc14..4dc60d44765 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/AsyncPackage.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/AsyncPackage.qll @@ -142,7 +142,7 @@ module AsyncPackage { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { exists(DataFlow::FunctionNode iteratee, IterationCall call | iteratee = call.getIteratorCallback() and // Require a closure to avoid spurious call/return mismatch. - pred = call.getCollection() and + pred = call.getCollection() and // TODO: needs a flow summary to ensure ArrayElement content is unfolded succ = iteratee.getParameter(0) ) } diff --git a/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.expected b/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.expected index 50e18f938a5..168f5ec5ace 100644 --- a/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.expected +++ b/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.expected @@ -1,10 +1,10 @@ legacyDataFlowDifference +| each.js:11:9:11:16 | source() | each.js:13:12:13:15 | item | only flow with OLD data flow library | +| map.js:10:13:10:20 | source() | map.js:12:14:12:17 | item | only flow with OLD data flow library | +| map.js:26:13:26:20 | source() | map.js:28:27:28:32 | result | only flow with OLD data flow library | +| sortBy.js:10:22:10:29 | source() | sortBy.js:12:27:12:32 | result | only flow with OLD data flow library | #select -| each.js:11:9:11:16 | source() | each.js:13:12:13:15 | item | -| map.js:10:13:10:20 | source() | map.js:12:14:12:17 | item | | map.js:20:19:20:26 | source() | map.js:23:27:23:32 | result | -| map.js:26:13:26:20 | source() | map.js:28:27:28:32 | result | -| sortBy.js:10:22:10:29 | source() | sortBy.js:12:27:12:32 | result | | waterfall.js:8:30:8:37 | source() | waterfall.js:11:12:11:16 | taint | | waterfall.js:8:30:8:37 | source() | waterfall.js:20:10:20:14 | taint | | waterfall.js:28:18:28:25 | source() | waterfall.js:39:10:39:12 | err | From cb5dbb919d55e1bac1fc3918bd87e7cdec87ae66 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 27 Aug 2024 11:33:32 +0200 Subject: [PATCH 259/514] JS: Update test to reflect implicit read flow has been fixed Shows the effect of https://github.com/github/codeql/pull/17262 --- .../library-tests/TaintTracking/BasicTaintTracking.expected | 2 -- .../library-tests/TaintTracking/use-use-after-implicit-read.js | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 2a1ca5c57f6..42b7ea80e8d 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -35,7 +35,6 @@ legacyDataFlowDifference | spread.js:4:15:4:22 | source() | spread.js:18:8:18:8 | y | only flow with NEW data flow library | | spread.js:4:15:4:22 | source() | spread.js:24:8:24:8 | y | only flow with NEW data flow library | | use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:15:10:15:10 | x | only flow with NEW data flow library | -| use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:16:10:16:10 | y | only flow with NEW data flow library | consistencyIssue | library-tests/TaintTracking/nested-props.js:20 | expected an alert, but found none | NOT OK - but not found | Consistency | | library-tests/TaintTracking/stringification-read-steps.js:17 | expected an alert, but found none | NOT OK | Consistency | @@ -297,7 +296,6 @@ flow | tst.js:2:13:2:20 | source() | tst.js:54:14:54:19 | unsafe | | use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:8:10:8:17 | captured | | use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:15:10:15:10 | x | -| use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:16:10:16:10 | y | | 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 | diff --git a/javascript/ql/test/library-tests/TaintTracking/use-use-after-implicit-read.js b/javascript/ql/test/library-tests/TaintTracking/use-use-after-implicit-read.js index 17c11b6a505..73e433deb39 100644 --- a/javascript/ql/test/library-tests/TaintTracking/use-use-after-implicit-read.js +++ b/javascript/ql/test/library-tests/TaintTracking/use-use-after-implicit-read.js @@ -13,5 +13,5 @@ function f(x) { function g(x, y) { sink(x); // NOT OK - sink(y); // OK [INCONSISTENCY] - implicit read confuses array index + sink(y); // OK } From f65879eef10b35769b6fda8d62005f14b629a92d Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 27 Aug 2024 11:34:03 +0200 Subject: [PATCH 260/514] JS: Update a test that no longer fails --- javascript/ql/test/library-tests/TripleDot/tst.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/test/library-tests/TripleDot/tst.js b/javascript/ql/test/library-tests/TripleDot/tst.js index 1a0f000fd50..07bec92a92f 100644 --- a/javascript/ql/test/library-tests/TripleDot/tst.js +++ b/javascript/ql/test/library-tests/TripleDot/tst.js @@ -133,7 +133,7 @@ function t13() { function target(x, y, ...rest) { sink(x); // $ SPURIOUS: hasTaintFlow=t13.1 sink(y); // $ hasTaintFlow=t13.1 - sink(rest); // $ MISSING: hasTaintFlow=t13.1 + sink(rest); // $ hasTaintFlow=t13.1 sink(rest[0]); // $ MISSING: hasTaintFlow=t13.1 } target("safe", ...source('t13.1')); From 65a36b0b3b4d7471f4d77601eb683ecdcebcdc54 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 29 Aug 2024 13:41:58 +0200 Subject: [PATCH 261/514] JS: Add regression test for argument position confusion --- .../Security/CWE-079/DomBasedXss/Xss.expected | 23 +++++++++++++++++++ .../XssWithAdditionalSources.expected | 20 ++++++++++++++++ .../tainted-url-suffix-arguments.js | 13 +++++++++++ 3 files changed, 56 insertions(+) create mode 100644 javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tainted-url-suffix-arguments.js diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 99fd4461775..96aa177e4c2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -330,6 +330,16 @@ nodes | string-manipulations.js:9:36:9:57 | documen ... on.href | semmle.label | documen ... on.href | | string-manipulations.js:10:16:10:45 | String( ... n.href) | semmle.label | String( ... n.href) | | string-manipulations.js:10:23:10:44 | documen ... on.href | semmle.label | documen ... on.href | +| tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | semmle.label | 'arguments' object of function foo [1] | +| tainted-url-suffix-arguments.js:3:14:3:14 | x | semmle.label | x | +| tainted-url-suffix-arguments.js:3:17:3:17 | y | semmle.label | y | +| tainted-url-suffix-arguments.js:3:20:3:20 | z | semmle.label | z | +| tainted-url-suffix-arguments.js:5:22:5:22 | x | semmle.label | x | +| tainted-url-suffix-arguments.js:6:22:6:22 | y | semmle.label | y | +| tainted-url-suffix-arguments.js:7:22:7:22 | z | semmle.label | z | +| tainted-url-suffix-arguments.js:11:11:11:36 | url | semmle.label | url | +| tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | semmle.label | window.location.href | +| tainted-url-suffix-arguments.js:12:17:12:19 | url | semmle.label | url | | tooltip.jsx:6:11:6:30 | source | semmle.label | source | | tooltip.jsx:6:20:6:30 | window.name | semmle.label | window.name | | tooltip.jsx:10:25:10:30 | source | semmle.label | source | @@ -949,6 +959,16 @@ edges | string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | provenance | Config | | string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | provenance | | | string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | provenance | Config | +| tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | tainted-url-suffix-arguments.js:3:14:3:14 | x | provenance | Config | +| tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | tainted-url-suffix-arguments.js:3:17:3:17 | y | provenance | Config | +| tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | tainted-url-suffix-arguments.js:3:20:3:20 | z | provenance | Config | +| tainted-url-suffix-arguments.js:3:14:3:14 | x | tainted-url-suffix-arguments.js:5:22:5:22 | x | provenance | | +| tainted-url-suffix-arguments.js:3:17:3:17 | y | tainted-url-suffix-arguments.js:6:22:6:22 | y | provenance | | +| tainted-url-suffix-arguments.js:3:20:3:20 | z | tainted-url-suffix-arguments.js:7:22:7:22 | z | provenance | | +| tainted-url-suffix-arguments.js:11:11:11:36 | url | tainted-url-suffix-arguments.js:12:17:12:19 | url | provenance | | +| tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | tainted-url-suffix-arguments.js:11:11:11:36 | url | provenance | | +| tainted-url-suffix-arguments.js:12:17:12:19 | url | tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | provenance | | +| tainted-url-suffix-arguments.js:12:17:12:19 | url | tainted-url-suffix-arguments.js:3:17:3:17 | y | provenance | | | tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | provenance | | | tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | provenance | | | tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source | provenance | | @@ -1378,6 +1398,9 @@ subpaths | string-manipulations.js:8:16:8:48 | documen ... mLeft() | string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | Cross-site scripting vulnerability due to $@. | string-manipulations.js:8:16:8:37 | documen ... on.href | user-provided value | | string-manipulations.js:9:16:9:58 | String. ... n.href) | string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | Cross-site scripting vulnerability due to $@. | string-manipulations.js:9:36:9:57 | documen ... on.href | user-provided value | | string-manipulations.js:10:16:10:45 | String( ... n.href) | string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | Cross-site scripting vulnerability due to $@. | string-manipulations.js:10:23:10:44 | documen ... on.href | user-provided value | +| tainted-url-suffix-arguments.js:5:22:5:22 | x | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | tainted-url-suffix-arguments.js:5:22:5:22 | x | Cross-site scripting vulnerability due to $@. | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | user-provided value | +| tainted-url-suffix-arguments.js:6:22:6:22 | y | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | tainted-url-suffix-arguments.js:6:22:6:22 | y | Cross-site scripting vulnerability due to $@. | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | user-provided value | +| tainted-url-suffix-arguments.js:7:22:7:22 | z | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | tainted-url-suffix-arguments.js:7:22:7:22 | z | Cross-site scripting vulnerability due to $@. | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | user-provided value | | tooltip.jsx:10:25:10:30 | source | tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:10:25:10:30 | source | Cross-site scripting vulnerability due to $@. | tooltip.jsx:6:20:6:30 | window.name | user-provided value | | tooltip.jsx:11:25:11:30 | source | tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:11:25:11:30 | source | Cross-site scripting vulnerability due to $@. | tooltip.jsx:6:20:6:30 | window.name | user-provided value | | tooltip.jsx:18:51:18:59 | provide() | tooltip.jsx:22:20:22:30 | window.name | tooltip.jsx:18:51:18:59 | provide() | Cross-site scripting vulnerability due to $@. | tooltip.jsx:22:20:22:30 | window.name | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index afd5effb4c3..4f908c6fe10 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -335,6 +335,16 @@ nodes | string-manipulations.js:9:36:9:57 | documen ... on.href | semmle.label | documen ... on.href | | string-manipulations.js:10:16:10:45 | String( ... n.href) | semmle.label | String( ... n.href) | | string-manipulations.js:10:23:10:44 | documen ... on.href | semmle.label | documen ... on.href | +| tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | semmle.label | 'arguments' object of function foo [1] | +| tainted-url-suffix-arguments.js:3:14:3:14 | x | semmle.label | x | +| tainted-url-suffix-arguments.js:3:17:3:17 | y | semmle.label | y | +| tainted-url-suffix-arguments.js:3:20:3:20 | z | semmle.label | z | +| tainted-url-suffix-arguments.js:5:22:5:22 | x | semmle.label | x | +| tainted-url-suffix-arguments.js:6:22:6:22 | y | semmle.label | y | +| tainted-url-suffix-arguments.js:7:22:7:22 | z | semmle.label | z | +| tainted-url-suffix-arguments.js:11:11:11:36 | url | semmle.label | url | +| tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | semmle.label | window.location.href | +| tainted-url-suffix-arguments.js:12:17:12:19 | url | semmle.label | url | | tooltip.jsx:6:11:6:30 | source | semmle.label | source | | tooltip.jsx:6:20:6:30 | window.name | semmle.label | window.name | | tooltip.jsx:10:25:10:30 | source | semmle.label | source | @@ -974,6 +984,16 @@ edges | string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | provenance | Config | | string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | provenance | | | string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | provenance | Config | +| tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | tainted-url-suffix-arguments.js:3:14:3:14 | x | provenance | Config | +| tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | tainted-url-suffix-arguments.js:3:17:3:17 | y | provenance | Config | +| tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | tainted-url-suffix-arguments.js:3:20:3:20 | z | provenance | Config | +| tainted-url-suffix-arguments.js:3:14:3:14 | x | tainted-url-suffix-arguments.js:5:22:5:22 | x | provenance | | +| tainted-url-suffix-arguments.js:3:17:3:17 | y | tainted-url-suffix-arguments.js:6:22:6:22 | y | provenance | | +| tainted-url-suffix-arguments.js:3:20:3:20 | z | tainted-url-suffix-arguments.js:7:22:7:22 | z | provenance | | +| tainted-url-suffix-arguments.js:11:11:11:36 | url | tainted-url-suffix-arguments.js:12:17:12:19 | url | provenance | | +| tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | tainted-url-suffix-arguments.js:11:11:11:36 | url | provenance | | +| tainted-url-suffix-arguments.js:12:17:12:19 | url | tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | provenance | | +| tainted-url-suffix-arguments.js:12:17:12:19 | url | tainted-url-suffix-arguments.js:3:17:3:17 | y | provenance | | | tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | provenance | | | tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | provenance | | | tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tainted-url-suffix-arguments.js b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tainted-url-suffix-arguments.js new file mode 100644 index 00000000000..c853b1ebfbc --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tainted-url-suffix-arguments.js @@ -0,0 +1,13 @@ +import 'dummy'; + +function foo(x, y, z) { + arguments; // ensure 'arguments' are used + document.writeln(x); // OK [INCONSISTENCY] + document.writeln(y); // NOT OK + document.writeln(z); // OK [INCONSISTENCY] +} + +function bar() { + const url = window.location.href; + foo('safe', url, 'safe'); +} From 4568967a76ca7effed60693b001b2eff0ace89aa Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 29 Aug 2024 13:36:44 +0200 Subject: [PATCH 262/514] JS: Do not use legacy taint steps in TaintedUrlSuffix Tainted URL suffix steps are added as configuration-specific additional steps, which means implicit reads may occur before any of these steps. These steps accidentally included the legacy taint steps which include a step from 'arguments' to all positional parameters. Combined with the implicit read, arguments could escape their array index and flow to any parameter while in the tainted-url flow state. --- .../javascript/security/TaintedUrlSuffix.qll | 2 +- .../Security/CWE-079/DomBasedXss/Xss.expected | 18 ------------------ .../XssWithAdditionalSources.expected | 16 ---------------- .../tainted-url-suffix-arguments.js | 4 ++-- 4 files changed, 3 insertions(+), 37 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll b/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll index 68a4f1c8d8e..683c5e19f4d 100644 --- a/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll +++ b/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll @@ -54,7 +54,7 @@ module TaintedUrlSuffix { // Inherit all ordinary taint steps except `x -> x.p` steps srclbl = label() and dstlbl = label() and - TaintTracking::sharedTaintStep(src, dst) and + TaintTracking::AdditionalTaintStep::step(src, dst) and not isSafeLocationProp(dst) or // Transition from URL suffix to full taint when extracting the query/fragment part. diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 96aa177e4c2..69a9515da11 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -330,13 +330,8 @@ nodes | string-manipulations.js:9:36:9:57 | documen ... on.href | semmle.label | documen ... on.href | | string-manipulations.js:10:16:10:45 | String( ... n.href) | semmle.label | String( ... n.href) | | string-manipulations.js:10:23:10:44 | documen ... on.href | semmle.label | documen ... on.href | -| tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | semmle.label | 'arguments' object of function foo [1] | -| tainted-url-suffix-arguments.js:3:14:3:14 | x | semmle.label | x | | tainted-url-suffix-arguments.js:3:17:3:17 | y | semmle.label | y | -| tainted-url-suffix-arguments.js:3:20:3:20 | z | semmle.label | z | -| tainted-url-suffix-arguments.js:5:22:5:22 | x | semmle.label | x | | tainted-url-suffix-arguments.js:6:22:6:22 | y | semmle.label | y | -| tainted-url-suffix-arguments.js:7:22:7:22 | z | semmle.label | z | | tainted-url-suffix-arguments.js:11:11:11:36 | url | semmle.label | url | | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | semmle.label | window.location.href | | tainted-url-suffix-arguments.js:12:17:12:19 | url | semmle.label | url | @@ -426,7 +421,6 @@ nodes | tst.js:64:25:64:48 | documen ... .search | semmle.label | documen ... .search | | tst.js:65:25:65:48 | documen ... .search | semmle.label | documen ... .search | | tst.js:68:16:68:20 | bar() | semmle.label | bar() | -| tst.js:70:1:70:27 | [,docum ... search] | semmle.label | [,docum ... search] | | tst.js:70:1:70:27 | [,docum ... search] [1] | semmle.label | [,docum ... search] [1] | | tst.js:70:3:70:26 | documen ... .search | semmle.label | documen ... .search | | tst.js:70:46:70:46 | x | semmle.label | x | @@ -959,15 +953,9 @@ edges | string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | provenance | Config | | string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | provenance | | | string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | provenance | Config | -| tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | tainted-url-suffix-arguments.js:3:14:3:14 | x | provenance | Config | -| tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | tainted-url-suffix-arguments.js:3:17:3:17 | y | provenance | Config | -| tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | tainted-url-suffix-arguments.js:3:20:3:20 | z | provenance | Config | -| tainted-url-suffix-arguments.js:3:14:3:14 | x | tainted-url-suffix-arguments.js:5:22:5:22 | x | provenance | | | tainted-url-suffix-arguments.js:3:17:3:17 | y | tainted-url-suffix-arguments.js:6:22:6:22 | y | provenance | | -| tainted-url-suffix-arguments.js:3:20:3:20 | z | tainted-url-suffix-arguments.js:7:22:7:22 | z | provenance | | | tainted-url-suffix-arguments.js:11:11:11:36 | url | tainted-url-suffix-arguments.js:12:17:12:19 | url | provenance | | | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | tainted-url-suffix-arguments.js:11:11:11:36 | url | provenance | | -| tainted-url-suffix-arguments.js:12:17:12:19 | url | tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | provenance | | | tainted-url-suffix-arguments.js:12:17:12:19 | url | tainted-url-suffix-arguments.js:3:17:3:17 | y | provenance | | | tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | provenance | | | tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | provenance | | @@ -1053,11 +1041,7 @@ edges | tst.js:60:34:60:34 | s | tst.js:62:18:62:18 | s | provenance | | | tst.js:64:25:64:48 | documen ... .search | tst.js:60:34:60:34 | s | provenance | | | tst.js:65:25:65:48 | documen ... .search | tst.js:60:34:60:34 | s | provenance | | -| tst.js:70:1:70:27 | [,docum ... search] | tst.js:70:46:70:46 | x | provenance | | -| tst.js:70:1:70:27 | [,docum ... search] | tst.js:70:46:70:46 | x | provenance | Config | | tst.js:70:1:70:27 | [,docum ... search] [1] | tst.js:70:46:70:46 | x | provenance | | -| tst.js:70:1:70:27 | [,docum ... search] [1] | tst.js:70:46:70:46 | x | provenance | Config | -| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] | provenance | Config | | tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] [1] | provenance | | | tst.js:70:46:70:46 | x | tst.js:73:20:73:20 | x | provenance | | | tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | provenance | | @@ -1398,9 +1382,7 @@ subpaths | string-manipulations.js:8:16:8:48 | documen ... mLeft() | string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | Cross-site scripting vulnerability due to $@. | string-manipulations.js:8:16:8:37 | documen ... on.href | user-provided value | | string-manipulations.js:9:16:9:58 | String. ... n.href) | string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | Cross-site scripting vulnerability due to $@. | string-manipulations.js:9:36:9:57 | documen ... on.href | user-provided value | | string-manipulations.js:10:16:10:45 | String( ... n.href) | string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | Cross-site scripting vulnerability due to $@. | string-manipulations.js:10:23:10:44 | documen ... on.href | user-provided value | -| tainted-url-suffix-arguments.js:5:22:5:22 | x | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | tainted-url-suffix-arguments.js:5:22:5:22 | x | Cross-site scripting vulnerability due to $@. | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | user-provided value | | tainted-url-suffix-arguments.js:6:22:6:22 | y | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | tainted-url-suffix-arguments.js:6:22:6:22 | y | Cross-site scripting vulnerability due to $@. | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | user-provided value | -| tainted-url-suffix-arguments.js:7:22:7:22 | z | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | tainted-url-suffix-arguments.js:7:22:7:22 | z | Cross-site scripting vulnerability due to $@. | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | user-provided value | | tooltip.jsx:10:25:10:30 | source | tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:10:25:10:30 | source | Cross-site scripting vulnerability due to $@. | tooltip.jsx:6:20:6:30 | window.name | user-provided value | | tooltip.jsx:11:25:11:30 | source | tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:11:25:11:30 | source | Cross-site scripting vulnerability due to $@. | tooltip.jsx:6:20:6:30 | window.name | user-provided value | | tooltip.jsx:18:51:18:59 | provide() | tooltip.jsx:22:20:22:30 | window.name | tooltip.jsx:18:51:18:59 | provide() | Cross-site scripting vulnerability due to $@. | tooltip.jsx:22:20:22:30 | window.name | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index 4f908c6fe10..2523b19237f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -335,13 +335,8 @@ nodes | string-manipulations.js:9:36:9:57 | documen ... on.href | semmle.label | documen ... on.href | | string-manipulations.js:10:16:10:45 | String( ... n.href) | semmle.label | String( ... n.href) | | string-manipulations.js:10:23:10:44 | documen ... on.href | semmle.label | documen ... on.href | -| tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | semmle.label | 'arguments' object of function foo [1] | -| tainted-url-suffix-arguments.js:3:14:3:14 | x | semmle.label | x | | tainted-url-suffix-arguments.js:3:17:3:17 | y | semmle.label | y | -| tainted-url-suffix-arguments.js:3:20:3:20 | z | semmle.label | z | -| tainted-url-suffix-arguments.js:5:22:5:22 | x | semmle.label | x | | tainted-url-suffix-arguments.js:6:22:6:22 | y | semmle.label | y | -| tainted-url-suffix-arguments.js:7:22:7:22 | z | semmle.label | z | | tainted-url-suffix-arguments.js:11:11:11:36 | url | semmle.label | url | | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | semmle.label | window.location.href | | tainted-url-suffix-arguments.js:12:17:12:19 | url | semmle.label | url | @@ -431,7 +426,6 @@ nodes | tst.js:64:25:64:48 | documen ... .search | semmle.label | documen ... .search | | tst.js:65:25:65:48 | documen ... .search | semmle.label | documen ... .search | | tst.js:68:16:68:20 | bar() | semmle.label | bar() | -| tst.js:70:1:70:27 | [,docum ... search] | semmle.label | [,docum ... search] | | tst.js:70:1:70:27 | [,docum ... search] [1] | semmle.label | [,docum ... search] [1] | | tst.js:70:3:70:26 | documen ... .search | semmle.label | documen ... .search | | tst.js:70:46:70:46 | x | semmle.label | x | @@ -984,15 +978,9 @@ edges | string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | provenance | Config | | string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | provenance | | | string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | provenance | Config | -| tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | tainted-url-suffix-arguments.js:3:14:3:14 | x | provenance | Config | -| tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | tainted-url-suffix-arguments.js:3:17:3:17 | y | provenance | Config | -| tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | tainted-url-suffix-arguments.js:3:20:3:20 | z | provenance | Config | -| tainted-url-suffix-arguments.js:3:14:3:14 | x | tainted-url-suffix-arguments.js:5:22:5:22 | x | provenance | | | tainted-url-suffix-arguments.js:3:17:3:17 | y | tainted-url-suffix-arguments.js:6:22:6:22 | y | provenance | | -| tainted-url-suffix-arguments.js:3:20:3:20 | z | tainted-url-suffix-arguments.js:7:22:7:22 | z | provenance | | | tainted-url-suffix-arguments.js:11:11:11:36 | url | tainted-url-suffix-arguments.js:12:17:12:19 | url | provenance | | | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | tainted-url-suffix-arguments.js:11:11:11:36 | url | provenance | | -| tainted-url-suffix-arguments.js:12:17:12:19 | url | tainted-url-suffix-arguments.js:3:1:8:1 | 'arguments' object of function foo [1] | provenance | | | tainted-url-suffix-arguments.js:12:17:12:19 | url | tainted-url-suffix-arguments.js:3:17:3:17 | y | provenance | | | tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | provenance | | | tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | provenance | | @@ -1078,11 +1066,7 @@ edges | tst.js:60:34:60:34 | s | tst.js:62:18:62:18 | s | provenance | | | tst.js:64:25:64:48 | documen ... .search | tst.js:60:34:60:34 | s | provenance | | | tst.js:65:25:65:48 | documen ... .search | tst.js:60:34:60:34 | s | provenance | | -| tst.js:70:1:70:27 | [,docum ... search] | tst.js:70:46:70:46 | x | provenance | | -| tst.js:70:1:70:27 | [,docum ... search] | tst.js:70:46:70:46 | x | provenance | Config | | tst.js:70:1:70:27 | [,docum ... search] [1] | tst.js:70:46:70:46 | x | provenance | | -| tst.js:70:1:70:27 | [,docum ... search] [1] | tst.js:70:46:70:46 | x | provenance | Config | -| tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] | provenance | Config | | tst.js:70:3:70:26 | documen ... .search | tst.js:70:1:70:27 | [,docum ... search] [1] | provenance | | | tst.js:70:46:70:46 | x | tst.js:73:20:73:20 | x | provenance | | | tst.js:107:7:107:44 | v | tst.js:110:18:110:18 | v | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tainted-url-suffix-arguments.js b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tainted-url-suffix-arguments.js index c853b1ebfbc..a1feef0267a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tainted-url-suffix-arguments.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tainted-url-suffix-arguments.js @@ -2,9 +2,9 @@ import 'dummy'; function foo(x, y, z) { arguments; // ensure 'arguments' are used - document.writeln(x); // OK [INCONSISTENCY] + document.writeln(x); // OK document.writeln(y); // NOT OK - document.writeln(z); // OK [INCONSISTENCY] + document.writeln(z); // OK } function bar() { From 92bb4b3da87ba7cdad07c053a76bae897b493fe8 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Sep 2024 11:32:07 +0200 Subject: [PATCH 263/514] JS: Address some comments from hvitved --- .../semmle/javascript/dataflow/internal/DataFlowPrivate.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 25fa75e0e71..9992495c163 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1052,7 +1052,7 @@ predicate simpleLocalFlowStep(Node node1, Node node2) { exists(Function f | // When the first parameter is a rest parameter, flow into the rest parameter as a local flow step // to ensure we preserve knowledge about array indices - (node1 = TStaticParameterArrayNode(f) or node1 = TDynamicParameterArrayNode(f)) + node1 = TStaticParameterArrayNode(f) or node1 = TDynamicParameterArrayNode(f) | // rest parameter at initial position exists(Parameter rest | @@ -1163,7 +1163,7 @@ predicate readStep(Node node1, ContentSet c, Node node2) { c = ContentSet::arrayElementUnknown() ) or - // Prepare to store spread arguments into the dynamic arguments array, when it isn't the initial spread argument + // Prepare to store spread arguments into the dynamic arguments array, when it isn't the initial argument exists(InvokeExpr invoke, int n, Expr argument, Content storeContent | invoke.getArgument(n).stripParens().(SpreadElement).getOperand() = argument and n > 0 and // n=0 is handled as a value step From 379c7ef20a6946590ceb4c0b30b0359ce7d9826b Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Sep 2024 11:48:38 +0200 Subject: [PATCH 264/514] JS: Add test to show lack of unknown array element being propagated --- .../ql/test/library-tests/TripleDot/tst.js | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/javascript/ql/test/library-tests/TripleDot/tst.js b/javascript/ql/test/library-tests/TripleDot/tst.js index 07bec92a92f..59bafd3187e 100644 --- a/javascript/ql/test/library-tests/TripleDot/tst.js +++ b/javascript/ql/test/library-tests/TripleDot/tst.js @@ -138,3 +138,28 @@ function t13() { } target("safe", ...source('t13.1')); } + +function t14() { + function target(x, y, ...rest) { + sink(x); // $ hasValueFlow=t14.1 + sink(y); // $ hasValueFlow=t14.1 + sink(rest.pop()); // $ hasValueFlow=t14.1 + sink(rest); // $ hasTaintFlow=t14.1 + } + const args = new Array(Math.floor(Math.random() * 10)); + args.push(source('t14.1')); + target(...args); +} + +function t15() { + function target(safe, x, y, ...rest) { + sink(safe); // $ SPURIOUS: hasTaintFlow=t15.1 + sink(x); // $ MISSING: hasValueFlow=t15.1 SPURIOUS: hasTaintFlow=t15.1 + sink(y); // $ MISSING: hasValueFlow=t15.1 SPURIOUS: hasTaintFlow=t15.1 + sink(rest.pop()); // $ MISSING: hasValueFlow=t15.1 SPURIOUS: hasTaintFlow=t15.1 + sink(rest); // $ hasTaintFlow=t15.1 + } + const args = new Array(Math.floor(Math.random() * 10)); + args.push(source('t15.1')); + target('safe', ...args); +} From a9a8351cce586fde007b7b8087f0c968f77eb937 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Sep 2024 12:01:25 +0200 Subject: [PATCH 265/514] JS: Fix one case of missing handling of unknown array index --- .../javascript/dataflow/internal/DataFlowPrivate.qll | 6 +++++- javascript/ql/test/library-tests/TripleDot/tst.js | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 9992495c163..d67ae91aeb8 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1173,7 +1173,11 @@ predicate readStep(Node node1, ContentSet c, Node node2) { then c = ContentSet::arrayElement() and // unknown start index when not the first spread operator storeContent.isUnknownArrayElement() - else storeContent.asArrayIndex() = n + c.asArrayIndex() + else ( + storeContent.asArrayIndex() = n + c.asArrayIndex() + or + storeContent.isUnknownArrayElement() and c.asSingleton() = storeContent + ) ) or exists(FlowSummaryNode parameter, ParameterPosition pos | diff --git a/javascript/ql/test/library-tests/TripleDot/tst.js b/javascript/ql/test/library-tests/TripleDot/tst.js index 59bafd3187e..df941b481cf 100644 --- a/javascript/ql/test/library-tests/TripleDot/tst.js +++ b/javascript/ql/test/library-tests/TripleDot/tst.js @@ -153,10 +153,10 @@ function t14() { function t15() { function target(safe, x, y, ...rest) { - sink(safe); // $ SPURIOUS: hasTaintFlow=t15.1 - sink(x); // $ MISSING: hasValueFlow=t15.1 SPURIOUS: hasTaintFlow=t15.1 - sink(y); // $ MISSING: hasValueFlow=t15.1 SPURIOUS: hasTaintFlow=t15.1 - sink(rest.pop()); // $ MISSING: hasValueFlow=t15.1 SPURIOUS: hasTaintFlow=t15.1 + sink(safe); // $ SPURIOUS: hasValueFlow=t15.1 + sink(x); // $ hasValueFlow=t15.1 + sink(y); // $ hasValueFlow=t15.1 + sink(rest.pop()); // $ hasValueFlow=t15.1 sink(rest); // $ hasTaintFlow=t15.1 } const args = new Array(Math.floor(Math.random() * 10)); From 1da68aac7367942ea4c84f028a95e01336b6396b Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Sep 2024 13:29:28 +0200 Subject: [PATCH 266/514] JS: Benign test output change This happened as a result of the bugfix in the previous commit --- javascript/ql/test/library-tests/Arrays/DataFlow.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/test/library-tests/Arrays/DataFlow.expected b/javascript/ql/test/library-tests/Arrays/DataFlow.expected index 21671a19464..3d8cfc8ac3b 100644 --- a/javascript/ql/test/library-tests/Arrays/DataFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/DataFlow.expected @@ -1,11 +1,11 @@ legacyDataFlowDifference -| arrays.js:2:16:2:23 | "source" | arrays.js:39:8:39:24 | arr4_spread.pop() | only flow with OLD data flow library | flow | arrays.js:2:16:2:23 | "source" | arrays.js:5:8:5:14 | obj.foo | | arrays.js:2:16:2:23 | "source" | arrays.js:11:10:11:15 | arr[i] | | arrays.js:2:16:2:23 | "source" | arrays.js:15:27:15:27 | e | | arrays.js:2:16:2:23 | "source" | arrays.js:16:23:16:23 | e | | arrays.js:2:16:2:23 | "source" | arrays.js:20:8:20:16 | arr.pop() | +| arrays.js:2:16:2:23 | "source" | arrays.js:39:8:39:24 | arr4_spread.pop() | | arrays.js:2:16:2:23 | "source" | arrays.js:61:10:61:10 | x | | arrays.js:2:16:2:23 | "source" | arrays.js:65:10:65:10 | x | | arrays.js:2:16:2:23 | "source" | arrays.js:69:10:69:10 | x | From fb9732a33fe91d8d5782909568b62a2add83d414 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Sep 2024 13:44:54 +0200 Subject: [PATCH 267/514] JS: Add another test and TODO about an issue with constant array indices --- .../lib/semmle/javascript/dataflow/internal/Contents.qll | 5 ++++- javascript/ql/test/library-tests/TripleDot/tst.js | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll index a359ee0d1d5..3ccff93d020 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll @@ -255,7 +255,10 @@ module Public { Content asSingleton() { this = MkSingletonContent(result) } /** Gets the property name to be accessed. */ - PropertyName asPropertyName() { result = this.asSingleton().asPropertyName() } + PropertyName asPropertyName() { + // TODO: array indices should be mapped to a ContentSet that also reads from UnknownArrayElement + result = this.asSingleton().asPropertyName() + } /** Gets the array index to be accessed. */ int asArrayIndex() { result = this.asSingleton().asArrayIndex() } diff --git a/javascript/ql/test/library-tests/TripleDot/tst.js b/javascript/ql/test/library-tests/TripleDot/tst.js index df941b481cf..8fce4285e5b 100644 --- a/javascript/ql/test/library-tests/TripleDot/tst.js +++ b/javascript/ql/test/library-tests/TripleDot/tst.js @@ -163,3 +163,12 @@ function t15() { args.push(source('t15.1')); target('safe', ...args); } + +function t16() { + let array = new Array(Math.floor(Math.random() * 10)) + array.push(source("t16.1")); + sink(array[0]); // $ MISSING: hasValueFlow=t16.1 SPURIOUS: hasTaintFlow=t16.1 + sink(array[1]); // $ MISSING: hasValueFlow=t16.1 SPURIOUS: hasTaintFlow=t16.1 + sink(array[2]); // $ MISSING: hasValueFlow=t16.1 SPURIOUS: hasTaintFlow=t16.1 + sink(array); // $ hasTaintFlow=t16.1 +} From 55d4e7e742415295e8ed25b3fb3adc7284d66743 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Sep 2024 13:43:18 +0200 Subject: [PATCH 268/514] JS: Use ArrayElementKnown when reading a constant array index --- .../javascript/dataflow/internal/DataFlowPrivate.qll | 7 ++++++- javascript/ql/test/library-tests/TripleDot/tst.js | 8 ++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index d67ae91aeb8..54deedf13b9 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1103,7 +1103,12 @@ predicate readStep(Node node1, ContentSet c, Node node2) { node1 = read.getBase() and node2 = read | - c.asPropertyName() = read.getPropertyName() + exists(PropertyName name | read.getPropertyName() = name | + not exists(name.asArrayIndex()) and + c = ContentSet::property(name) + or + c = ContentSet::arrayElementKnown(name.asArrayIndex()) + ) or not exists(read.getPropertyName()) and c = ContentSet::arrayElement() diff --git a/javascript/ql/test/library-tests/TripleDot/tst.js b/javascript/ql/test/library-tests/TripleDot/tst.js index 8fce4285e5b..6f776264e84 100644 --- a/javascript/ql/test/library-tests/TripleDot/tst.js +++ b/javascript/ql/test/library-tests/TripleDot/tst.js @@ -134,7 +134,7 @@ function t13() { sink(x); // $ SPURIOUS: hasTaintFlow=t13.1 sink(y); // $ hasTaintFlow=t13.1 sink(rest); // $ hasTaintFlow=t13.1 - sink(rest[0]); // $ MISSING: hasTaintFlow=t13.1 + sink(rest[0]); // $ hasTaintFlow=t13.1 } target("safe", ...source('t13.1')); } @@ -167,8 +167,8 @@ function t15() { function t16() { let array = new Array(Math.floor(Math.random() * 10)) array.push(source("t16.1")); - sink(array[0]); // $ MISSING: hasValueFlow=t16.1 SPURIOUS: hasTaintFlow=t16.1 - sink(array[1]); // $ MISSING: hasValueFlow=t16.1 SPURIOUS: hasTaintFlow=t16.1 - sink(array[2]); // $ MISSING: hasValueFlow=t16.1 SPURIOUS: hasTaintFlow=t16.1 + sink(array[0]); // $ hasValueFlow=t16.1 + sink(array[1]); // $ hasValueFlow=t16.1 + sink(array[2]); // $ hasValueFlow=t16.1 sink(array); // $ hasTaintFlow=t16.1 } From 013d226ae39dc81dc00cbcd03738fa8a222a1036 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Sep 2024 13:46:26 +0200 Subject: [PATCH 269/514] JS: Update comment --- .../lib/semmle/javascript/dataflow/internal/Contents.qll | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll index 3ccff93d020..fc86032c502 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll @@ -254,11 +254,8 @@ module Public { /** Gets the singleton content to be accessed. */ Content asSingleton() { this = MkSingletonContent(result) } - /** Gets the property name to be accessed. */ - PropertyName asPropertyName() { - // TODO: array indices should be mapped to a ContentSet that also reads from UnknownArrayElement - result = this.asSingleton().asPropertyName() - } + /** Gets the property name to be accessed, provided that this is a singleton content set. */ + PropertyName asPropertyName() { result = this.asSingleton().asPropertyName() } /** Gets the array index to be accessed. */ int asArrayIndex() { result = this.asSingleton().asArrayIndex() } From 3d4287b7cc0dc4c9ca76bee820fd25c3444e52dd Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 6 Sep 2024 13:54:57 +0200 Subject: [PATCH 270/514] JS: Remove ContentSet#asArrayIndex() For ContentSet it is ambiguous whether asArrayIndex() should get a singleton content set, or the KnownArrayElement content set. The user will now have to choose between asSingleton().asArrayIndex() or ContentSet::arrayElementKnown. --- .../lib/semmle/javascript/dataflow/internal/Contents.qll | 3 --- .../javascript/dataflow/internal/DataFlowPrivate.qll | 8 ++++---- .../javascript/internal/flow_summaries/ForOfLoops.qll | 4 ++-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll index fc86032c502..a915ef47d0f 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll @@ -257,9 +257,6 @@ module Public { /** Gets the property name to be accessed, provided that this is a singleton content set. */ PropertyName asPropertyName() { result = this.asSingleton().asPropertyName() } - /** Gets the array index to be accessed. */ - int asArrayIndex() { result = this.asSingleton().asArrayIndex() } - /** * Gets a string representation of this content set. */ diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 54deedf13b9..dc5b61821d7 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1162,7 +1162,7 @@ predicate readStep(Node node1, ContentSet c, Node node2) { node2 = TRestParameterStoreNode(function, content) | // shift known array indices - c.asArrayIndex() = content.asArrayIndex() + restIndex + c.asSingleton().asArrayIndex() = content.asArrayIndex() + restIndex or content.isUnknownArrayElement() and // TODO: don't read unknown array elements from static array c = ContentSet::arrayElementUnknown() @@ -1179,7 +1179,7 @@ predicate readStep(Node node1, ContentSet c, Node node2) { c = ContentSet::arrayElement() and // unknown start index when not the first spread operator storeContent.isUnknownArrayElement() else ( - storeContent.asArrayIndex() = n + c.asArrayIndex() + storeContent.asArrayIndex() = n + c.asSingleton().asArrayIndex() or storeContent.isUnknownArrayElement() and c.asSingleton() = storeContent ) @@ -1190,7 +1190,7 @@ predicate readStep(Node node1, ContentSet c, Node node2) { node1 = TFlowSummaryDynamicParameterArrayNode(parameter.getSummarizedCallable()) and node2 = parameter and ( - c.asArrayIndex() = pos.asPositional() + c.asSingleton().asArrayIndex() = pos.asPositional() or c = ContentSet::arrayElementLowerBound(pos.asPositionalLowerBound()) ) @@ -1261,7 +1261,7 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { exists(InvokeExpr invoke, int n | node1 = TValueNode(invoke.getArgument(n)) and node2 = TStaticArgumentArrayNode(invoke) and - c.asArrayIndex() = n and + c.asSingleton().asArrayIndex() = n and not n >= firstSpreadArgumentIndex(invoke) ) or diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ForOfLoops.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ForOfLoops.qll index 1407ce7c79e..ecc84170026 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ForOfLoops.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ForOfLoops.qll @@ -48,10 +48,10 @@ class ForOfLoopStep extends AdditionalFlowInternal { ) { exists(ForOfStmt stmt | pred = getSynthesizedNode(stmt, "for-of-map-key") and - contents.asArrayIndex() = 0 + contents.asSingleton().asArrayIndex() = 0 or pred = getSynthesizedNode(stmt, "for-of-map-value") and - contents.asArrayIndex() = 1 + contents.asSingleton().asArrayIndex() = 1 | succ = DataFlow::lvalueNode(stmt.getLValue()) ) From e0ca1b04820ef56d12e8a74aa021866a74ee9993 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Sep 2024 13:07:24 +0200 Subject: [PATCH 271/514] JS: Benign test updates --- javascript/ql/test/library-tests/Arrays/DataFlow.expected | 2 ++ javascript/ql/test/library-tests/Arrays/arrays.js | 2 +- javascript/ql/test/library-tests/FlowSummary/tst.js | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/javascript/ql/test/library-tests/Arrays/DataFlow.expected b/javascript/ql/test/library-tests/Arrays/DataFlow.expected index 3d8cfc8ac3b..35a04acc4a1 100644 --- a/javascript/ql/test/library-tests/Arrays/DataFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/DataFlow.expected @@ -1,4 +1,5 @@ legacyDataFlowDifference +| arrays.js:2:16:2:23 | "source" | arrays.js:58:8:58:13 | arr[0] | only flow with NEW data flow library | flow | arrays.js:2:16:2:23 | "source" | arrays.js:5:8:5:14 | obj.foo | | arrays.js:2:16:2:23 | "source" | arrays.js:11:10:11:15 | arr[i] | @@ -6,6 +7,7 @@ flow | arrays.js:2:16:2:23 | "source" | arrays.js:16:23:16:23 | e | | arrays.js:2:16:2:23 | "source" | arrays.js:20:8:20:16 | arr.pop() | | arrays.js:2:16:2:23 | "source" | arrays.js:39:8:39:24 | arr4_spread.pop() | +| arrays.js:2:16:2:23 | "source" | arrays.js:58:8:58:13 | arr[0] | | arrays.js:2:16:2:23 | "source" | arrays.js:61:10:61:10 | x | | arrays.js:2:16:2:23 | "source" | arrays.js:65:10:65:10 | x | | arrays.js:2:16:2:23 | "source" | arrays.js:69:10:69:10 | x | diff --git a/javascript/ql/test/library-tests/Arrays/arrays.js b/javascript/ql/test/library-tests/Arrays/arrays.js index 8c981a33a1f..a994bd7bc57 100644 --- a/javascript/ql/test/library-tests/Arrays/arrays.js +++ b/javascript/ql/test/library-tests/Arrays/arrays.js @@ -55,7 +55,7 @@ sink(ary); // OK - its the array itself, not an element. }); - sink(arr[0]); // OK - tuple like usage. + sink(arr[0]); // NOT OK for (const x of arr) { sink(x); // NOT OK diff --git a/javascript/ql/test/library-tests/FlowSummary/tst.js b/javascript/ql/test/library-tests/FlowSummary/tst.js index 264c304f0f3..f3bf8513840 100644 --- a/javascript/ql/test/library-tests/FlowSummary/tst.js +++ b/javascript/ql/test/library-tests/FlowSummary/tst.js @@ -28,7 +28,7 @@ function m3() { function m4() { const flowIntoArrayElement = mkSummary("Argument[0]", "ReturnValue.ArrayElement"); sink(flowIntoArrayElement(source()).pop()); // NOT OK - sink(flowIntoArrayElement(source())[0]); // NOT OK [INCONSISTENCY] + sink(flowIntoArrayElement(source())[0]); // NOT OK sink(flowIntoArrayElement(source())[Math.random()]); // NOT OK sink(flowIntoArrayElement(source()).prop); // OK } From 0ddb1c87f57bb3a58c70d532114ed067ba98d880 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Sep 2024 13:14:37 +0200 Subject: [PATCH 272/514] JS: Test update indicating a problem with .split() --- .../query-tests/Security/CWE-079/DomBasedXss/Xss.expected | 6 ++++++ .../CWE-079/DomBasedXss/XssWithAdditionalSources.expected | 5 +++++ .../ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 69a9515da11..d6dc0b1b44e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -514,6 +514,9 @@ nodes | tst.js:371:7:371:39 | target | semmle.label | target | | tst.js:371:16:371:39 | documen ... .search | semmle.label | documen ... .search | | tst.js:374:18:374:23 | target | semmle.label | target | +| tst.js:377:18:377:39 | documen ... on.href | semmle.label | documen ... on.href | +| tst.js:377:18:377:50 | documen ... it("?") [ArrayElement] | semmle.label | documen ... it("?") [ArrayElement] | +| tst.js:377:18:377:53 | documen ... "?")[0] | semmle.label | documen ... "?")[0] | | tst.js:381:7:381:39 | target | semmle.label | target | | tst.js:381:7:381:39 | target [taint3] | semmle.label | target [taint3] | | tst.js:381:7:381:39 | target [taint8] | semmle.label | target [taint8] | @@ -1112,6 +1115,8 @@ edges | tst.js:355:19:355:42 | documen ... .search | tst.js:355:10:355:42 | target | provenance | | | tst.js:371:7:371:39 | target | tst.js:374:18:374:23 | target | provenance | | | tst.js:371:16:371:39 | documen ... .search | tst.js:371:7:371:39 | target | provenance | | +| tst.js:377:18:377:39 | documen ... on.href | tst.js:377:18:377:50 | documen ... it("?") [ArrayElement] | provenance | | +| tst.js:377:18:377:50 | documen ... it("?") [ArrayElement] | tst.js:377:18:377:53 | documen ... "?")[0] | provenance | | | tst.js:381:7:381:39 | target | tst.js:384:18:384:23 | target | provenance | | | tst.js:381:7:381:39 | target | tst.js:386:18:386:23 | target | provenance | | | tst.js:381:7:381:39 | target | tst.js:397:18:397:23 | target | provenance | | @@ -1455,6 +1460,7 @@ subpaths | tst.js:360:21:360:26 | target | tst.js:355:19:355:42 | documen ... .search | tst.js:360:21:360:26 | target | Cross-site scripting vulnerability due to $@. | tst.js:355:19:355:42 | documen ... .search | user-provided value | | tst.js:363:18:363:23 | target | tst.js:355:19:355:42 | documen ... .search | tst.js:363:18:363:23 | target | Cross-site scripting vulnerability due to $@. | tst.js:355:19:355:42 | documen ... .search | user-provided value | | tst.js:374:18:374:23 | target | tst.js:371:16:371:39 | documen ... .search | tst.js:374:18:374:23 | target | Cross-site scripting vulnerability due to $@. | tst.js:371:16:371:39 | documen ... .search | user-provided value | +| tst.js:377:18:377:53 | documen ... "?")[0] | tst.js:377:18:377:39 | documen ... on.href | tst.js:377:18:377:53 | documen ... "?")[0] | Cross-site scripting vulnerability due to $@. | tst.js:377:18:377:39 | documen ... on.href | user-provided value | | tst.js:384:18:384:23 | target | tst.js:381:16:381:39 | documen ... .search | tst.js:384:18:384:23 | target | Cross-site scripting vulnerability due to $@. | tst.js:381:16:381:39 | documen ... .search | user-provided value | | tst.js:386:18:386:29 | target.taint | tst.js:381:16:381:39 | documen ... .search | tst.js:386:18:386:29 | target.taint | Cross-site scripting vulnerability due to $@. | tst.js:381:16:381:39 | documen ... .search | user-provided value | | tst.js:392:18:392:30 | target.taint3 | tst.js:391:19:391:42 | documen ... .search | tst.js:392:18:392:30 | target.taint3 | Cross-site scripting vulnerability due to $@. | tst.js:391:19:391:42 | documen ... .search | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index 2523b19237f..0390a90f7e9 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -519,6 +519,9 @@ nodes | tst.js:371:7:371:39 | target | semmle.label | target | | tst.js:371:16:371:39 | documen ... .search | semmle.label | documen ... .search | | tst.js:374:18:374:23 | target | semmle.label | target | +| tst.js:377:18:377:39 | documen ... on.href | semmle.label | documen ... on.href | +| tst.js:377:18:377:50 | documen ... it("?") [ArrayElement] | semmle.label | documen ... it("?") [ArrayElement] | +| tst.js:377:18:377:53 | documen ... "?")[0] | semmle.label | documen ... "?")[0] | | tst.js:381:7:381:39 | target | semmle.label | target | | tst.js:381:7:381:39 | target [taint3] | semmle.label | target [taint3] | | tst.js:381:7:381:39 | target [taint8] | semmle.label | target [taint8] | @@ -1137,6 +1140,8 @@ edges | tst.js:355:19:355:42 | documen ... .search | tst.js:355:10:355:42 | target | provenance | | | tst.js:371:7:371:39 | target | tst.js:374:18:374:23 | target | provenance | | | tst.js:371:16:371:39 | documen ... .search | tst.js:371:7:371:39 | target | provenance | | +| tst.js:377:18:377:39 | documen ... on.href | tst.js:377:18:377:50 | documen ... it("?") [ArrayElement] | provenance | | +| tst.js:377:18:377:50 | documen ... it("?") [ArrayElement] | tst.js:377:18:377:53 | documen ... "?")[0] | provenance | | | tst.js:381:7:381:39 | target | tst.js:384:18:384:23 | target | provenance | | | tst.js:381:7:381:39 | target | tst.js:386:18:386:23 | target | provenance | | | tst.js:381:7:381:39 | target | tst.js:397:18:397:23 | target | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js index 3a8c5992645..1e42fa97fe2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js @@ -373,7 +373,7 @@ function test() { // NOT OK $('myId').html(target) - // OK + // OK [INCONSISTENCY] (TODO: fix) $('myid').html(document.location.href.split("?")[0]); } From 87454a4f113ed4ef90b36bd1de94c5965595e2f9 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Sep 2024 14:44:49 +0200 Subject: [PATCH 273/514] JS: Remove unused predicate --- .../semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll | 3 --- 1 file changed, 3 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index 3611d34667e..63826e5878c 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -124,9 +124,6 @@ string encodeArgumentPosition(ArgumentPosition pos) { /** Gets the return kind corresponding to specification `"ReturnValue"`. */ ReturnKind getStandardReturnValueKind() { result = MkNormalReturnKind() } -/** Gets the return kind corresponding to specification `"ReturnValue"`. */ -MkNormalReturnKind getReturnValueKind() { any() } - private module FlowSummaryStepInput implements Private::StepsInputSig { DataFlowCall getACall(SummarizedCallable sc) { exists(LibraryCallable callable | callable = sc | From 24983a5836198c09fda46b72b86471fe8bf1f08c Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Sep 2024 14:59:39 +0200 Subject: [PATCH 274/514] JS: Add OptionalStep and OptionalBarrier MaD tokens OptionalStep[foo] and OptionalBarrier[foo] contribute steps/barriers that are not active by default, but can be opted into by specific queries or for specific flow states. (Will be used in the following commits) --- .../javascript/dataflow/internal/Contents.qll | 20 +++++++++++++++-- .../dataflow/internal/DataFlowPrivate.qll | 22 +++++++++++++++++++ .../dataflow/internal/FlowSummaryPrivate.qll | 4 ++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll index a915ef47d0f..a8743423922 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll @@ -93,14 +93,20 @@ module Private { // than an ordinary content component. These special content sets should never appear in a step. MkAwaited() or MkAnyPropertyDeep() or - MkArrayElementDeep() + MkArrayElementDeep() or + MkOptionalStep(string name) { isAccessPathTokenPresent("OptionalStep", name) } or + MkOptionalBarrier(string name) { isAccessPathTokenPresent("OptionalBarrier", name) } /** * Holds if `cs` is used to encode a special operation as a content component, but should not * be treated as an ordinary content component. */ predicate isSpecialContentSet(ContentSet cs) { - cs = MkAwaited() or cs = MkAnyPropertyDeep() or cs = MkArrayElementDeep() + cs = MkAwaited() or + cs = MkAnyPropertyDeep() or + cs = MkArrayElementDeep() or + cs instanceof MkOptionalStep or + cs instanceof MkOptionalBarrier } } @@ -288,6 +294,16 @@ module Public { or this = MkAnyCapturedContent() and result = "AnyCapturedContent" + or + exists(string name | + this = MkOptionalStep(name) and + result = "OptionalStep[" + name + "]" + ) + or + exists(string name | + this = MkOptionalBarrier(name) and + result = "OptionalBarrier[" + name + "]" + ) } } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index dc5b61821d7..f8f86e04c08 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1035,6 +1035,11 @@ predicate simpleLocalFlowStep(Node node1, Node node2) { FlowSummaryPrivate::Steps::summaryReadStep(input, MkAwaited(), output) and node1 = TFlowSummaryNode(input) and node2 = TFlowSummaryNode(output) + or + // Add flow through optional barriers. This step is then blocked by the barrier for queries that choose to use the barrier. + FlowSummaryPrivate::Steps::summaryReadStep(input, MkOptionalBarrier(_), output) and + node1 = TFlowSummaryNode(input) and + node2 = TFlowSummaryNode(output) ) or VariableCaptureOutput::localFlowStep(getClosureNode(node1), getClosureNode(node2)) @@ -1389,3 +1394,20 @@ class ArgumentNode extends DataFlow::Node { class ParameterNode extends DataFlow::Node { ParameterNode() { isParameterNodeImpl(this, _, _) } } + +cached +private module OptionalSteps { + cached + predicate optionalStep(Node node1, string name, Node node2) { + FlowSummaryPrivate::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), + MkOptionalStep(name), node2.(FlowSummaryNode).getSummaryNode()) + } + + cached + predicate optionalBarrier(Node node, string name) { + FlowSummaryPrivate::Steps::summaryReadStep(_, MkOptionalBarrier(name), + node.(FlowSummaryNode).getSummaryNode()) + } +} + +import OptionalSteps diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index 63826e5878c..e969ab39d37 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -95,6 +95,10 @@ private string encodeContentAux(ContentSet cs, string arg) { cs = MkAnyPropertyDeep() and result = "AnyMemberDeep" and arg = "" or cs = MkArrayElementDeep() and result = "ArrayElementDeep" and arg = "" + or + cs = MkOptionalStep(arg) and result = "OptionalStep" + or + cs = MkOptionalBarrier(arg) and result = "OptionalBarrier" } /** From 3b34cd72f2490f137316e25fc934b70a8dc83d0e Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Sep 2024 15:01:51 +0200 Subject: [PATCH 275/514] JS: Handle split() with '#' or '?' separator in a separate summary This summary uses the notion of optional steps/barriers so it becomes configurable whether there is flow into the zero'th array element. Also makes sure we handle the second-argument version of split(). --- .../internal/flow_summaries/Strings.qll | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll index 941b9a825c3..1135f6cb7f0 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll @@ -55,7 +55,9 @@ class StringSplit extends SummarizedCallable { StringSplit() { this = "String#split" } override DataFlow::MethodCallNode getACallSimple() { - result.getMethodName() = "split" and result.getNumArgument() = 1 + result.getMethodName() = "split" and + result.getNumArgument() = [1, 2] and + not result.getArgument(0).getStringValue() = ["#", "?"] } override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { @@ -64,3 +66,33 @@ class StringSplit extends SummarizedCallable { output = "ReturnValue.ArrayElement" } } + +/** + * A call of form `x.split("#")` or `x.split("?")`. + * + * These are of special significance when tracking a tainted URL suffix, such as `window.location.href`, + * because the first element of the resulting array should not be considered tainted. + * + * This summary defaults to the same behaviour as the general `.split()` case, but it contains optional steps + * and barriers named `tainted-url-suffix` that should be activated when tracking a tainted URL suffix. + */ +class StringSplitHashOrQuestionMark extends SummarizedCallable { + StringSplitHashOrQuestionMark() { this = "String#split with '#' or '?'" } + + override DataFlow::MethodCallNode getACallSimple() { + result.getMethodName() = "split" and + result.getNumArgument() = [1, 2] and + result.getArgument(0).getStringValue() = ["#", "?"] + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = false and + ( + input = "Argument[this].OptionalBarrier[tainted-url-suffix]" and + output = "ReturnValue.ArrayElement" + or + input = "Argument[this].OptionalStep[tainted-url-suffix]" and + output = "ReturnValue.ArrayElement[1]" // TODO: support ArrayElement[1..] + ) + } +} From 7790f68fe2ad3bc6b37a813f9f7fa85281fa0604 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Sep 2024 15:02:29 +0200 Subject: [PATCH 276/514] JS: Make the TaintedUrlSuffix library use optional steps/barriers --- .../javascript/security/TaintedUrlSuffix.qll | 10 ++++++++++ .../security/dataflow/DomBasedXssQuery.qll | 2 ++ .../Security/CWE-079/DomBasedXss/Xss.expected | 14 ++++---------- .../DomBasedXss/XssWithAdditionalSources.expected | 13 ++++--------- .../Security/CWE-079/DomBasedXss/tst.js | 2 +- 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll b/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll index 683c5e19f4d..39ea36a60c6 100644 --- a/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll +++ b/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll @@ -4,6 +4,7 @@ */ import javascript +private import semmle.javascript.dataflow.internal.DataFlowPrivate as DataFlowPrivate /** * Provides a flow label for reasoning about URLs with a tainted query and fragment part, @@ -45,6 +46,11 @@ module TaintedUrlSuffix { ] } + predicate isBarrier(Node node, FlowLabel label) { + label = label() and + DataFlowPrivate::optionalBarrier(node, "tainted-url-suffix") + } + /** * Holds if there is a flow step `src -> dst` involving the URL suffix taint label. * @@ -57,6 +63,10 @@ module TaintedUrlSuffix { TaintTracking::AdditionalTaintStep::step(src, dst) and not isSafeLocationProp(dst) or + srclbl = label() and + dstlbl.isTaint() and + DataFlowPrivate::optionalStep(src, "tainted-url-suffix", dst) + or // Transition from URL suffix to full taint when extracting the query/fragment part. srclbl = label() and dstlbl.isTaint() and diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll index 4da51cccb8c..8a53e4f0790 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll @@ -76,6 +76,8 @@ module DomBasedXssConfig implements DataFlow::StateConfigSig { isOptionallySanitizedNode(node) and lbl = [DataFlow::FlowLabel::taint(), prefixLabel(), TaintedUrlSuffix::label()] or + TaintedUrlSuffix::isBarrier(node, lbl) + or node = DataFlow::MakeLabeledBarrierGuard::getABarrierNode(lbl) } diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index d6dc0b1b44e..28c31f30595 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -514,9 +514,6 @@ nodes | tst.js:371:7:371:39 | target | semmle.label | target | | tst.js:371:16:371:39 | documen ... .search | semmle.label | documen ... .search | | tst.js:374:18:374:23 | target | semmle.label | target | -| tst.js:377:18:377:39 | documen ... on.href | semmle.label | documen ... on.href | -| tst.js:377:18:377:50 | documen ... it("?") [ArrayElement] | semmle.label | documen ... it("?") [ArrayElement] | -| tst.js:377:18:377:53 | documen ... "?")[0] | semmle.label | documen ... "?")[0] | | tst.js:381:7:381:39 | target | semmle.label | target | | tst.js:381:7:381:39 | target [taint3] | semmle.label | target [taint3] | | tst.js:381:7:381:39 | target [taint8] | semmle.label | target [taint8] | @@ -549,7 +546,7 @@ nodes | tst.js:421:20:421:27 | match[1] | semmle.label | match[1] | | tst.js:424:18:424:37 | window.location.hash | semmle.label | window.location.hash | | tst.js:424:18:424:48 | window. ... it('#') | semmle.label | window. ... it('#') | -| tst.js:424:18:424:48 | window. ... it('#') [ArrayElement] | semmle.label | window. ... it('#') [ArrayElement] | +| tst.js:424:18:424:48 | window. ... it('#') [1] | semmle.label | window. ... it('#') [1] | | tst.js:424:18:424:51 | window. ... '#')[1] | semmle.label | window. ... '#')[1] | | tst.js:428:7:428:39 | target | semmle.label | target | | tst.js:428:16:428:39 | documen ... .search | semmle.label | documen ... .search | @@ -1115,8 +1112,6 @@ edges | tst.js:355:19:355:42 | documen ... .search | tst.js:355:10:355:42 | target | provenance | | | tst.js:371:7:371:39 | target | tst.js:374:18:374:23 | target | provenance | | | tst.js:371:16:371:39 | documen ... .search | tst.js:371:7:371:39 | target | provenance | | -| tst.js:377:18:377:39 | documen ... on.href | tst.js:377:18:377:50 | documen ... it("?") [ArrayElement] | provenance | | -| tst.js:377:18:377:50 | documen ... it("?") [ArrayElement] | tst.js:377:18:377:53 | documen ... "?")[0] | provenance | | | tst.js:381:7:381:39 | target | tst.js:384:18:384:23 | target | provenance | | | tst.js:381:7:381:39 | target | tst.js:386:18:386:23 | target | provenance | | | tst.js:381:7:381:39 | target | tst.js:397:18:397:23 | target | provenance | | @@ -1153,11 +1148,11 @@ edges | tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | provenance | Config | | tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | provenance | | | tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | provenance | Config | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') [ArrayElement] | provenance | | +| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') [1] | provenance | Config | | tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | | tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | Config | -| tst.js:424:18:424:48 | window. ... it('#') [ArrayElement] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | -| tst.js:424:18:424:48 | window. ... it('#') [ArrayElement] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | Config | +| tst.js:424:18:424:48 | window. ... it('#') [1] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | +| tst.js:424:18:424:48 | window. ... it('#') [1] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | Config | | tst.js:428:7:428:39 | target | tst.js:430:18:430:23 | target | provenance | | | tst.js:428:16:428:39 | documen ... .search | tst.js:428:7:428:39 | target | provenance | | | tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | provenance | | @@ -1460,7 +1455,6 @@ subpaths | tst.js:360:21:360:26 | target | tst.js:355:19:355:42 | documen ... .search | tst.js:360:21:360:26 | target | Cross-site scripting vulnerability due to $@. | tst.js:355:19:355:42 | documen ... .search | user-provided value | | tst.js:363:18:363:23 | target | tst.js:355:19:355:42 | documen ... .search | tst.js:363:18:363:23 | target | Cross-site scripting vulnerability due to $@. | tst.js:355:19:355:42 | documen ... .search | user-provided value | | tst.js:374:18:374:23 | target | tst.js:371:16:371:39 | documen ... .search | tst.js:374:18:374:23 | target | Cross-site scripting vulnerability due to $@. | tst.js:371:16:371:39 | documen ... .search | user-provided value | -| tst.js:377:18:377:53 | documen ... "?")[0] | tst.js:377:18:377:39 | documen ... on.href | tst.js:377:18:377:53 | documen ... "?")[0] | Cross-site scripting vulnerability due to $@. | tst.js:377:18:377:39 | documen ... on.href | user-provided value | | tst.js:384:18:384:23 | target | tst.js:381:16:381:39 | documen ... .search | tst.js:384:18:384:23 | target | Cross-site scripting vulnerability due to $@. | tst.js:381:16:381:39 | documen ... .search | user-provided value | | tst.js:386:18:386:29 | target.taint | tst.js:381:16:381:39 | documen ... .search | tst.js:386:18:386:29 | target.taint | Cross-site scripting vulnerability due to $@. | tst.js:381:16:381:39 | documen ... .search | user-provided value | | tst.js:392:18:392:30 | target.taint3 | tst.js:391:19:391:42 | documen ... .search | tst.js:392:18:392:30 | target.taint3 | Cross-site scripting vulnerability due to $@. | tst.js:391:19:391:42 | documen ... .search | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index 0390a90f7e9..d5118254128 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -519,9 +519,6 @@ nodes | tst.js:371:7:371:39 | target | semmle.label | target | | tst.js:371:16:371:39 | documen ... .search | semmle.label | documen ... .search | | tst.js:374:18:374:23 | target | semmle.label | target | -| tst.js:377:18:377:39 | documen ... on.href | semmle.label | documen ... on.href | -| tst.js:377:18:377:50 | documen ... it("?") [ArrayElement] | semmle.label | documen ... it("?") [ArrayElement] | -| tst.js:377:18:377:53 | documen ... "?")[0] | semmle.label | documen ... "?")[0] | | tst.js:381:7:381:39 | target | semmle.label | target | | tst.js:381:7:381:39 | target [taint3] | semmle.label | target [taint3] | | tst.js:381:7:381:39 | target [taint8] | semmle.label | target [taint8] | @@ -554,7 +551,7 @@ nodes | tst.js:421:20:421:27 | match[1] | semmle.label | match[1] | | tst.js:424:18:424:37 | window.location.hash | semmle.label | window.location.hash | | tst.js:424:18:424:48 | window. ... it('#') | semmle.label | window. ... it('#') | -| tst.js:424:18:424:48 | window. ... it('#') [ArrayElement] | semmle.label | window. ... it('#') [ArrayElement] | +| tst.js:424:18:424:48 | window. ... it('#') [1] | semmle.label | window. ... it('#') [1] | | tst.js:424:18:424:51 | window. ... '#')[1] | semmle.label | window. ... '#')[1] | | tst.js:428:7:428:39 | target | semmle.label | target | | tst.js:428:16:428:39 | documen ... .search | semmle.label | documen ... .search | @@ -1140,8 +1137,6 @@ edges | tst.js:355:19:355:42 | documen ... .search | tst.js:355:10:355:42 | target | provenance | | | tst.js:371:7:371:39 | target | tst.js:374:18:374:23 | target | provenance | | | tst.js:371:16:371:39 | documen ... .search | tst.js:371:7:371:39 | target | provenance | | -| tst.js:377:18:377:39 | documen ... on.href | tst.js:377:18:377:50 | documen ... it("?") [ArrayElement] | provenance | | -| tst.js:377:18:377:50 | documen ... it("?") [ArrayElement] | tst.js:377:18:377:53 | documen ... "?")[0] | provenance | | | tst.js:381:7:381:39 | target | tst.js:384:18:384:23 | target | provenance | | | tst.js:381:7:381:39 | target | tst.js:386:18:386:23 | target | provenance | | | tst.js:381:7:381:39 | target | tst.js:397:18:397:23 | target | provenance | | @@ -1178,11 +1173,11 @@ edges | tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | provenance | Config | | tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | provenance | | | tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | provenance | Config | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') [ArrayElement] | provenance | | +| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') [1] | provenance | Config | | tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | | tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | Config | -| tst.js:424:18:424:48 | window. ... it('#') [ArrayElement] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | -| tst.js:424:18:424:48 | window. ... it('#') [ArrayElement] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | Config | +| tst.js:424:18:424:48 | window. ... it('#') [1] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | +| tst.js:424:18:424:48 | window. ... it('#') [1] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | Config | | tst.js:428:7:428:39 | target | tst.js:430:18:430:23 | target | provenance | | | tst.js:428:16:428:39 | documen ... .search | tst.js:428:7:428:39 | target | provenance | | | tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js index 1e42fa97fe2..3a8c5992645 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js @@ -373,7 +373,7 @@ function test() { // NOT OK $('myId').html(target) - // OK [INCONSISTENCY] (TODO: fix) + // OK $('myid').html(document.location.href.split("?")[0]); } From e87e543850bb5614280bfcea0d258ed740bef60c Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Sep 2024 15:02:51 +0200 Subject: [PATCH 277/514] JS: Ensure optional steps/barriers are computed in the correct stage --- .../dataflow/internal/FlowSummaryPrivate.qll | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index e969ab39d37..6ae42a90bd2 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -126,7 +126,7 @@ string encodeArgumentPosition(ArgumentPosition pos) { } /** Gets the return kind corresponding to specification `"ReturnValue"`. */ -ReturnKind getStandardReturnValueKind() { result = MkNormalReturnKind() } +ReturnKind getStandardReturnValueKind() { result = MkNormalReturnKind() and Stage::ref() } private module FlowSummaryStepInput implements Private::StepsInputSig { DataFlowCall getACall(SummarizedCallable sc) { @@ -238,3 +238,12 @@ ContentSet decodeUnknownWithoutContent(AccessPathSyntax::AccessPathTokenBase tok */ bindingset[token] ContentSet decodeUnknownWithContent(AccessPathSyntax::AccessPathTokenBase token) { none() } + +cached +module Stage { + cached + predicate ref() { 1 = 1 } + + cached + predicate backref() { optionalStep(_, _, _) } +} From 133b016c7c659302d42e535dd2d08ddd0a61133b Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Sep 2024 15:21:03 +0200 Subject: [PATCH 278/514] JS: Remove old 'split' handling from TaintedUrlSuffix --- .../ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll | 5 ----- 1 file changed, 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll b/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll index 39ea36a60c6..79dee94c58f 100644 --- a/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll +++ b/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll @@ -80,11 +80,6 @@ module TaintedUrlSuffix { name = StringOps::substringMethodName() and not call.getArgument(0).getIntValue() = 0 or - // Split around '#' or '?' and extract the suffix - name = "split" and - call.getArgument(0).getStringValue() = ["#", "?"] and - not exists(call.getAPropertyRead("0")) // Avoid false flow to the prefix - or // Replace '#' and '?' with nothing name = "replace" and call.getArgument(0).getStringValue() = ["#", "?"] and From da696817a326c34f295e24662475da92c5f077bd Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Sep 2024 15:21:24 +0200 Subject: [PATCH 279/514] JS: Convert 'split' taint step to legacy taint step --- .../semmle/javascript/dataflow/TaintTracking.qll | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index e6eccf6097d..13970c16143 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -356,6 +356,16 @@ module TaintTracking { } } + private class LegacySplitTaintStep extends LegacyTaintStep { + override predicate stringManipulationStep(DataFlow::Node pred, DataFlow::Node target) { + exists(DataFlow::MethodCallNode call | + call.getMethodName() = "split" and + pred = call.getReceiver() and + target = call + ) + } + } + /** * A taint propagating data flow edge arising from string manipulation * functions defined in the standard library. @@ -372,9 +382,8 @@ module TaintTracking { [ "anchor", "big", "blink", "bold", "concat", "fixed", "fontcolor", "fontsize", "italics", "link", "padEnd", "padStart", "repeat", "replace", "replaceAll", "slice", - "small", "split", "strike", "sub", "substr", "substring", "sup", - "toLocaleLowerCase", "toLocaleUpperCase", "toLowerCase", "toUpperCase", "trim", - "trimLeft", "trimRight" + "small", "strike", "sub", "substr", "substring", "sup", "toLocaleLowerCase", + "toLocaleUpperCase", "toLowerCase", "toUpperCase", "trim", "trimLeft", "trimRight" ] or // sorted, interesting, properties of Object.prototype From 15fc450a9edeca2487efc7e35560e82ced894086 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Sep 2024 15:22:11 +0200 Subject: [PATCH 280/514] JS: Add reminder to update ClientSideUrlRedirect --- .../security/dataflow/ClientSideUrlRedirectCustomizations.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll index e79acdbf396..65d9b01fe88 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll @@ -35,7 +35,7 @@ module ClientSideUrlRedirect { * hence are only partially user-controlled. */ abstract class DocumentUrl extends DataFlow::FlowLabel { - DocumentUrl() { this = "document.url" } + DocumentUrl() { this = "document.url" } // TODO: replace with TaintedUrlSuffix } /** A source of remote user input, considered as a flow source for unvalidated URL redirects. */ From e4f7560bcdfa65353354c6d5aa3692225330d6b5 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 10 Sep 2024 15:32:53 +0200 Subject: [PATCH 281/514] JS: Add missing qldoc --- .../ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll b/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll index 79dee94c58f..8f9e13354c3 100644 --- a/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll +++ b/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll @@ -46,6 +46,12 @@ module TaintedUrlSuffix { ] } + /** + * Holds if `node` should be a barrier for the given `label`. + * + * This should be used in the `isBarrier` predicate of a configuration that uses the tainted-url-suffix + * label. + */ predicate isBarrier(Node node, FlowLabel label) { label = label() and DataFlowPrivate::optionalBarrier(node, "tainted-url-suffix") From 3fcf4ef7a19c13836660877f004c3f4d1ae677aa Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 11 Sep 2024 10:48:59 +0200 Subject: [PATCH 282/514] JS: More precise model of .shift() Array.prototype.shift only returns the first array element. The mutation of Argument[this] is not yet modelled, and is better handled when we have use-use flow. --- .../ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll index 0723cbf3767..614d67ae077 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll @@ -484,7 +484,7 @@ class Shift extends SummarizedCallable { override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { preservesValue = true and - input = "Argument[this].ArrayElement" and + input = "Argument[this].ArrayElement[0]" and output = "ReturnValue" } } From 3ea1134cc15a95439427ef015f2ee4098f3f0dca Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 11 Sep 2024 11:04:41 +0200 Subject: [PATCH 283/514] JS: Add inline test for .shift() method --- .../ql/test/library-tests/TripleDot/arrays.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 javascript/ql/test/library-tests/TripleDot/arrays.js diff --git a/javascript/ql/test/library-tests/TripleDot/arrays.js b/javascript/ql/test/library-tests/TripleDot/arrays.js new file mode 100644 index 00000000000..d6171c56c26 --- /dev/null +++ b/javascript/ql/test/library-tests/TripleDot/arrays.js @@ -0,0 +1,15 @@ +import 'dummy'; + +function shiftKnown() { + let array = [source('shift.1'), source('shift.2')]; + sink(array.shift()); // $ hasValueFlow=shift.1 + sink(array.shift()); // $ SPURIOUS: hasValueFlow=shift.1 MISSING: hasValueFlow=shift.2 +} + +function shiftUnknown() { + const array = new Array(Math.floor(Math.random() * 10)); + array.push(source('shift.unkn')); + sink(array.shift()); // $ hasValueFlow=shift.unkn + sink(array.shift()); // $ hasValueFlow=shift.unkn + sink(array.shift()); // $ hasValueFlow=shift.unkn +} From 3b09bc548e60be45342caecb744b0dfe7c48572a Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 11 Sep 2024 13:23:10 +0200 Subject: [PATCH 284/514] JS: Add taint step for shift() --- .../semmle/javascript/internal/flow_summaries/Arrays.qll | 5 +++++ javascript/ql/test/library-tests/TripleDot/arrays.js | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll index 614d67ae077..e242ed35a67 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll @@ -486,6 +486,11 @@ class Shift extends SummarizedCallable { preservesValue = true and input = "Argument[this].ArrayElement[0]" and output = "ReturnValue" + or + // ArrayElement[0] is not automatically converted to a taint step, so add it manually + preservesValue = false and + input = "Argument[this]" and + output = "ReturnValue" } } diff --git a/javascript/ql/test/library-tests/TripleDot/arrays.js b/javascript/ql/test/library-tests/TripleDot/arrays.js index d6171c56c26..0a18066eb76 100644 --- a/javascript/ql/test/library-tests/TripleDot/arrays.js +++ b/javascript/ql/test/library-tests/TripleDot/arrays.js @@ -13,3 +13,10 @@ function shiftUnknown() { sink(array.shift()); // $ hasValueFlow=shift.unkn sink(array.shift()); // $ hasValueFlow=shift.unkn } + +function shiftTaint() { + const array = source('shift.directly-tainted'); + sink(array.shift()); // $ hasTaintFlow=shift.directly-tainted + sink(array.shift()); // $ hasTaintFlow=shift.directly-tainted + sink(array.shift()); // $ hasTaintFlow=shift.directly-tainted +} From cf90c83604db7944caa546473a7d028a288b7329 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 11 Sep 2024 13:27:12 +0200 Subject: [PATCH 285/514] JS: Accept changes to nodes/edges results --- .../IndirectCommandInjection.expected | 31 +++++++++++++++++++ .../Security/CWE-079/DomBasedXss/Xss.expected | 6 ---- .../XssWithAdditionalSources.expected | 6 ---- .../ClientSideUrlRedirect.expected | 9 ++++++ .../PrototypePollutingAssignment.expected | 9 ++++++ 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected index a6b90c01ff1..60a29847a10 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected @@ -7,33 +7,52 @@ edges | command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:11:14:11:17 | args | provenance | | | command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:12:26:12:29 | args | provenance | | | command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:14:18:14:21 | args | provenance | | +| command-line-parameter-command-injection.js:10:6:10:33 | args [ArrayElement] | command-line-parameter-command-injection.js:11:14:11:17 | args [ArrayElement] | provenance | | +| command-line-parameter-command-injection.js:10:6:10:33 | args [ArrayElement] | command-line-parameter-command-injection.js:12:26:12:29 | args [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:10:6:10:33 | args [ArrayElement] | command-line-parameter-command-injection.js:14:18:14:21 | args [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | provenance | | | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | command-line-parameter-command-injection.js:10:6:10:33 | args | provenance | | | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) [ArrayElement] | command-line-parameter-command-injection.js:10:6:10:33 | args [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:11:14:11:17 | args | command-line-parameter-command-injection.js:11:14:11:20 | args[0] | provenance | | +| command-line-parameter-command-injection.js:11:14:11:17 | args [ArrayElement] | command-line-parameter-command-injection.js:11:14:11:20 | args[0] | provenance | | | command-line-parameter-command-injection.js:12:26:12:29 | args | command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | provenance | | +| command-line-parameter-command-injection.js:12:26:12:29 | args [ArrayElement] | command-line-parameter-command-injection.js:12:26:12:32 | args[0] | provenance | | +| command-line-parameter-command-injection.js:12:26:12:32 | args[0] | command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | provenance | | | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | provenance | | | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | provenance | | | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | provenance | | +| command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs [ArrayElement] | command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs [ArrayElement] | provenance | | +| command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs [ArrayElement] | command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs [ArrayElement] | provenance | | +| command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs [ArrayElement] | command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:14:18:14:21 | args | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | provenance | | +| command-line-parameter-command-injection.js:14:18:14:21 | args | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:14:18:14:21 | args [ArrayElement] | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | provenance | | +| command-line-parameter-command-injection.js:14:18:14:21 | args [ArrayElement] | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | provenance | | +| command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) [ArrayElement] | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | provenance | | +| command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs [ArrayElement] | command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | provenance | | | command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | provenance | | +| command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs [ArrayElement] | command-line-parameter-command-injection.js:16:26:16:37 | fewerArgs[0] | provenance | | +| command-line-parameter-command-injection.js:16:26:16:37 | fewerArgs[0] | command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | provenance | | | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | command-line-parameter-command-injection.js:19:14:19:17 | arg0 | provenance | | | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | command-line-parameter-command-injection.js:20:26:20:29 | arg0 | provenance | | | command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | provenance | | +| command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs [ArrayElement] | command-line-parameter-command-injection.js:18:13:18:24 | fewerArgs[0] | provenance | | +| command-line-parameter-command-injection.js:18:13:18:24 | fewerArgs[0] | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | provenance | | | command-line-parameter-command-injection.js:20:26:20:29 | arg0 | command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | provenance | | | command-line-parameter-command-injection.js:24:8:24:35 | args | command-line-parameter-command-injection.js:26:32:26:35 | args | provenance | | | command-line-parameter-command-injection.js:24:8:24:35 | args | command-line-parameter-command-injection.js:27:32:27:35 | args | provenance | | +| command-line-parameter-command-injection.js:24:8:24:35 | args [ArrayElement] | command-line-parameter-command-injection.js:26:32:26:35 | args [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:24:8:24:35 | args [ArrayElement] | command-line-parameter-command-injection.js:27:32:27:35 | args [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:24:15:24:26 | process.argv | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | provenance | | | command-line-parameter-command-injection.js:24:15:24:26 | process.argv | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | command-line-parameter-command-injection.js:24:8:24:35 | args | provenance | | | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) [ArrayElement] | command-line-parameter-command-injection.js:24:8:24:35 | args [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:26:32:26:35 | args | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | provenance | | +| command-line-parameter-command-injection.js:26:32:26:35 | args [ArrayElement] | command-line-parameter-command-injection.js:26:32:26:38 | args[0] | provenance | | +| command-line-parameter-command-injection.js:26:32:26:38 | args[0] | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | provenance | | | command-line-parameter-command-injection.js:27:32:27:35 | args | command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | provenance | | | command-line-parameter-command-injection.js:27:32:27:35 | args [ArrayElement] | command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | provenance | | | command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | provenance | | @@ -139,19 +158,29 @@ nodes | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | semmle.label | process ... lice(2) | | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) [ArrayElement] | semmle.label | process ... lice(2) [ArrayElement] | | command-line-parameter-command-injection.js:11:14:11:17 | args | semmle.label | args | +| command-line-parameter-command-injection.js:11:14:11:17 | args [ArrayElement] | semmle.label | args [ArrayElement] | | command-line-parameter-command-injection.js:11:14:11:20 | args[0] | semmle.label | args[0] | | command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | semmle.label | "cmd.sh " + args[0] | | command-line-parameter-command-injection.js:12:26:12:29 | args | semmle.label | args | +| command-line-parameter-command-injection.js:12:26:12:29 | args [ArrayElement] | semmle.label | args [ArrayElement] | +| command-line-parameter-command-injection.js:12:26:12:32 | args[0] | semmle.label | args[0] | | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | semmle.label | fewerArgs | +| command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs [ArrayElement] | semmle.label | fewerArgs [ArrayElement] | | command-line-parameter-command-injection.js:14:18:14:21 | args | semmle.label | args | | command-line-parameter-command-injection.js:14:18:14:21 | args [ArrayElement] | semmle.label | args [ArrayElement] | | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | semmle.label | args.slice(1) | +| command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) [ArrayElement] | semmle.label | args.slice(1) [ArrayElement] | | command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | semmle.label | fewerArgs | +| command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs [ArrayElement] | semmle.label | fewerArgs [ArrayElement] | | command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | semmle.label | fewerArgs[0] | | command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | semmle.label | "cmd.sh ... Args[0] | | command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | semmle.label | fewerArgs | +| command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs [ArrayElement] | semmle.label | fewerArgs [ArrayElement] | +| command-line-parameter-command-injection.js:16:26:16:37 | fewerArgs[0] | semmle.label | fewerArgs[0] | | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | semmle.label | arg0 | | command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | semmle.label | fewerArgs | +| command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs [ArrayElement] | semmle.label | fewerArgs [ArrayElement] | +| command-line-parameter-command-injection.js:18:13:18:24 | fewerArgs[0] | semmle.label | fewerArgs[0] | | command-line-parameter-command-injection.js:19:14:19:17 | arg0 | semmle.label | arg0 | | command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | semmle.label | "cmd.sh " + arg0 | | command-line-parameter-command-injection.js:20:26:20:29 | arg0 | semmle.label | arg0 | @@ -162,6 +191,8 @@ nodes | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) [ArrayElement] | semmle.label | process ... lice(2) [ArrayElement] | | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | semmle.label | `node $ ... ption"` | | command-line-parameter-command-injection.js:26:32:26:35 | args | semmle.label | args | +| command-line-parameter-command-injection.js:26:32:26:35 | args [ArrayElement] | semmle.label | args [ArrayElement] | +| command-line-parameter-command-injection.js:26:32:26:38 | args[0] | semmle.label | args[0] | | command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | semmle.label | `node $ ... ption"` | | command-line-parameter-command-injection.js:27:32:27:35 | args | semmle.label | args | | command-line-parameter-command-injection.js:27:32:27:35 | args [ArrayElement] | semmle.label | args [ArrayElement] | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 28c31f30595..1e35f0d6edb 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -545,7 +545,6 @@ nodes | tst.js:421:20:421:24 | match | semmle.label | match | | tst.js:421:20:421:27 | match[1] | semmle.label | match[1] | | tst.js:424:18:424:37 | window.location.hash | semmle.label | window.location.hash | -| tst.js:424:18:424:48 | window. ... it('#') | semmle.label | window. ... it('#') | | tst.js:424:18:424:48 | window. ... it('#') [1] | semmle.label | window. ... it('#') [1] | | tst.js:424:18:424:51 | window. ... '#')[1] | semmle.label | window. ... '#')[1] | | tst.js:428:7:428:39 | target | semmle.label | target | @@ -1146,13 +1145,8 @@ edges | tst.js:419:15:419:55 | window. ... (\\w+)/) | tst.js:419:7:419:55 | match | provenance | | | tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | provenance | | | tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | provenance | Config | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | provenance | | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | provenance | Config | | tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') [1] | provenance | Config | -| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | -| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | Config | | tst.js:424:18:424:48 | window. ... it('#') [1] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | -| tst.js:424:18:424:48 | window. ... it('#') [1] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | Config | | tst.js:428:7:428:39 | target | tst.js:430:18:430:23 | target | provenance | | | tst.js:428:16:428:39 | documen ... .search | tst.js:428:7:428:39 | target | provenance | | | tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index d5118254128..42841b5ffd7 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -550,7 +550,6 @@ nodes | tst.js:421:20:421:24 | match | semmle.label | match | | tst.js:421:20:421:27 | match[1] | semmle.label | match[1] | | tst.js:424:18:424:37 | window.location.hash | semmle.label | window.location.hash | -| tst.js:424:18:424:48 | window. ... it('#') | semmle.label | window. ... it('#') | | tst.js:424:18:424:48 | window. ... it('#') [1] | semmle.label | window. ... it('#') [1] | | tst.js:424:18:424:51 | window. ... '#')[1] | semmle.label | window. ... '#')[1] | | tst.js:428:7:428:39 | target | semmle.label | target | @@ -1171,13 +1170,8 @@ edges | tst.js:419:15:419:55 | window. ... (\\w+)/) | tst.js:419:7:419:55 | match | provenance | | | tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | provenance | | | tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | provenance | Config | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | provenance | | -| tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') | provenance | Config | | tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') [1] | provenance | Config | -| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | -| tst.js:424:18:424:48 | window. ... it('#') | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | Config | | tst.js:424:18:424:48 | window. ... it('#') [1] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | -| tst.js:424:18:424:48 | window. ... it('#') [1] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | Config | | tst.js:428:7:428:39 | target | tst.js:430:18:430:23 | target | provenance | | | tst.js:428:16:428:39 | documen ... .search | tst.js:428:7:428:39 | target | provenance | | | tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected index c245c3e3a10..e1194cd8154 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected @@ -42,10 +42,14 @@ nodes | tst10.js:14:17:14:56 | 'https: ... .search | semmle.label | 'https: ... .search | | tst10.js:14:33:14:56 | documen ... .search | semmle.label | documen ... .search | | tst12.js:3:9:3:50 | urlParts | semmle.label | urlParts | +| tst12.js:3:9:3:50 | urlParts [ArrayElement] | semmle.label | urlParts [ArrayElement] | | tst12.js:3:20:3:39 | window.location.hash | semmle.label | window.location.hash | | tst12.js:3:20:3:50 | window. ... it('?') | semmle.label | window. ... it('?') | +| tst12.js:3:20:3:50 | window. ... it('?') [ArrayElement] | semmle.label | window. ... it('?') [ArrayElement] | | tst12.js:4:9:4:45 | loc | semmle.label | loc | | tst12.js:4:15:4:22 | urlParts | semmle.label | urlParts | +| tst12.js:4:15:4:22 | urlParts [ArrayElement] | semmle.label | urlParts [ArrayElement] | +| tst12.js:4:15:4:25 | urlParts[0] | semmle.label | urlParts[0] | | tst12.js:5:23:5:25 | loc | semmle.label | loc | | tst13.js:2:9:2:52 | payload | semmle.label | payload | | tst13.js:2:19:2:42 | documen ... .search | semmle.label | documen ... .search | @@ -146,10 +150,15 @@ edges | tst10.js:11:27:11:50 | documen ... .search | tst10.js:11:17:11:50 | '//foo' ... .search | provenance | | | tst10.js:14:33:14:56 | documen ... .search | tst10.js:14:17:14:56 | 'https: ... .search | provenance | | | tst12.js:3:9:3:50 | urlParts | tst12.js:4:15:4:22 | urlParts | provenance | | +| tst12.js:3:9:3:50 | urlParts [ArrayElement] | tst12.js:4:15:4:22 | urlParts [ArrayElement] | provenance | | | tst12.js:3:20:3:39 | window.location.hash | tst12.js:3:20:3:50 | window. ... it('?') | provenance | | +| tst12.js:3:20:3:39 | window.location.hash | tst12.js:3:20:3:50 | window. ... it('?') [ArrayElement] | provenance | | | tst12.js:3:20:3:50 | window. ... it('?') | tst12.js:3:9:3:50 | urlParts | provenance | | +| tst12.js:3:20:3:50 | window. ... it('?') [ArrayElement] | tst12.js:3:9:3:50 | urlParts [ArrayElement] | provenance | | | tst12.js:4:9:4:45 | loc | tst12.js:5:23:5:25 | loc | provenance | | | tst12.js:4:15:4:22 | urlParts | tst12.js:4:9:4:45 | loc | provenance | | +| tst12.js:4:15:4:22 | urlParts [ArrayElement] | tst12.js:4:15:4:25 | urlParts[0] | provenance | | +| tst12.js:4:15:4:25 | urlParts[0] | tst12.js:4:9:4:45 | loc | provenance | | | tst13.js:2:9:2:52 | payload | tst13.js:4:15:4:21 | payload | provenance | | | tst13.js:2:9:2:52 | payload | tst13.js:8:21:8:27 | payload | provenance | | | tst13.js:2:9:2:52 | payload | tst13.js:12:14:12:20 | payload | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected index 46afcf5a14f..46e9be97d63 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected @@ -18,11 +18,16 @@ edges | lib.js:26:14:26:17 | path | lib.js:26:14:26:20 | path[0] | provenance | Config | | lib.js:26:14:26:20 | path[0] | lib.js:26:10:26:21 | obj[path[0]] | provenance | Config | | lib.js:30:9:30:52 | args | lib.js:32:14:32:17 | args | provenance | | +| lib.js:30:9:30:52 | args [ArrayElement] | lib.js:32:14:32:17 | args [ArrayElement] | provenance | | | lib.js:30:16:30:52 | Array.p ... uments) | lib.js:30:9:30:52 | args | provenance | | +| lib.js:30:16:30:52 | Array.p ... uments) [ArrayElement] | lib.js:30:9:30:52 | args [ArrayElement] | provenance | | | lib.js:30:16:30:52 | reflective call | lib.js:30:16:30:52 | Array.p ... uments) | provenance | | +| lib.js:30:16:30:52 | reflective call [ArrayElement] | lib.js:30:16:30:52 | Array.p ... uments) [ArrayElement] | provenance | | | lib.js:30:43:30:51 | arguments | lib.js:30:16:30:52 | reflective call | provenance | Config | +| lib.js:30:43:30:51 | arguments | lib.js:30:16:30:52 | reflective call [ArrayElement] | provenance | Config | | lib.js:32:7:32:20 | path | lib.js:34:7:34:10 | path | provenance | | | lib.js:32:14:32:17 | args | lib.js:32:14:32:20 | args[1] | provenance | Config | +| lib.js:32:14:32:17 | args [ArrayElement] | lib.js:32:14:32:20 | args[1] | provenance | | | lib.js:32:14:32:20 | args[1] | lib.js:32:7:32:20 | path | provenance | | | lib.js:34:7:34:10 | path | lib.js:34:7:34:13 | path[0] | provenance | Config | | lib.js:34:7:34:13 | path[0] | lib.js:34:3:34:14 | obj[path[0]] | provenance | Config | @@ -125,11 +130,15 @@ nodes | 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:9:30:52 | args [ArrayElement] | semmle.label | args [ArrayElement] | | lib.js:30:16:30:52 | Array.p ... uments) | semmle.label | Array.p ... uments) | +| lib.js:30:16:30:52 | Array.p ... uments) [ArrayElement] | semmle.label | Array.p ... uments) [ArrayElement] | | lib.js:30:16:30:52 | reflective call | semmle.label | reflective call | +| lib.js:30:16:30:52 | reflective call [ArrayElement] | semmle.label | reflective call [ArrayElement] | | 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:17 | args [ArrayElement] | semmle.label | args [ArrayElement] | | 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 | From e1bed42481b2b48f82d35742939d32daffc589ea Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 11 Sep 2024 15:02:36 +0200 Subject: [PATCH 286/514] JS: Add inline expectation test specifically for TaintedUrlSuffix --- .../TaintedUrlSuffix/test.expected | 2 + .../library-tests/TaintedUrlSuffix/test.ql | 52 +++++++++++++++++++ .../library-tests/TaintedUrlSuffix/tst.js | 22 ++++++++ 3 files changed, 76 insertions(+) create mode 100644 javascript/ql/test/library-tests/TaintedUrlSuffix/test.expected create mode 100644 javascript/ql/test/library-tests/TaintedUrlSuffix/test.ql create mode 100644 javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js diff --git a/javascript/ql/test/library-tests/TaintedUrlSuffix/test.expected b/javascript/ql/test/library-tests/TaintedUrlSuffix/test.expected new file mode 100644 index 00000000000..8ec8033d086 --- /dev/null +++ b/javascript/ql/test/library-tests/TaintedUrlSuffix/test.expected @@ -0,0 +1,2 @@ +testFailures +failures diff --git a/javascript/ql/test/library-tests/TaintedUrlSuffix/test.ql b/javascript/ql/test/library-tests/TaintedUrlSuffix/test.ql new file mode 100644 index 00000000000..f3d43dd4104 --- /dev/null +++ b/javascript/ql/test/library-tests/TaintedUrlSuffix/test.ql @@ -0,0 +1,52 @@ +import javascript +import testUtilities.InlineExpectationsTest +import semmle.javascript.security.TaintedUrlSuffix + +module TestConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; + + predicate isSource(DataFlow::Node node, DataFlow::FlowLabel state) { + node = TaintedUrlSuffix::source() and state = TaintedUrlSuffix::label() + or + node instanceof RemoteFlowSource and + not node = TaintedUrlSuffix::source() and + state.isTaint() + } + + predicate isSink(DataFlow::Node node, DataFlow::FlowLabel state) { none() } + + predicate isSink(DataFlow::Node node) { + exists(DataFlow::CallNode call | + call.getCalleeName() = "sink" and + node = call.getArgument(0) + ) + } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowLabel state1, DataFlow::Node node2, + DataFlow::FlowLabel state2 + ) { + TaintedUrlSuffix::step(node1, node2, state1, state2) + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel label) { + TaintedUrlSuffix::isBarrier(node, label) + } +} + +module TestFlow = TaintTracking::GlobalWithState; + +module InlineTest implements TestSig { + string getARelevantTag() { result = "flow" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "flow" and + exists(TestFlow::PathNode src, TestFlow::PathNode sink | TestFlow::flowPath(src, sink) | + sink.getLocation() = location and + element = "" and + value = sink.getState() + ) + } +} + +import MakeTest diff --git a/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js b/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js new file mode 100644 index 00000000000..3fdfd969306 --- /dev/null +++ b/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js @@ -0,0 +1,22 @@ +import 'dummy'; + +function t1() { + const href = window.location.href; + + sink(href); // $ flow=tainted-url-suffix + + sink(href.split('#')[0]); // $ MISSING: flow=tainted-url-suffix SPURIOUS: flow=taint + sink(href.split('#')[1]); // $ flow=taint + sink(href.split('#').pop()); // $ flow=taint + sink(href.split('#')[2]); // $ flow=taint + + sink(href.split('?')[0]); // $ MISSING: flow=tainted-url-suffix + sink(href.split('?')[1]); // $ flow=taint + sink(href.split('?').pop()); // $ flow=taint + sink(href.split('?')[2]); // $ flow=taint + + sink(href.split(blah())[0]); // $ flow=tainted-url-suffix + sink(href.split(blah())[1]); // $ flow=tainted-url-suffix + sink(href.split(blah()).pop()); // $ flow=tainted-url-suffix + sink(href.split(blah())[2]); // $ flow=tainted-url-suffix +} From bc04131c72d3a88394f0136219c1b82d5bf1c057 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 11 Sep 2024 15:06:48 +0200 Subject: [PATCH 287/514] JS: Disallow implicit reads before an optional step --- .../javascript/dataflow/internal/TaintTrackingPrivate.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index 69d275a74dc..a16da33664d 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -61,5 +61,7 @@ predicate defaultTaintSanitizer(DataFlow::Node node) { bindingset[node] predicate defaultImplicitTaintRead(DataFlow::Node node, ContentSet c) { exists(node) and - c = [ContentSet::promiseValue(), ContentSet::arrayElement()] + c = [ContentSet::promiseValue(), ContentSet::arrayElement()] and + // Optional steps are added through isAdditionalFlowStep but we don't want the implicit reads + not optionalStep(node, _, _) } From 2712bf821addd46e49aa249559a5f80be85e1663 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 11 Sep 2024 15:09:03 +0200 Subject: [PATCH 288/514] JS: Fix a bug in isSafeClientSideUrlProperty --- javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll | 2 +- javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 13970c16143..ad42131ca4d 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -255,7 +255,7 @@ module TaintTracking { exists(StringSplitCall c | c.getBaseString().getALocalSource() = [DOM::locationRef(), DOM::locationRef().getAPropertyRead("href")] and - c.getSeparator() = "?" and + c.getSeparator() = ["?", "#"] and read = c.getAPropertyRead("0") ) } diff --git a/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js b/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js index 3fdfd969306..243b0374697 100644 --- a/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js +++ b/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js @@ -5,7 +5,7 @@ function t1() { sink(href); // $ flow=tainted-url-suffix - sink(href.split('#')[0]); // $ MISSING: flow=tainted-url-suffix SPURIOUS: flow=taint + sink(href.split('#')[0]); // $ MISSING: flow=tainted-url-suffix sink(href.split('#')[1]); // $ flow=taint sink(href.split('#').pop()); // $ flow=taint sink(href.split('#')[2]); // $ flow=taint From 74ab346348e4257d12a9bc3bb66ed4854f4b6a64 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 11 Sep 2024 15:38:39 +0200 Subject: [PATCH 289/514] JS: Do not include taint steps in TaintedUrlSuffix::step TaintedUrlSuffix is currently only used in TaintTracking configs meaning it is already propagated by taint steps. The inclusion of these taint steps here however meant that implicit reads could appear prior to any of these steps. This was is problematic for PropRead steps as an expression like x[0] could spuriously read from array element 1 via the path: x [element 1] x [empty access path] (after implicit read) x[0] (taint step through PropRead) --- .../javascript/security/TaintedUrlSuffix.qll | 16 ---------------- .../test/library-tests/TaintedUrlSuffix/tst.js | 4 ++-- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll b/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll index 8f9e13354c3..231e6e4dc9b 100644 --- a/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll +++ b/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll @@ -36,16 +36,6 @@ module TaintedUrlSuffix { result.getKind().isUrl() } - /** Holds for `pred -> succ` is a step of form `x -> x.p` */ - private predicate isSafeLocationProp(DataFlow::PropRead read) { - // Ignore properties that refer to the scheme, domain, port, auth, or path. - read.getPropertyName() = - [ - "protocol", "scheme", "host", "hostname", "domain", "origin", "port", "path", "pathname", - "username", "password", "auth" - ] - } - /** * Holds if `node` should be a barrier for the given `label`. * @@ -63,12 +53,6 @@ module TaintedUrlSuffix { * This handles steps through string operations, promises, URL parsers, and URL accessors. */ predicate step(Node src, Node dst, FlowLabel srclbl, FlowLabel dstlbl) { - // Inherit all ordinary taint steps except `x -> x.p` steps - srclbl = label() and - dstlbl = label() and - TaintTracking::AdditionalTaintStep::step(src, dst) and - not isSafeLocationProp(dst) - or srclbl = label() and dstlbl.isTaint() and DataFlowPrivate::optionalStep(src, "tainted-url-suffix", dst) diff --git a/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js b/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js index 243b0374697..80d80597e8a 100644 --- a/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js +++ b/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js @@ -8,12 +8,12 @@ function t1() { sink(href.split('#')[0]); // $ MISSING: flow=tainted-url-suffix sink(href.split('#')[1]); // $ flow=taint sink(href.split('#').pop()); // $ flow=taint - sink(href.split('#')[2]); // $ flow=taint + sink(href.split('#')[2]); // $ MISSING: flow=taint // currently the split() summary only propagates to index 1 sink(href.split('?')[0]); // $ MISSING: flow=tainted-url-suffix sink(href.split('?')[1]); // $ flow=taint sink(href.split('?').pop()); // $ flow=taint - sink(href.split('?')[2]); // $ flow=taint + sink(href.split('?')[2]); // $ MISSING: flow=taint sink(href.split(blah())[0]); // $ flow=tainted-url-suffix sink(href.split(blah())[1]); // $ flow=tainted-url-suffix From 0e4e0f4fdd42d2ab85ef52f820845589d0b46264 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 11 Sep 2024 15:47:35 +0200 Subject: [PATCH 290/514] JS: Preverse tainted-url-suffix when stepping into prefix A URL of form https://example.com?evil#bar will contain '?evil' after splitting out the '#' suffix, and vice versa. --- .../semmle/javascript/internal/flow_summaries/Strings.qll | 7 +++++-- .../lib/semmle/javascript/security/TaintedUrlSuffix.qll | 8 ++++++-- javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js | 8 ++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll index 1135f6cb7f0..9267ab598fb 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll @@ -88,10 +88,13 @@ class StringSplitHashOrQuestionMark extends SummarizedCallable { override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { preservesValue = false and ( - input = "Argument[this].OptionalBarrier[tainted-url-suffix]" and + input = "Argument[this].OptionalBarrier[split-url-suffix]" and output = "ReturnValue.ArrayElement" or - input = "Argument[this].OptionalStep[tainted-url-suffix]" and + input = "Argument[this].OptionalStep[split-url-suffix-pre]" and + output = "ReturnValue.ArrayElement[0]" + or + input = "Argument[this].OptionalStep[split-url-suffix-post]" and output = "ReturnValue.ArrayElement[1]" // TODO: support ArrayElement[1..] ) } diff --git a/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll b/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll index 231e6e4dc9b..9f20a5fb644 100644 --- a/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll +++ b/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll @@ -44,7 +44,7 @@ module TaintedUrlSuffix { */ predicate isBarrier(Node node, FlowLabel label) { label = label() and - DataFlowPrivate::optionalBarrier(node, "tainted-url-suffix") + DataFlowPrivate::optionalBarrier(node, "split-url-suffix") } /** @@ -55,7 +55,11 @@ module TaintedUrlSuffix { predicate step(Node src, Node dst, FlowLabel srclbl, FlowLabel dstlbl) { srclbl = label() and dstlbl.isTaint() and - DataFlowPrivate::optionalStep(src, "tainted-url-suffix", dst) + DataFlowPrivate::optionalStep(src, "split-url-suffix-post", dst) + or + srclbl = label() and + dstlbl = label() and + DataFlowPrivate::optionalStep(src, "split-url-suffix-pre", dst) or // Transition from URL suffix to full taint when extracting the query/fragment part. srclbl = label() and diff --git a/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js b/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js index 80d80597e8a..8f08dce9250 100644 --- a/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js +++ b/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js @@ -5,14 +5,14 @@ function t1() { sink(href); // $ flow=tainted-url-suffix - sink(href.split('#')[0]); // $ MISSING: flow=tainted-url-suffix + sink(href.split('#')[0]); // $ flow=tainted-url-suffix sink(href.split('#')[1]); // $ flow=taint - sink(href.split('#').pop()); // $ flow=taint + sink(href.split('#').pop()); // $ flow=taint flow=tainted-url-suffix sink(href.split('#')[2]); // $ MISSING: flow=taint // currently the split() summary only propagates to index 1 - sink(href.split('?')[0]); // $ MISSING: flow=tainted-url-suffix + sink(href.split('?')[0]); // $ flow=tainted-url-suffix sink(href.split('?')[1]); // $ flow=taint - sink(href.split('?').pop()); // $ flow=taint + sink(href.split('?').pop()); // $ flow=taint flow=tainted-url-suffix sink(href.split('?')[2]); // $ MISSING: flow=taint sink(href.split(blah())[0]); // $ flow=tainted-url-suffix From 1df69ec1d22112ec380e7a0ce250426619db2d02 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 12 Sep 2024 13:16:52 +0200 Subject: [PATCH 291/514] JS: Actually don't propagate into array element 0 Preserving tainted-url-suffix into array element 0 seemed like a good idea, but didn't work out so well. --- .../javascript/security/TaintedUrlSuffix.qll | 12 +- .../library-tests/TaintedUrlSuffix/tst.js | 8 +- .../Security/CWE-079/DomBasedXss/Xss.expected | 112 ++--------------- .../XssWithAdditionalSources.expected | 116 ++---------------- .../Security/CWE-079/DomBasedXss/tst.js | 2 +- 5 files changed, 34 insertions(+), 216 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll b/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll index 9f20a5fb644..0158b146679 100644 --- a/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll +++ b/javascript/ql/lib/semmle/javascript/security/TaintedUrlSuffix.qll @@ -53,14 +53,18 @@ module TaintedUrlSuffix { * This handles steps through string operations, promises, URL parsers, and URL accessors. */ predicate step(Node src, Node dst, FlowLabel srclbl, FlowLabel dstlbl) { + // Transition from tainted-url-suffix to general taint when entering the second array element + // of a split('#') or split('?') array. + // + // x [tainted-url-suffix] --> x.split('#') [array element 1] [taint] + // + // Technically we should also preverse tainted-url-suffix when entering the first array element of such + // a split, but this mostly leads to FPs since we currently don't track if the taint has been through URI-decoding. + // (The query/fragment parts are often URI-decoded in practice, but not the other URL parts are not) srclbl = label() and dstlbl.isTaint() and DataFlowPrivate::optionalStep(src, "split-url-suffix-post", dst) or - srclbl = label() and - dstlbl = label() and - DataFlowPrivate::optionalStep(src, "split-url-suffix-pre", dst) - or // Transition from URL suffix to full taint when extracting the query/fragment part. srclbl = label() and dstlbl.isTaint() and diff --git a/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js b/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js index 8f08dce9250..0c755ac6512 100644 --- a/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js +++ b/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js @@ -5,14 +5,14 @@ function t1() { sink(href); // $ flow=tainted-url-suffix - sink(href.split('#')[0]); // $ flow=tainted-url-suffix + sink(href.split('#')[0]); // could be 'tainted-url-suffix', but omitted due to FPs from URI-encoding sink(href.split('#')[1]); // $ flow=taint - sink(href.split('#').pop()); // $ flow=taint flow=tainted-url-suffix + sink(href.split('#').pop()); // $ flow=taint sink(href.split('#')[2]); // $ MISSING: flow=taint // currently the split() summary only propagates to index 1 - sink(href.split('?')[0]); // $ flow=tainted-url-suffix + sink(href.split('?')[0]); sink(href.split('?')[1]); // $ flow=taint - sink(href.split('?').pop()); // $ flow=taint flow=tainted-url-suffix + sink(href.split('?').pop()); // $ flow=taint sink(href.split('?')[2]); // $ MISSING: flow=taint sink(href.split(blah())[0]); // $ flow=tainted-url-suffix diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 1e35f0d6edb..922118ef84b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -4,7 +4,6 @@ nodes | addEventListener.js:2:20:2:29 | event.data | semmle.label | event.data | | addEventListener.js:5:43:5:48 | data | semmle.label | data | | addEventListener.js:5:43:5:48 | {data} | semmle.label | {data} | -| addEventListener.js:5:44:5:47 | data | semmle.label | data | | addEventListener.js:6:20:6:23 | data | semmle.label | data | | addEventListener.js:10:21:10:25 | event | semmle.label | event | | addEventListener.js:12:24:12:28 | event | semmle.label | event | @@ -189,9 +188,7 @@ nodes | jquery.js:37:31:37:37 | tainted | semmle.label | tainted | | json-stringify.jsx:5:9:5:36 | locale | semmle.label | locale | | json-stringify.jsx:5:18:5:36 | req.param("locale") | semmle.label | req.param("locale") | -| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | semmle.label | `https: ... ocale}` | | json-stringify.jsx:11:51:11:56 | locale | semmle.label | locale | -| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | semmle.label | `https: ... ocale}` | | json-stringify.jsx:19:56:19:61 | locale | semmle.label | locale | | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | semmle.label | JSON.st ... locale) | | json-stringify.jsx:31:55:31:60 | locale | semmle.label | locale | @@ -239,7 +236,6 @@ nodes | pages/[id].jsx:3:30:3:35 | params [q] | semmle.label | params [q] | | pages/[id].jsx:5:9:5:14 | { id } | semmle.label | { id } | | pages/[id].jsx:5:9:5:29 | id | semmle.label | id | -| pages/[id].jsx:5:11:5:12 | id | semmle.label | id | | pages/[id].jsx:5:18:5:29 | router.query | semmle.label | router.query | | pages/[id].jsx:10:44:10:45 | id | semmle.label | id | | pages/[id].jsx:13:44:13:49 | params [id] | semmle.label | params [id] | @@ -249,10 +245,8 @@ nodes | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | semmle.label | {\\n ... ,\\n } [id] | | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | semmle.label | {\\n ... ,\\n } [q] | | pages/[id].jsx:25:11:25:24 | context.params | semmle.label | context.params | -| pages/[id].jsx:25:11:25:27 | context.params.id | semmle.label | context.params.id | | pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | semmle.label | context ... d \|\| "" | | pages/[id].jsx:26:10:26:22 | context.query | semmle.label | context.query | -| pages/[id].jsx:26:10:26:30 | context ... .foobar | semmle.label | context ... .foobar | | pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | semmle.label | context ... r \|\| "" | | react-native.js:7:7:7:33 | tainted | semmle.label | tainted | | react-native.js:7:17:7:33 | req.param("code") | semmle.label | req.param("code") | @@ -273,11 +267,9 @@ nodes | react-use-router.js:33:21:33:32 | router.query | semmle.label | router.query | | react-use-router.js:33:21:33:39 | router.query.foobar | semmle.label | router.query.foobar | | react-use-state.js:4:9:4:49 | state | semmle.label | state | -| react-use-state.js:4:10:4:14 | state | semmle.label | state | | react-use-state.js:4:38:4:48 | window.name | semmle.label | window.name | | react-use-state.js:5:51:5:55 | state | semmle.label | state | | react-use-state.js:9:9:9:43 | state | semmle.label | state | -| react-use-state.js:9:10:9:14 | state | semmle.label | state | | react-use-state.js:10:14:10:24 | window.name | semmle.label | window.name | | react-use-state.js:11:51:11:55 | state | semmle.label | state | | react-use-state.js:15:9:15:43 | state | semmle.label | state | @@ -616,7 +608,6 @@ nodes | various-concat-obfuscations.js:15:10:15:83 | '
    ' | semmle.label | '
    ' | | various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | semmle.label | (attrs. ... 'left') | | various-concat-obfuscations.js:15:28:15:32 | attrs | semmle.label | attrs | -| various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | semmle.label | attrs.defaultattr | | various-concat-obfuscations.js:17:24:17:28 | attrs | semmle.label | attrs | | various-concat-obfuscations.js:18:10:18:59 | '
    ') | semmle.label | '
    ') | | various-concat-obfuscations.js:18:10:18:105 | '
    ') [ArrayElement] | semmle.label | '
    ') [ArrayElement] | | various-concat-obfuscations.js:18:32:18:36 | attrs | semmle.label | attrs | -| various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | semmle.label | attrs.defaultattr | | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | semmle.label | attrs.d ... 'left' | | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) | semmle.label | indirec ... .attrs) | | various-concat-obfuscations.js:20:17:20:40 | documen ... .search | semmle.label | documen ... .search | @@ -642,8 +632,7 @@ edges | addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | provenance | | | addEventListener.js:2:20:2:24 | event | addEventListener.js:2:20:2:29 | event.data | provenance | | | addEventListener.js:5:43:5:48 | data | addEventListener.js:6:20:6:23 | data | provenance | | -| addEventListener.js:5:43:5:48 | {data} | addEventListener.js:5:44:5:47 | data | provenance | | -| addEventListener.js:5:44:5:47 | data | addEventListener.js:5:43:5:48 | data | provenance | | +| addEventListener.js:5:43:5:48 | {data} | addEventListener.js:5:43:5:48 | data | provenance | | | addEventListener.js:10:21:10:25 | event | addEventListener.js:12:24:12:28 | event | provenance | | | addEventListener.js:12:24:12:28 | event | addEventListener.js:12:24:12:33 | event.data | provenance | | | angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | provenance | | @@ -689,31 +678,18 @@ edges | dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | provenance | | | dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | provenance | Config | | dates.js:9:36:9:68 | window. ... ring(1) | dates.js:9:17:9:69 | decodeU ... ing(1)) | provenance | | -| dates.js:9:36:9:68 | window. ... ring(1) | dates.js:9:17:9:69 | decodeU ... ing(1)) | provenance | Config | | dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | provenance | | -| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | provenance | Config | | dates.js:11:63:11:67 | taint | dates.js:11:42:11:68 | dateFns ... taint) | provenance | | -| dates.js:11:63:11:67 | taint | dates.js:11:42:11:68 | dateFns ... taint) | provenance | Config | | dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | provenance | | -| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | provenance | Config | | dates.js:12:66:12:70 | taint | dates.js:12:42:12:71 | dateFns ... taint) | provenance | | -| dates.js:12:66:12:70 | taint | dates.js:12:42:12:71 | dateFns ... taint) | provenance | Config | | dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | provenance | | -| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | provenance | Config | | dates.js:13:59:13:63 | taint | dates.js:13:42:13:70 | dateFns ... )(time) | provenance | | -| dates.js:13:59:13:63 | taint | dates.js:13:42:13:70 | dateFns ... )(time) | provenance | Config | | dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | provenance | | -| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | provenance | Config | | dates.js:16:62:16:66 | taint | dates.js:16:42:16:67 | moment( ... (taint) | provenance | | -| dates.js:16:62:16:66 | taint | dates.js:16:42:16:67 | moment( ... (taint) | provenance | Config | | dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | provenance | | -| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | provenance | Config | | dates.js:18:59:18:63 | taint | dates.js:18:42:18:64 | datefor ... taint) | provenance | | -| dates.js:18:59:18:63 | taint | dates.js:18:42:18:64 | datefor ... taint) | provenance | Config | | dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | provenance | | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | provenance | Config | | dates.js:21:61:21:65 | taint | dates.js:21:42:21:66 | dayjs(t ... (taint) | provenance | | -| dates.js:21:61:21:65 | taint | dates.js:21:42:21:66 | dayjs(t ... (taint) | provenance | Config | | dates.js:30:9:30:69 | taint | dates.js:37:77:37:81 | taint | provenance | | | dates.js:30:9:30:69 | taint | dates.js:38:77:38:81 | taint | provenance | | | dates.js:30:9:30:69 | taint | dates.js:39:79:39:83 | taint | provenance | | @@ -722,23 +698,14 @@ edges | dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | provenance | | | dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | provenance | Config | | dates.js:30:36:30:68 | window. ... ring(1) | dates.js:30:17:30:69 | decodeU ... ing(1)) | provenance | | -| dates.js:30:36:30:68 | window. ... ring(1) | dates.js:30:17:30:69 | decodeU ... ing(1)) | provenance | Config | | dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | provenance | | -| dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | provenance | Config | | dates.js:37:77:37:81 | taint | dates.js:37:42:37:82 | dateFns ... taint) | provenance | | -| dates.js:37:77:37:81 | taint | dates.js:37:42:37:82 | dateFns ... taint) | provenance | Config | | dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | provenance | | -| dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | provenance | Config | | dates.js:38:77:38:81 | taint | dates.js:38:42:38:82 | luxon.f ... taint) | provenance | | -| dates.js:38:77:38:81 | taint | dates.js:38:42:38:82 | luxon.f ... taint) | provenance | Config | | dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | provenance | | -| dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | provenance | Config | | dates.js:39:79:39:83 | taint | dates.js:39:42:39:84 | moment. ... taint) | provenance | | -| dates.js:39:79:39:83 | taint | dates.js:39:42:39:84 | moment. ... taint) | provenance | Config | | dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | provenance | | -| dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | provenance | Config | | dates.js:40:77:40:81 | taint | dates.js:40:42:40:82 | dayjs.f ... taint) | provenance | | -| dates.js:40:77:40:81 | taint | dates.js:40:42:40:82 | dayjs.f ... taint) | provenance | Config | | dates.js:46:9:46:69 | taint | dates.js:48:83:48:87 | taint | provenance | | | dates.js:46:9:46:69 | taint | dates.js:49:82:49:86 | taint | provenance | | | dates.js:46:9:46:69 | taint | dates.js:50:97:50:101 | taint | provenance | | @@ -746,19 +713,12 @@ edges | dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | provenance | | | dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | provenance | Config | | dates.js:46:36:46:68 | window. ... ring(1) | dates.js:46:17:46:69 | decodeU ... ing(1)) | provenance | | -| dates.js:46:36:46:68 | window. ... ring(1) | dates.js:46:17:46:69 | decodeU ... ing(1)) | provenance | Config | | dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | provenance | | -| dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | provenance | Config | | dates.js:48:83:48:87 | taint | dates.js:48:42:48:88 | DateTim ... (taint) | provenance | | -| dates.js:48:83:48:87 | taint | dates.js:48:42:48:88 | DateTim ... (taint) | provenance | Config | | dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | provenance | | -| dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | provenance | Config | | dates.js:49:82:49:86 | taint | dates.js:49:42:49:87 | new Dat ... (taint) | provenance | | -| dates.js:49:82:49:86 | taint | dates.js:49:42:49:87 | new Dat ... (taint) | provenance | Config | | dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | provenance | | -| dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | provenance | Config | | dates.js:50:97:50:101 | taint | dates.js:50:42:50:102 | DateTim ... (taint) | provenance | | -| dates.js:50:97:50:101 | taint | dates.js:50:42:50:102 | DateTim ... (taint) | provenance | Config | | dates.js:54:9:54:69 | taint | dates.js:57:94:57:98 | taint | provenance | | | dates.js:54:9:54:69 | taint | dates.js:59:80:59:84 | taint | provenance | | | dates.js:54:9:54:69 | taint | dates.js:61:81:61:85 | taint | provenance | | @@ -766,19 +726,12 @@ edges | dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | provenance | | | dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | provenance | Config | | dates.js:54:36:54:68 | window. ... ring(1) | dates.js:54:17:54:69 | decodeU ... ing(1)) | provenance | | -| dates.js:54:36:54:68 | window. ... ring(1) | dates.js:54:17:54:69 | decodeU ... ing(1)) | provenance | Config | | dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | provenance | | -| dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | provenance | Config | | dates.js:57:94:57:98 | taint | dates.js:57:42:57:99 | moment. ... (taint) | provenance | | -| dates.js:57:94:57:98 | taint | dates.js:57:42:57:99 | moment. ... (taint) | provenance | Config | | dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | provenance | | -| dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | provenance | Config | | dates.js:59:80:59:84 | taint | dates.js:59:42:59:85 | luxon.e ... (taint) | provenance | | -| dates.js:59:80:59:84 | taint | dates.js:59:42:59:85 | luxon.e ... (taint) | provenance | Config | | dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | provenance | | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | provenance | Config | | dates.js:61:81:61:85 | taint | dates.js:61:42:61:86 | dayjs.s ... (taint) | provenance | | -| dates.js:61:81:61:85 | taint | dates.js:61:42:61:86 | dayjs.s ... (taint) | provenance | Config | | dragAndDrop.ts:8:11:8:50 | html | dragAndDrop.ts:15:25:15:28 | html | provenance | | | dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | dragAndDrop.ts:8:11:8:50 | html | provenance | | | dragAndDrop.ts:43:15:43:54 | html | dragAndDrop.ts:50:29:50:32 | html | provenance | | @@ -794,18 +747,12 @@ edges | jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | provenance | | | jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "
    " | provenance | Config | | jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | provenance | | -| jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | provenance | Config | | jquery.js:10:13:10:20 | location | jquery.js:10:13:10:31 | location.toString() | provenance | | -| jquery.js:10:13:10:20 | location | jquery.js:10:13:10:31 | location.toString() | provenance | Config | | jquery.js:10:13:10:31 | location.toString() | jquery.js:10:5:10:40 | "" + ... "" | provenance | Config | | jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | provenance | | -| jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | provenance | Config | | jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | provenance | | -| jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | provenance | Config | | jquery.js:16:38:16:52 | window.location | jquery.js:16:38:16:63 | window. ... tring() | provenance | | -| jquery.js:16:38:16:52 | window.location | jquery.js:16:38:16:63 | window. ... tring() | provenance | Config | | jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) | provenance | | -| jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) | provenance | Config | | jquery.js:18:7:18:33 | hash | jquery.js:21:5:21:8 | hash | provenance | | | jquery.js:18:7:18:33 | hash | jquery.js:22:5:22:8 | hash | provenance | | | jquery.js:18:7:18:33 | hash | jquery.js:23:5:23:8 | hash | provenance | | @@ -825,10 +772,8 @@ edges | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:19:56:19:61 | locale | provenance | | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:31:55:31:60 | locale | provenance | | | json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | provenance | | -| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | provenance | | -| json-stringify.jsx:11:51:11:56 | locale | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | provenance | | -| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | provenance | | -| json-stringify.jsx:19:56:19:61 | locale | json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | provenance | | +| json-stringify.jsx:11:51:11:56 | locale | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | provenance | | +| json-stringify.jsx:19:56:19:61 | locale | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | provenance | | | json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | provenance | | | jwt-server.js:7:9:7:35 | taint | jwt-server.js:9:16:9:20 | taint | provenance | | | jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint | provenance | | @@ -872,19 +817,16 @@ edges | optionalSanitizer.js:45:51:45:56 | target | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | provenance | | | pages/[id].jsx:3:30:3:35 | params [id] | pages/[id].jsx:13:44:13:49 | params [id] | provenance | | | pages/[id].jsx:3:30:3:35 | params [q] | pages/[id].jsx:16:44:16:49 | params [q] | provenance | | -| pages/[id].jsx:5:9:5:14 | { id } | pages/[id].jsx:5:11:5:12 | id | provenance | | +| pages/[id].jsx:5:9:5:14 | { id } | pages/[id].jsx:5:9:5:29 | id | provenance | | | pages/[id].jsx:5:9:5:29 | id | pages/[id].jsx:10:44:10:45 | id | provenance | | -| pages/[id].jsx:5:11:5:12 | id | pages/[id].jsx:5:9:5:29 | id | provenance | | | pages/[id].jsx:5:18:5:29 | router.query | pages/[id].jsx:5:9:5:14 | { id } | provenance | | | pages/[id].jsx:13:44:13:49 | params [id] | pages/[id].jsx:13:44:13:52 | params.id | provenance | | | pages/[id].jsx:16:44:16:49 | params [q] | pages/[id].jsx:16:44:16:51 | params.q | provenance | | | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | pages/[id].jsx:3:30:3:35 | params [id] | provenance | | | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | pages/[id].jsx:3:30:3:35 | params [q] | provenance | | -| pages/[id].jsx:25:11:25:24 | context.params | pages/[id].jsx:25:11:25:27 | context.params.id | provenance | | -| pages/[id].jsx:25:11:25:27 | context.params.id | pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | provenance | | +| pages/[id].jsx:25:11:25:24 | context.params | pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | provenance | | | pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | provenance | | -| pages/[id].jsx:26:10:26:22 | context.query | pages/[id].jsx:26:10:26:30 | context ... .foobar | provenance | | -| pages/[id].jsx:26:10:26:30 | context ... .foobar | pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | provenance | | +| pages/[id].jsx:26:10:26:22 | context.query | pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | provenance | | | pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | provenance | | | react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted | provenance | | | react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted | provenance | | @@ -900,11 +842,9 @@ edges | react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:31:23:36 | [post update] router [ArrayElement] | provenance | | | react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | provenance | | | react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | provenance | | -| react-use-state.js:4:10:4:14 | state | react-use-state.js:4:9:4:49 | state | provenance | | -| react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:10:4:14 | state | provenance | | +| react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:9:4:49 | state | provenance | | | react-use-state.js:9:9:9:43 | state | react-use-state.js:11:51:11:55 | state | provenance | | -| react-use-state.js:9:10:9:14 | state | react-use-state.js:9:9:9:43 | state | provenance | | -| react-use-state.js:10:14:10:24 | window.name | react-use-state.js:9:10:9:14 | state | provenance | | +| react-use-state.js:10:14:10:24 | window.name | react-use-state.js:9:9:9:43 | state | provenance | | | react-use-state.js:15:9:15:43 | state | react-use-state.js:17:51:17:55 | state | provenance | | | react-use-state.js:15:10:15:14 | state | react-use-state.js:15:9:15:43 | state | provenance | | | react-use-state.js:16:20:16:30 | window.name | react-use-state.js:15:10:15:14 | state | provenance | | @@ -931,27 +871,18 @@ edges | sanitiser.js:45:29:45:35 | tainted | sanitiser.js:45:21:45:44 | '' + ... '' | provenance | | | sanitiser.js:48:19:48:25 | tainted | sanitiser.js:48:19:48:46 | tainted ... /g, '') | provenance | | | stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | provenance | | -| stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | provenance | Config | | stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | provenance | | -| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | provenance | Config | | stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:10:16:10:44 | localSt ... local') | provenance | | -| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:10:16:10:44 | localSt ... local') | provenance | Config | | stored-xss.js:10:9:10:44 | href | stored-xss.js:12:35:12:38 | href | provenance | | | stored-xss.js:10:16:10:44 | localSt ... local') | stored-xss.js:10:9:10:44 | href | provenance | | | stored-xss.js:12:35:12:38 | href | stored-xss.js:12:20:12:54 | "" | provenance | | | stored-xss.js:12:35:12:38 | href | stored-xss.js:12:20:12:54 | "" | provenance | Config | | string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | provenance | | -| string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | provenance | Config | | string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | provenance | | -| string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | provenance | Config | | string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | provenance | | -| string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | provenance | Config | | string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | provenance | | -| string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | provenance | Config | | string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | provenance | | -| string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | provenance | Config | | string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | provenance | | -| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | provenance | Config | | tainted-url-suffix-arguments.js:3:17:3:17 | y | tainted-url-suffix-arguments.js:6:22:6:22 | y | provenance | | | tainted-url-suffix-arguments.js:11:11:11:36 | url | tainted-url-suffix-arguments.js:12:17:12:19 | url | provenance | | | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | tainted-url-suffix-arguments.js:11:11:11:36 | url | provenance | | @@ -967,7 +898,6 @@ edges | translate.js:7:7:7:61 | searchParams | translate.js:9:27:9:38 | searchParams | provenance | | | translate.js:7:22:7:61 | new URL ... ing(1)) | translate.js:7:7:7:61 | searchParams | provenance | | | translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | provenance | | -| translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | provenance | Config | | translate.js:7:42:7:60 | target.substring(1) | translate.js:7:22:7:61 | new URL ... ing(1)) | provenance | | | translate.js:9:27:9:38 | searchParams | translate.js:9:27:9:50 | searchP ... 'term') | provenance | Config | | trusted-types-lib.js:1:28:1:28 | x | trusted-types-lib.js:2:12:2:12 | x | provenance | | @@ -1005,7 +935,6 @@ edges | tst.js:20:7:20:61 | searchParams | tst.js:21:18:21:29 | searchParams | provenance | | | tst.js:20:22:20:61 | new URL ... ing(1)) | tst.js:20:7:20:61 | searchParams | provenance | | | tst.js:20:42:20:47 | target | tst.js:20:42:20:60 | target.substring(1) | provenance | | -| tst.js:20:42:20:47 | target | tst.js:20:42:20:60 | target.substring(1) | provenance | Config | | tst.js:20:42:20:60 | target.substring(1) | tst.js:20:22:20:61 | new URL ... ing(1)) | provenance | | | tst.js:21:18:21:29 | searchParams | tst.js:21:18:21:41 | searchP ... 'name') | provenance | Config | | tst.js:24:14:24:19 | target | tst.js:26:18:26:23 | target | provenance | | @@ -1073,19 +1002,14 @@ edges | tst.js:197:9:197:42 | tainted | tst.js:255:23:255:29 | tainted | provenance | | | tst.js:197:19:197:42 | documen ... .search | tst.js:197:9:197:42 | tainted | provenance | | | tst.js:204:35:204:41 | tainted | tst.js:212:28:212:46 | this.state.tainted1 | provenance | | -| tst.js:204:35:204:41 | tainted | tst.js:212:28:212:46 | this.state.tainted1 | provenance | Config | | tst.js:206:46:206:52 | tainted | tst.js:213:28:213:46 | this.state.tainted2 | provenance | | -| tst.js:206:46:206:52 | tainted | tst.js:213:28:213:46 | this.state.tainted2 | provenance | Config | | tst.js:207:38:207:44 | tainted | tst.js:214:28:214:46 | this.state.tainted3 | provenance | | -| tst.js:207:38:207:44 | tainted | tst.js:214:28:214:46 | this.state.tainted3 | provenance | Config | | tst.js:208:35:208:41 | tainted | tst.js:218:32:218:49 | prevState.tainted4 | provenance | | -| tst.js:208:35:208:41 | tainted | tst.js:218:32:218:49 | prevState.tainted4 | provenance | Config | | tst.js:236:35:236:41 | tainted | tst.js:225:28:225:46 | this.props.tainted1 | provenance | | | tst.js:238:20:238:26 | tainted | tst.js:226:28:226:46 | this.props.tainted2 | provenance | | | tst.js:240:23:240:29 | tainted | tst.js:227:28:227:46 | this.props.tainted3 | provenance | | | tst.js:241:23:241:29 | tainted | tst.js:231:32:231:49 | prevProps.tainted4 | provenance | | | tst.js:247:39:247:55 | props.propTainted | tst.js:251:60:251:82 | this.st ... Tainted | provenance | | -| tst.js:247:39:247:55 | props.propTainted | tst.js:251:60:251:82 | this.st ... Tainted | provenance | Config | | tst.js:255:23:255:29 | tainted | tst.js:247:39:247:55 | props.propTainted | provenance | | | tst.js:285:9:285:29 | tainted | tst.js:288:59:288:65 | tainted | provenance | | | tst.js:285:19:285:29 | window.name | tst.js:285:9:285:29 | tainted | provenance | | @@ -1121,17 +1045,13 @@ edges | tst.js:381:7:381:39 | target [taint8] | tst.js:409:18:409:23 | target [taint8] | provenance | | | tst.js:381:16:381:39 | documen ... .search | tst.js:381:7:381:39 | target | provenance | | | tst.js:386:18:386:23 | target | tst.js:386:18:386:29 | target.taint | provenance | | -| tst.js:386:18:386:23 | target | tst.js:386:18:386:29 | target.taint | provenance | Config | | tst.js:391:3:391:8 | [post update] target [taint3] | tst.js:381:7:381:39 | target [taint3] | provenance | | | tst.js:391:19:391:42 | documen ... .search | tst.js:391:3:391:8 | [post update] target [taint3] | provenance | | | tst.js:392:18:392:23 | target [taint3] | tst.js:392:18:392:30 | target.taint3 | provenance | | | tst.js:397:18:397:23 | target | tst.js:397:18:397:30 | target.taint5 | provenance | | -| tst.js:397:18:397:23 | target | tst.js:397:18:397:30 | target.taint5 | provenance | Config | | tst.js:406:18:406:23 | target | tst.js:406:18:406:30 | target.taint7 | provenance | | -| tst.js:406:18:406:23 | target | tst.js:406:18:406:30 | target.taint7 | provenance | Config | | tst.js:408:3:408:8 | [post update] target [taint8] | tst.js:381:7:381:39 | target [taint8] | provenance | | | tst.js:408:19:408:24 | target | tst.js:408:19:408:31 | target.taint8 | provenance | | -| tst.js:408:19:408:24 | target | tst.js:408:19:408:31 | target.taint8 | provenance | Config | | tst.js:408:19:408:24 | target [taint8] | tst.js:408:19:408:31 | target.taint8 | provenance | | | tst.js:408:19:408:31 | target.taint8 | tst.js:408:3:408:8 | [post update] target [taint8] | provenance | | | tst.js:409:18:409:23 | target [taint8] | tst.js:409:18:409:30 | target.taint8 | provenance | | @@ -1141,16 +1061,13 @@ edges | tst.js:416:17:416:46 | window. ... bstr(1) | tst.js:416:7:416:46 | payload | provenance | | | tst.js:419:7:419:55 | match | tst.js:421:20:421:24 | match | provenance | | | tst.js:419:15:419:34 | window.location.hash | tst.js:419:15:419:55 | window. ... (\\w+)/) | provenance | | -| tst.js:419:15:419:34 | window.location.hash | tst.js:419:15:419:55 | window. ... (\\w+)/) | provenance | Config | | tst.js:419:15:419:55 | window. ... (\\w+)/) | tst.js:419:7:419:55 | match | provenance | | | tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | provenance | | -| tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | provenance | Config | | tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') [1] | provenance | Config | | tst.js:424:18:424:48 | window. ... it('#') [1] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | | tst.js:428:7:428:39 | target | tst.js:430:18:430:23 | target | provenance | | | tst.js:428:16:428:39 | documen ... .search | tst.js:428:7:428:39 | target | provenance | | | tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | provenance | | -| tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | provenance | Config | | tst.js:436:6:436:38 | source | tst.js:440:28:440:33 | source | provenance | | | tst.js:436:6:436:38 | source | tst.js:441:33:441:38 | source | provenance | | | tst.js:436:6:436:38 | source | tst.js:442:34:442:39 | source | provenance | | @@ -1162,7 +1079,6 @@ edges | tst.js:453:7:453:39 | source | tst.js:456:36:456:41 | source | provenance | | | tst.js:453:16:453:39 | documen ... .search | tst.js:453:7:453:39 | source | provenance | | | tst.js:456:36:456:41 | source | tst.js:456:18:456:42 | ansiToH ... source) | provenance | | -| tst.js:456:36:456:41 | source | tst.js:456:18:456:42 | ansiToH ... source) | provenance | Config | | tst.js:460:6:460:38 | source | tst.js:463:21:463:26 | source | provenance | | | tst.js:460:6:460:38 | source | tst.js:465:19:465:24 | source | provenance | | | tst.js:460:6:460:38 | source | tst.js:467:20:467:25 | source | provenance | | @@ -1177,11 +1093,9 @@ edges | tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | provenance | Config | | tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | provenance | Config | | tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | provenance | | -| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | provenance | Config | | typeahead.js:20:13:20:45 | target | typeahead.js:21:12:21:17 | target | provenance | | | typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target | provenance | | | typeahead.js:21:12:21:17 | target | typeahead.js:24:30:24:32 | val | provenance | | -| typeahead.js:21:12:21:17 | target | typeahead.js:24:30:24:32 | val | provenance | Config | | typeahead.js:24:30:24:32 | val | typeahead.js:25:18:25:20 | val | provenance | | | various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:4:14:4:20 | tainted | provenance | | | various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:5:12:5:18 | tainted | provenance | | @@ -1210,9 +1124,7 @@ edges | various-concat-obfuscations.js:12:19:12:25 | tainted | various-concat-obfuscations.js:12:4:12:34 | ["
    "] | provenance | Config | | various-concat-obfuscations.js:14:24:14:28 | attrs | various-concat-obfuscations.js:15:28:15:32 | attrs | provenance | | | various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | various-concat-obfuscations.js:15:10:15:83 | '
    ' | provenance | Config | -| various-concat-obfuscations.js:15:28:15:32 | attrs | various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | provenance | | -| various-concat-obfuscations.js:15:28:15:32 | attrs | various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | provenance | Config | -| various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | provenance | | +| various-concat-obfuscations.js:15:28:15:32 | attrs | various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | provenance | | | various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:32:18:36 | attrs | provenance | | | various-concat-obfuscations.js:18:10:18:59 | '
    ') [ArrayElement] | provenance | | | various-concat-obfuscations.js:18:10:18:88 | '
    ') | provenance | | | various-concat-obfuscations.js:18:10:18:88 | '
    ') [ArrayElement] | provenance | | -| various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | provenance | | -| various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | provenance | Config | -| various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | provenance | | +| various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | provenance | | | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | various-concat-obfuscations.js:18:10:18:59 | '
    ' | semmle.label | '
    ' | | various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | semmle.label | (attrs. ... 'left') | | various-concat-obfuscations.js:15:28:15:32 | attrs | semmle.label | attrs | -| various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | semmle.label | attrs.defaultattr | | various-concat-obfuscations.js:17:24:17:28 | attrs | semmle.label | attrs | | various-concat-obfuscations.js:18:10:18:59 | '
    ') | semmle.label | '
    ') | | various-concat-obfuscations.js:18:10:18:105 | '
    ') [ArrayElement] | semmle.label | '
    ') [ArrayElement] | | various-concat-obfuscations.js:18:32:18:36 | attrs | semmle.label | attrs | -| various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | semmle.label | attrs.defaultattr | | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | semmle.label | attrs.d ... 'left' | | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) | semmle.label | indirec ... .attrs) | | various-concat-obfuscations.js:20:17:20:40 | documen ... .search | semmle.label | documen ... .search | @@ -656,15 +646,13 @@ nodes | xmlRequest.js:21:11:21:38 | json | semmle.label | json | | xmlRequest.js:21:18:21:38 | JSON.pa ... p.body) | semmle.label | JSON.pa ... p.body) | | xmlRequest.js:21:29:21:32 | resp | semmle.label | resp | -| xmlRequest.js:21:29:21:37 | resp.body | semmle.label | resp.body | | xmlRequest.js:22:24:22:27 | json | semmle.label | json | | xmlRequest.js:22:24:22:35 | json.message | semmle.label | json.message | edges | addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | provenance | | | addEventListener.js:2:20:2:24 | event | addEventListener.js:2:20:2:29 | event.data | provenance | | | addEventListener.js:5:43:5:48 | data | addEventListener.js:6:20:6:23 | data | provenance | | -| addEventListener.js:5:43:5:48 | {data} | addEventListener.js:5:44:5:47 | data | provenance | | -| addEventListener.js:5:44:5:47 | data | addEventListener.js:5:43:5:48 | data | provenance | | +| addEventListener.js:5:43:5:48 | {data} | addEventListener.js:5:43:5:48 | data | provenance | | | addEventListener.js:10:21:10:25 | event | addEventListener.js:12:24:12:28 | event | provenance | | | addEventListener.js:12:24:12:28 | event | addEventListener.js:12:24:12:33 | event.data | provenance | | | angular2-client.ts:24:44:24:69 | this.ro ... .params | angular2-client.ts:24:44:24:73 | this.ro ... ams.foo | provenance | | @@ -710,31 +698,18 @@ edges | dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | provenance | | | dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) | provenance | Config | | dates.js:9:36:9:68 | window. ... ring(1) | dates.js:9:17:9:69 | decodeU ... ing(1)) | provenance | | -| dates.js:9:36:9:68 | window. ... ring(1) | dates.js:9:17:9:69 | decodeU ... ing(1)) | provenance | Config | | dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | provenance | | -| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` | provenance | Config | | dates.js:11:63:11:67 | taint | dates.js:11:42:11:68 | dateFns ... taint) | provenance | | -| dates.js:11:63:11:67 | taint | dates.js:11:42:11:68 | dateFns ... taint) | provenance | Config | | dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | provenance | | -| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` | provenance | Config | | dates.js:12:66:12:70 | taint | dates.js:12:42:12:71 | dateFns ... taint) | provenance | | -| dates.js:12:66:12:70 | taint | dates.js:12:42:12:71 | dateFns ... taint) | provenance | Config | | dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | provenance | | -| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` | provenance | Config | | dates.js:13:59:13:63 | taint | dates.js:13:42:13:70 | dateFns ... )(time) | provenance | | -| dates.js:13:59:13:63 | taint | dates.js:13:42:13:70 | dateFns ... )(time) | provenance | Config | | dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | provenance | | -| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` | provenance | Config | | dates.js:16:62:16:66 | taint | dates.js:16:42:16:67 | moment( ... (taint) | provenance | | -| dates.js:16:62:16:66 | taint | dates.js:16:42:16:67 | moment( ... (taint) | provenance | Config | | dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | provenance | | -| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` | provenance | Config | | dates.js:18:59:18:63 | taint | dates.js:18:42:18:64 | datefor ... taint) | provenance | | -| dates.js:18:59:18:63 | taint | dates.js:18:42:18:64 | datefor ... taint) | provenance | Config | | dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | provenance | | -| dates.js:21:42:21:66 | dayjs(t ... (taint) | dates.js:21:31:21:68 | `Time i ... aint)}` | provenance | Config | | dates.js:21:61:21:65 | taint | dates.js:21:42:21:66 | dayjs(t ... (taint) | provenance | | -| dates.js:21:61:21:65 | taint | dates.js:21:42:21:66 | dayjs(t ... (taint) | provenance | Config | | dates.js:30:9:30:69 | taint | dates.js:37:77:37:81 | taint | provenance | | | dates.js:30:9:30:69 | taint | dates.js:38:77:38:81 | taint | provenance | | | dates.js:30:9:30:69 | taint | dates.js:39:79:39:83 | taint | provenance | | @@ -743,23 +718,14 @@ edges | dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | provenance | | | dates.js:30:36:30:55 | window.location.hash | dates.js:30:36:30:68 | window. ... ring(1) | provenance | Config | | dates.js:30:36:30:68 | window. ... ring(1) | dates.js:30:17:30:69 | decodeU ... ing(1)) | provenance | | -| dates.js:30:36:30:68 | window. ... ring(1) | dates.js:30:17:30:69 | decodeU ... ing(1)) | provenance | Config | | dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | provenance | | -| dates.js:37:42:37:82 | dateFns ... taint) | dates.js:37:31:37:84 | `Time i ... aint)}` | provenance | Config | | dates.js:37:77:37:81 | taint | dates.js:37:42:37:82 | dateFns ... taint) | provenance | | -| dates.js:37:77:37:81 | taint | dates.js:37:42:37:82 | dateFns ... taint) | provenance | Config | | dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | provenance | | -| dates.js:38:42:38:82 | luxon.f ... taint) | dates.js:38:31:38:84 | `Time i ... aint)}` | provenance | Config | | dates.js:38:77:38:81 | taint | dates.js:38:42:38:82 | luxon.f ... taint) | provenance | | -| dates.js:38:77:38:81 | taint | dates.js:38:42:38:82 | luxon.f ... taint) | provenance | Config | | dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | provenance | | -| dates.js:39:42:39:84 | moment. ... taint) | dates.js:39:31:39:86 | `Time i ... aint)}` | provenance | Config | | dates.js:39:79:39:83 | taint | dates.js:39:42:39:84 | moment. ... taint) | provenance | | -| dates.js:39:79:39:83 | taint | dates.js:39:42:39:84 | moment. ... taint) | provenance | Config | | dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | provenance | | -| dates.js:40:42:40:82 | dayjs.f ... taint) | dates.js:40:31:40:84 | `Time i ... aint)}` | provenance | Config | | dates.js:40:77:40:81 | taint | dates.js:40:42:40:82 | dayjs.f ... taint) | provenance | | -| dates.js:40:77:40:81 | taint | dates.js:40:42:40:82 | dayjs.f ... taint) | provenance | Config | | dates.js:46:9:46:69 | taint | dates.js:48:83:48:87 | taint | provenance | | | dates.js:46:9:46:69 | taint | dates.js:49:82:49:86 | taint | provenance | | | dates.js:46:9:46:69 | taint | dates.js:50:97:50:101 | taint | provenance | | @@ -767,19 +733,12 @@ edges | dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | provenance | | | dates.js:46:36:46:55 | window.location.hash | dates.js:46:36:46:68 | window. ... ring(1) | provenance | Config | | dates.js:46:36:46:68 | window. ... ring(1) | dates.js:46:17:46:69 | decodeU ... ing(1)) | provenance | | -| dates.js:46:36:46:68 | window. ... ring(1) | dates.js:46:17:46:69 | decodeU ... ing(1)) | provenance | Config | | dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | provenance | | -| dates.js:48:42:48:88 | DateTim ... (taint) | dates.js:48:31:48:90 | `Time i ... aint)}` | provenance | Config | | dates.js:48:83:48:87 | taint | dates.js:48:42:48:88 | DateTim ... (taint) | provenance | | -| dates.js:48:83:48:87 | taint | dates.js:48:42:48:88 | DateTim ... (taint) | provenance | Config | | dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | provenance | | -| dates.js:49:42:49:87 | new Dat ... (taint) | dates.js:49:31:49:89 | `Time i ... aint)}` | provenance | Config | | dates.js:49:82:49:86 | taint | dates.js:49:42:49:87 | new Dat ... (taint) | provenance | | -| dates.js:49:82:49:86 | taint | dates.js:49:42:49:87 | new Dat ... (taint) | provenance | Config | | dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | provenance | | -| dates.js:50:42:50:102 | DateTim ... (taint) | dates.js:50:31:50:104 | `Time i ... aint)}` | provenance | Config | | dates.js:50:97:50:101 | taint | dates.js:50:42:50:102 | DateTim ... (taint) | provenance | | -| dates.js:50:97:50:101 | taint | dates.js:50:42:50:102 | DateTim ... (taint) | provenance | Config | | dates.js:54:9:54:69 | taint | dates.js:57:94:57:98 | taint | provenance | | | dates.js:54:9:54:69 | taint | dates.js:59:80:59:84 | taint | provenance | | | dates.js:54:9:54:69 | taint | dates.js:61:81:61:85 | taint | provenance | | @@ -787,19 +746,12 @@ edges | dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | provenance | | | dates.js:54:36:54:55 | window.location.hash | dates.js:54:36:54:68 | window. ... ring(1) | provenance | Config | | dates.js:54:36:54:68 | window. ... ring(1) | dates.js:54:17:54:69 | decodeU ... ing(1)) | provenance | | -| dates.js:54:36:54:68 | window. ... ring(1) | dates.js:54:17:54:69 | decodeU ... ing(1)) | provenance | Config | | dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | provenance | | -| dates.js:57:42:57:99 | moment. ... (taint) | dates.js:57:31:57:101 | `Time i ... aint)}` | provenance | Config | | dates.js:57:94:57:98 | taint | dates.js:57:42:57:99 | moment. ... (taint) | provenance | | -| dates.js:57:94:57:98 | taint | dates.js:57:42:57:99 | moment. ... (taint) | provenance | Config | | dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | provenance | | -| dates.js:59:42:59:85 | luxon.e ... (taint) | dates.js:59:31:59:87 | `Time i ... aint)}` | provenance | Config | | dates.js:59:80:59:84 | taint | dates.js:59:42:59:85 | luxon.e ... (taint) | provenance | | -| dates.js:59:80:59:84 | taint | dates.js:59:42:59:85 | luxon.e ... (taint) | provenance | Config | | dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | provenance | | -| dates.js:61:42:61:86 | dayjs.s ... (taint) | dates.js:61:31:61:88 | `Time i ... aint)}` | provenance | Config | | dates.js:61:81:61:85 | taint | dates.js:61:42:61:86 | dayjs.s ... (taint) | provenance | | -| dates.js:61:81:61:85 | taint | dates.js:61:42:61:86 | dayjs.s ... (taint) | provenance | Config | | dragAndDrop.ts:8:11:8:50 | html | dragAndDrop.ts:15:25:15:28 | html | provenance | | | dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | dragAndDrop.ts:8:11:8:50 | html | provenance | | | dragAndDrop.ts:43:15:43:54 | html | dragAndDrop.ts:50:29:50:32 | html | provenance | | @@ -815,18 +767,12 @@ edges | jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | provenance | | | jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "
    " | provenance | Config | | jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | provenance | | -| jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | provenance | Config | | jquery.js:10:13:10:20 | location | jquery.js:10:13:10:31 | location.toString() | provenance | | -| jquery.js:10:13:10:20 | location | jquery.js:10:13:10:31 | location.toString() | provenance | Config | | jquery.js:10:13:10:31 | location.toString() | jquery.js:10:5:10:40 | "" + ... "" | provenance | Config | | jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | provenance | | -| jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | provenance | Config | | jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | provenance | | -| jquery.js:15:38:15:59 | window. ... .search | jquery.js:15:19:15:60 | decodeU ... search) | provenance | Config | | jquery.js:16:38:16:52 | window.location | jquery.js:16:38:16:63 | window. ... tring() | provenance | | -| jquery.js:16:38:16:52 | window.location | jquery.js:16:38:16:63 | window. ... tring() | provenance | Config | | jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) | provenance | | -| jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) | provenance | Config | | jquery.js:18:7:18:33 | hash | jquery.js:21:5:21:8 | hash | provenance | | | jquery.js:18:7:18:33 | hash | jquery.js:22:5:22:8 | hash | provenance | | | jquery.js:18:7:18:33 | hash | jquery.js:23:5:23:8 | hash | provenance | | @@ -846,10 +792,8 @@ edges | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:19:56:19:61 | locale | provenance | | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:31:55:31:60 | locale | provenance | | | json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | provenance | | -| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | provenance | | -| json-stringify.jsx:11:51:11:56 | locale | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | provenance | | -| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | provenance | | -| json-stringify.jsx:19:56:19:61 | locale | json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | provenance | | +| json-stringify.jsx:11:51:11:56 | locale | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | provenance | | +| json-stringify.jsx:19:56:19:61 | locale | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | provenance | | | json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | provenance | | | jwt-server.js:7:9:7:35 | taint | jwt-server.js:9:16:9:20 | taint | provenance | | | jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint | provenance | | @@ -897,19 +841,16 @@ edges | optionalSanitizer.js:45:51:45:56 | target | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | provenance | | | pages/[id].jsx:3:30:3:35 | params [id] | pages/[id].jsx:13:44:13:49 | params [id] | provenance | | | pages/[id].jsx:3:30:3:35 | params [q] | pages/[id].jsx:16:44:16:49 | params [q] | provenance | | -| pages/[id].jsx:5:9:5:14 | { id } | pages/[id].jsx:5:11:5:12 | id | provenance | | +| pages/[id].jsx:5:9:5:14 | { id } | pages/[id].jsx:5:9:5:29 | id | provenance | | | pages/[id].jsx:5:9:5:29 | id | pages/[id].jsx:10:44:10:45 | id | provenance | | -| pages/[id].jsx:5:11:5:12 | id | pages/[id].jsx:5:9:5:29 | id | provenance | | | pages/[id].jsx:5:18:5:29 | router.query | pages/[id].jsx:5:9:5:14 | { id } | provenance | | | pages/[id].jsx:13:44:13:49 | params [id] | pages/[id].jsx:13:44:13:52 | params.id | provenance | | | pages/[id].jsx:16:44:16:49 | params [q] | pages/[id].jsx:16:44:16:51 | params.q | provenance | | | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | pages/[id].jsx:3:30:3:35 | params [id] | provenance | | | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | pages/[id].jsx:3:30:3:35 | params [q] | provenance | | -| pages/[id].jsx:25:11:25:24 | context.params | pages/[id].jsx:25:11:25:27 | context.params.id | provenance | | -| pages/[id].jsx:25:11:25:27 | context.params.id | pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | provenance | | +| pages/[id].jsx:25:11:25:24 | context.params | pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | provenance | | | pages/[id].jsx:25:11:25:33 | context ... d \|\| "" | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [id] | provenance | | -| pages/[id].jsx:26:10:26:22 | context.query | pages/[id].jsx:26:10:26:30 | context ... .foobar | provenance | | -| pages/[id].jsx:26:10:26:30 | context ... .foobar | pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | provenance | | +| pages/[id].jsx:26:10:26:22 | context.query | pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | provenance | | | pages/[id].jsx:26:10:26:36 | context ... r \|\| "" | pages/[id].jsx:24:12:27:5 | {\\n ... ,\\n } [q] | provenance | | | react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted | provenance | | | react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted | provenance | | @@ -925,11 +866,9 @@ edges | react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:31:23:36 | [post update] router [ArrayElement] | provenance | | | react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | provenance | | | react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | provenance | | -| react-use-state.js:4:10:4:14 | state | react-use-state.js:4:9:4:49 | state | provenance | | -| react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:10:4:14 | state | provenance | | +| react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:9:4:49 | state | provenance | | | react-use-state.js:9:9:9:43 | state | react-use-state.js:11:51:11:55 | state | provenance | | -| react-use-state.js:9:10:9:14 | state | react-use-state.js:9:9:9:43 | state | provenance | | -| react-use-state.js:10:14:10:24 | window.name | react-use-state.js:9:10:9:14 | state | provenance | | +| react-use-state.js:10:14:10:24 | window.name | react-use-state.js:9:9:9:43 | state | provenance | | | react-use-state.js:15:9:15:43 | state | react-use-state.js:17:51:17:55 | state | provenance | | | react-use-state.js:15:10:15:14 | state | react-use-state.js:15:9:15:43 | state | provenance | | | react-use-state.js:16:20:16:30 | window.name | react-use-state.js:15:10:15:14 | state | provenance | | @@ -956,27 +895,18 @@ edges | sanitiser.js:45:29:45:35 | tainted | sanitiser.js:45:21:45:44 | '' + ... '' | provenance | | | sanitiser.js:48:19:48:25 | tainted | sanitiser.js:48:19:48:46 | tainted ... /g, '') | provenance | | | stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | provenance | | -| stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | provenance | Config | | stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | provenance | | -| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | provenance | Config | | stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:10:16:10:44 | localSt ... local') | provenance | | -| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:10:16:10:44 | localSt ... local') | provenance | Config | | stored-xss.js:10:9:10:44 | href | stored-xss.js:12:35:12:38 | href | provenance | | | stored-xss.js:10:16:10:44 | localSt ... local') | stored-xss.js:10:9:10:44 | href | provenance | | | stored-xss.js:12:35:12:38 | href | stored-xss.js:12:20:12:54 | "" | provenance | | | stored-xss.js:12:35:12:38 | href | stored-xss.js:12:20:12:54 | "" | provenance | Config | | string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | provenance | | -| string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | provenance | Config | | string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | provenance | | -| string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | provenance | Config | | string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | provenance | | -| string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | provenance | Config | | string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | provenance | | -| string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | provenance | Config | | string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | provenance | | -| string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | provenance | Config | | string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | provenance | | -| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | provenance | Config | | tainted-url-suffix-arguments.js:3:17:3:17 | y | tainted-url-suffix-arguments.js:6:22:6:22 | y | provenance | | | tainted-url-suffix-arguments.js:11:11:11:36 | url | tainted-url-suffix-arguments.js:12:17:12:19 | url | provenance | | | tainted-url-suffix-arguments.js:11:17:11:36 | window.location.href | tainted-url-suffix-arguments.js:11:11:11:36 | url | provenance | | @@ -992,7 +922,6 @@ edges | translate.js:7:7:7:61 | searchParams | translate.js:9:27:9:38 | searchParams | provenance | | | translate.js:7:22:7:61 | new URL ... ing(1)) | translate.js:7:7:7:61 | searchParams | provenance | | | translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | provenance | | -| translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | provenance | Config | | translate.js:7:42:7:60 | target.substring(1) | translate.js:7:22:7:61 | new URL ... ing(1)) | provenance | | | translate.js:9:27:9:38 | searchParams | translate.js:9:27:9:50 | searchP ... 'term') | provenance | Config | | trusted-types-lib.js:1:28:1:28 | x | trusted-types-lib.js:2:12:2:12 | x | provenance | | @@ -1030,7 +959,6 @@ edges | tst.js:20:7:20:61 | searchParams | tst.js:21:18:21:29 | searchParams | provenance | | | tst.js:20:22:20:61 | new URL ... ing(1)) | tst.js:20:7:20:61 | searchParams | provenance | | | tst.js:20:42:20:47 | target | tst.js:20:42:20:60 | target.substring(1) | provenance | | -| tst.js:20:42:20:47 | target | tst.js:20:42:20:60 | target.substring(1) | provenance | Config | | tst.js:20:42:20:60 | target.substring(1) | tst.js:20:22:20:61 | new URL ... ing(1)) | provenance | | | tst.js:21:18:21:29 | searchParams | tst.js:21:18:21:41 | searchP ... 'name') | provenance | Config | | tst.js:24:14:24:19 | target | tst.js:26:18:26:23 | target | provenance | | @@ -1098,19 +1026,14 @@ edges | tst.js:197:9:197:42 | tainted | tst.js:255:23:255:29 | tainted | provenance | | | tst.js:197:19:197:42 | documen ... .search | tst.js:197:9:197:42 | tainted | provenance | | | tst.js:204:35:204:41 | tainted | tst.js:212:28:212:46 | this.state.tainted1 | provenance | | -| tst.js:204:35:204:41 | tainted | tst.js:212:28:212:46 | this.state.tainted1 | provenance | Config | | tst.js:206:46:206:52 | tainted | tst.js:213:28:213:46 | this.state.tainted2 | provenance | | -| tst.js:206:46:206:52 | tainted | tst.js:213:28:213:46 | this.state.tainted2 | provenance | Config | | tst.js:207:38:207:44 | tainted | tst.js:214:28:214:46 | this.state.tainted3 | provenance | | -| tst.js:207:38:207:44 | tainted | tst.js:214:28:214:46 | this.state.tainted3 | provenance | Config | | tst.js:208:35:208:41 | tainted | tst.js:218:32:218:49 | prevState.tainted4 | provenance | | -| tst.js:208:35:208:41 | tainted | tst.js:218:32:218:49 | prevState.tainted4 | provenance | Config | | tst.js:236:35:236:41 | tainted | tst.js:225:28:225:46 | this.props.tainted1 | provenance | | | tst.js:238:20:238:26 | tainted | tst.js:226:28:226:46 | this.props.tainted2 | provenance | | | tst.js:240:23:240:29 | tainted | tst.js:227:28:227:46 | this.props.tainted3 | provenance | | | tst.js:241:23:241:29 | tainted | tst.js:231:32:231:49 | prevProps.tainted4 | provenance | | | tst.js:247:39:247:55 | props.propTainted | tst.js:251:60:251:82 | this.st ... Tainted | provenance | | -| tst.js:247:39:247:55 | props.propTainted | tst.js:251:60:251:82 | this.st ... Tainted | provenance | Config | | tst.js:255:23:255:29 | tainted | tst.js:247:39:247:55 | props.propTainted | provenance | | | tst.js:285:9:285:29 | tainted | tst.js:288:59:288:65 | tainted | provenance | | | tst.js:285:19:285:29 | window.name | tst.js:285:9:285:29 | tainted | provenance | | @@ -1146,17 +1069,13 @@ edges | tst.js:381:7:381:39 | target [taint8] | tst.js:409:18:409:23 | target [taint8] | provenance | | | tst.js:381:16:381:39 | documen ... .search | tst.js:381:7:381:39 | target | provenance | | | tst.js:386:18:386:23 | target | tst.js:386:18:386:29 | target.taint | provenance | | -| tst.js:386:18:386:23 | target | tst.js:386:18:386:29 | target.taint | provenance | Config | | tst.js:391:3:391:8 | [post update] target [taint3] | tst.js:381:7:381:39 | target [taint3] | provenance | | | tst.js:391:19:391:42 | documen ... .search | tst.js:391:3:391:8 | [post update] target [taint3] | provenance | | | tst.js:392:18:392:23 | target [taint3] | tst.js:392:18:392:30 | target.taint3 | provenance | | | tst.js:397:18:397:23 | target | tst.js:397:18:397:30 | target.taint5 | provenance | | -| tst.js:397:18:397:23 | target | tst.js:397:18:397:30 | target.taint5 | provenance | Config | | tst.js:406:18:406:23 | target | tst.js:406:18:406:30 | target.taint7 | provenance | | -| tst.js:406:18:406:23 | target | tst.js:406:18:406:30 | target.taint7 | provenance | Config | | tst.js:408:3:408:8 | [post update] target [taint8] | tst.js:381:7:381:39 | target [taint8] | provenance | | | tst.js:408:19:408:24 | target | tst.js:408:19:408:31 | target.taint8 | provenance | | -| tst.js:408:19:408:24 | target | tst.js:408:19:408:31 | target.taint8 | provenance | Config | | tst.js:408:19:408:24 | target [taint8] | tst.js:408:19:408:31 | target.taint8 | provenance | | | tst.js:408:19:408:31 | target.taint8 | tst.js:408:3:408:8 | [post update] target [taint8] | provenance | | | tst.js:409:18:409:23 | target [taint8] | tst.js:409:18:409:30 | target.taint8 | provenance | | @@ -1166,16 +1085,13 @@ edges | tst.js:416:17:416:46 | window. ... bstr(1) | tst.js:416:7:416:46 | payload | provenance | | | tst.js:419:7:419:55 | match | tst.js:421:20:421:24 | match | provenance | | | tst.js:419:15:419:34 | window.location.hash | tst.js:419:15:419:55 | window. ... (\\w+)/) | provenance | | -| tst.js:419:15:419:34 | window.location.hash | tst.js:419:15:419:55 | window. ... (\\w+)/) | provenance | Config | | tst.js:419:15:419:55 | window. ... (\\w+)/) | tst.js:419:7:419:55 | match | provenance | | | tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | provenance | | -| tst.js:421:20:421:24 | match | tst.js:421:20:421:27 | match[1] | provenance | Config | | tst.js:424:18:424:37 | window.location.hash | tst.js:424:18:424:48 | window. ... it('#') [1] | provenance | Config | | tst.js:424:18:424:48 | window. ... it('#') [1] | tst.js:424:18:424:51 | window. ... '#')[1] | provenance | | | tst.js:428:7:428:39 | target | tst.js:430:18:430:23 | target | provenance | | | tst.js:428:16:428:39 | documen ... .search | tst.js:428:7:428:39 | target | provenance | | | tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | provenance | | -| tst.js:430:18:430:23 | target | tst.js:430:18:430:89 | target. ... data>') | provenance | Config | | tst.js:436:6:436:38 | source | tst.js:440:28:440:33 | source | provenance | | | tst.js:436:6:436:38 | source | tst.js:441:33:441:38 | source | provenance | | | tst.js:436:6:436:38 | source | tst.js:442:34:442:39 | source | provenance | | @@ -1187,7 +1103,6 @@ edges | tst.js:453:7:453:39 | source | tst.js:456:36:456:41 | source | provenance | | | tst.js:453:16:453:39 | documen ... .search | tst.js:453:7:453:39 | source | provenance | | | tst.js:456:36:456:41 | source | tst.js:456:18:456:42 | ansiToH ... source) | provenance | | -| tst.js:456:36:456:41 | source | tst.js:456:18:456:42 | ansiToH ... source) | provenance | Config | | tst.js:460:6:460:38 | source | tst.js:463:21:463:26 | source | provenance | | | tst.js:460:6:460:38 | source | tst.js:465:19:465:24 | source | provenance | | | tst.js:460:6:460:38 | source | tst.js:467:20:467:25 | source | provenance | | @@ -1202,12 +1117,10 @@ edges | tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | provenance | Config | | tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | provenance | Config | | tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | provenance | | -| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | provenance | Config | | typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | provenance | | | typeahead.js:20:13:20:45 | target | typeahead.js:21:12:21:17 | target | provenance | | | typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target | provenance | | | typeahead.js:21:12:21:17 | target | typeahead.js:24:30:24:32 | val | provenance | | -| typeahead.js:21:12:21:17 | target | typeahead.js:24:30:24:32 | val | provenance | Config | | typeahead.js:24:30:24:32 | val | typeahead.js:25:18:25:20 | val | provenance | | | various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:4:14:4:20 | tainted | provenance | | | various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:5:12:5:18 | tainted | provenance | | @@ -1236,9 +1149,7 @@ edges | various-concat-obfuscations.js:12:19:12:25 | tainted | various-concat-obfuscations.js:12:4:12:34 | ["
    "] | provenance | Config | | various-concat-obfuscations.js:14:24:14:28 | attrs | various-concat-obfuscations.js:15:28:15:32 | attrs | provenance | | | various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | various-concat-obfuscations.js:15:10:15:83 | '
    ' | provenance | Config | -| various-concat-obfuscations.js:15:28:15:32 | attrs | various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | provenance | | -| various-concat-obfuscations.js:15:28:15:32 | attrs | various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | provenance | Config | -| various-concat-obfuscations.js:15:28:15:44 | attrs.defaultattr | various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | provenance | | +| various-concat-obfuscations.js:15:28:15:32 | attrs | various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | provenance | | | various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:32:18:36 | attrs | provenance | | | various-concat-obfuscations.js:18:10:18:59 | '
    ') [ArrayElement] | provenance | | | various-concat-obfuscations.js:18:10:18:88 | '
    ') | provenance | | | various-concat-obfuscations.js:18:10:18:88 | '
    ') [ArrayElement] | provenance | | -| various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | provenance | | -| various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | provenance | Config | -| various-concat-obfuscations.js:18:32:18:48 | attrs.defaultattr | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | provenance | | +| various-concat-obfuscations.js:18:32:18:36 | attrs | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | provenance | | | various-concat-obfuscations.js:18:32:18:58 | attrs.d ... 'left' | various-concat-obfuscations.js:18:10:18:59 | '
    Date: Tue, 17 Sep 2024 15:59:04 +0200 Subject: [PATCH 292/514] JS: Clarify a comment --- .../lib/semmle/javascript/internal/flow_summaries/Arrays.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll index e242ed35a67..9381ca98dd7 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll @@ -487,7 +487,8 @@ class Shift extends SummarizedCallable { input = "Argument[this].ArrayElement[0]" and output = "ReturnValue" or - // ArrayElement[0] is not automatically converted to a taint step, so add it manually + // ArrayElement[0] in the above summary is not automatically converted to a taint step, so manully add + // one from the array to the return value. preservesValue = false and input = "Argument[this]" and output = "ReturnValue" From 341bacfe55d4792c8f4d7beac00cf9c1b19a00b1 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 1 Oct 2024 12:14:03 +0200 Subject: [PATCH 293/514] JS: Fix bug causing re-evaluation of cached barriers --- .../javascript/dataflow/Configuration.qll | 17 ++++++++-- .../javascript/dataflow/TaintTracking.qll | 34 ++++++++++++++++++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index 981155a5fee..3d62ca33a66 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -287,6 +287,9 @@ private predicate isBarrierGuardInternal(Configuration cfg, BarrierGuardNodeInte guard.(AdditionalBarrierGuardNode).appliesTo(cfg) or guard.(DerivedBarrierGuardNode).appliesTo(cfg) + or + cfg instanceof TaintTracking::Configuration and + guard.(TaintTracking::AdditionalSanitizerGuardNode).appliesTo(cfg) } /** @@ -390,6 +393,12 @@ abstract private class DerivedBarrierGuardNode extends BarrierGuardNodeInternal abstract predicate blocks(boolean outcome, Expr e, string label); } +/** + * Barrier guards derived from `AdditionalSanitizerGuard` + */ +private class BarrierGuardNodeFromAdditionalSanitizerGuard extends BarrierGuardNodeInternal instanceof TaintTracking::AdditionalSanitizerGuardNode +{ } + /** * Holds if data flow node `guard` acts as a barrier for data flow. * @@ -404,6 +413,10 @@ private predicate barrierGuardBlocksExpr( guard.(BarrierGuardNode).blocks(outcome, test, label) or guard.(DerivedBarrierGuardNode).blocks(outcome, test, label) + or + guard.(TaintTracking::AdditionalSanitizerGuardNode).sanitizes(outcome, test) and label = "taint" + or + guard.(TaintTracking::AdditionalSanitizerGuardNode).sanitizes(outcome, test, label) } /** @@ -534,7 +547,7 @@ private predicate isBarrierEdgeRaw(Configuration cfg, DataFlow::Node pred, DataF cfg.isBarrierEdge(pred, succ) or exists(BarrierGuardNodeInternal guard | - cfg.isBarrierGuard(guard) and + isBarrierGuardInternal(cfg, guard) and barrierGuardBlocksEdge(guard, pred, succ, "") ) } @@ -564,7 +577,7 @@ private predicate isLabeledBarrierEdgeRaw( cfg.isBarrierEdge(pred, succ, label) or exists(BarrierGuardNodeInternal guard | - cfg.isBarrierGuard(guard) and + isBarrierGuardInternal(cfg, guard) and barrierGuardBlocksEdge(guard, pred, succ, label) ) } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index ad42131ca4d..d95c27ad5d1 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -182,7 +182,39 @@ module TaintTracking { * for analysis-specific taint sanitizer guards. */ cached - abstract class AdditionalSanitizerGuardNode extends SanitizerGuardNode { + abstract class AdditionalSanitizerGuardNode extends DataFlow::Node { + // For backwards compatibility, this contains a copy of the SanitizerGuard interface, + // but is does not inherit from it as that would cause re-evaluation of cached barriers. + /** + * Holds if this node blocks expression `e`, provided it evaluates to `outcome`. + */ + cached + predicate blocks(boolean outcome, Expr e) { none() } + + /** + * Holds if this node sanitizes expression `e`, provided it evaluates + * to `outcome`. + */ + cached + abstract predicate sanitizes(boolean outcome, Expr e); + + /** + * Holds if this node blocks expression `e` from flow of type `label`, provided it evaluates to `outcome`. + */ + cached + predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel label) { + this.sanitizes(outcome, e) and label.isTaint() + or + this.sanitizes(outcome, e, label) + } + + /** + * Holds if this node sanitizes expression `e`, provided it evaluates + * to `outcome`. + */ + cached + predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { none() } + /** * Holds if this guard applies to the flow in `cfg`. */ From 6cbe04dcb7dcbc064ece5a17b49cc375816575f2 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 2 Oct 2024 14:36:53 +0200 Subject: [PATCH 294/514] JS: Consistently use the shared XSS barrier guards in the XSS queries Previously only reflected XSS used shared barrier guards. --- .../security/dataflow/DomBasedXssQuery.qll | 4 +++- .../security/dataflow/ExceptionXssQuery.qll | 4 +++- .../security/dataflow/StoredXssQuery.qll | 4 +++- .../dataflow/UnsafeHtmlConstructionQuery.qll | 2 ++ .../security/dataflow/XssThroughDomQuery.qll | 3 ++- .../DomBasedXss/ConsistencyDomBasedXss.expected | 3 --- .../Security/CWE-079/DomBasedXss/Xss.expected | 15 --------------- .../DomBasedXss/XssWithAdditionalSources.expected | 12 ------------ 8 files changed, 13 insertions(+), 34 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll index 8a53e4f0790..9c326c4f389 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll @@ -55,7 +55,9 @@ module DomBasedXssConfig implements DataFlow::StateConfigSig { label = prefixLabel() } - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + predicate isBarrier(DataFlow::Node node) { + node instanceof Sanitizer or node = Shared::BarrierGuard::getABarrierNode() + } predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel lbl) { // copy all taint barrier guards to the TaintedUrlSuffix/PrefixLabel label diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ExceptionXssQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ExceptionXssQuery.qll index 9a748c0c301..6908e50960d 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ExceptionXssQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ExceptionXssQuery.qll @@ -140,7 +140,9 @@ module ExceptionXssConfig implements DataFlow::StateConfigSig { sink instanceof XssShared::Sink and not label instanceof NotYetThrown } - predicate isBarrier(DataFlow::Node node) { node instanceof XssShared::Sanitizer } + predicate isBarrier(DataFlow::Node node) { + node instanceof XssShared::Sanitizer or node = XssShared::BarrierGuard::getABarrierNode() + } predicate isAdditionalFlowStep( DataFlow::Node pred, DataFlow::FlowLabel inlbl, DataFlow::Node succ, DataFlow::FlowLabel outlbl diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssQuery.qll index b40b610b71e..87a870abe35 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssQuery.qll @@ -15,7 +15,9 @@ module StoredXssConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + predicate isBarrier(DataFlow::Node node) { + node instanceof Sanitizer or node = Shared::BarrierGuard::getABarrierNode() + } } /** diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionQuery.qll index 3101836334f..dc3b7c96b99 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionQuery.qll @@ -34,6 +34,8 @@ module UnsafeHtmlConstructionConfig implements DataFlow::StateConfigSig { node instanceof UnsafeJQueryPlugin::Sanitizer or DomBasedXss::isOptionallySanitizedNode(node) + or + node = Shared::BarrierGuard::getABarrierNode() } predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel label) { diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll index c9d8112ba5d..22486167db3 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll @@ -22,7 +22,8 @@ module XssThroughDomConfig implements DataFlow::ConfigSig { node instanceof DomBasedXss::Sanitizer or DomBasedXss::isOptionallySanitizedNode(node) or node = DataFlow::MakeBarrierGuard::getABarrierNode() or - node = DataFlow::MakeBarrierGuard::getABarrierNode() + node = DataFlow::MakeBarrierGuard::getABarrierNode() or + node = Shared::BarrierGuard::getABarrierNode() } predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected index 3ea47160e92..e69de29bb2d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected @@ -1,3 +0,0 @@ -| query-tests/Security/CWE-079/DomBasedXss/sanitiser.js:25 | did not expect an alert, but found an alert for HtmlInjection | OK | ConsistencyConfig | -| query-tests/Security/CWE-079/DomBasedXss/sanitiser.js:28 | did not expect an alert, but found an alert for HtmlInjection | OK | ConsistencyConfig | -| query-tests/Security/CWE-079/DomBasedXss/sanitiser.js:35 | did not expect an alert, but found an alert for HtmlInjection | OK | ConsistencyConfig | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 922118ef84b..0b29d370c6c 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -284,16 +284,10 @@ nodes | sanitiser.js:16:17:16:27 | window.name | semmle.label | window.name | | sanitiser.js:23:21:23:44 | '' + ... '' | semmle.label | '' + ... '' | | sanitiser.js:23:29:23:35 | tainted | semmle.label | tainted | -| sanitiser.js:25:21:25:44 | '' + ... '' | semmle.label | '' + ... '' | -| sanitiser.js:25:29:25:35 | tainted | semmle.label | tainted | -| sanitiser.js:28:21:28:44 | '' + ... '' | semmle.label | '' + ... '' | -| sanitiser.js:28:29:28:35 | tainted | semmle.label | tainted | | sanitiser.js:30:21:30:44 | '' + ... '' | semmle.label | '' + ... '' | | sanitiser.js:30:29:30:35 | tainted | semmle.label | tainted | | sanitiser.js:33:21:33:44 | '' + ... '' | semmle.label | '' + ... '' | | sanitiser.js:33:29:33:35 | tainted | semmle.label | tainted | -| sanitiser.js:35:21:35:44 | '' + ... '' | semmle.label | '' + ... '' | -| sanitiser.js:35:29:35:35 | tainted | semmle.label | tainted | | sanitiser.js:38:21:38:44 | '' + ... '' | semmle.label | '' + ... '' | | sanitiser.js:38:29:38:35 | tainted | semmle.label | tainted | | sanitiser.js:45:21:45:44 | '' + ... '' | semmle.label | '' + ... '' | @@ -852,21 +846,15 @@ edges | react-use-state.js:22:14:22:17 | prev | react-use-state.js:23:35:23:38 | prev | provenance | | | react-use-state.js:25:20:25:30 | window.name | react-use-state.js:21:10:21:14 | state | provenance | | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:23:29:23:35 | tainted | provenance | | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:25:29:25:35 | tainted | provenance | | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:28:29:28:35 | tainted | provenance | | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:30:29:30:35 | tainted | provenance | | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:33:29:33:35 | tainted | provenance | | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:35:29:35:35 | tainted | provenance | | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:38:29:38:35 | tainted | provenance | | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:45:29:45:35 | tainted | provenance | | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:48:19:48:25 | tainted | provenance | | | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:16:7:16:27 | tainted | provenance | | | sanitiser.js:23:29:23:35 | tainted | sanitiser.js:23:21:23:44 | '' + ... '' | provenance | | -| sanitiser.js:25:29:25:35 | tainted | sanitiser.js:25:21:25:44 | '' + ... '' | provenance | | -| sanitiser.js:28:29:28:35 | tainted | sanitiser.js:28:21:28:44 | '' + ... '' | provenance | | | sanitiser.js:30:29:30:35 | tainted | sanitiser.js:30:21:30:44 | '' + ... '' | provenance | | | sanitiser.js:33:29:33:35 | tainted | sanitiser.js:33:21:33:44 | '' + ... '' | provenance | | -| sanitiser.js:35:29:35:35 | tainted | sanitiser.js:35:21:35:44 | '' + ... '' | provenance | | | sanitiser.js:38:29:38:35 | tainted | sanitiser.js:38:21:38:44 | '' + ... '' | provenance | | | sanitiser.js:45:29:45:35 | tainted | sanitiser.js:45:21:45:44 | '' + ... '' | provenance | | | sanitiser.js:48:19:48:25 | tainted | sanitiser.js:48:19:48:46 | tainted ... /g, '') | provenance | | @@ -1265,11 +1253,8 @@ subpaths | react-use-state.js:17:51:17:55 | state | react-use-state.js:16:20:16:30 | window.name | react-use-state.js:17:51:17:55 | state | Cross-site scripting vulnerability due to $@. | react-use-state.js:16:20:16:30 | window.name | user-provided value | | react-use-state.js:23:35:23:38 | prev | react-use-state.js:25:20:25:30 | window.name | react-use-state.js:23:35:23:38 | prev | Cross-site scripting vulnerability due to $@. | react-use-state.js:25:20:25:30 | window.name | user-provided value | | sanitiser.js:23:21:23:44 | '' + ... '' | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:23:21:23:44 | '' + ... '' | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | -| sanitiser.js:25:21:25:44 | '' + ... '' | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:25:21:25:44 | '' + ... '' | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | -| sanitiser.js:28:21:28:44 | '' + ... '' | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:28:21:28:44 | '' + ... '' | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | | sanitiser.js:30:21:30:44 | '' + ... '' | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:30:21:30:44 | '' + ... '' | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | | sanitiser.js:33:21:33:44 | '' + ... '' | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:33:21:33:44 | '' + ... '' | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | -| sanitiser.js:35:21:35:44 | '' + ... '' | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:35:21:35:44 | '' + ... '' | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | | sanitiser.js:38:21:38:44 | '' + ... '' | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:38:21:38:44 | '' + ... '' | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | | sanitiser.js:45:21:45:44 | '' + ... '' | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:45:21:45:44 | '' + ... '' | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | | sanitiser.js:48:19:48:46 | tainted ... /g, '') | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:48:19:48:46 | tainted ... /g, '') | Cross-site scripting vulnerability due to $@. | sanitiser.js:16:17:16:27 | window.name | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index b5be3dc820c..c857ff42b09 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -289,16 +289,10 @@ nodes | sanitiser.js:16:17:16:27 | window.name | semmle.label | window.name | | sanitiser.js:23:21:23:44 | '' + ... '' | semmle.label | '' + ... '' | | sanitiser.js:23:29:23:35 | tainted | semmle.label | tainted | -| sanitiser.js:25:21:25:44 | '' + ... '' | semmle.label | '' + ... '' | -| sanitiser.js:25:29:25:35 | tainted | semmle.label | tainted | -| sanitiser.js:28:21:28:44 | '' + ... '' | semmle.label | '' + ... '' | -| sanitiser.js:28:29:28:35 | tainted | semmle.label | tainted | | sanitiser.js:30:21:30:44 | '' + ... '' | semmle.label | '' + ... '' | | sanitiser.js:30:29:30:35 | tainted | semmle.label | tainted | | sanitiser.js:33:21:33:44 | '' + ... '' | semmle.label | '' + ... '' | | sanitiser.js:33:29:33:35 | tainted | semmle.label | tainted | -| sanitiser.js:35:21:35:44 | '' + ... '' | semmle.label | '' + ... '' | -| sanitiser.js:35:29:35:35 | tainted | semmle.label | tainted | | sanitiser.js:38:21:38:44 | '' + ... '' | semmle.label | '' + ... '' | | sanitiser.js:38:29:38:35 | tainted | semmle.label | tainted | | sanitiser.js:45:21:45:44 | '' + ... '' | semmle.label | '' + ... '' | @@ -876,21 +870,15 @@ edges | react-use-state.js:22:14:22:17 | prev | react-use-state.js:23:35:23:38 | prev | provenance | | | react-use-state.js:25:20:25:30 | window.name | react-use-state.js:21:10:21:14 | state | provenance | | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:23:29:23:35 | tainted | provenance | | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:25:29:25:35 | tainted | provenance | | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:28:29:28:35 | tainted | provenance | | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:30:29:30:35 | tainted | provenance | | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:33:29:33:35 | tainted | provenance | | -| sanitiser.js:16:7:16:27 | tainted | sanitiser.js:35:29:35:35 | tainted | provenance | | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:38:29:38:35 | tainted | provenance | | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:45:29:45:35 | tainted | provenance | | | sanitiser.js:16:7:16:27 | tainted | sanitiser.js:48:19:48:25 | tainted | provenance | | | sanitiser.js:16:17:16:27 | window.name | sanitiser.js:16:7:16:27 | tainted | provenance | | | sanitiser.js:23:29:23:35 | tainted | sanitiser.js:23:21:23:44 | '' + ... '' | provenance | | -| sanitiser.js:25:29:25:35 | tainted | sanitiser.js:25:21:25:44 | '' + ... '' | provenance | | -| sanitiser.js:28:29:28:35 | tainted | sanitiser.js:28:21:28:44 | '' + ... '' | provenance | | | sanitiser.js:30:29:30:35 | tainted | sanitiser.js:30:21:30:44 | '' + ... '' | provenance | | | sanitiser.js:33:29:33:35 | tainted | sanitiser.js:33:21:33:44 | '' + ... '' | provenance | | -| sanitiser.js:35:29:35:35 | tainted | sanitiser.js:35:21:35:44 | '' + ... '' | provenance | | | sanitiser.js:38:29:38:35 | tainted | sanitiser.js:38:21:38:44 | '' + ... '' | provenance | | | sanitiser.js:45:29:45:35 | tainted | sanitiser.js:45:21:45:44 | '' + ... '' | provenance | | | sanitiser.js:48:19:48:25 | tainted | sanitiser.js:48:19:48:46 | tainted ... /g, '') | provenance | | From 5d2ce172ebff2674533a030a3bdc0e8d49b59183 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 2 Oct 2024 14:39:45 +0200 Subject: [PATCH 295/514] JS: Update a test to handle AdditionalSanitizerGuardNode --- javascript/ql/test/library-tests/TaintBarriers/tests.ql | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/javascript/ql/test/library-tests/TaintBarriers/tests.ql b/javascript/ql/test/library-tests/TaintBarriers/tests.ql index 0feeae23a64..d6f3b4ae845 100644 --- a/javascript/ql/test/library-tests/TaintBarriers/tests.ql +++ b/javascript/ql/test/library-tests/TaintBarriers/tests.ql @@ -11,8 +11,10 @@ query predicate isLabeledBarrier( query predicate isSanitizer(ExampleConfiguration cfg, DataFlow::Node n) { cfg.isSanitizer(n) } -query predicate sanitizingGuard(TaintTracking::SanitizerGuardNode g, Expr e, boolean b) { - g.sanitizes(b, e) +query predicate sanitizingGuard(DataFlow::Node g, Expr e, boolean b) { + g.(TaintTracking::SanitizerGuardNode).sanitizes(b, e) + or + g.(TaintTracking::AdditionalSanitizerGuardNode).sanitizes(b, e) } query predicate taintedSink(DataFlow::Node source, DataFlow::Node sink) { From 12e316b99d2824302704f2bfc1af494fc3cbe5c8 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 8 Oct 2024 10:10:53 +0200 Subject: [PATCH 296/514] JS: Update test output after merging in 'main' - Paths are now relative to the test case, not the qlpack - Paths going through an implicit reads have changed slightly --- .../TaintTracking/BasicTaintTracking.expected | 6 ++-- .../UntrustedDataToExternalAPI.expected | 8 ++--- .../CommandInjection.expected | 10 +----- .../UnsafeShellCommandConstruction.expected | 13 ++------ .../Security/CWE-079/DomBasedXss/Xss.expected | 11 +------ .../XssWithAdditionalSources.expected | 11 +------ .../CWE-079/StoredXss/StoredXss.expected | 2 +- .../CWE-089/untyped/SqlInjection.expected | 12 ++----- .../Security/CWE-201/PostMessageStar.expected | 4 +-- .../CWE-312/BuildArtifactLeak.expected | 4 +-- .../CWE-312/CleartextLogging.expected | 32 +++++++------------ .../ServerSideUrlRedirect.expected | 4 +-- .../Consistency.expected | 2 +- .../PrototypePollutingMergeCall.expected | 8 ++--- 14 files changed, 32 insertions(+), 95 deletions(-) diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 16d5fa3a591..ff2c1a61750 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -38,9 +38,9 @@ legacyDataFlowDifference | spread.js:4:15:4:22 | source() | spread.js:24:8:24:8 | y | only flow with NEW data flow library | | use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:15:10:15:10 | x | only flow with NEW data flow library | consistencyIssue -| library-tests/TaintTracking/nested-props.js:20 | expected an alert, but found none | NOT OK - but not found | Consistency | -| library-tests/TaintTracking/stringification-read-steps.js:17 | expected an alert, but found none | NOT OK | Consistency | -| library-tests/TaintTracking/stringification-read-steps.js:25 | expected an alert, but found none | NOT OK | Consistency | +| nested-props.js:20 | expected an alert, but found none | NOT OK - but not found | Consistency | +| stringification-read-steps.js:17 | expected an alert, but found none | NOT OK | Consistency | +| stringification-read-steps.js:25 | expected an alert, but found none | NOT OK | Consistency | flow | access-path-sanitizer.js:2:18:2:25 | source() | access-path-sanitizer.js:4:8:4:12 | obj.x | | addexpr.js:4:10:4:17 | source() | addexpr.js:7:8:7:8 | x | diff --git a/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected b/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected index 35daa024535..c7a61da6e36 100644 --- a/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected +++ b/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected @@ -13,10 +13,8 @@ edges | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:43:8:43:16 | untrusted | provenance | | | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | tst-UntrustedDataToExternalAPI.js:44:8:44:16 | untrusted | provenance | | | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | provenance | | -| tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] [1] | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | provenance | | -| tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] [1] | provenance | | -| tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } [y, z] | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } | provenance | | -| tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } [z] | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } [y, z] | provenance | | +| tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | provenance | | +| tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } [z] | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } | provenance | | | tst-UntrustedDataToExternalAPI.js:15:16:15:24 | untrusted | tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } [z] | provenance | | | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [x] | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | provenance | | | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [x] | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | provenance | | @@ -36,11 +34,9 @@ nodes | tst-UntrustedDataToExternalAPI.js:8:31:8:39 | untrusted | semmle.label | untrusted | | tst-UntrustedDataToExternalAPI.js:9:18:9:26 | untrusted | semmle.label | untrusted | | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | semmle.label | ['x', u ... d, 'y'] | -| tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] [1] | semmle.label | ['x', u ... d, 'y'] [1] | | tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | semmle.label | untrusted | | tst-UntrustedDataToExternalAPI.js:11:20:11:28 | untrusted | semmle.label | untrusted | | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } | semmle.label | {\\n ... }\\n } | -| tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } [y, z] | semmle.label | {\\n ... }\\n } [y, z] | | tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } [z] | semmle.label | {\\n ... } [z] | | tst-UntrustedDataToExternalAPI.js:15:16:15:24 | untrusted | semmle.label | untrusted | | tst-UntrustedDataToExternalAPI.js:33:14:33:22 | untrusted | semmle.label | untrusted | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected index f4a573e957c..ad14af14118 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected @@ -30,15 +30,10 @@ edges | child_process-test.js:46:9:46:17 | args [1] | child_process-test.js:49:15:49:18 | args [1] | provenance | | | child_process-test.js:48:5:48:8 | [post update] args [1] | child_process-test.js:46:9:46:17 | args [1] | provenance | | | child_process-test.js:48:15:48:17 | cmd | child_process-test.js:48:5:48:8 | [post update] args [1] | provenance | | -| child_process-test.js:49:15:49:18 | args [1] | child_process-test.js:66:19:66:22 | args [1] | provenance | | -| child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) [ArrayElement] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | provenance | | +| child_process-test.js:49:15:49:18 | args [1] | child_process-test.js:66:19:66:22 | args | provenance | | | child_process-test.js:56:46:56:57 | ["bar", cmd] [1] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | provenance | | -| child_process-test.js:56:46:56:57 | ["bar", cmd] [1] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) [ArrayElement] | provenance | | | child_process-test.js:56:54:56:56 | cmd | child_process-test.js:56:46:56:57 | ["bar", cmd] [1] | provenance | | -| child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) [ArrayElement] | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) | provenance | | | child_process-test.js:57:46:57:48 | cmd | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) | provenance | | -| child_process-test.js:57:46:57:48 | cmd | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) [ArrayElement] | provenance | | -| child_process-test.js:66:19:66:22 | args [1] | child_process-test.js:66:19:66:22 | args | provenance | | | child_process-test.js:73:9:73:49 | cmd | child_process-test.js:75:29:75:31 | cmd | provenance | | | child_process-test.js:73:15:73:38 | url.par ... , true) | child_process-test.js:73:9:73:49 | cmd | provenance | | | child_process-test.js:73:25:73:31 | req.url | child_process-test.js:73:15:73:38 | url.par ... , true) | provenance | | @@ -133,15 +128,12 @@ nodes | child_process-test.js:49:15:49:18 | args [1] | semmle.label | args [1] | | child_process-test.js:53:15:53:17 | cmd | semmle.label | cmd | | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | semmle.label | ['/C', ... , cmd]) | -| child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) [ArrayElement] | semmle.label | ['/C', ... , cmd]) [ArrayElement] | | child_process-test.js:56:46:56:57 | ["bar", cmd] [1] | semmle.label | ["bar", cmd] [1] | | child_process-test.js:56:54:56:56 | cmd | semmle.label | cmd | | child_process-test.js:56:54:56:56 | cmd | semmle.label | cmd | | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) | semmle.label | ['/C', ... at(cmd) | -| child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) [ArrayElement] | semmle.label | ['/C', ... at(cmd) [ArrayElement] | | child_process-test.js:57:46:57:48 | cmd | semmle.label | cmd | | child_process-test.js:66:19:66:22 | args | semmle.label | args | -| child_process-test.js:66:19:66:22 | args [1] | semmle.label | args [1] | | child_process-test.js:73:9:73:49 | cmd | semmle.label | cmd | | child_process-test.js:73:15:73:38 | url.par ... , true) | semmle.label | url.par ... , true) | | child_process-test.js:73:25:73:31 | req.url | semmle.label | req.url | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected index 2f91b5e8c76..786c18cb8da 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected @@ -90,15 +90,12 @@ edges | lib/lib.js:414:40:414:43 | name | lib/lib.js:426:11:426:14 | name | provenance | | | lib/lib.js:414:40:414:43 | name | lib/lib.js:428:36:428:39 | name | provenance | | | lib/lib.js:425:6:425:13 | arr | lib/lib.js:427:14:427:16 | arr | provenance | | -| lib/lib.js:425:6:425:13 | arr [ArrayElement] | lib/lib.js:427:14:427:16 | arr [ArrayElement] | provenance | | +| lib/lib.js:425:6:425:13 | arr [ArrayElement] | lib/lib.js:427:14:427:16 | arr | provenance | | | lib/lib.js:426:2:426:4 | [post update] arr | lib/lib.js:425:6:425:13 | arr | provenance | | | lib/lib.js:426:2:426:4 | [post update] arr [ArrayElement] | lib/lib.js:425:6:425:13 | arr [ArrayElement] | provenance | | | lib/lib.js:426:11:426:14 | name | lib/lib.js:426:2:426:4 | [post update] arr | provenance | | | lib/lib.js:426:11:426:14 | name | lib/lib.js:426:2:426:4 | [post update] arr [ArrayElement] | provenance | | -| lib/lib.js:427:14:427:16 | arr [ArrayElement] | lib/lib.js:427:14:427:16 | arr | provenance | | -| lib/lib.js:428:14:428:58 | build(" ... + '-') [ArrayElement] | lib/lib.js:428:14:428:58 | build(" ... + '-') | provenance | | | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:428:14:428:58 | build(" ... + '-') | provenance | | -| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:428:14:428:58 | build(" ... + '-') [ArrayElement] | provenance | | | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:431:23:431:26 | last | provenance | | | lib/lib.js:428:36:428:39 | name | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | provenance | | | lib/lib.js:431:23:431:26 | last | lib/lib.js:436:19:436:22 | last | provenance | | @@ -125,8 +122,7 @@ edges | lib/lib.js:509:39:509:42 | name | lib/lib.js:545:23:545:26 | name | provenance | | | lib/lib.js:550:39:550:42 | name | lib/lib.js:555:33:555:36 | name | provenance | | | lib/lib.js:550:39:550:42 | name | lib/lib.js:555:33:555:36 | name | provenance | | -| lib/lib.js:551:33:551:36 | args [1] | lib/lib.js:552:23:552:26 | args [1] | provenance | | -| lib/lib.js:552:23:552:26 | args [1] | lib/lib.js:552:23:552:26 | args | provenance | | +| lib/lib.js:551:33:551:36 | args [1] | lib/lib.js:552:23:552:26 | args | provenance | | | lib/lib.js:555:25:555:37 | ["-rf", name] [1] | lib/lib.js:551:33:551:36 | args [1] | provenance | | | lib/lib.js:555:33:555:36 | name | lib/lib.js:555:25:555:37 | ["-rf", name] [1] | provenance | | | lib/lib.js:558:41:558:44 | name | lib/lib.js:560:26:560:29 | name | provenance | | @@ -283,9 +279,7 @@ nodes | lib/lib.js:426:11:426:14 | name | semmle.label | name | | lib/lib.js:426:11:426:14 | name | semmle.label | name | | lib/lib.js:427:14:427:16 | arr | semmle.label | arr | -| lib/lib.js:427:14:427:16 | arr [ArrayElement] | semmle.label | arr [ArrayElement] | | lib/lib.js:428:14:428:58 | build(" ... + '-') | semmle.label | build(" ... + '-') | -| lib/lib.js:428:14:428:58 | build(" ... + '-') [ArrayElement] | semmle.label | build(" ... + '-') [ArrayElement] | | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | semmle.label | (name ? ... ) + '-' | | lib/lib.js:428:36:428:39 | name | semmle.label | name | | lib/lib.js:431:23:431:26 | last | semmle.label | last | @@ -320,7 +314,6 @@ nodes | lib/lib.js:550:39:550:42 | name | semmle.label | name | | lib/lib.js:551:33:551:36 | args [1] | semmle.label | args [1] | | lib/lib.js:552:23:552:26 | args | semmle.label | args | -| lib/lib.js:552:23:552:26 | args [1] | semmle.label | args [1] | | lib/lib.js:555:25:555:37 | ["-rf", name] [1] | semmle.label | ["-rf", name] [1] | | lib/lib.js:555:33:555:36 | name | semmle.label | name | | lib/lib.js:555:33:555:36 | name | semmle.label | name | @@ -359,7 +352,7 @@ subpaths | lib/lib.js:251:27:251:30 | name | lib/lib.js:239:28:239:28 | s | lib/lib.js:245:9:245:9 | s | lib/lib.js:251:16:251:31 | cleanInput(name) | | lib/lib.js:340:25:340:25 | n | lib/lib.js:329:13:329:13 | x | lib/lib.js:330:9:330:9 | x | lib/lib.js:340:22:340:26 | id(n) | | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:431:23:431:26 | last | lib/lib.js:437:9:437:11 | arr | lib/lib.js:428:14:428:58 | build(" ... + '-') | -| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:431:23:431:26 | last | lib/lib.js:437:9:437:11 | arr [ArrayElement] | lib/lib.js:428:14:428:58 | build(" ... + '-') [ArrayElement] | +| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:431:23:431:26 | last | lib/lib.js:437:9:437:11 | arr [ArrayElement] | lib/lib.js:428:14:428:58 | build(" ... + '-') | #select | lib/isImported.js:6:10:6:25 | "rm -rf " + name | lib/isImported.js:5:49:5:52 | name | lib/isImported.js:6:22:6:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/isImported.js:5:49:5:52 | name | library input | lib/isImported.js:6:2:6:26 | cp.exec ... + name) | shell command | | lib/lib2.js:4:10:4:25 | "rm -rf " + name | lib/lib2.js:3:28:3:31 | name | lib/lib2.js:4:22:4:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib2.js:3:28:3:31 | name | library input | lib/lib2.js:4:2:4:26 | cp.exec ... + name) | shell command | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 0b29d370c6c..3d5623ff3f2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -582,7 +582,6 @@ nodes | various-concat-obfuscations.js:5:12:5:18 | tainted | semmle.label | tainted | | various-concat-obfuscations.js:6:4:6:26 | "
    " ... ainted) | semmle.label | "
    " ... ainted) | | various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") | semmle.label | "
    " ... /div>") | -| various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") [ArrayElement] | semmle.label | "
    " ... /div>") [ArrayElement] | | various-concat-obfuscations.js:6:19:6:25 | tainted | semmle.label | tainted | | various-concat-obfuscations.js:7:4:7:31 | ["
    ... /div>"] | semmle.label | ["
    ... /div>"] | | various-concat-obfuscations.js:7:4:7:38 | ["
    ... .join() | semmle.label | ["
    ... .join() | @@ -593,7 +592,6 @@ nodes | various-concat-obfuscations.js:10:16:10:22 | tainted | semmle.label | tainted | | various-concat-obfuscations.js:11:4:11:31 | "
    ") | semmle.label | "
    ") | -| various-concat-obfuscations.js:11:4:11:44 | "
    ") [ArrayElement] | semmle.label | "
    ") [ArrayElement] | | various-concat-obfuscations.js:11:24:11:30 | tainted | semmle.label | tainted | | various-concat-obfuscations.js:12:4:12:34 | ["
    "] | semmle.label | ["
    "] | | various-concat-obfuscations.js:12:4:12:41 | ["
    " ...
    " | provenance | Config | | various-concat-obfuscations.js:5:12:5:18 | tainted | various-concat-obfuscations.js:5:4:5:26 | `
    $ ...
    ` | provenance | Config | | various-concat-obfuscations.js:6:4:6:26 | "
    " ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") | provenance | | -| various-concat-obfuscations.js:6:4:6:26 | "
    " ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") [ArrayElement] | provenance | | -| various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") [ArrayElement] | various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") | provenance | | | various-concat-obfuscations.js:6:19:6:25 | tainted | various-concat-obfuscations.js:6:4:6:26 | "
    " ... ainted) | provenance | Config | | various-concat-obfuscations.js:7:4:7:31 | ["
    ... /div>"] | various-concat-obfuscations.js:7:4:7:38 | ["
    ... .join() | provenance | | | various-concat-obfuscations.js:7:14:7:20 | tainted | various-concat-obfuscations.js:7:4:7:31 | ["
    ... /div>"] | provenance | Config | | various-concat-obfuscations.js:9:19:9:25 | tainted | various-concat-obfuscations.js:9:4:9:34 | "
    " | provenance | Config | | various-concat-obfuscations.js:10:16:10:22 | tainted | various-concat-obfuscations.js:10:4:10:27 | `
    ` | provenance | Config | | various-concat-obfuscations.js:11:4:11:31 | "
    ") | provenance | | -| various-concat-obfuscations.js:11:4:11:31 | "
    ") [ArrayElement] | provenance | | -| various-concat-obfuscations.js:11:4:11:44 | "
    ") [ArrayElement] | various-concat-obfuscations.js:11:4:11:44 | "
    ") | provenance | | | various-concat-obfuscations.js:11:24:11:30 | tainted | various-concat-obfuscations.js:11:4:11:31 | "
    "] | various-concat-obfuscations.js:12:4:12:41 | ["
    "] | provenance | Config | @@ -1125,11 +1118,9 @@ edges | various-concat-obfuscations.js:20:17:20:40 | documen ... .search | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | provenance | | | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:14:24:14:28 | attrs | provenance | | | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) | provenance | Config | -| various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) [ArrayElement] | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | provenance | | | various-concat-obfuscations.js:21:17:21:40 | documen ... .search | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | provenance | | | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | provenance | | | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | provenance | Config | -| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) [ArrayElement] | provenance | Config | | winjs.js:2:7:2:53 | tainted | winjs.js:3:43:3:49 | tainted | provenance | | | winjs.js:2:7:2:53 | tainted | winjs.js:4:43:4:49 | tainted | provenance | | | winjs.js:2:17:2:40 | documen ... .search | winjs.js:2:17:2:53 | documen ... ring(1) | provenance | | @@ -1147,7 +1138,7 @@ subpaths | tst.js:58:26:58:30 | bar() | tst.js:48:15:48:15 | s | tst.js:50:12:50:22 | s.substr(1) | tst.js:58:21:58:31 | chop(bar()) | | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:14:24:14:28 | attrs | various-concat-obfuscations.js:15:10:15:83 | '
    ' | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) | | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:10:18:105 | '
    ') | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | -| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:10:18:105 | '
    ') [ArrayElement] | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) [ArrayElement] | +| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:10:18:105 | '
    ') [ArrayElement] | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | #select | addEventListener.js:2:20:2:29 | event.data | addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:29 | event.data | Cross-site scripting vulnerability due to $@. | addEventListener.js:1:43:1:47 | event | user-provided value | | addEventListener.js:6:20:6:23 | data | addEventListener.js:5:43:5:48 | {data} | addEventListener.js:6:20:6:23 | data | Cross-site scripting vulnerability due to $@. | addEventListener.js:5:43:5:48 | {data} | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index c857ff42b09..e9d44d1ee0e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -589,7 +589,6 @@ nodes | various-concat-obfuscations.js:5:12:5:18 | tainted | semmle.label | tainted | | various-concat-obfuscations.js:6:4:6:26 | "
    " ... ainted) | semmle.label | "
    " ... ainted) | | various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") | semmle.label | "
    " ... /div>") | -| various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") [ArrayElement] | semmle.label | "
    " ... /div>") [ArrayElement] | | various-concat-obfuscations.js:6:19:6:25 | tainted | semmle.label | tainted | | various-concat-obfuscations.js:7:4:7:31 | ["
    ... /div>"] | semmle.label | ["
    ... /div>"] | | various-concat-obfuscations.js:7:4:7:38 | ["
    ... .join() | semmle.label | ["
    ... .join() | @@ -600,7 +599,6 @@ nodes | various-concat-obfuscations.js:10:16:10:22 | tainted | semmle.label | tainted | | various-concat-obfuscations.js:11:4:11:31 | "
    ") | semmle.label | "
    ") | -| various-concat-obfuscations.js:11:4:11:44 | "
    ") [ArrayElement] | semmle.label | "
    ") [ArrayElement] | | various-concat-obfuscations.js:11:24:11:30 | tainted | semmle.label | tainted | | various-concat-obfuscations.js:12:4:12:34 | ["
    "] | semmle.label | ["
    "] | | various-concat-obfuscations.js:12:4:12:41 | ["
    " ...
    " | provenance | Config | | various-concat-obfuscations.js:5:12:5:18 | tainted | various-concat-obfuscations.js:5:4:5:26 | `
    $ ...
    ` | provenance | Config | | various-concat-obfuscations.js:6:4:6:26 | "
    " ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") | provenance | | -| various-concat-obfuscations.js:6:4:6:26 | "
    " ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") [ArrayElement] | provenance | | -| various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") [ArrayElement] | various-concat-obfuscations.js:6:4:6:43 | "
    " ... /div>") | provenance | | | various-concat-obfuscations.js:6:19:6:25 | tainted | various-concat-obfuscations.js:6:4:6:26 | "
    " ... ainted) | provenance | Config | | various-concat-obfuscations.js:7:4:7:31 | ["
    ... /div>"] | various-concat-obfuscations.js:7:4:7:38 | ["
    ... .join() | provenance | | | various-concat-obfuscations.js:7:14:7:20 | tainted | various-concat-obfuscations.js:7:4:7:31 | ["
    ... /div>"] | provenance | Config | | various-concat-obfuscations.js:9:19:9:25 | tainted | various-concat-obfuscations.js:9:4:9:34 | "
    " | provenance | Config | | various-concat-obfuscations.js:10:16:10:22 | tainted | various-concat-obfuscations.js:10:4:10:27 | `
    ` | provenance | Config | | various-concat-obfuscations.js:11:4:11:31 | "
    ") | provenance | | -| various-concat-obfuscations.js:11:4:11:31 | "
    ") [ArrayElement] | provenance | | -| various-concat-obfuscations.js:11:4:11:44 | "
    ") [ArrayElement] | various-concat-obfuscations.js:11:4:11:44 | "
    ") | provenance | | | various-concat-obfuscations.js:11:24:11:30 | tainted | various-concat-obfuscations.js:11:4:11:31 | "
    "] | various-concat-obfuscations.js:12:4:12:41 | ["
    "] | provenance | Config | @@ -1150,11 +1143,9 @@ edges | various-concat-obfuscations.js:20:17:20:40 | documen ... .search | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | provenance | | | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:14:24:14:28 | attrs | provenance | | | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) | provenance | Config | -| various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) [ArrayElement] | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | provenance | | | various-concat-obfuscations.js:21:17:21:40 | documen ... .search | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | provenance | | | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | provenance | | | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | provenance | Config | -| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) [ArrayElement] | provenance | Config | | winjs.js:2:7:2:53 | tainted | winjs.js:3:43:3:49 | tainted | provenance | | | winjs.js:2:7:2:53 | tainted | winjs.js:4:43:4:49 | tainted | provenance | | | winjs.js:2:17:2:40 | documen ... .search | winjs.js:2:17:2:53 | documen ... ring(1) | provenance | | @@ -1183,7 +1174,7 @@ subpaths | tst.js:58:26:58:30 | bar() | tst.js:48:15:48:15 | s | tst.js:50:12:50:22 | s.substr(1) | tst.js:58:21:58:31 | chop(bar()) | | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:14:24:14:28 | attrs | various-concat-obfuscations.js:15:10:15:83 | '
    ' | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) | | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:10:18:105 | '
    ') | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | -| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:10:18:105 | '
    ') [ArrayElement] | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) [ArrayElement] | +| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:10:18:105 | '
    ') [ArrayElement] | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | #select | jwt.js:6:14:6:20 | decoded | jwt.js:4:36:4:39 | data | jwt.js:6:14:6:20 | decoded | Cross-site scripting vulnerability due to $@. | jwt.js:4:36:4:39 | data | user-provided value | | typeahead.js:10:16:10:18 | loc | typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | Cross-site scripting vulnerability due to $@. | typeahead.js:9:28:9:30 | loc | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected index 33b967f346c..3e8fa512c85 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected @@ -36,7 +36,6 @@ edges | xss-through-filenames.js:31:25:31:28 | file | xss-through-filenames.js:31:13:31:18 | [post update] files2 | provenance | | | xss-through-filenames.js:31:25:31:28 | file | xss-through-filenames.js:31:13:31:18 | [post update] files2 [ArrayElement] | provenance | | | xss-through-filenames.js:33:19:33:24 | files2 | xss-through-filenames.js:35:29:35:34 | files2 | provenance | | -| xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | xss-through-filenames.js:33:19:33:24 | files2 | provenance | | | xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | provenance | | | xss-through-filenames.js:35:13:35:35 | files3 | xss-through-filenames.js:37:19:37:24 | files3 | provenance | | | xss-through-filenames.js:35:22:35:35 | format(files2) | xss-through-filenames.js:35:13:35:35 | files3 | provenance | | @@ -97,6 +96,7 @@ subpaths | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:19:45:19:48 | file | xss-through-filenames.js:20:13:20:18 | [post update] files3 [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 [ArrayElement] | | xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:30:34:30:37 | file | xss-through-filenames.js:31:13:31:18 | [post update] files2 | xss-through-filenames.js:33:19:33:24 | files2 | | xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:30:34:30:37 | file | xss-through-filenames.js:31:13:31:18 | [post update] files2 | xss-through-filenames.js:33:19:33:24 | files2 | +| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:30:34:30:37 | file | xss-through-filenames.js:31:13:31:18 | [post update] files2 [ArrayElement] | xss-through-filenames.js:33:19:33:24 | files2 | | xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:30:34:30:37 | file | xss-through-filenames.js:31:13:31:18 | [post update] files2 [ArrayElement] | xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | | xss-through-filenames.js:35:29:35:34 | files2 | xss-through-filenames.js:17:21:17:26 | files2 | xss-through-filenames.js:22:16:22:30 | files3.join('') | xss-through-filenames.js:35:22:35:35 | format(files2) | | xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | xss-through-filenames.js:17:21:17:26 | files2 [ArrayElement] | xss-through-filenames.js:22:16:22:30 | files3.join('') | xss-through-filenames.js:35:22:35:35 | format(files2) | diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected index 6c1a83cc421..1f9ea0d7817 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected @@ -243,9 +243,6 @@ nodes | pg-promise.js:30:13:30:25 | req.params.id | semmle.label | req.params.id | | pg-promise.js:34:13:34:25 | req.params.id | semmle.label | req.params.id | | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | semmle.label | [\\n ... n\\n ] | -| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [0] | semmle.label | [\\n ... n\\n ] [0] | -| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [1] | semmle.label | [\\n ... n\\n ] [1] | -| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [2] | semmle.label | [\\n ... n\\n ] [2] | | pg-promise.js:39:7:39:19 | req.params.id | semmle.label | req.params.id | | pg-promise.js:40:7:40:21 | req.params.name | semmle.label | req.params.name | | pg-promise.js:41:7:41:20 | req.params.foo | semmle.label | req.params.foo | @@ -612,12 +609,9 @@ edges | pg-promise.js:22:11:22:15 | query | pg-promise.js:60:20:60:24 | query | provenance | | | pg-promise.js:22:11:22:15 | query | pg-promise.js:63:23:63:27 | query | provenance | | | pg-promise.js:22:11:22:15 | query | pg-promise.js:64:16:64:20 | query | provenance | | -| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [0] | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | provenance | | -| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [1] | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | provenance | | -| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [2] | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | provenance | | -| pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [0] | provenance | | -| pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [1] | provenance | | -| pg-promise.js:41:7:41:20 | req.params.foo | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] [2] | provenance | | +| pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | provenance | | +| pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | provenance | | +| pg-promise.js:41:7:41:20 | req.params.foo | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | provenance | | | redis.js:10:16:10:23 | req.body | redis.js:10:16:10:27 | req.body.key | provenance | Config | | redis.js:12:9:12:26 | key | redis.js:13:16:13:18 | key | provenance | | | redis.js:12:9:12:26 | key | redis.js:18:16:18:18 | key | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected b/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected index c6c416c93e0..23f4ed0c9b6 100644 --- a/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected +++ b/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected @@ -1,9 +1,8 @@ edges -| PostMessageStar2.js:4:7:4:15 | data [foo] | PostMessageStar2.js:8:29:8:32 | data [foo] | provenance | | +| PostMessageStar2.js:4:7:4:15 | data [foo] | PostMessageStar2.js:8:29:8:32 | data | provenance | | | PostMessageStar2.js:4:7:4:15 | data [foo] | PostMessageStar2.js:9:29:9:32 | data [foo] | provenance | | | PostMessageStar2.js:5:3:5:6 | [post update] data [foo] | PostMessageStar2.js:4:7:4:15 | data [foo] | provenance | | | PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:5:3:5:6 | [post update] data [foo] | provenance | | -| PostMessageStar2.js:8:29:8:32 | data [foo] | PostMessageStar2.js:8:29:8:32 | data | provenance | | | PostMessageStar2.js:9:29:9:32 | data [foo] | PostMessageStar2.js:9:29:9:36 | data.foo | provenance | | nodes | PostMessageStar2.js:1:27:1:34 | password | semmle.label | password | @@ -11,7 +10,6 @@ nodes | PostMessageStar2.js:5:3:5:6 | [post update] data [foo] | semmle.label | [post update] data [foo] | | PostMessageStar2.js:5:14:5:21 | password | semmle.label | password | | PostMessageStar2.js:8:29:8:32 | data | semmle.label | data | -| PostMessageStar2.js:8:29:8:32 | data [foo] | semmle.label | data [foo] | | PostMessageStar2.js:9:29:9:32 | data [foo] | semmle.label | data [foo] | | PostMessageStar2.js:9:29:9:36 | data.foo | semmle.label | data.foo | | PostMessageStar2.js:13:27:13:33 | authKey | semmle.label | authKey | diff --git a/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected b/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected index 88ce227af45..f891e9e7a64 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected @@ -33,8 +33,7 @@ edges | build-leaks.js:25:12:25:13 | {} | build-leaks.js:22:49:22:51 | env | provenance | | | build-leaks.js:28:12:31:5 | {\\n ... d\\n } [stringified, process.env] | build-leaks.js:34:26:34:45 | getEnv('production') [stringified, process.env] | provenance | | | build-leaks.js:30:22:30:31 | stringifed [process.env] | build-leaks.js:28:12:31:5 | {\\n ... d\\n } [stringified, process.env] | provenance | | -| build-leaks.js:34:26:34:45 | getEnv('production') [stringified, process.env] | build-leaks.js:34:26:34:57 | getEnv( ... ngified [process.env] | provenance | | -| build-leaks.js:34:26:34:57 | getEnv( ... ngified [process.env] | build-leaks.js:34:26:34:57 | getEnv( ... ngified | provenance | | +| build-leaks.js:34:26:34:45 | getEnv('production') [stringified, process.env] | build-leaks.js:34:26:34:57 | getEnv( ... ngified | provenance | | | build-leaks.js:40:9:40:60 | pw | build-leaks.js:41:82:41:83 | pw | provenance | | | build-leaks.js:40:14:40:60 | url.par ... assword | build-leaks.js:40:9:40:60 | pw | provenance | | | build-leaks.js:41:43:41:86 | [post update] { "proc ... y(pw) } [process.env.secret] | build-leaks.js:41:43:41:86 | { "proc ... y(pw) } | provenance | | @@ -73,7 +72,6 @@ nodes | build-leaks.js:30:22:30:31 | stringifed [process.env] | semmle.label | stringifed [process.env] | | build-leaks.js:34:26:34:45 | getEnv('production') [stringified, process.env] | semmle.label | getEnv('production') [stringified, process.env] | | build-leaks.js:34:26:34:57 | getEnv( ... ngified | semmle.label | getEnv( ... ngified | -| build-leaks.js:34:26:34:57 | getEnv( ... ngified [process.env] | semmle.label | getEnv( ... ngified [process.env] | | build-leaks.js:40:9:40:60 | pw | semmle.label | pw | | build-leaks.js:40:14:40:60 | url.par ... assword | semmle.label | url.par ... assword | | build-leaks.js:41:43:41:86 | [post update] { "proc ... y(pw) } [process.env.secret] | semmle.label | [post update] { "proc ... y(pw) } [process.env.secret] | diff --git a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index b18ece7460a..26871214fd0 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -3,16 +3,13 @@ edges | passwords.js:10:11:10:18 | password | passwords.js:7:20:7:20 | x | provenance | | | passwords.js:14:31:14:38 | password | passwords.js:14:17:14:38 | name + ... assword | provenance | | | passwords.js:16:29:16:36 | password | passwords.js:16:17:16:38 | `${name ... sword}` | provenance | | -| passwords.js:18:9:20:5 | obj1 [password] | passwords.js:21:17:21:20 | obj1 [password] | provenance | | +| passwords.js:18:9:20:5 | obj1 [password] | passwords.js:21:17:21:20 | obj1 | provenance | | | passwords.js:18:16:20:5 | {\\n ... x\\n } [password] | passwords.js:18:9:20:5 | obj1 [password] | provenance | | | passwords.js:19:19:19:19 | x | passwords.js:18:16:20:5 | {\\n ... x\\n } [password] | provenance | | -| passwords.js:21:17:21:20 | obj1 [password] | passwords.js:21:17:21:20 | obj1 | provenance | | -| passwords.js:23:9:25:5 | obj2 [x] | passwords.js:26:17:26:20 | obj2 [x] | provenance | | +| passwords.js:23:9:25:5 | obj2 [x] | passwords.js:26:17:26:20 | obj2 | provenance | | | passwords.js:23:16:25:5 | {\\n ... d\\n } [x] | passwords.js:23:9:25:5 | obj2 [x] | provenance | | | passwords.js:24:12:24:19 | password | passwords.js:23:16:25:5 | {\\n ... d\\n } [x] | provenance | | -| passwords.js:26:17:26:20 | obj2 [x] | passwords.js:26:17:26:20 | obj2 | provenance | | -| passwords.js:28:9:28:17 | obj3 [x] | passwords.js:29:17:29:20 | obj3 [x] | provenance | | -| passwords.js:29:17:29:20 | obj3 [x] | passwords.js:29:17:29:20 | obj3 | provenance | | +| passwords.js:28:9:28:17 | obj3 [x] | passwords.js:29:17:29:20 | obj3 | provenance | | | passwords.js:30:5:30:8 | [post update] obj3 [x] | passwords.js:28:9:28:17 | obj3 [x] | provenance | | | passwords.js:30:14:30:21 | password | passwords.js:30:5:30:8 | [post update] obj3 [x] | provenance | | | passwords.js:77:9:77:55 | temp [encryptedPassword] | passwords.js:78:17:78:20 | temp [encryptedPassword] | provenance | | @@ -32,10 +29,10 @@ edges | passwords.js:122:31:122:49 | password.toString() | passwords.js:122:17:122:49 | name + ... tring() | provenance | | | passwords.js:123:31:123:38 | password | passwords.js:123:31:123:48 | password.valueOf() | provenance | | | passwords.js:123:31:123:48 | password.valueOf() | passwords.js:123:17:123:48 | name + ... lueOf() | provenance | | -| passwords.js:127:9:132:5 | config [password] | passwords.js:135:17:135:22 | config [password] | provenance | | -| passwords.js:127:9:132:5 | config [x] | passwords.js:135:17:135:22 | config [x] | provenance | | +| passwords.js:127:9:132:5 | config [password] | passwords.js:135:17:135:22 | config | provenance | | +| passwords.js:127:9:132:5 | config [x] | passwords.js:135:17:135:22 | config | provenance | | | passwords.js:127:9:132:5 | config [x] | passwords.js:136:17:136:22 | config [x] | provenance | | -| passwords.js:127:9:132:5 | config [y] | passwords.js:135:17:135:22 | config [y] | provenance | | +| passwords.js:127:9:132:5 | config [y] | passwords.js:135:17:135:22 | config | provenance | | | passwords.js:127:9:132:5 | config [y] | passwords.js:137:17:137:22 | config [y] | provenance | | | passwords.js:127:18:132:5 | {\\n ... )\\n } [password] | passwords.js:127:9:132:5 | config [password] | provenance | | | passwords.js:127:18:132:5 | {\\n ... )\\n } [x] | passwords.js:127:9:132:5 | config [x] | provenance | | @@ -43,27 +40,25 @@ edges | passwords.js:128:19:128:19 | x | passwords.js:127:18:132:5 | {\\n ... )\\n } [password] | provenance | | | passwords.js:130:12:130:19 | password | passwords.js:127:18:132:5 | {\\n ... )\\n } [x] | provenance | | | passwords.js:131:12:131:24 | getPassword() | passwords.js:127:18:132:5 | {\\n ... )\\n } [y] | provenance | | -| passwords.js:135:17:135:22 | config [password] | passwords.js:135:17:135:22 | config | provenance | | -| passwords.js:135:17:135:22 | config [x] | passwords.js:135:17:135:22 | config | provenance | | -| passwords.js:135:17:135:22 | config [y] | passwords.js:135:17:135:22 | config | provenance | | | passwords.js:136:17:136:22 | config [x] | passwords.js:136:17:136:24 | config.x | provenance | | | passwords.js:137:17:137:22 | config [y] | passwords.js:137:17:137:24 | config.y | provenance | | +| passwords.js:142:26:142:34 | [apply call taint node] | passwords.js:142:26:142:34 | arguments | provenance | | +| passwords.js:142:26:142:34 | [apply call taint node] | passwords.js:142:26:142:34 | arguments | provenance | | | passwords.js:142:26:142:34 | [apply call taint node] | passwords.js:142:26:142:34 | arguments [ArrayElement] | provenance | | | passwords.js:142:26:142:34 | [apply call taint node] | passwords.js:142:26:142:34 | arguments [ArrayElement] | provenance | | | passwords.js:142:26:142:34 | arguments | passwords.js:142:26:142:34 | [apply call taint node] | provenance | | | passwords.js:142:26:142:34 | arguments [0] | passwords.js:142:26:142:34 | [apply call taint node] | provenance | | -| passwords.js:142:26:142:34 | arguments [0] | passwords.js:142:26:142:34 | arguments | provenance | | | passwords.js:142:26:142:34 | arguments [ArrayElement] | passwords.js:142:26:142:34 | [apply call taint node] | provenance | | | passwords.js:142:26:142:34 | arguments [ArrayElement] | passwords.js:142:26:142:34 | [apply call taint node] | provenance | | -| passwords.js:142:26:142:34 | arguments [ArrayElement] | passwords.js:142:26:142:34 | arguments | provenance | | -| passwords.js:142:26:142:34 | arguments [ArrayElement] | passwords.js:142:26:142:34 | arguments | provenance | | | passwords.js:146:9:148:5 | config [x] | passwords.js:149:21:149:26 | config [x] | provenance | | | passwords.js:146:18:148:5 | {\\n ... d\\n } [x] | passwords.js:146:9:148:5 | config [x] | provenance | | | passwords.js:147:12:147:19 | password | passwords.js:146:18:148:5 | {\\n ... d\\n } [x] | provenance | | | passwords.js:149:21:149:26 | config [x] | passwords.js:149:21:149:28 | config.x | provenance | | +| passwords.js:149:21:149:28 | config.x | passwords.js:142:26:142:34 | arguments | provenance | | | passwords.js:149:21:149:28 | config.x | passwords.js:142:26:142:34 | arguments | provenance | Config | | passwords.js:149:21:149:28 | config.x | passwords.js:142:26:142:34 | arguments | provenance | Config | | passwords.js:149:21:149:28 | config.x | passwords.js:142:26:142:34 | arguments [0] | provenance | | +| passwords.js:150:21:150:31 | process.env | passwords.js:142:26:142:34 | arguments | provenance | | | passwords.js:150:21:150:31 | process.env | passwords.js:142:26:142:34 | arguments | provenance | Config | | passwords.js:150:21:150:31 | process.env | passwords.js:142:26:142:34 | arguments | provenance | Config | | passwords.js:150:21:150:31 | process.env | passwords.js:142:26:142:34 | arguments [0] | provenance | | @@ -71,6 +66,7 @@ edges | passwords.js:152:20:152:44 | Util.in ... ss.env) | passwords.js:152:20:152:63 | Util.in ... /g, '') | provenance | | | passwords.js:152:20:152:63 | Util.in ... /g, '') | passwords.js:152:9:152:63 | procdesc | provenance | | | passwords.js:152:33:152:43 | process.env | passwords.js:152:20:152:44 | Util.in ... ss.env) | provenance | | +| passwords.js:154:21:154:28 | procdesc | passwords.js:142:26:142:34 | arguments | provenance | | | passwords.js:154:21:154:28 | procdesc | passwords.js:142:26:142:34 | arguments | provenance | Config | | passwords.js:154:21:154:28 | procdesc | passwords.js:142:26:142:34 | arguments | provenance | Config | | passwords.js:154:21:154:28 | procdesc | passwords.js:142:26:142:34 | arguments [0] | provenance | | @@ -97,15 +93,12 @@ nodes | passwords.js:18:16:20:5 | {\\n ... x\\n } [password] | semmle.label | {\\n ... x\\n } [password] | | passwords.js:19:19:19:19 | x | semmle.label | x | | passwords.js:21:17:21:20 | obj1 | semmle.label | obj1 | -| passwords.js:21:17:21:20 | obj1 [password] | semmle.label | obj1 [password] | | passwords.js:23:9:25:5 | obj2 [x] | semmle.label | obj2 [x] | | passwords.js:23:16:25:5 | {\\n ... d\\n } [x] | semmle.label | {\\n ... d\\n } [x] | | passwords.js:24:12:24:19 | password | semmle.label | password | | passwords.js:26:17:26:20 | obj2 | semmle.label | obj2 | -| passwords.js:26:17:26:20 | obj2 [x] | semmle.label | obj2 [x] | | passwords.js:28:9:28:17 | obj3 [x] | semmle.label | obj3 [x] | | passwords.js:29:17:29:20 | obj3 | semmle.label | obj3 | -| passwords.js:29:17:29:20 | obj3 [x] | semmle.label | obj3 [x] | | passwords.js:30:5:30:8 | [post update] obj3 [x] | semmle.label | [post update] obj3 [x] | | passwords.js:30:14:30:21 | password | semmle.label | password | | passwords.js:77:9:77:55 | temp [encryptedPassword] | semmle.label | temp [encryptedPassword] | @@ -145,9 +138,6 @@ nodes | passwords.js:130:12:130:19 | password | semmle.label | password | | passwords.js:131:12:131:24 | getPassword() | semmle.label | getPassword() | | passwords.js:135:17:135:22 | config | semmle.label | config | -| passwords.js:135:17:135:22 | config [password] | semmle.label | config [password] | -| passwords.js:135:17:135:22 | config [x] | semmle.label | config [x] | -| passwords.js:135:17:135:22 | config [y] | semmle.label | config [y] | | passwords.js:136:17:136:22 | config [x] | semmle.label | config [x] | | passwords.js:136:17:136:24 | config.x | semmle.label | config.x | | passwords.js:137:17:137:22 | config [y] | semmle.label | config [y] | diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected b/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected index aa992b9c707..058a52a54e8 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected +++ b/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected @@ -22,13 +22,12 @@ edges | express.js:150:7:150:34 | target | express.js:160:18:160:23 | target | provenance | | | express.js:150:16:150:34 | req.param("target") | express.js:150:7:150:34 | target | provenance | | | express.js:164:7:164:54 | myThing | express.js:165:16:165:22 | myThing | provenance | | -| express.js:164:7:164:54 | myThing [ArrayElement] | express.js:165:16:165:22 | myThing [ArrayElement] | provenance | | +| express.js:164:7:164:54 | myThing [ArrayElement] | express.js:165:16:165:22 | myThing | provenance | | | express.js:164:17:164:41 | JSON.st ... .query) | express.js:164:17:164:54 | JSON.st ... (1, -1) | provenance | | | express.js:164:17:164:41 | JSON.st ... .query) | express.js:164:17:164:54 | JSON.st ... (1, -1) [ArrayElement] | provenance | | | express.js:164:17:164:54 | JSON.st ... (1, -1) | express.js:164:7:164:54 | myThing | provenance | | | express.js:164:17:164:54 | JSON.st ... (1, -1) [ArrayElement] | express.js:164:7:164:54 | myThing [ArrayElement] | provenance | | | express.js:164:32:164:40 | req.query | express.js:164:17:164:41 | JSON.st ... .query) | provenance | | -| express.js:165:16:165:22 | myThing [ArrayElement] | express.js:165:16:165:22 | myThing | provenance | | | koa.js:6:6:6:27 | url | koa.js:7:15:7:17 | url | provenance | | | koa.js:6:6:6:27 | url | koa.js:8:18:8:20 | url | provenance | | | koa.js:6:6:6:27 | url | koa.js:14:16:14:18 | url | provenance | | @@ -93,7 +92,6 @@ nodes | express.js:164:17:164:54 | JSON.st ... (1, -1) [ArrayElement] | semmle.label | JSON.st ... (1, -1) [ArrayElement] | | express.js:164:32:164:40 | req.query | semmle.label | req.query | | express.js:165:16:165:22 | myThing | semmle.label | myThing | -| express.js:165:16:165:22 | myThing [ArrayElement] | semmle.label | myThing [ArrayElement] | | koa.js:6:6:6:27 | url | semmle.label | url | | koa.js:6:12:6:27 | ctx.query.target | semmle.label | ctx.query.target | | koa.js:7:15:7:17 | url | semmle.label | url | diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.expected index 8d013c40b5f..8efa3a055b1 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.expected @@ -1 +1 @@ -| query-tests/Security/CWE-915/PrototypePollutingAssignment/lib.js:70 | expected an alert, but found none | NOT OK | Config | +| lib.js:70 | expected an alert, but found none | NOT OK | Config | diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected index b773f9b2dee..195a5fec4ec 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected @@ -6,14 +6,12 @@ nodes | 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 | @@ -34,14 +32,12 @@ edges | angularmerge.js:1:30:1:34 | event | angularmerge.js:2:32:2:36 | event | provenance | | | angularmerge.js:2:32:2:36 | event | angularmerge.js:2:32:2:41 | event.data | provenance | | | angularmerge.js:2:32:2:41 | event.data | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | provenance | Config | -| 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] | provenance | | -| 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 } | provenance | | +| 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 } | provenance | | | 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] | provenance | | | src-vulnerable-lodash/tst.js:14:9:16:5 | opts [thing] | src-vulnerable-lodash/tst.js:18:16:18:19 | opts [thing] | provenance | | | src-vulnerable-lodash/tst.js:14:16:16:5 | {\\n ... e\\n } [thing] | src-vulnerable-lodash/tst.js:14:9:16:5 | opts [thing] | provenance | | | 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] | provenance | | -| 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] | provenance | | -| 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 } | provenance | | +| 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 } | provenance | | | src-vulnerable-lodash/tst.js:18:16:18:19 | opts [thing] | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | provenance | | | 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] | provenance | | | webix/webix.html:3:34:3:38 | event | webix/webix.html:4:37:4:41 | event | provenance | | From a258489551a8378e251c7a456df3375bc58f0463 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 19 Sep 2024 14:52:32 +0200 Subject: [PATCH 297/514] JS: Refactor some internal methods to make them easier to alias We need these to return the dominator instead of declaring it in the parameter list, so that we can use it directly to fulfill part of the signature for the SSA library. We can't rewrite it with an inline predicate since the SSA module calls with a transitive closure '*', which does not permit inline predicates. --- .../ql/lib/semmle/javascript/BasicBlocks.qll | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/BasicBlocks.qll b/javascript/ql/lib/semmle/javascript/BasicBlocks.qll index 6e6579d6f7e..a3504357c2d 100644 --- a/javascript/ql/lib/semmle/javascript/BasicBlocks.qll +++ b/javascript/ql/lib/semmle/javascript/BasicBlocks.qll @@ -102,15 +102,15 @@ private module Internal { private import Internal -/** Holds if `dom` is an immediate dominator of `bb`. */ +/** Gets the immediate dominator of `bb`. */ cached -private predicate bbIDominates(BasicBlock dom, BasicBlock bb) = - idominance(entryBB/1, succBB/2)(_, dom, bb) +private BasicBlock immediateDominator(BasicBlock bb) = + idominance(entryBB/1, succBB/2)(_, result, bb) -/** Holds if `dom` is an immediate post-dominator of `bb`. */ +/** Gets the immediate post-dominator of `bb`. */ cached -private predicate bbIPostDominates(BasicBlock dom, BasicBlock bb) = - idominance(exitBB/1, predBB/2)(_, dom, bb) +private BasicBlock immediatePostDominator(BasicBlock bb) = + idominance(exitBB/1, predBB/2)(_, result, bb) /** * A basic block, that is, a maximal straight-line sequence of control flow nodes @@ -279,7 +279,7 @@ class BasicBlock extends @cfg_node, NodeInStmtContainer { /** * Gets the basic block that immediately dominates this basic block. */ - ReachableBasicBlock getImmediateDominator() { bbIDominates(result, this) } + ReachableBasicBlock getImmediateDominator() { result = immediateDominator(this) } } /** @@ -308,7 +308,7 @@ class ReachableBasicBlock extends BasicBlock { * Holds if this basic block strictly dominates `bb`. */ pragma[inline] - predicate strictlyDominates(ReachableBasicBlock bb) { bbIDominates+(this, bb) } + predicate strictlyDominates(ReachableBasicBlock bb) { this = immediateDominator+(bb) } /** * Holds if this basic block dominates `bb`. @@ -316,13 +316,13 @@ class ReachableBasicBlock extends BasicBlock { * This predicate is reflexive: each reachable basic block dominates itself. */ pragma[inline] - predicate dominates(ReachableBasicBlock bb) { bbIDominates*(this, bb) } + predicate dominates(ReachableBasicBlock bb) { this = immediateDominator*(bb) } /** * Holds if this basic block strictly post-dominates `bb`. */ pragma[inline] - predicate strictlyPostDominates(ReachableBasicBlock bb) { bbIPostDominates+(this, bb) } + predicate strictlyPostDominates(ReachableBasicBlock bb) { this = immediatePostDominator+(bb) } /** * Holds if this basic block post-dominates `bb`. @@ -330,7 +330,7 @@ class ReachableBasicBlock extends BasicBlock { * This predicate is reflexive: each reachable basic block post-dominates itself. */ pragma[inline] - predicate postDominates(ReachableBasicBlock bb) { bbIPostDominates*(this, bb) } + predicate postDominates(ReachableBasicBlock bb) { this = immediatePostDominator*(bb) } } /** From 7363b578b10103259136933fed67f9d13c92c55c Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 19 Sep 2024 15:04:01 +0200 Subject: [PATCH 298/514] JS: Instantiate shared SSA library JS: Remove with statement comment --- javascript/ql/lib/qlpack.yml | 1 + .../ql/lib/semmle/javascript/BasicBlocks.qll | 10 +++ .../dataflow/internal/sharedlib/Ssa.qll | 68 +++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 34347c17efd..0a0c21e5d67 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -9,6 +9,7 @@ dependencies: codeql/dataflow: ${workspace} codeql/mad: ${workspace} codeql/regex: ${workspace} + codeql/ssa: ${workspace} codeql/tutorial: ${workspace} codeql/util: ${workspace} codeql/xml: ${workspace} diff --git a/javascript/ql/lib/semmle/javascript/BasicBlocks.qll b/javascript/ql/lib/semmle/javascript/BasicBlocks.qll index a3504357c2d..450046b34da 100644 --- a/javascript/ql/lib/semmle/javascript/BasicBlocks.qll +++ b/javascript/ql/lib/semmle/javascript/BasicBlocks.qll @@ -7,6 +7,11 @@ import javascript private import internal.StmtContainers private import semmle.javascript.internal.CachedStages +module BasicBlockInternal { + // TODO: Expose these as public predicate in a private module instead of this hack. + predicate getImmediateBasicBlockDominator = immediateDominator/1; +} + /** * Holds if `nd` starts a new basic block. */ @@ -280,6 +285,11 @@ class BasicBlock extends @cfg_node, NodeInStmtContainer { * Gets the basic block that immediately dominates this basic block. */ ReachableBasicBlock getImmediateDominator() { result = immediateDominator(this) } + + /** + * Holds if this if a basic block whose last node is an exit node. + */ + predicate isExitBlock() { exitBB(this) } } /** diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll new file mode 100644 index 00000000000..03b73121b1e --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll @@ -0,0 +1,68 @@ +/** + * Instantiates the shared SSA library for JavaScript, but only to establish use-use flow. + * + * JavaScript's old SSA library is still responsible for the ordinary SSA flow. + */ + +private import javascript as js +private import codeql.ssa.Ssa + +private module SsaConfig implements InputSig { + class ControlFlowNode = js::ControlFlowNode; + + class BasicBlock = js::BasicBlock; + + class ExitBasicBlock extends BasicBlock { + ExitBasicBlock() { this.isExitBlock() } + } + + class SourceVariable = js::PurelyLocalVariable; // TODO: include 'this' as it is relevant for use-use flow + + pragma[nomagic] + private js::EntryBasicBlock getEntryBlock(js::StmtContainer container) { + result.getContainer() = container + } + + predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) { + certain = true and + ( + bb.defAt(i, v, _) + or + // Implicit initialization and function parameters + bb = getEntryBlock(v.getDeclaringContainer()) and + i = -1 + ) + } + + predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) { + bb.useAt(i, v, _) and certain = true + } + + predicate getImmediateBasicBlockDominator = + js::BasicBlockInternal::getImmediateBasicBlockDominator/1; + + pragma[inline] + BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() } +} + +import Make + +private module SsaDataflowInput implements DataFlowIntegrationInputSig { + class Expr extends js::VarUse { + predicate hasCfgNode(js::BasicBlock bb, int i) { this = bb.getNode(i) } + } + + predicate ssaDefAssigns(WriteDefinition def, Expr value) { none() } // Not handled here + + class Parameter = js::Parameter; + + predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) { none() } // Not handled here + + abstract class Guard extends Expr { } // empty class + + predicate guardControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) { none() } + + js::BasicBlock getAConditionalBasicBlockSuccessor(js::BasicBlock bb, boolean branch) { none() } +} + +import DataFlowIntegration From 81e74d8bb57ff8eff365d2148d22abfe8fe18c3f Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 19 Sep 2024 15:09:55 +0200 Subject: [PATCH 299/514] JS: Add test case for spurious flow from lack of use-use --- .../ql/test/library-tests/TripleDot/useuse.js | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 javascript/ql/test/library-tests/TripleDot/useuse.js diff --git a/javascript/ql/test/library-tests/TripleDot/useuse.js b/javascript/ql/test/library-tests/TripleDot/useuse.js new file mode 100644 index 00000000000..8cf017a261f --- /dev/null +++ b/javascript/ql/test/library-tests/TripleDot/useuse.js @@ -0,0 +1,30 @@ +import 'dummy'; + +function t1() { + const obj = {}; + + sink(obj.field); // $ SPURIOUS: hasValueFlow=t1.1 hasValueFlow=t1.2 + + obj.field = source('t1.1'); + sink(obj.field); // $ hasValueFlow=t1.1 SPURIOUS: hasValueFlow=t1.2 + + obj.field = "safe"; + sink(obj.field); // $ SPURIOUS: hasValueFlow=t1.1 hasValueFlow=t1.2 + + obj.field = source('t1.2'); + sink(obj.field); // $ hasValueFlow=t1.2 SPURIOUS: hasValueFlow=t1.1 +} + +function t2() { + let obj; + + if (Math.random()) { + obj = {}; + sink(obj.field); + } else { + obj = {}; + obj.field = source('t2.1'); + sink(obj.field); // $ hasValueFlow=t2.1 + } + sink(obj.field); // $ hasValueFlow=t2.1 +} From 78e961cef30e31e730c9f45fb3a794268eeb9567 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 20 Sep 2024 13:02:09 +0200 Subject: [PATCH 300/514] JS: Add use-use flow --- .../dataflow/internal/DataFlowNode.qll | 8 ++ .../dataflow/internal/DataFlowPrivate.qll | 102 ++++++++++++++++-- .../ql/test/library-tests/TripleDot/useuse.js | 6 +- 3 files changed, 105 insertions(+), 11 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index cd027d00862..8f718080698 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -8,6 +8,7 @@ private import javascript private import semmle.javascript.dataflow.internal.AdditionalFlowInternal private import semmle.javascript.dataflow.internal.Contents::Private private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon +private import semmle.javascript.dataflow.internal.sharedlib.Ssa as Ssa2 private import semmle.javascript.dataflow.internal.DataFlowPrivate as DataFlowPrivate private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as FlowSummaryImpl private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate @@ -27,7 +28,14 @@ private module Cached { cached newtype TNode = TValueNode(AST::ValueNode nd) or + /** An SSA node from the legacy SSA library */ TSsaDefNode(SsaDefinition d) or + /** Use of a variable with flow from a post-update node (from an earlier use) */ + TSsaUseNode(VarUse use) { use.getVariable() instanceof PurelyLocalVariable } or + /** Phi-read node (new SSA library). Ordinary phi nodes are represented by TSsaDefNode. */ + TSsaPhiReadNode(Ssa2::PhiReadNode phi) or + /** Input to a phi node (new SSA library) */ + TSsaInputNode(Ssa2::SsaInputNode input) or TCapturedVariableNode(LocalVariable v) { v.isCaptured() } or TPropNode(@property p) or TRestPatternNode(DestructuringPattern dp, Expr rest) { rest = dp.getRest() } or diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index f8f86e04c08..e77ff3c4693 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -6,6 +6,7 @@ private import semmle.javascript.dataflow.internal.AdditionalFlowInternal private import semmle.javascript.dataflow.internal.Contents::Private private import semmle.javascript.dataflow.internal.VariableCapture private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon +private import semmle.javascript.dataflow.internal.sharedlib.Ssa as Ssa2 private import semmle.javascript.internal.flow_summaries.AllFlowSummaries private import sharedlib.FlowSummaryImpl as FlowSummaryImpl private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate @@ -18,6 +19,55 @@ private class Node = DataFlow::Node; class PostUpdateNode = DataFlow::PostUpdateNode; +class SsaUseNode extends DataFlow::Node, TSsaUseNode { + private VarAccess access; + + SsaUseNode() { this = TSsaUseNode(access) } + + cached + override string toString() { result = "[ssa-use] " + access.toString() } + + cached + override StmtContainer getContainer() { result = access.getContainer() } + + cached + override Location getLocation() { result = access.getLocation() } +} + +class SsaPhiReadNode extends DataFlow::Node, TSsaPhiReadNode { + private Ssa2::PhiReadNode phi; + + SsaPhiReadNode() { this = TSsaPhiReadNode(phi) } + + cached + override string toString() { result = "[ssa-phi-read] " + phi.getSourceVariable().getName() } + + cached + override StmtContainer getContainer() { result = phi.getSourceVariable().getDeclaringContainer() } + + cached + override Location getLocation() { result = phi.getLocation() } +} + +class SsaInputNode extends DataFlow::Node, TSsaInputNode { + private Ssa2::SsaInputNode input; + + SsaInputNode() { this = TSsaInputNode(input) } + + cached + override string toString() { + result = "[ssa-input] " + input.getDefinitionExt().getSourceVariable().getName() + } + + cached + override StmtContainer getContainer() { + result = input.getDefinitionExt().getSourceVariable().getDeclaringContainer() + } + + cached + override Location getLocation() { result = input.getLocation() } +} + class FlowSummaryNode extends DataFlow::Node, TFlowSummaryNode { FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) } @@ -535,6 +585,12 @@ predicate nodeIsHidden(Node node) { node instanceof DynamicParameterArrayNode or node instanceof RestParameterStoreNode + or + node instanceof SsaUseNode + or + node instanceof SsaPhiReadNode + or + node instanceof SsaInputNode } predicate neverSkipInPathGraph(Node node) { @@ -999,20 +1055,48 @@ private predicate valuePreservingStep(Node node1, Node node2) { or FlowSummaryPrivate::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(), node2.(FlowSummaryNode).getSummaryNode(), true, _) // TODO: preserve 'model' - or - // Step from post-update nodes to local sources of the pre-update node. This emulates how JS usually tracks side effects. - exists(PostUpdateNode postUpdate | - node1 = postUpdate and - node2 = postUpdate.getPreUpdateNode().getALocalSource() and - node1 != node2 and // exclude trivial edges - sameContainer(node1, node2) - ) } predicate knownSourceModel(Node sink, string model) { none() } predicate knownSinkModel(Node sink, string model) { none() } +private predicate samePhi(SsaPhiNode legacyPhi, Ssa2::PhiNode newPhi) { + exists(BasicBlock bb, PurelyLocalVariable v | + newPhi.definesAt(v, bb, _) and + legacyPhi.definesAt(bb, _, v) + ) +} + +private Node getNodeFromSsa2(Ssa2::Node node) { + result = TSsaUseNode(node.(Ssa2::ExprNode).getExpr()) + or + result = TExprPostUpdateNode(node.(Ssa2::ExprPostUpdateNode).getExpr()) + or + result = TSsaPhiReadNode(node.(Ssa2::SsaDefinitionExtNode).getDefinitionExt()) + or + result = TSsaInputNode(node.(Ssa2::SsaInputNode)) + or + exists(SsaPhiNode legacyPhi, Ssa2::PhiNode ssaPhi | + node.(Ssa2::SsaDefinitionExtNode).getDefinitionExt() = ssaPhi and + samePhi(legacyPhi, ssaPhi) and + result = TSsaDefNode(legacyPhi) + ) +} + +private predicate useUseFlow(Node node1, Node node2) { + exists(Ssa2::DefinitionExt def, Ssa2::Node ssa1, Ssa2::Node ssa2, boolean isUseStep | + Ssa2::localFlowStep(def, ssa1, ssa2, isUseStep) and + node1 = getNodeFromSsa2(ssa1) and + node2 = getNodeFromSsa2(ssa2) + ) + or + exists(VarUse use | + node1 = TSsaUseNode(use) and + node2 = TValueNode(use) + ) +} + predicate simpleLocalFlowStep(Node node1, Node node2, string model) { simpleLocalFlowStep(node1, node2) and model = "" } @@ -1022,6 +1106,8 @@ predicate simpleLocalFlowStep(Node node1, Node node2) { nodeGetEnclosingCallable(pragma[only_bind_out](node1)) = nodeGetEnclosingCallable(pragma[only_bind_out](node2)) or + useUseFlow(node1, node2) + or exists(FlowSummaryImpl::Private::SummaryNode input, FlowSummaryImpl::Private::SummaryNode output | FlowSummaryPrivate::Steps::summaryStoreStep(input, MkAwaited(), output) and node1 = TFlowSummaryNode(input) and diff --git a/javascript/ql/test/library-tests/TripleDot/useuse.js b/javascript/ql/test/library-tests/TripleDot/useuse.js index 8cf017a261f..67999165595 100644 --- a/javascript/ql/test/library-tests/TripleDot/useuse.js +++ b/javascript/ql/test/library-tests/TripleDot/useuse.js @@ -3,13 +3,13 @@ import 'dummy'; function t1() { const obj = {}; - sink(obj.field); // $ SPURIOUS: hasValueFlow=t1.1 hasValueFlow=t1.2 + sink(obj.field); obj.field = source('t1.1'); - sink(obj.field); // $ hasValueFlow=t1.1 SPURIOUS: hasValueFlow=t1.2 + sink(obj.field); // $ hasValueFlow=t1.1 obj.field = "safe"; - sink(obj.field); // $ SPURIOUS: hasValueFlow=t1.1 hasValueFlow=t1.2 + sink(obj.field); // $ SPURIOUS: hasValueFlow=t1.1 obj.field = source('t1.2'); sink(obj.field); // $ hasValueFlow=t1.2 SPURIOUS: hasValueFlow=t1.1 From 9e600424cc35cf08944a8163b9106d0a77651e72 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 20 Sep 2024 15:03:57 +0200 Subject: [PATCH 301/514] JS: Remove unused predicate --- .../semmle/javascript/dataflow/internal/DataFlowPrivate.qll | 6 ------ 1 file changed, 6 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index e77ff3c4693..64a401c384f 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -994,12 +994,6 @@ predicate mayBenefitFromCallContext(DataFlowCall call) { none() } */ DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { none() } -bindingset[node1, node2] -pragma[inline_late] -private predicate sameContainer(Node node1, Node node2) { - node1.getContainer() = node2.getContainer() -} - bindingset[node, fun] pragma[inline_late] private predicate sameContainerAsEnclosingContainer(Node node, Function fun) { From 211b42d0ce6b2ab21f56f34215f239dae1c4c7d4 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Sep 2024 10:27:13 +0200 Subject: [PATCH 302/514] JS: Move BasicBlocks.qll -> internal/BasicBlocksInternal.qll --- .../ql/lib/semmle/javascript/BasicBlocks.qll | 369 +----------------- .../internal/BasicBlockInternal.qll | 368 +++++++++++++++++ 2 files changed, 369 insertions(+), 368 deletions(-) create mode 100644 javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll diff --git a/javascript/ql/lib/semmle/javascript/BasicBlocks.qll b/javascript/ql/lib/semmle/javascript/BasicBlocks.qll index 450046b34da..a6ce180d5ec 100644 --- a/javascript/ql/lib/semmle/javascript/BasicBlocks.qll +++ b/javascript/ql/lib/semmle/javascript/BasicBlocks.qll @@ -1,368 +1 @@ -/** - * Provides classes for working with basic blocks, and predicates for computing - * liveness information for local variables. - */ - -import javascript -private import internal.StmtContainers -private import semmle.javascript.internal.CachedStages - -module BasicBlockInternal { - // TODO: Expose these as public predicate in a private module instead of this hack. - predicate getImmediateBasicBlockDominator = immediateDominator/1; -} - -/** - * Holds if `nd` starts a new basic block. - */ -private predicate startsBB(ControlFlowNode nd) { - not exists(nd.getAPredecessor()) and exists(nd.getASuccessor()) - or - nd.isJoin() - or - nd.getAPredecessor().isBranch() -} - -/** - * Holds if the first node of basic block `succ` is a control flow - * successor of the last node of basic block `bb`. - */ -private predicate succBB(BasicBlock bb, BasicBlock succ) { succ = bb.getLastNode().getASuccessor() } - -/** - * Holds if the first node of basic block `bb` is a control flow - * successor of the last node of basic block `pre`. - */ -private predicate predBB(BasicBlock bb, BasicBlock pre) { succBB(pre, bb) } - -/** Holds if `bb` is an entry basic block. */ -private predicate entryBB(BasicBlock bb) { bb.getFirstNode() instanceof ControlFlowEntryNode } - -/** Holds if `bb` is an exit basic block. */ -private predicate exitBB(BasicBlock bb) { bb.getLastNode() instanceof ControlFlowExitNode } - -cached -private module Internal { - /** - * Holds if `succ` is a control flow successor of `nd` within the same basic block. - */ - private predicate intraBBSucc(ControlFlowNode nd, ControlFlowNode succ) { - succ = nd.getASuccessor() and - not succ instanceof BasicBlock - } - - /** - * Holds if `nd` is the `i`th node in basic block `bb`. - * - * In other words, `i` is the shortest distance from a node `bb` - * that starts a basic block to `nd` along the `intraBBSucc` relation. - */ - cached - predicate bbIndex(BasicBlock bb, ControlFlowNode nd, int i) = - shortestDistances(startsBB/1, intraBBSucc/2)(bb, nd, i) - - cached - int bbLength(BasicBlock bb) { result = strictcount(ControlFlowNode nd | bbIndex(bb, nd, _)) } - - cached - predicate useAt(BasicBlock bb, int i, Variable v, VarUse u) { - Stages::BasicBlocks::ref() and - v = u.getVariable() and - bbIndex(bb, u, i) - } - - cached - predicate defAt(BasicBlock bb, int i, Variable v, VarDef d) { - exists(VarRef lhs | - lhs = d.getTarget().(BindingPattern).getABindingVarRef() and - v = lhs.getVariable() - | - lhs = d.getTarget() and - bbIndex(bb, d, i) - or - exists(PropertyPattern pp | - lhs = pp.getValuePattern() and - bbIndex(bb, pp, i) - ) - or - exists(ObjectPattern op | - lhs = op.getRest() and - bbIndex(bb, lhs, i) - ) - or - exists(ArrayPattern ap | - lhs = ap.getAnElement() and - bbIndex(bb, lhs, i) - ) - ) - } - - cached - predicate reachableBB(BasicBlock bb) { - entryBB(bb) - or - exists(BasicBlock predBB | succBB(predBB, bb) | reachableBB(predBB)) - } -} - -private import Internal - -/** Gets the immediate dominator of `bb`. */ -cached -private BasicBlock immediateDominator(BasicBlock bb) = - idominance(entryBB/1, succBB/2)(_, result, bb) - -/** Gets the immediate post-dominator of `bb`. */ -cached -private BasicBlock immediatePostDominator(BasicBlock bb) = - idominance(exitBB/1, predBB/2)(_, result, bb) - -/** - * A basic block, that is, a maximal straight-line sequence of control flow nodes - * without branches or joins. - * - * At the database level, a basic block is represented by its first control flow node. - */ -class BasicBlock extends @cfg_node, NodeInStmtContainer { - cached - BasicBlock() { Stages::BasicBlocks::ref() and startsBB(this) } - - /** Gets a basic block succeeding this one. */ - BasicBlock getASuccessor() { succBB(this, result) } - - /** Gets a basic block preceding this one. */ - BasicBlock getAPredecessor() { result.getASuccessor() = this } - - /** Gets a node in this block. */ - ControlFlowNode getANode() { result = this.getNode(_) } - - /** Gets the node at the given position in this block. */ - ControlFlowNode getNode(int pos) { bbIndex(this, result, pos) } - - /** Gets the first node in this block. */ - ControlFlowNode getFirstNode() { result = this } - - /** Gets the last node in this block. */ - ControlFlowNode getLastNode() { result = this.getNode(this.length() - 1) } - - /** Gets the length of this block. */ - int length() { result = bbLength(this) } - - /** Holds if this basic block uses variable `v` in its `i`th node `u`. */ - predicate useAt(int i, Variable v, VarUse u) { useAt(this, i, v, u) } - - /** Holds if this basic block defines variable `v` in its `i`th node `d`. */ - predicate defAt(int i, Variable v, VarDef d) { defAt(this, i, v, d) } - - /** - * Holds if `v` is live at entry to this basic block and `u` is a use of `v` - * witnessing the liveness. - * - * In other words, `u` is a use of `v` that is reachable from the - * entry node of this basic block without going through a redefinition - * of `v`. The use `u` may either be in this basic block, or in another - * basic block reachable from this one. - */ - predicate isLiveAtEntry(Variable v, VarUse u) { - // restrict `u` to be reachable from this basic block - u = this.getASuccessor*().getANode() and - ( - // shortcut: if `v` is never defined, then it must be live - this.isDefinedInSameContainer(v) - implies - // otherwise, do full liveness computation - this.isLiveAtEntryImpl(v, u) - ) - } - - /** - * Holds if `v` is live at entry to this basic block and `u` is a use of `v` - * witnessing the liveness, where `v` is defined at least once in the enclosing - * function or script. - */ - private predicate isLiveAtEntryImpl(Variable v, VarUse u) { - this.isLocallyLiveAtEntry(v, u) - or - this.isDefinedInSameContainer(v) and - not this.defAt(_, v, _) and - this.getASuccessor().isLiveAtEntryImpl(v, u) - } - - /** - * Holds if `v` is defined at least once in the function or script to which - * this basic block belongs. - */ - private predicate isDefinedInSameContainer(Variable v) { - exists(VarDef def | def.getAVariable() = v and def.getContainer() = this.getContainer()) - } - - /** - * Holds if `v` is a variable that is live at entry to this basic block. - * - * Note that this is equivalent to `bb.isLiveAtEntry(v, _)`, but may - * be more efficient on large databases. - */ - predicate isLiveAtEntry(Variable v) { - this.isLocallyLiveAtEntry(v, _) - or - not this.defAt(_, v, _) and this.getASuccessor().isLiveAtEntry(v) - } - - /** - * Holds if local variable `v` is live at entry to this basic block and - * `u` is a use of `v` witnessing the liveness. - */ - predicate localIsLiveAtEntry(LocalVariable v, VarUse u) { - this.isLocallyLiveAtEntry(v, u) - or - not this.defAt(_, v, _) and this.getASuccessor().localIsLiveAtEntry(v, u) - } - - /** - * Holds if local variable `v` is live at entry to this basic block. - */ - predicate localIsLiveAtEntry(LocalVariable v) { - this.isLocallyLiveAtEntry(v, _) - or - not this.defAt(_, v, _) and this.getASuccessor().localIsLiveAtEntry(v) - } - - /** - * Holds if `d` is a definition of `v` that is reachable from the beginning of - * this basic block without going through a redefinition of `v`. - */ - predicate localMayBeOverwritten(LocalVariable v, VarDef d) { - this.isLocallyOverwritten(v, d) - or - not this.defAt(_, v, _) and this.getASuccessor().localMayBeOverwritten(v, d) - } - - /** - * Gets the next index after `i` in this basic block at which `v` is - * defined or used, provided that `d` is a definition of `v` at index `i`. - * If there are no further uses or definitions of `v` after `i`, the - * result is the length of this basic block. - */ - private int nextDefOrUseAfter(PurelyLocalVariable v, int i, VarDef d) { - this.defAt(i, v, d) and - result = - min(int j | - (this.defAt(j, v, _) or this.useAt(j, v, _) or j = this.length()) and - j > i - ) - } - - /** - * Holds if `d` defines variable `v` at the `i`th node of this basic block, and - * the definition is live, that is, the variable may be read after this - * definition and before a re-definition. - */ - predicate localLiveDefAt(PurelyLocalVariable v, int i, VarDef d) { - exists(int j | j = this.nextDefOrUseAfter(v, i, d) | - this.useAt(j, v, _) - or - j = this.length() and this.getASuccessor().localIsLiveAtEntry(v) - ) - } - - /** - * Holds if `u` is a use of `v` in this basic block, and there are - * no definitions of `v` before it. - */ - private predicate isLocallyLiveAtEntry(Variable v, VarUse u) { - exists(int n | this.useAt(n, v, u) | not exists(int m | m < n | this.defAt(m, v, _))) - } - - /** - * Holds if `d` is a definition of `v` in this basic block, and there are - * no other definitions of `v` before it. - */ - private predicate isLocallyOverwritten(Variable v, VarDef d) { - exists(int n | this.defAt(n, v, d) | not exists(int m | m < n | this.defAt(m, v, _))) - } - - /** - * Gets the basic block that immediately dominates this basic block. - */ - ReachableBasicBlock getImmediateDominator() { result = immediateDominator(this) } - - /** - * Holds if this if a basic block whose last node is an exit node. - */ - predicate isExitBlock() { exitBB(this) } -} - -/** - * An unreachable basic block, that is, a basic block - * whose first node is unreachable. - */ -class UnreachableBlock extends BasicBlock { - UnreachableBlock() { this.getFirstNode().isUnreachable() } -} - -/** - * An entry basic block, that is, a basic block - * whose first node is the entry node of a statement container. - */ -class EntryBasicBlock extends BasicBlock { - EntryBasicBlock() { entryBB(this) } -} - -/** - * A basic block that is reachable from an entry basic block. - */ -class ReachableBasicBlock extends BasicBlock { - ReachableBasicBlock() { reachableBB(this) } - - /** - * Holds if this basic block strictly dominates `bb`. - */ - pragma[inline] - predicate strictlyDominates(ReachableBasicBlock bb) { this = immediateDominator+(bb) } - - /** - * Holds if this basic block dominates `bb`. - * - * This predicate is reflexive: each reachable basic block dominates itself. - */ - pragma[inline] - predicate dominates(ReachableBasicBlock bb) { this = immediateDominator*(bb) } - - /** - * Holds if this basic block strictly post-dominates `bb`. - */ - pragma[inline] - predicate strictlyPostDominates(ReachableBasicBlock bb) { this = immediatePostDominator+(bb) } - - /** - * Holds if this basic block post-dominates `bb`. - * - * This predicate is reflexive: each reachable basic block post-dominates itself. - */ - pragma[inline] - predicate postDominates(ReachableBasicBlock bb) { this = immediatePostDominator*(bb) } -} - -/** - * A reachable basic block with more than one predecessor. - */ -class ReachableJoinBlock extends ReachableBasicBlock { - ReachableJoinBlock() { this.getFirstNode().isJoin() } - - /** - * Holds if this basic block belongs to the dominance frontier of `b`, that is - * `b` dominates a predecessor of this block, but not this block itself. - * - * Algorithm from Cooper et al., "A Simple, Fast Dominance Algorithm" (Figure 5), - * who in turn attribute it to Ferrante et al., "The program dependence graph and - * its use in optimization". - */ - predicate inDominanceFrontierOf(ReachableBasicBlock b) { - b = this.getAPredecessor() and not b = this.getImmediateDominator() - or - exists(ReachableBasicBlock prev | this.inDominanceFrontierOf(prev) | - b = prev.getImmediateDominator() and - not b = this.getImmediateDominator() - ) - } -} +import internal.BasicBlockInternal diff --git a/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll b/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll new file mode 100644 index 00000000000..ef8ff1545b3 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll @@ -0,0 +1,368 @@ +/** + * Provides classes for working with basic blocks, and predicates for computing + * liveness information for local variables. + */ + +import javascript +private import semmle.javascript.internal.StmtContainers +private import semmle.javascript.internal.CachedStages + +module BasicBlockInternal { + // TODO: Expose these as public predicate in a private module instead of this hack. + predicate getImmediateBasicBlockDominator = immediateDominator/1; +} + +/** + * Holds if `nd` starts a new basic block. + */ +private predicate startsBB(ControlFlowNode nd) { + not exists(nd.getAPredecessor()) and exists(nd.getASuccessor()) + or + nd.isJoin() + or + nd.getAPredecessor().isBranch() +} + +/** + * Holds if the first node of basic block `succ` is a control flow + * successor of the last node of basic block `bb`. + */ +private predicate succBB(BasicBlock bb, BasicBlock succ) { succ = bb.getLastNode().getASuccessor() } + +/** + * Holds if the first node of basic block `bb` is a control flow + * successor of the last node of basic block `pre`. + */ +private predicate predBB(BasicBlock bb, BasicBlock pre) { succBB(pre, bb) } + +/** Holds if `bb` is an entry basic block. */ +private predicate entryBB(BasicBlock bb) { bb.getFirstNode() instanceof ControlFlowEntryNode } + +/** Holds if `bb` is an exit basic block. */ +private predicate exitBB(BasicBlock bb) { bb.getLastNode() instanceof ControlFlowExitNode } + +cached +private module Internal { + /** + * Holds if `succ` is a control flow successor of `nd` within the same basic block. + */ + private predicate intraBBSucc(ControlFlowNode nd, ControlFlowNode succ) { + succ = nd.getASuccessor() and + not succ instanceof BasicBlock + } + + /** + * Holds if `nd` is the `i`th node in basic block `bb`. + * + * In other words, `i` is the shortest distance from a node `bb` + * that starts a basic block to `nd` along the `intraBBSucc` relation. + */ + cached + predicate bbIndex(BasicBlock bb, ControlFlowNode nd, int i) = + shortestDistances(startsBB/1, intraBBSucc/2)(bb, nd, i) + + cached + int bbLength(BasicBlock bb) { result = strictcount(ControlFlowNode nd | bbIndex(bb, nd, _)) } + + cached + predicate useAt(BasicBlock bb, int i, Variable v, VarUse u) { + Stages::BasicBlocks::ref() and + v = u.getVariable() and + bbIndex(bb, u, i) + } + + cached + predicate defAt(BasicBlock bb, int i, Variable v, VarDef d) { + exists(VarRef lhs | + lhs = d.getTarget().(BindingPattern).getABindingVarRef() and + v = lhs.getVariable() + | + lhs = d.getTarget() and + bbIndex(bb, d, i) + or + exists(PropertyPattern pp | + lhs = pp.getValuePattern() and + bbIndex(bb, pp, i) + ) + or + exists(ObjectPattern op | + lhs = op.getRest() and + bbIndex(bb, lhs, i) + ) + or + exists(ArrayPattern ap | + lhs = ap.getAnElement() and + bbIndex(bb, lhs, i) + ) + ) + } + + cached + predicate reachableBB(BasicBlock bb) { + entryBB(bb) + or + exists(BasicBlock predBB | succBB(predBB, bb) | reachableBB(predBB)) + } +} + +private import Internal + +/** Gets the immediate dominator of `bb`. */ +cached +private BasicBlock immediateDominator(BasicBlock bb) = + idominance(entryBB/1, succBB/2)(_, result, bb) + +/** Gets the immediate post-dominator of `bb`. */ +cached +private BasicBlock immediatePostDominator(BasicBlock bb) = + idominance(exitBB/1, predBB/2)(_, result, bb) + +/** + * A basic block, that is, a maximal straight-line sequence of control flow nodes + * without branches or joins. + * + * At the database level, a basic block is represented by its first control flow node. + */ +class BasicBlock extends @cfg_node, NodeInStmtContainer { + cached + BasicBlock() { Stages::BasicBlocks::ref() and startsBB(this) } + + /** Gets a basic block succeeding this one. */ + BasicBlock getASuccessor() { succBB(this, result) } + + /** Gets a basic block preceding this one. */ + BasicBlock getAPredecessor() { result.getASuccessor() = this } + + /** Gets a node in this block. */ + ControlFlowNode getANode() { result = this.getNode(_) } + + /** Gets the node at the given position in this block. */ + ControlFlowNode getNode(int pos) { bbIndex(this, result, pos) } + + /** Gets the first node in this block. */ + ControlFlowNode getFirstNode() { result = this } + + /** Gets the last node in this block. */ + ControlFlowNode getLastNode() { result = this.getNode(this.length() - 1) } + + /** Gets the length of this block. */ + int length() { result = bbLength(this) } + + /** Holds if this basic block uses variable `v` in its `i`th node `u`. */ + predicate useAt(int i, Variable v, VarUse u) { useAt(this, i, v, u) } + + /** Holds if this basic block defines variable `v` in its `i`th node `d`. */ + predicate defAt(int i, Variable v, VarDef d) { defAt(this, i, v, d) } + + /** + * Holds if `v` is live at entry to this basic block and `u` is a use of `v` + * witnessing the liveness. + * + * In other words, `u` is a use of `v` that is reachable from the + * entry node of this basic block without going through a redefinition + * of `v`. The use `u` may either be in this basic block, or in another + * basic block reachable from this one. + */ + predicate isLiveAtEntry(Variable v, VarUse u) { + // restrict `u` to be reachable from this basic block + u = this.getASuccessor*().getANode() and + ( + // shortcut: if `v` is never defined, then it must be live + this.isDefinedInSameContainer(v) + implies + // otherwise, do full liveness computation + this.isLiveAtEntryImpl(v, u) + ) + } + + /** + * Holds if `v` is live at entry to this basic block and `u` is a use of `v` + * witnessing the liveness, where `v` is defined at least once in the enclosing + * function or script. + */ + private predicate isLiveAtEntryImpl(Variable v, VarUse u) { + this.isLocallyLiveAtEntry(v, u) + or + this.isDefinedInSameContainer(v) and + not this.defAt(_, v, _) and + this.getASuccessor().isLiveAtEntryImpl(v, u) + } + + /** + * Holds if `v` is defined at least once in the function or script to which + * this basic block belongs. + */ + private predicate isDefinedInSameContainer(Variable v) { + exists(VarDef def | def.getAVariable() = v and def.getContainer() = this.getContainer()) + } + + /** + * Holds if `v` is a variable that is live at entry to this basic block. + * + * Note that this is equivalent to `bb.isLiveAtEntry(v, _)`, but may + * be more efficient on large databases. + */ + predicate isLiveAtEntry(Variable v) { + this.isLocallyLiveAtEntry(v, _) + or + not this.defAt(_, v, _) and this.getASuccessor().isLiveAtEntry(v) + } + + /** + * Holds if local variable `v` is live at entry to this basic block and + * `u` is a use of `v` witnessing the liveness. + */ + predicate localIsLiveAtEntry(LocalVariable v, VarUse u) { + this.isLocallyLiveAtEntry(v, u) + or + not this.defAt(_, v, _) and this.getASuccessor().localIsLiveAtEntry(v, u) + } + + /** + * Holds if local variable `v` is live at entry to this basic block. + */ + predicate localIsLiveAtEntry(LocalVariable v) { + this.isLocallyLiveAtEntry(v, _) + or + not this.defAt(_, v, _) and this.getASuccessor().localIsLiveAtEntry(v) + } + + /** + * Holds if `d` is a definition of `v` that is reachable from the beginning of + * this basic block without going through a redefinition of `v`. + */ + predicate localMayBeOverwritten(LocalVariable v, VarDef d) { + this.isLocallyOverwritten(v, d) + or + not this.defAt(_, v, _) and this.getASuccessor().localMayBeOverwritten(v, d) + } + + /** + * Gets the next index after `i` in this basic block at which `v` is + * defined or used, provided that `d` is a definition of `v` at index `i`. + * If there are no further uses or definitions of `v` after `i`, the + * result is the length of this basic block. + */ + private int nextDefOrUseAfter(PurelyLocalVariable v, int i, VarDef d) { + this.defAt(i, v, d) and + result = + min(int j | + (this.defAt(j, v, _) or this.useAt(j, v, _) or j = this.length()) and + j > i + ) + } + + /** + * Holds if `d` defines variable `v` at the `i`th node of this basic block, and + * the definition is live, that is, the variable may be read after this + * definition and before a re-definition. + */ + predicate localLiveDefAt(PurelyLocalVariable v, int i, VarDef d) { + exists(int j | j = this.nextDefOrUseAfter(v, i, d) | + this.useAt(j, v, _) + or + j = this.length() and this.getASuccessor().localIsLiveAtEntry(v) + ) + } + + /** + * Holds if `u` is a use of `v` in this basic block, and there are + * no definitions of `v` before it. + */ + private predicate isLocallyLiveAtEntry(Variable v, VarUse u) { + exists(int n | this.useAt(n, v, u) | not exists(int m | m < n | this.defAt(m, v, _))) + } + + /** + * Holds if `d` is a definition of `v` in this basic block, and there are + * no other definitions of `v` before it. + */ + private predicate isLocallyOverwritten(Variable v, VarDef d) { + exists(int n | this.defAt(n, v, d) | not exists(int m | m < n | this.defAt(m, v, _))) + } + + /** + * Gets the basic block that immediately dominates this basic block. + */ + ReachableBasicBlock getImmediateDominator() { result = immediateDominator(this) } + + /** + * Holds if this if a basic block whose last node is an exit node. + */ + predicate isExitBlock() { exitBB(this) } +} + +/** + * An unreachable basic block, that is, a basic block + * whose first node is unreachable. + */ +class UnreachableBlock extends BasicBlock { + UnreachableBlock() { this.getFirstNode().isUnreachable() } +} + +/** + * An entry basic block, that is, a basic block + * whose first node is the entry node of a statement container. + */ +class EntryBasicBlock extends BasicBlock { + EntryBasicBlock() { entryBB(this) } +} + +/** + * A basic block that is reachable from an entry basic block. + */ +class ReachableBasicBlock extends BasicBlock { + ReachableBasicBlock() { reachableBB(this) } + + /** + * Holds if this basic block strictly dominates `bb`. + */ + pragma[inline] + predicate strictlyDominates(ReachableBasicBlock bb) { this = immediateDominator+(bb) } + + /** + * Holds if this basic block dominates `bb`. + * + * This predicate is reflexive: each reachable basic block dominates itself. + */ + pragma[inline] + predicate dominates(ReachableBasicBlock bb) { this = immediateDominator*(bb) } + + /** + * Holds if this basic block strictly post-dominates `bb`. + */ + pragma[inline] + predicate strictlyPostDominates(ReachableBasicBlock bb) { this = immediatePostDominator+(bb) } + + /** + * Holds if this basic block post-dominates `bb`. + * + * This predicate is reflexive: each reachable basic block post-dominates itself. + */ + pragma[inline] + predicate postDominates(ReachableBasicBlock bb) { this = immediatePostDominator*(bb) } +} + +/** + * A reachable basic block with more than one predecessor. + */ +class ReachableJoinBlock extends ReachableBasicBlock { + ReachableJoinBlock() { this.getFirstNode().isJoin() } + + /** + * Holds if this basic block belongs to the dominance frontier of `b`, that is + * `b` dominates a predecessor of this block, but not this block itself. + * + * Algorithm from Cooper et al., "A Simple, Fast Dominance Algorithm" (Figure 5), + * who in turn attribute it to Ferrante et al., "The program dependence graph and + * its use in optimization". + */ + predicate inDominanceFrontierOf(ReachableBasicBlock b) { + b = this.getAPredecessor() and not b = this.getImmediateDominator() + or + exists(ReachableBasicBlock prev | this.inDominanceFrontierOf(prev) | + b = prev.getImmediateDominator() and + not b = this.getImmediateDominator() + ) + } +} From 3b663bd2f6fa09e886c8e6478abf83297796ccd7 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Sep 2024 10:32:14 +0200 Subject: [PATCH 303/514] JS: Remove BasicBlockInternal module and mark relevant predicates as public This exposes the predicates publicly, but will be hidden again in the next commit. --- .../javascript/dataflow/internal/sharedlib/Ssa.qll | 4 ++-- .../semmle/javascript/internal/BasicBlockInternal.qll | 11 ++--------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll index 03b73121b1e..65b705368e7 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll @@ -6,6 +6,7 @@ private import javascript as js private import codeql.ssa.Ssa +private import semmle.javascript.internal.BasicBlockInternal as BasicBlockInternal private module SsaConfig implements InputSig { class ControlFlowNode = js::ControlFlowNode; @@ -38,8 +39,7 @@ private module SsaConfig implements InputSig { bb.useAt(i, v, _) and certain = true } - predicate getImmediateBasicBlockDominator = - js::BasicBlockInternal::getImmediateBasicBlockDominator/1; + predicate getImmediateBasicBlockDominator = BasicBlockInternal::immediateDominator/1; pragma[inline] BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() } diff --git a/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll b/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll index ef8ff1545b3..dae3a727f83 100644 --- a/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll +++ b/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll @@ -7,11 +7,6 @@ import javascript private import semmle.javascript.internal.StmtContainers private import semmle.javascript.internal.CachedStages -module BasicBlockInternal { - // TODO: Expose these as public predicate in a private module instead of this hack. - predicate getImmediateBasicBlockDominator = immediateDominator/1; -} - /** * Holds if `nd` starts a new basic block. */ @@ -109,13 +104,11 @@ private import Internal /** Gets the immediate dominator of `bb`. */ cached -private BasicBlock immediateDominator(BasicBlock bb) = - idominance(entryBB/1, succBB/2)(_, result, bb) +BasicBlock immediateDominator(BasicBlock bb) = idominance(entryBB/1, succBB/2)(_, result, bb) /** Gets the immediate post-dominator of `bb`. */ cached -private BasicBlock immediatePostDominator(BasicBlock bb) = - idominance(exitBB/1, predBB/2)(_, result, bb) +BasicBlock immediatePostDominator(BasicBlock bb) = idominance(exitBB/1, predBB/2)(_, result, bb) /** * A basic block, that is, a maximal straight-line sequence of control flow nodes From ed0af958a9ccb384907c1bb584f3647f593b32b4 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Sep 2024 10:33:30 +0200 Subject: [PATCH 304/514] JS: Add Public module and only expose that Indentation will be fixed in next commit --- javascript/ql/lib/semmle/javascript/BasicBlocks.qll | 2 +- .../ql/lib/semmle/javascript/internal/BasicBlockInternal.qll | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/BasicBlocks.qll b/javascript/ql/lib/semmle/javascript/BasicBlocks.qll index a6ce180d5ec..1b377bd0dd5 100644 --- a/javascript/ql/lib/semmle/javascript/BasicBlocks.qll +++ b/javascript/ql/lib/semmle/javascript/BasicBlocks.qll @@ -1 +1 @@ -import internal.BasicBlockInternal +import internal.BasicBlockInternal::Public diff --git a/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll b/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll index dae3a727f83..dd28852aae9 100644 --- a/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll +++ b/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll @@ -110,6 +110,9 @@ BasicBlock immediateDominator(BasicBlock bb) = idominance(entryBB/1, succBB/2)(_ cached BasicBlock immediatePostDominator(BasicBlock bb) = idominance(exitBB/1, predBB/2)(_, result, bb) +import Public + +module Public { /** * A basic block, that is, a maximal straight-line sequence of control flow nodes * without branches or joins. @@ -359,3 +362,5 @@ class ReachableJoinBlock extends ReachableBasicBlock { ) } } + +} \ No newline at end of file From 3fca27bee22f2bfc4ad098d0e0204b6aa73ab3a8 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Sep 2024 10:33:47 +0200 Subject: [PATCH 305/514] JS: Fix indentation Only formatting changes --- .../internal/BasicBlockInternal.qll | 439 +++++++++--------- 1 file changed, 219 insertions(+), 220 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll b/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll index dd28852aae9..c7b7aa29404 100644 --- a/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll +++ b/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll @@ -113,254 +113,253 @@ BasicBlock immediatePostDominator(BasicBlock bb) = idominance(exitBB/1, predBB/2 import Public module Public { -/** - * A basic block, that is, a maximal straight-line sequence of control flow nodes - * without branches or joins. - * - * At the database level, a basic block is represented by its first control flow node. - */ -class BasicBlock extends @cfg_node, NodeInStmtContainer { - cached - BasicBlock() { Stages::BasicBlocks::ref() and startsBB(this) } - - /** Gets a basic block succeeding this one. */ - BasicBlock getASuccessor() { succBB(this, result) } - - /** Gets a basic block preceding this one. */ - BasicBlock getAPredecessor() { result.getASuccessor() = this } - - /** Gets a node in this block. */ - ControlFlowNode getANode() { result = this.getNode(_) } - - /** Gets the node at the given position in this block. */ - ControlFlowNode getNode(int pos) { bbIndex(this, result, pos) } - - /** Gets the first node in this block. */ - ControlFlowNode getFirstNode() { result = this } - - /** Gets the last node in this block. */ - ControlFlowNode getLastNode() { result = this.getNode(this.length() - 1) } - - /** Gets the length of this block. */ - int length() { result = bbLength(this) } - - /** Holds if this basic block uses variable `v` in its `i`th node `u`. */ - predicate useAt(int i, Variable v, VarUse u) { useAt(this, i, v, u) } - - /** Holds if this basic block defines variable `v` in its `i`th node `d`. */ - predicate defAt(int i, Variable v, VarDef d) { defAt(this, i, v, d) } - /** - * Holds if `v` is live at entry to this basic block and `u` is a use of `v` - * witnessing the liveness. + * A basic block, that is, a maximal straight-line sequence of control flow nodes + * without branches or joins. * - * In other words, `u` is a use of `v` that is reachable from the - * entry node of this basic block without going through a redefinition - * of `v`. The use `u` may either be in this basic block, or in another - * basic block reachable from this one. + * At the database level, a basic block is represented by its first control flow node. */ - predicate isLiveAtEntry(Variable v, VarUse u) { - // restrict `u` to be reachable from this basic block - u = this.getASuccessor*().getANode() and - ( - // shortcut: if `v` is never defined, then it must be live - this.isDefinedInSameContainer(v) - implies - // otherwise, do full liveness computation - this.isLiveAtEntryImpl(v, u) - ) - } + class BasicBlock extends @cfg_node, NodeInStmtContainer { + cached + BasicBlock() { Stages::BasicBlocks::ref() and startsBB(this) } - /** - * Holds if `v` is live at entry to this basic block and `u` is a use of `v` - * witnessing the liveness, where `v` is defined at least once in the enclosing - * function or script. - */ - private predicate isLiveAtEntryImpl(Variable v, VarUse u) { - this.isLocallyLiveAtEntry(v, u) - or - this.isDefinedInSameContainer(v) and - not this.defAt(_, v, _) and - this.getASuccessor().isLiveAtEntryImpl(v, u) - } + /** Gets a basic block succeeding this one. */ + BasicBlock getASuccessor() { succBB(this, result) } - /** - * Holds if `v` is defined at least once in the function or script to which - * this basic block belongs. - */ - private predicate isDefinedInSameContainer(Variable v) { - exists(VarDef def | def.getAVariable() = v and def.getContainer() = this.getContainer()) - } + /** Gets a basic block preceding this one. */ + BasicBlock getAPredecessor() { result.getASuccessor() = this } - /** - * Holds if `v` is a variable that is live at entry to this basic block. - * - * Note that this is equivalent to `bb.isLiveAtEntry(v, _)`, but may - * be more efficient on large databases. - */ - predicate isLiveAtEntry(Variable v) { - this.isLocallyLiveAtEntry(v, _) - or - not this.defAt(_, v, _) and this.getASuccessor().isLiveAtEntry(v) - } + /** Gets a node in this block. */ + ControlFlowNode getANode() { result = this.getNode(_) } - /** - * Holds if local variable `v` is live at entry to this basic block and - * `u` is a use of `v` witnessing the liveness. - */ - predicate localIsLiveAtEntry(LocalVariable v, VarUse u) { - this.isLocallyLiveAtEntry(v, u) - or - not this.defAt(_, v, _) and this.getASuccessor().localIsLiveAtEntry(v, u) - } + /** Gets the node at the given position in this block. */ + ControlFlowNode getNode(int pos) { bbIndex(this, result, pos) } - /** - * Holds if local variable `v` is live at entry to this basic block. - */ - predicate localIsLiveAtEntry(LocalVariable v) { - this.isLocallyLiveAtEntry(v, _) - or - not this.defAt(_, v, _) and this.getASuccessor().localIsLiveAtEntry(v) - } + /** Gets the first node in this block. */ + ControlFlowNode getFirstNode() { result = this } - /** - * Holds if `d` is a definition of `v` that is reachable from the beginning of - * this basic block without going through a redefinition of `v`. - */ - predicate localMayBeOverwritten(LocalVariable v, VarDef d) { - this.isLocallyOverwritten(v, d) - or - not this.defAt(_, v, _) and this.getASuccessor().localMayBeOverwritten(v, d) - } + /** Gets the last node in this block. */ + ControlFlowNode getLastNode() { result = this.getNode(this.length() - 1) } - /** - * Gets the next index after `i` in this basic block at which `v` is - * defined or used, provided that `d` is a definition of `v` at index `i`. - * If there are no further uses or definitions of `v` after `i`, the - * result is the length of this basic block. - */ - private int nextDefOrUseAfter(PurelyLocalVariable v, int i, VarDef d) { - this.defAt(i, v, d) and - result = - min(int j | - (this.defAt(j, v, _) or this.useAt(j, v, _) or j = this.length()) and - j > i + /** Gets the length of this block. */ + int length() { result = bbLength(this) } + + /** Holds if this basic block uses variable `v` in its `i`th node `u`. */ + predicate useAt(int i, Variable v, VarUse u) { useAt(this, i, v, u) } + + /** Holds if this basic block defines variable `v` in its `i`th node `d`. */ + predicate defAt(int i, Variable v, VarDef d) { defAt(this, i, v, d) } + + /** + * Holds if `v` is live at entry to this basic block and `u` is a use of `v` + * witnessing the liveness. + * + * In other words, `u` is a use of `v` that is reachable from the + * entry node of this basic block without going through a redefinition + * of `v`. The use `u` may either be in this basic block, or in another + * basic block reachable from this one. + */ + predicate isLiveAtEntry(Variable v, VarUse u) { + // restrict `u` to be reachable from this basic block + u = this.getASuccessor*().getANode() and + ( + // shortcut: if `v` is never defined, then it must be live + this.isDefinedInSameContainer(v) + implies + // otherwise, do full liveness computation + this.isLiveAtEntryImpl(v, u) ) - } + } - /** - * Holds if `d` defines variable `v` at the `i`th node of this basic block, and - * the definition is live, that is, the variable may be read after this - * definition and before a re-definition. - */ - predicate localLiveDefAt(PurelyLocalVariable v, int i, VarDef d) { - exists(int j | j = this.nextDefOrUseAfter(v, i, d) | - this.useAt(j, v, _) + /** + * Holds if `v` is live at entry to this basic block and `u` is a use of `v` + * witnessing the liveness, where `v` is defined at least once in the enclosing + * function or script. + */ + private predicate isLiveAtEntryImpl(Variable v, VarUse u) { + this.isLocallyLiveAtEntry(v, u) or - j = this.length() and this.getASuccessor().localIsLiveAtEntry(v) - ) + this.isDefinedInSameContainer(v) and + not this.defAt(_, v, _) and + this.getASuccessor().isLiveAtEntryImpl(v, u) + } + + /** + * Holds if `v` is defined at least once in the function or script to which + * this basic block belongs. + */ + private predicate isDefinedInSameContainer(Variable v) { + exists(VarDef def | def.getAVariable() = v and def.getContainer() = this.getContainer()) + } + + /** + * Holds if `v` is a variable that is live at entry to this basic block. + * + * Note that this is equivalent to `bb.isLiveAtEntry(v, _)`, but may + * be more efficient on large databases. + */ + predicate isLiveAtEntry(Variable v) { + this.isLocallyLiveAtEntry(v, _) + or + not this.defAt(_, v, _) and this.getASuccessor().isLiveAtEntry(v) + } + + /** + * Holds if local variable `v` is live at entry to this basic block and + * `u` is a use of `v` witnessing the liveness. + */ + predicate localIsLiveAtEntry(LocalVariable v, VarUse u) { + this.isLocallyLiveAtEntry(v, u) + or + not this.defAt(_, v, _) and this.getASuccessor().localIsLiveAtEntry(v, u) + } + + /** + * Holds if local variable `v` is live at entry to this basic block. + */ + predicate localIsLiveAtEntry(LocalVariable v) { + this.isLocallyLiveAtEntry(v, _) + or + not this.defAt(_, v, _) and this.getASuccessor().localIsLiveAtEntry(v) + } + + /** + * Holds if `d` is a definition of `v` that is reachable from the beginning of + * this basic block without going through a redefinition of `v`. + */ + predicate localMayBeOverwritten(LocalVariable v, VarDef d) { + this.isLocallyOverwritten(v, d) + or + not this.defAt(_, v, _) and this.getASuccessor().localMayBeOverwritten(v, d) + } + + /** + * Gets the next index after `i` in this basic block at which `v` is + * defined or used, provided that `d` is a definition of `v` at index `i`. + * If there are no further uses or definitions of `v` after `i`, the + * result is the length of this basic block. + */ + private int nextDefOrUseAfter(PurelyLocalVariable v, int i, VarDef d) { + this.defAt(i, v, d) and + result = + min(int j | + (this.defAt(j, v, _) or this.useAt(j, v, _) or j = this.length()) and + j > i + ) + } + + /** + * Holds if `d` defines variable `v` at the `i`th node of this basic block, and + * the definition is live, that is, the variable may be read after this + * definition and before a re-definition. + */ + predicate localLiveDefAt(PurelyLocalVariable v, int i, VarDef d) { + exists(int j | j = this.nextDefOrUseAfter(v, i, d) | + this.useAt(j, v, _) + or + j = this.length() and this.getASuccessor().localIsLiveAtEntry(v) + ) + } + + /** + * Holds if `u` is a use of `v` in this basic block, and there are + * no definitions of `v` before it. + */ + private predicate isLocallyLiveAtEntry(Variable v, VarUse u) { + exists(int n | this.useAt(n, v, u) | not exists(int m | m < n | this.defAt(m, v, _))) + } + + /** + * Holds if `d` is a definition of `v` in this basic block, and there are + * no other definitions of `v` before it. + */ + private predicate isLocallyOverwritten(Variable v, VarDef d) { + exists(int n | this.defAt(n, v, d) | not exists(int m | m < n | this.defAt(m, v, _))) + } + + /** + * Gets the basic block that immediately dominates this basic block. + */ + ReachableBasicBlock getImmediateDominator() { result = immediateDominator(this) } + + /** + * Holds if this if a basic block whose last node is an exit node. + */ + predicate isExitBlock() { exitBB(this) } } /** - * Holds if `u` is a use of `v` in this basic block, and there are - * no definitions of `v` before it. + * An unreachable basic block, that is, a basic block + * whose first node is unreachable. */ - private predicate isLocallyLiveAtEntry(Variable v, VarUse u) { - exists(int n | this.useAt(n, v, u) | not exists(int m | m < n | this.defAt(m, v, _))) + class UnreachableBlock extends BasicBlock { + UnreachableBlock() { this.getFirstNode().isUnreachable() } } /** - * Holds if `d` is a definition of `v` in this basic block, and there are - * no other definitions of `v` before it. + * An entry basic block, that is, a basic block + * whose first node is the entry node of a statement container. */ - private predicate isLocallyOverwritten(Variable v, VarDef d) { - exists(int n | this.defAt(n, v, d) | not exists(int m | m < n | this.defAt(m, v, _))) + class EntryBasicBlock extends BasicBlock { + EntryBasicBlock() { entryBB(this) } } /** - * Gets the basic block that immediately dominates this basic block. + * A basic block that is reachable from an entry basic block. */ - ReachableBasicBlock getImmediateDominator() { result = immediateDominator(this) } + class ReachableBasicBlock extends BasicBlock { + ReachableBasicBlock() { reachableBB(this) } + + /** + * Holds if this basic block strictly dominates `bb`. + */ + pragma[inline] + predicate strictlyDominates(ReachableBasicBlock bb) { this = immediateDominator+(bb) } + + /** + * Holds if this basic block dominates `bb`. + * + * This predicate is reflexive: each reachable basic block dominates itself. + */ + pragma[inline] + predicate dominates(ReachableBasicBlock bb) { this = immediateDominator*(bb) } + + /** + * Holds if this basic block strictly post-dominates `bb`. + */ + pragma[inline] + predicate strictlyPostDominates(ReachableBasicBlock bb) { this = immediatePostDominator+(bb) } + + /** + * Holds if this basic block post-dominates `bb`. + * + * This predicate is reflexive: each reachable basic block post-dominates itself. + */ + pragma[inline] + predicate postDominates(ReachableBasicBlock bb) { this = immediatePostDominator*(bb) } + } /** - * Holds if this if a basic block whose last node is an exit node. + * A reachable basic block with more than one predecessor. */ - predicate isExitBlock() { exitBB(this) } -} + class ReachableJoinBlock extends ReachableBasicBlock { + ReachableJoinBlock() { this.getFirstNode().isJoin() } -/** - * An unreachable basic block, that is, a basic block - * whose first node is unreachable. - */ -class UnreachableBlock extends BasicBlock { - UnreachableBlock() { this.getFirstNode().isUnreachable() } -} - -/** - * An entry basic block, that is, a basic block - * whose first node is the entry node of a statement container. - */ -class EntryBasicBlock extends BasicBlock { - EntryBasicBlock() { entryBB(this) } -} - -/** - * A basic block that is reachable from an entry basic block. - */ -class ReachableBasicBlock extends BasicBlock { - ReachableBasicBlock() { reachableBB(this) } - - /** - * Holds if this basic block strictly dominates `bb`. - */ - pragma[inline] - predicate strictlyDominates(ReachableBasicBlock bb) { this = immediateDominator+(bb) } - - /** - * Holds if this basic block dominates `bb`. - * - * This predicate is reflexive: each reachable basic block dominates itself. - */ - pragma[inline] - predicate dominates(ReachableBasicBlock bb) { this = immediateDominator*(bb) } - - /** - * Holds if this basic block strictly post-dominates `bb`. - */ - pragma[inline] - predicate strictlyPostDominates(ReachableBasicBlock bb) { this = immediatePostDominator+(bb) } - - /** - * Holds if this basic block post-dominates `bb`. - * - * This predicate is reflexive: each reachable basic block post-dominates itself. - */ - pragma[inline] - predicate postDominates(ReachableBasicBlock bb) { this = immediatePostDominator*(bb) } -} - -/** - * A reachable basic block with more than one predecessor. - */ -class ReachableJoinBlock extends ReachableBasicBlock { - ReachableJoinBlock() { this.getFirstNode().isJoin() } - - /** - * Holds if this basic block belongs to the dominance frontier of `b`, that is - * `b` dominates a predecessor of this block, but not this block itself. - * - * Algorithm from Cooper et al., "A Simple, Fast Dominance Algorithm" (Figure 5), - * who in turn attribute it to Ferrante et al., "The program dependence graph and - * its use in optimization". - */ - predicate inDominanceFrontierOf(ReachableBasicBlock b) { - b = this.getAPredecessor() and not b = this.getImmediateDominator() - or - exists(ReachableBasicBlock prev | this.inDominanceFrontierOf(prev) | - b = prev.getImmediateDominator() and - not b = this.getImmediateDominator() - ) + /** + * Holds if this basic block belongs to the dominance frontier of `b`, that is + * `b` dominates a predecessor of this block, but not this block itself. + * + * Algorithm from Cooper et al., "A Simple, Fast Dominance Algorithm" (Figure 5), + * who in turn attribute it to Ferrante et al., "The program dependence graph and + * its use in optimization". + */ + predicate inDominanceFrontierOf(ReachableBasicBlock b) { + b = this.getAPredecessor() and not b = this.getImmediateDominator() + or + exists(ReachableBasicBlock prev | this.inDominanceFrontierOf(prev) | + b = prev.getImmediateDominator() and + not b = this.getImmediateDominator() + ) + } } } - -} \ No newline at end of file From beaacf96b38a7774db929e20fd9d66f3ba63a4b7 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Sep 2024 10:35:11 +0200 Subject: [PATCH 306/514] JS: Rename Internal -> Cached since whole file is internal now --- .../ql/lib/semmle/javascript/internal/BasicBlockInternal.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll b/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll index c7b7aa29404..c7ad2a1ada8 100644 --- a/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll +++ b/javascript/ql/lib/semmle/javascript/internal/BasicBlockInternal.qll @@ -37,7 +37,7 @@ private predicate entryBB(BasicBlock bb) { bb.getFirstNode() instanceof ControlF private predicate exitBB(BasicBlock bb) { bb.getLastNode() instanceof ControlFlowExitNode } cached -private module Internal { +private module Cached { /** * Holds if `succ` is a control flow successor of `nd` within the same basic block. */ @@ -100,7 +100,7 @@ private module Internal { } } -private import Internal +private import Cached /** Gets the immediate dominator of `bb`. */ cached From 992c144559da30a9a4ec60f4af0762e570bf6c32 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Sep 2024 10:48:25 +0200 Subject: [PATCH 307/514] JS: Add qldoc to file --- javascript/ql/lib/semmle/javascript/BasicBlocks.qll | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/BasicBlocks.qll b/javascript/ql/lib/semmle/javascript/BasicBlocks.qll index 1b377bd0dd5..dfd9c3956b1 100644 --- a/javascript/ql/lib/semmle/javascript/BasicBlocks.qll +++ b/javascript/ql/lib/semmle/javascript/BasicBlocks.qll @@ -1 +1,6 @@ +/** + * Provides classes for working with basic blocks, and predicates for computing + * liveness information for local variables. + */ + import internal.BasicBlockInternal::Public From d626e79ed3111e4649ebada802e413ba3c18970c Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Sep 2024 11:17:31 +0200 Subject: [PATCH 308/514] JS: Add two test cases for missing flow --- .../ql/test/library-tests/TripleDot/useuse.js | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/javascript/ql/test/library-tests/TripleDot/useuse.js b/javascript/ql/test/library-tests/TripleDot/useuse.js index 67999165595..9fff03d0aa2 100644 --- a/javascript/ql/test/library-tests/TripleDot/useuse.js +++ b/javascript/ql/test/library-tests/TripleDot/useuse.js @@ -28,3 +28,26 @@ function t2() { } sink(obj.field); // $ hasValueFlow=t2.1 } + +function t3() { + function inner(obj) { + sink(obj.foo); // $ hasValueFlow=t3.2 MISSING: hasValueFlow=t3.1 + } + + inner({foo: source('t3.1')}); + + let obj = {}; + obj.foo = source('t3.2'); + inner(obj); +} + +function t4() { + class C { + constructor(x) { + this.foo = x; + sink(this.foo); // $ MISSING: hasValueFlow=t4.1 + } + } + const c = new C(source('t4.1')); + sink(c.foo); // $ hasValueFlow=t4.1 +} From 9fc99d6f9db0e58de970d6aadb7a5b3e9b5749b8 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Sep 2024 11:14:51 +0200 Subject: [PATCH 309/514] JS: Fix store into object literals that have a post-update node --- .../dataflow/internal/DataFlowPrivate.qll | 27 ++++++++++++++----- .../ql/test/library-tests/TripleDot/useuse.js | 2 +- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 64a401c384f..aad2543d72f 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1283,15 +1283,28 @@ predicate readStep(Node node1, ContentSet c, Node node2) { } /** Gets the post-update node for which `node` is the corresponding pre-update node. */ -private Node getPostUpdate(Node node) { result.(PostUpdateNode).getPreUpdateNode() = node } +private Node getPostUpdateForStore(Node base) { + // Some nodes have post-update nodes but should not be targeted by a PropWrite store. + // Notably, an object literal can have a post-update node it if is an argument to a call, + // but in this case, we should not target the post-update node, as this would prevent data from + // flowing into the call. + exists(Expr expr | + base = TValueNode(expr) and + result = TExprPostUpdateNode(expr) + | + expr instanceof PropAccess or + expr instanceof VarAccess or + expr instanceof ThisExpr + ) +} -/** Gets the post-update node for which node is the pre-update node, if one exists, otherwise gets `node` itself. */ +/** Gets node to target with a store to the given `base` object.. */ pragma[inline] -private Node tryGetPostUpdate(Node node) { - result = getPostUpdate(node) +private Node getStoreTarget(Node base) { + result = getPostUpdateForStore(base) or - not exists(getPostUpdate(node)) and - result = node + not exists(getPostUpdateForStore(base)) and + result = base } pragma[nomagic] @@ -1309,7 +1322,7 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { node1 = write.getRhs() and c.asPropertyName() = write.getPropertyName() and // Target the post-update node if one exists (for object literals we do not generate post-update nodes) - node2 = tryGetPostUpdate(write.getBase()) + node2 = getStoreTarget(write.getBase()) ) or FlowSummaryPrivate::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c, diff --git a/javascript/ql/test/library-tests/TripleDot/useuse.js b/javascript/ql/test/library-tests/TripleDot/useuse.js index 9fff03d0aa2..c98ea6cf5eb 100644 --- a/javascript/ql/test/library-tests/TripleDot/useuse.js +++ b/javascript/ql/test/library-tests/TripleDot/useuse.js @@ -31,7 +31,7 @@ function t2() { function t3() { function inner(obj) { - sink(obj.foo); // $ hasValueFlow=t3.2 MISSING: hasValueFlow=t3.1 + sink(obj.foo); // $ hasValueFlow=t3.2 hasValueFlow=t3.1 } inner({foo: source('t3.1')}); From c3c003b2751d9b1897f70fb367b82c7506ed33b9 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Sep 2024 13:06:57 +0200 Subject: [PATCH 310/514] JS: Fix post-update flow into 'this' --- .../dataflow/internal/DataFlowNode.qll | 4 +- .../dataflow/internal/DataFlowPrivate.qll | 20 ++--- .../dataflow/internal/VariableOrThis.qll | 76 +++++++++++++++++++ .../dataflow/internal/sharedlib/Ssa.qll | 19 +++-- .../ql/test/library-tests/TripleDot/useuse.js | 2 +- 5 files changed, 104 insertions(+), 17 deletions(-) create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/VariableOrThis.qll diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index 8f718080698..ccfdb592250 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -30,8 +30,8 @@ private module Cached { TValueNode(AST::ValueNode nd) or /** An SSA node from the legacy SSA library */ TSsaDefNode(SsaDefinition d) or - /** Use of a variable with flow from a post-update node (from an earlier use) */ - TSsaUseNode(VarUse use) { use.getVariable() instanceof PurelyLocalVariable } or + /** Use of a variable or 'this', with flow from a post-update node (from an earlier use) */ + TSsaUseNode(Expr use) { use = any(Ssa2::SsaConfig::SourceVariable v).getAnAccess() } or /** Phi-read node (new SSA library). Ordinary phi nodes are represented by TSsaDefNode. */ TSsaPhiReadNode(Ssa2::PhiReadNode phi) or /** Input to a phi node (new SSA library) */ diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index aad2543d72f..b90665f4707 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -5,6 +5,7 @@ private import semmle.javascript.dataflow.internal.FlowSteps as FlowSteps private import semmle.javascript.dataflow.internal.AdditionalFlowInternal private import semmle.javascript.dataflow.internal.Contents::Private private import semmle.javascript.dataflow.internal.VariableCapture +private import semmle.javascript.dataflow.internal.VariableOrThis private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon private import semmle.javascript.dataflow.internal.sharedlib.Ssa as Ssa2 private import semmle.javascript.internal.flow_summaries.AllFlowSummaries @@ -20,18 +21,18 @@ private class Node = DataFlow::Node; class PostUpdateNode = DataFlow::PostUpdateNode; class SsaUseNode extends DataFlow::Node, TSsaUseNode { - private VarAccess access; + private Expr expr; - SsaUseNode() { this = TSsaUseNode(access) } + SsaUseNode() { this = TSsaUseNode(expr) } cached - override string toString() { result = "[ssa-use] " + access.toString() } + override string toString() { result = "[ssa-use] " + expr.toString() } cached - override StmtContainer getContainer() { result = access.getContainer() } + override StmtContainer getContainer() { result = expr.getContainer() } cached - override Location getLocation() { result = access.getLocation() } + override Location getLocation() { result = expr.getLocation() } } class SsaPhiReadNode extends DataFlow::Node, TSsaPhiReadNode { @@ -1056,9 +1057,9 @@ predicate knownSourceModel(Node sink, string model) { none() } predicate knownSinkModel(Node sink, string model) { none() } private predicate samePhi(SsaPhiNode legacyPhi, Ssa2::PhiNode newPhi) { - exists(BasicBlock bb, PurelyLocalVariable v | + exists(BasicBlock bb, LocalVariableOrThis v | newPhi.definesAt(v, bb, _) and - legacyPhi.definesAt(bb, _, v) + legacyPhi.definesAt(bb, _, v.asLocalVariable()) ) } @@ -1082,10 +1083,11 @@ private predicate useUseFlow(Node node1, Node node2) { exists(Ssa2::DefinitionExt def, Ssa2::Node ssa1, Ssa2::Node ssa2, boolean isUseStep | Ssa2::localFlowStep(def, ssa1, ssa2, isUseStep) and node1 = getNodeFromSsa2(ssa1) and - node2 = getNodeFromSsa2(ssa2) + node2 = getNodeFromSsa2(ssa2) and + not node1.getTopLevel().isExterns() ) or - exists(VarUse use | + exists(Expr use | node1 = TSsaUseNode(use) and node2 = TValueNode(use) ) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableOrThis.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableOrThis.qll new file mode 100644 index 00000000000..a465921fb70 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableOrThis.qll @@ -0,0 +1,76 @@ +private import javascript + +cached +private newtype TLocalVariableOrThis = + TLocalVariable(LocalVariable var) or + TThis(StmtContainer container) { not container instanceof ArrowFunctionExpr } + +/** A local variable or `this` in a particular container. */ +class LocalVariableOrThis extends TLocalVariableOrThis { + /** Gets the local variable represented by this newtype, if any. */ + LocalVariable asLocalVariable() { this = TLocalVariable(result) } + + /** If this represents `this`, gets the enclosing container */ + StmtContainer asThisContainer() { this = TThis(result) } + + /** Gets the name of the variable or the string `"this"`. */ + string toString() { result = this.getName() } + + /** Gets the name of the variable or the string `"this"`. */ + string getName() { + result = this.asLocalVariable().getName() + or + this instanceof TThis and result = "this" + } + + /** Gets the location of a declaration of this variable, or the declaring container if this is `this`. */ + DbLocation getLocation() { + result = this.asLocalVariable().getLocation() + or + result = this.asThisContainer().getLocation() + } + + /** Holds if this is a captured variable or captured `this`. */ + predicate isCaptured() { + this.asLocalVariable().isCaptured() + or + hasCapturedThis(this.asThisContainer()) + } + + /** Gets the container declaring this variable or is the enclosing container for `this`. */ + StmtContainer getDeclaringContainer() { + result = this.asLocalVariable().getDeclaringContainer() + or + result = this.asThisContainer() + } + + /** Gets an access to `this` represented by this value. */ + ThisExpr getAThisAccess() { result.getBindingContainer() = this.asThisContainer() } + + /** Gets an access to variable or `this`. */ + Expr getAnAccess() { + result = this.asLocalVariable().getAnAccess() + or + result = this.getAThisAccess() + } +} + +bindingset[c1, c2] +pragma[inline_late] +private predicate sameContainer(StmtContainer c1, StmtContainer c2) { c1 = c2 } + +pragma[nomagic] +private predicate hasCapturedThis(StmtContainer c) { + exists(ThisExpr expr | + expr.getBindingContainer() = c and + not sameContainer(c, expr.getContainer()) + ) +} + +module LocalVariableOrThis { + /** Gets the representation of the given local variable. */ + LocalVariableOrThis variable(LocalVariable v) { result.asLocalVariable() = v } + + /** Gets the representation of `this` in the given container. */ + LocalVariableOrThis thisInContainer(StmtContainer c) { result = TThis(c) } +} diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll index 65b705368e7..f26a52d457b 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll @@ -7,8 +7,9 @@ private import javascript as js private import codeql.ssa.Ssa private import semmle.javascript.internal.BasicBlockInternal as BasicBlockInternal +private import semmle.javascript.dataflow.internal.VariableOrThis -private module SsaConfig implements InputSig { +module SsaConfig implements InputSig { class ControlFlowNode = js::ControlFlowNode; class BasicBlock = js::BasicBlock; @@ -17,7 +18,9 @@ private module SsaConfig implements InputSig { ExitBasicBlock() { this.isExitBlock() } } - class SourceVariable = js::PurelyLocalVariable; // TODO: include 'this' as it is relevant for use-use flow + class SourceVariable extends LocalVariableOrThis { + SourceVariable() { not this.isCaptured() } + } pragma[nomagic] private js::EntryBasicBlock getEntryBlock(js::StmtContainer container) { @@ -27,7 +30,7 @@ private module SsaConfig implements InputSig { predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) { certain = true and ( - bb.defAt(i, v, _) + bb.defAt(i, v.asLocalVariable(), _) or // Implicit initialization and function parameters bb = getEntryBlock(v.getDeclaringContainer()) and @@ -36,7 +39,11 @@ private module SsaConfig implements InputSig { } predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) { - bb.useAt(i, v, _) and certain = true + bb.useAt(i, v.asLocalVariable(), _) and certain = true + or + certain = true and + bb.getNode(i) = v.getAThisAccess() + // TODO: also account for: super() and field initialisers } predicate getImmediateBasicBlockDominator = BasicBlockInternal::immediateDominator/1; @@ -48,7 +55,9 @@ private module SsaConfig implements InputSig { import Make private module SsaDataflowInput implements DataFlowIntegrationInputSig { - class Expr extends js::VarUse { + class Expr extends js::Expr { + Expr() { this = any(SsaConfig::SourceVariable v).getAnAccess() } + predicate hasCfgNode(js::BasicBlock bb, int i) { this = bb.getNode(i) } } diff --git a/javascript/ql/test/library-tests/TripleDot/useuse.js b/javascript/ql/test/library-tests/TripleDot/useuse.js index c98ea6cf5eb..1f54527dab9 100644 --- a/javascript/ql/test/library-tests/TripleDot/useuse.js +++ b/javascript/ql/test/library-tests/TripleDot/useuse.js @@ -45,7 +45,7 @@ function t4() { class C { constructor(x) { this.foo = x; - sink(this.foo); // $ MISSING: hasValueFlow=t4.1 + sink(this.foo); // $ hasValueFlow=t4.1 } } const c = new C(source('t4.1')); From 8dc0505f84134e83bc27d65bd901fad81fa078dd Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Sep 2024 13:08:41 +0200 Subject: [PATCH 311/514] JS: Add test for missing flow into 'this' in field initializers --- javascript/ql/test/library-tests/TripleDot/useuse.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/javascript/ql/test/library-tests/TripleDot/useuse.js b/javascript/ql/test/library-tests/TripleDot/useuse.js index 1f54527dab9..6c1017b54bc 100644 --- a/javascript/ql/test/library-tests/TripleDot/useuse.js +++ b/javascript/ql/test/library-tests/TripleDot/useuse.js @@ -51,3 +51,14 @@ function t4() { const c = new C(source('t4.1')); sink(c.foo); // $ hasValueFlow=t4.1 } + +function t5() { + class C { + field = source('t5.1') + constructor() { + sink(this.field); // $ hasValueFlow=t5.1 + } + } + const c = new C(); + sink(c.field); // $ MISSING: hasValueFlow=t5.1 +} From d31499d72795dac4ccd70f06d2def75e187bdb69 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Sep 2024 14:11:51 +0200 Subject: [PATCH 312/514] JS: introduce implicit this uses in general --- .../semmle/javascript/dataflow/DataFlow.qll | 48 ++++++++------- .../dataflow/internal/DataFlowNode.qll | 13 ++-- .../dataflow/internal/DataFlowPrivate.qll | 34 +++++++---- .../dataflow/internal/VariableOrThis.qll | 61 +++++++++++++++++-- .../dataflow/internal/sharedlib/Ssa.qll | 7 +-- .../ql/test/library-tests/TripleDot/useuse.js | 2 +- 6 files changed, 115 insertions(+), 50 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index 433cf286c34..263e5cdc007 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -26,6 +26,7 @@ private import internal.AnalyzedParameters private import internal.PreCallGraphStep private import semmle.javascript.internal.CachedStages private import semmle.javascript.dataflow.internal.DataFlowPrivate as Private +private import semmle.javascript.dataflow.internal.VariableOrThis module DataFlow { /** @@ -729,9 +730,7 @@ module DataFlow { private class ParameterFieldAsPropWrite extends PropWrite, PropNode { override ParameterField prop; - override Node getBase() { - thisNode(result, prop.getDeclaringClass().getConstructor().getBody()) - } + override Node getBase() { result = TImplicitThisUse(prop, false) } override Expr getPropertyNameExpr() { none() // The parameter value is not the name of the field @@ -758,9 +757,7 @@ module DataFlow { exists(prop.getInit()) } - override Node getBase() { - thisNode(result, prop.getDeclaringClass().getConstructor().getBody()) - } + override Node getBase() { result = TImplicitThisUse(prop, false) } override Expr getPropertyNameExpr() { result = prop.getNameExpr() } @@ -1045,12 +1042,12 @@ module DataFlow { } /** - * A node representing the value passed as `this` argument in a `new` call or a `super` call. + * A node representing the value passed as `this` argument in a `new` call. */ - class ConstructorThisArgumentNode extends TConstructorThisArgumentNode, DataFlow::Node { - private InvokeExpr expr; + class NewCallThisArgumentNode extends TNewCallThisArgument, DataFlow::Node { + private NewExpr expr; - ConstructorThisArgumentNode() { this = TConstructorThisArgumentNode(expr) } + NewCallThisArgumentNode() { this = TNewCallThisArgument(expr) } override string toString() { result = "implicit 'this' argument of " + expr } @@ -1060,18 +1057,23 @@ module DataFlow { } /** - * A node representing the post-update node corresponding to implicit uses of `this` in a constructor. + * A node representing an implicit use of `this` or its post-update node. */ - private class ConstructorThisPostUpdateNode extends TConstructorThisPostUpdate, DataFlow::Node { - private Function constructor; + private class ImplicitThisUseNode extends TImplicitThisUse, DataFlow::Node { + private ImplicitThisUse use; + private boolean isPost; - ConstructorThisPostUpdateNode() { this = TConstructorThisPostUpdate(constructor) } + ImplicitThisUseNode() { this = TImplicitThisUse(use, isPost) } - override string toString() { result = "[post-update] 'this' parameter of " + constructor } + override string toString() { + if isPost = false + then result = "implicit 'this'" + else result = "[post-update] implicit 'this'" + } - override StmtContainer getContainer() { result = constructor } + override StmtContainer getContainer() { result = use.getUseContainer() } - override Location getLocation() { result = constructor.getLocation() } + override Location getLocation() { result = use.getLocation() } } /** @@ -1682,6 +1684,12 @@ module DataFlow { pred = TReflectiveCallNode(call, _) and succ = TValueNode(call) ) + or + // Pass 'this' into implicit uses of 'this' + exists(ImplicitThisUse use | + pred = TThisNode(use.getBindingContainer()) and + succ = TImplicitThisUse(use, false) + ) } pragma[nomagic] @@ -1772,12 +1780,6 @@ module DataFlow { pred = TReflectiveParametersNode(f) and succ = TValueNode(f.getArgumentsVariable().getAnAccess()) ) - or - // Pass 'this' into super calls - exists(SuperCall call | - pred = TThisNode(call.getBinder()) and - succ = TConstructorThisArgumentNode(call) - ) } private class ReflectiveParamsStep extends LegacyPreCallGraphStep { diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index ccfdb592250..6d2be5a1537 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -5,6 +5,7 @@ */ private import javascript +private import codeql.util.Boolean private import semmle.javascript.dataflow.internal.AdditionalFlowInternal private import semmle.javascript.dataflow.internal.Contents::Private private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon @@ -13,6 +14,7 @@ private import semmle.javascript.dataflow.internal.DataFlowPrivate as DataFlowPr private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as FlowSummaryImpl private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate private import semmle.javascript.dataflow.internal.VariableCapture as VariableCapture +private import semmle.javascript.dataflow.internal.VariableOrThis cached private module Cached { @@ -31,7 +33,7 @@ private module Cached { /** An SSA node from the legacy SSA library */ TSsaDefNode(SsaDefinition d) or /** Use of a variable or 'this', with flow from a post-update node (from an earlier use) */ - TSsaUseNode(Expr use) { use = any(Ssa2::SsaConfig::SourceVariable v).getAnAccess() } or + TSsaUseNode(ControlFlowNode use) { use = any(Ssa2::SsaConfig::SourceVariable v).getAUse() } or /** Phi-read node (new SSA library). Ordinary phi nodes are represented by TSsaDefNode. */ TSsaPhiReadNode(Ssa2::PhiReadNode phi) or /** Input to a phi node (new SSA library) */ @@ -88,8 +90,8 @@ private module Cached { // The RHS of an assignment can be an argument to a setter-call, so it needs a post-update node e = any(Assignment asn | asn.getTarget() instanceof PropAccess).getRhs() } or - TConstructorThisArgumentNode(InvokeExpr e) { e instanceof NewExpr or e instanceof SuperCall } or - TConstructorThisPostUpdate(Constructor ctor) or + TNewCallThisArgument(NewExpr e) or + TImplicitThisUse(ImplicitThisUse use, Boolean isPost) or TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or TFlowSummaryDynamicParameterArrayNode(FlowSummaryImpl::Public::SummarizedCallable callable) or TFlowSummaryIntermediateAwaitStoreNode(FlowSummaryImpl::Private::SummaryNode sn) { @@ -130,8 +132,9 @@ private class TEarlyStageNode = TFunctionSelfReferenceNode or TDestructuredModuleImportNode or THtmlAttributeNode or TFunctionReturnNode or TExceptionalFunctionReturnNode or TExceptionalInvocationReturnNode or TGlobalAccessPathRoot or TTemplatePlaceholderTag or TReflectiveParametersNode or - TExprPostUpdateNode or TConstructorThisArgumentNode or TStaticArgumentArrayNode or - TDynamicArgumentArrayNode or TStaticParameterArrayNode or TDynamicParameterArrayNode; + TExprPostUpdateNode or TNewCallThisArgument or TStaticArgumentArrayNode or + TDynamicArgumentArrayNode or TStaticParameterArrayNode or TDynamicParameterArrayNode or + TImplicitThisUse; /** * A data-flow node that is not a flow summary node. diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index b90665f4707..608554c1893 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -21,7 +21,7 @@ private class Node = DataFlow::Node; class PostUpdateNode = DataFlow::PostUpdateNode; class SsaUseNode extends DataFlow::Node, TSsaUseNode { - private Expr expr; + private ControlFlowNode expr; SsaUseNode() { this = TSsaUseNode(expr) } @@ -333,18 +333,13 @@ predicate postUpdatePair(Node pre, Node post) { ) or exists(NewExpr expr | - pre = TConstructorThisArgumentNode(expr) and + pre = TNewCallThisArgument(expr) and post = TValueNode(expr) ) or - exists(SuperCall expr | - pre = TConstructorThisArgumentNode(expr) and - post = TConstructorThisPostUpdate(expr.getBinder()) - ) - or - exists(Function constructor | - pre = TThisNode(constructor) and - post = TConstructorThisPostUpdate(constructor) + exists(ImplicitThisUse use | + pre = TImplicitThisUse(use, false) and + post = TImplicitThisUse(use, true) ) or FlowSummaryImpl::Private::summaryPostUpdateNode(post.(FlowSummaryNode).getSummaryNode(), @@ -473,7 +468,7 @@ private predicate isArgumentNodeImpl(Node n, DataFlowCall call, ArgumentPosition pos.isThis() ) or - pos.isThis() and n = TConstructorThisArgumentNode(call.asOrdinaryCall().asExpr()) + pos.isThis() and n = TNewCallThisArgument(call.asOrdinaryCall().asExpr()) or // receiver of accessor call pos.isThis() and n = call.asAccessorCall().getBase() @@ -1068,6 +1063,11 @@ private Node getNodeFromSsa2(Ssa2::Node node) { or result = TExprPostUpdateNode(node.(Ssa2::ExprPostUpdateNode).getExpr()) or + exists(ImplicitThisUse use | + node.(Ssa2::ExprPostUpdateNode).getExpr() = use and + result = TImplicitThisUse(use, true) + ) + or result = TSsaPhiReadNode(node.(Ssa2::SsaDefinitionExtNode).getDefinitionExt()) or result = TSsaInputNode(node.(Ssa2::SsaInputNode)) @@ -1091,6 +1091,11 @@ private predicate useUseFlow(Node node1, Node node2) { node1 = TSsaUseNode(use) and node2 = TValueNode(use) ) + or + exists(ImplicitThisUse use | + node1 = TSsaUseNode(use) and + node2 = TImplicitThisUse(use, false) + ) } predicate simpleLocalFlowStep(Node node1, Node node2, string model) { @@ -1298,11 +1303,16 @@ private Node getPostUpdateForStore(Node base) { expr instanceof VarAccess or expr instanceof ThisExpr ) + or + exists(ImplicitThisUse use | + base = TImplicitThisUse(use, false) and + result = TImplicitThisUse(use, true) + ) } /** Gets node to target with a store to the given `base` object.. */ pragma[inline] -private Node getStoreTarget(Node base) { +private Node getStoreTarget(DataFlow::Node base) { result = getPostUpdateForStore(base) or not exists(getPostUpdateForStore(base)) and diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableOrThis.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableOrThis.qll index a465921fb70..92a3ad24d81 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableOrThis.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableOrThis.qll @@ -1,4 +1,5 @@ private import javascript +private import DataFlowNode cached private newtype TLocalVariableOrThis = @@ -44,14 +45,17 @@ class LocalVariableOrThis extends TLocalVariableOrThis { result = this.asThisContainer() } - /** Gets an access to `this` represented by this value. */ - ThisExpr getAThisAccess() { result.getBindingContainer() = this.asThisContainer() } + /** Gets an explicit access to `this` represented by this value. */ + ThisExpr getAThisExpr() { result.getBindingContainer() = this.asThisContainer() } - /** Gets an access to variable or `this`. */ - Expr getAnAccess() { + /** Gets an implicit or explicit use of the `this` represented by this value. */ + ThisUse getAThisUse() { result.getBindingContainer() = this.asThisContainer() } + + /** Gets an expression that accesses this variable or `this`. */ + ControlFlowNode getAUse() { result = this.asLocalVariable().getAnAccess() or - result = this.getAThisAccess() + result = this.getAThisUse() } } @@ -74,3 +78,50 @@ module LocalVariableOrThis { /** Gets the representation of `this` in the given container. */ LocalVariableOrThis thisInContainer(StmtContainer c) { result = TThis(c) } } + +/** + * An explicit or implicit use of `this`. + * + * Implicit uses include `super()` calls and instance field initializers (which includes TypeScript parameter fields). + */ +abstract class ThisUse instanceof ControlFlowNode { + /** Gets the container binding the `this` being accessed */ + abstract StmtContainer getBindingContainer(); + + abstract StmtContainer getUseContainer(); + + string toString() { result = super.toString() } + + DbLocation getLocation() { result = super.getLocation() } +} + +private predicate implicitThisUse(ControlFlowNode node, StmtContainer thisBinder) { + thisBinder = node.(SuperExpr).getBinder() + or + exists(FieldDefinition field | + not field.isStatic() and + node = field and + thisBinder = field.getDeclaringClass().getConstructor().getBody() + ) +} + +class ImplicitThisUse extends ThisUse { + ImplicitThisUse() { implicitThisUse(this, _) } + + override StmtContainer getBindingContainer() { implicitThisUse(this, result) } + + override StmtContainer getUseContainer() { + // The following differs from FieldDefinition.getContainer() which returns the container enclosing + // the class, not the class constructor. + // TODO: consider changing this in FieldDefinition.getContainer() + result = this.(FieldDefinition).getDeclaringClass().getConstructor().getBody() + or + result = this.(SuperExpr).getContainer() + } +} + +private class ExplicitThisUse extends ThisUse instanceof ThisExpr { + override StmtContainer getBindingContainer() { result = ThisExpr.super.getBindingContainer() } + + override StmtContainer getUseContainer() { result = ThisExpr.super.getContainer() } +} diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll index f26a52d457b..c2f3696a7ba 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll @@ -42,8 +42,7 @@ module SsaConfig implements InputSig { bb.useAt(i, v.asLocalVariable(), _) and certain = true or certain = true and - bb.getNode(i) = v.getAThisAccess() - // TODO: also account for: super() and field initialisers + bb.getNode(i).(ThisUse).getBindingContainer() = v.asThisContainer() } predicate getImmediateBasicBlockDominator = BasicBlockInternal::immediateDominator/1; @@ -55,8 +54,8 @@ module SsaConfig implements InputSig { import Make private module SsaDataflowInput implements DataFlowIntegrationInputSig { - class Expr extends js::Expr { - Expr() { this = any(SsaConfig::SourceVariable v).getAnAccess() } + class Expr extends js::ControlFlowNode { + Expr() { this = any(SsaConfig::SourceVariable v).getAUse() } predicate hasCfgNode(js::BasicBlock bb, int i) { this = bb.getNode(i) } } diff --git a/javascript/ql/test/library-tests/TripleDot/useuse.js b/javascript/ql/test/library-tests/TripleDot/useuse.js index 6c1017b54bc..8a11eaa933f 100644 --- a/javascript/ql/test/library-tests/TripleDot/useuse.js +++ b/javascript/ql/test/library-tests/TripleDot/useuse.js @@ -60,5 +60,5 @@ function t5() { } } const c = new C(); - sink(c.field); // $ MISSING: hasValueFlow=t5.1 + sink(c.field); // $ hasValueFlow=t5.1 } From 0ebe8bdd91751aca58c61bf2fcbdd81895d786fa Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Sep 2024 15:25:46 +0200 Subject: [PATCH 313/514] JS: Add test for missing capture flow for 'this' --- .../ql/test/library-tests/TripleDot/useuse.js | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/javascript/ql/test/library-tests/TripleDot/useuse.js b/javascript/ql/test/library-tests/TripleDot/useuse.js index 8a11eaa933f..a63edab205f 100644 --- a/javascript/ql/test/library-tests/TripleDot/useuse.js +++ b/javascript/ql/test/library-tests/TripleDot/useuse.js @@ -62,3 +62,34 @@ function t5() { const c = new C(); sink(c.field); // $ hasValueFlow=t5.1 } + + +function t6() { + function invoke(fn) { + fn(); + } + class C { + constructor(x, y) { + this.x = x; + invoke(() => { + this.y = y; + }); + + sink(this.x); // $ MISSING: hasValueFlow=t6.1 + sink(this.y); // $ MISSING: hasValueFlow=t6.1 + + invoke(() => { + sink(this.x); // $ MISSING: hasValueFlow=t6.1 + sink(this.y); // $ MISSING: hasValueFlow=t6.2 + }); + + this.methodLike = function() { + sink(this.x); // $ MISSING: hasValueFlow=t6.1 + sink(this.y); // $ MISSING: hasValueFlow=t6.2 + } + } + } + const c = new C(source('t6.1'), source('t6.2')); + sink(c.x); // $ hasValueFlow=t6.1 + sink(c.y); // $ MISSING: hasValueFlow=t6.2 +} From 12370e92103a572a126098067bbd69a5007d475c Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Sep 2024 15:44:32 +0200 Subject: [PATCH 314/514] JS: Use VariableOrThis in variable capture as well --- .../javascript/dataflow/internal/Contents.qll | 5 +-- .../dataflow/internal/DataFlowPrivate.qll | 6 ++-- .../dataflow/internal/VariableCapture.qll | 32 +++++++++++++------ .../ql/test/library-tests/TripleDot/useuse.js | 15 +++++---- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll index a8743423922..23b2311594e 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll @@ -1,6 +1,7 @@ private import javascript private import semmle.javascript.frameworks.data.internal.ApiGraphModels as ApiGraphModels private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate +private import semmle.javascript.dataflow.internal.VariableOrThis private import codeql.dataflow.internal.AccessPathSyntax as AccessPathSyntax module Private { @@ -75,7 +76,7 @@ module Private { MkIteratorError() or MkPromiseValue() or MkPromiseError() or - MkCapturedContent(LocalVariable v) { v.isCaptured() } + MkCapturedContent(LocalVariableOrThis v) { v.isCaptured() } cached newtype TContentSet = @@ -163,7 +164,7 @@ module Public { int asArrayIndex() { result = this.asPropertyName().(PropertyName).asArrayIndex() } /** Gets the captured variable represented by this content, if any. */ - LocalVariable asCapturedVariable() { this = MkCapturedContent(result) } + LocalVariableOrThis asCapturedVariable() { this = MkCapturedContent(result) } /** Holds if this represents values stored at an unknown array index. */ predicate isUnknownArrayElement() { this = MkArrayElementUnknown() } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 608554c1893..5e8a49a6b74 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1022,7 +1022,7 @@ private predicate isBlockedLegacyNode(Node node) { // Note that some variables, such as top-level variables, are still modelled with these nodes (which will result in jump steps). exists(LocalVariable variable | node = TCapturedVariableNode(variable) and - variable instanceof VariableCaptureConfig::CapturedVariable + variable = any(VariableCaptureConfig::CapturedVariable v).asLocalVariable() ) or legacyBarrier(node) @@ -1230,7 +1230,7 @@ predicate readStep(Node node1, ContentSet c, Node node2) { c = ContentSet::arrayElement() ) or - exists(LocalVariable variable | + exists(LocalVariableOrThis variable | VariableCaptureOutput::readStep(getClosureNode(node1), variable, getClosureNode(node2)) and c.asSingleton() = MkCapturedContent(variable) ) @@ -1349,7 +1349,7 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { c = ContentSet::promiseValue() ) or - exists(LocalVariable variable | + exists(LocalVariableOrThis variable | VariableCaptureOutput::storeStep(getClosureNode(node1), variable, getClosureNode(node2)) and c.asSingleton() = MkCapturedContent(variable) ) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll index 8f95c88d72a..247f7690894 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll @@ -1,5 +1,6 @@ private import javascript as js private import semmle.javascript.dataflow.internal.DataFlowNode +private import semmle.javascript.dataflow.internal.VariableOrThis private import codeql.dataflow.VariableCapture private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon @@ -51,7 +52,7 @@ module VariableCaptureConfig implements InputSig { ) } - class CapturedVariable extends js::LocalVariable { + class CapturedVariable extends LocalVariableOrThis { CapturedVariable() { DataFlowImplCommon::forceCachingInSameStage() and this.isCaptured() and @@ -63,7 +64,9 @@ module VariableCaptureConfig implements InputSig { additional predicate captures(js::Function fun, CapturedVariable variable) { ( - variable.getAnAccess().getContainer().getFunctionBoundary() = fun + variable.asLocalVariable().getAnAccess().getContainer().getFunctionBoundary() = fun + or + variable.getAThisUse().getUseContainer() = fun or exists(js::Function inner | captures(inner, variable) and @@ -122,7 +125,8 @@ module VariableCaptureConfig implements InputSig { private predicate isCapturedByOwnInitializer(js::VariableDeclarator decl) { exists(js::Function function | function = getACapturingFunctionInTree(decl.getInit()) and - captures(function, decl.getBindingPattern().(js::VarDecl).getVariable()) + captures(function, + LocalVariableOrThis::variable(decl.getBindingPattern().(js::VarDecl).getVariable())) ) } @@ -141,7 +145,7 @@ module VariableCaptureConfig implements InputSig { } class CapturedParameter extends CapturedVariable { - CapturedParameter() { this.isParameter() } + CapturedParameter() { this.asLocalVariable().isParameter() or exists(this.asThisContainer()) } } class Expr extends js::AST::ValueNode { @@ -152,10 +156,10 @@ module VariableCaptureConfig implements InputSig { } } - class VariableRead extends Expr instanceof js::VarAccess, js::RValue { + class VariableRead extends Expr instanceof js::ControlFlowNode { private CapturedVariable variable; - VariableRead() { this = variable.getAnAccess() } + VariableRead() { this = variable.getAUse() } CapturedVariable getVariable() { result = variable } } @@ -178,7 +182,7 @@ module VariableCaptureConfig implements InputSig { private newtype TVariableWrite = MkExplicitVariableWrite(js::VarRef pattern) { exists(js::DataFlow::lvalueNodeInternal(pattern)) and - pattern.getVariable() instanceof CapturedVariable + any(CapturedVariable v).asLocalVariable() = pattern.getVariable() } or MkImplicitVariableInit(CapturedVariable v) { not v instanceof CapturedParameter } @@ -200,7 +204,7 @@ module VariableCaptureConfig implements InputSig { ExplicitVariableWrite() { this = MkExplicitVariableWrite(pattern) } - override CapturedVariable getVariable() { result = pattern.getVariable() } + override CapturedVariable getVariable() { result.asLocalVariable() = pattern.getVariable() } override string toString() { result = pattern.toString() } @@ -248,7 +252,9 @@ module VariableCaptureConfig implements InputSig { override predicate hasCfgNode(BasicBlock bb, int i) { // 'i' would normally be bound to 0, but we lower it to -1 so FunctionDeclStmts can be evaluated // at index 0. - any(js::SsaImplicitInit def).definesAt(bb, _, variable) and i = -1 + any(js::SsaImplicitInit def).definesAt(bb, _, variable.asLocalVariable()) and i = -1 + or + bb.(js::EntryBasicBlock).getContainer() = variable.asThisContainer() and i = -1 } } @@ -266,7 +272,13 @@ module VariableCaptureOutput = Flow; js::DataFlow::Node getNodeFromClosureNode(VariableCaptureOutput::ClosureNode node) { result = TValueNode(node.(VariableCaptureOutput::ExprNode).getExpr()) or - result = TValueNode(node.(VariableCaptureOutput::ParameterNode).getParameter().getADeclaration()) // TODO: is this subsumed by the ExprNode case? + result = + TValueNode(node.(VariableCaptureOutput::ParameterNode) + .getParameter() + .asLocalVariable() + .getADeclaration()) // TODO: is this subsumed by the ExprNode case? + or + result = TThisNode(node.(VariableCaptureOutput::ParameterNode).getParameter().asThisContainer()) or result = TExprPostUpdateNode(node.(VariableCaptureOutput::ExprPostUpdateNode).getExpr()) or diff --git a/javascript/ql/test/library-tests/TripleDot/useuse.js b/javascript/ql/test/library-tests/TripleDot/useuse.js index a63edab205f..ac7f5fc6cdb 100644 --- a/javascript/ql/test/library-tests/TripleDot/useuse.js +++ b/javascript/ql/test/library-tests/TripleDot/useuse.js @@ -75,21 +75,22 @@ function t6() { this.y = y; }); - sink(this.x); // $ MISSING: hasValueFlow=t6.1 - sink(this.y); // $ MISSING: hasValueFlow=t6.1 + sink(this.x); // $ hasValueFlow=t6.1 + sink(this.y); // $ hasValueFlow=t6.2 invoke(() => { - sink(this.x); // $ MISSING: hasValueFlow=t6.1 - sink(this.y); // $ MISSING: hasValueFlow=t6.2 + sink(this.x); // $ hasValueFlow=t6.1 + sink(this.y); // $ hasValueFlow=t6.2 }); this.methodLike = function() { - sink(this.x); // $ MISSING: hasValueFlow=t6.1 - sink(this.y); // $ MISSING: hasValueFlow=t6.2 + sink(this.x); // $ hasValueFlow=t6.1 + sink(this.y); // $ hasValueFlow=t6.2 } } } const c = new C(source('t6.1'), source('t6.2')); sink(c.x); // $ hasValueFlow=t6.1 - sink(c.y); // $ MISSING: hasValueFlow=t6.2 + sink(c.y); // $ hasValueFlow=t6.2 + c.methodLike(); } From 81af9a1658a11049f832318fc5d1e91224c79815 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 24 Sep 2024 13:31:53 +0200 Subject: [PATCH 315/514] Fix missing flow through super calls --- .../dataflow/internal/DataFlowPrivate.qll | 3 +++ .../ql/test/library-tests/TripleDot/useuse.js | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 5e8a49a6b74..92878f4dc22 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -470,6 +470,9 @@ private predicate isArgumentNodeImpl(Node n, DataFlowCall call, ArgumentPosition or pos.isThis() and n = TNewCallThisArgument(call.asOrdinaryCall().asExpr()) or + pos.isThis() and + n = TImplicitThisUse(call.asOrdinaryCall().asExpr().(SuperCall).getCallee(), false) + or // receiver of accessor call pos.isThis() and n = call.asAccessorCall().getBase() or diff --git a/javascript/ql/test/library-tests/TripleDot/useuse.js b/javascript/ql/test/library-tests/TripleDot/useuse.js index ac7f5fc6cdb..05b17dfb72b 100644 --- a/javascript/ql/test/library-tests/TripleDot/useuse.js +++ b/javascript/ql/test/library-tests/TripleDot/useuse.js @@ -94,3 +94,20 @@ function t6() { sink(c.y); // $ hasValueFlow=t6.2 c.methodLike(); } + +function t7() { + class Base { + constructor(x) { + this.field = x; + sink(this.field); // $ hasTaintFlow=t7.1 + } + } + class Sub extends Base { + constructor(x) { + super(x + '!'); + sink(this.field); // $ hasTaintFlow=t7.1 + } + } + const c = new Sub(source('t7.1')); + sink(c.field); // $ hasTaintFlow=t7.1 +} From 67fdd864c917cd3f6439bf905561a91e412b1c7f Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 24 Sep 2024 11:51:10 +0200 Subject: [PATCH 316/514] JS: Add TODO --- .../lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 92878f4dc22..d561ab6eeb3 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -20,6 +20,7 @@ private class Node = DataFlow::Node; class PostUpdateNode = DataFlow::PostUpdateNode; +// TODO: this bypasses refinement nodes, and therefore some sanitisers class SsaUseNode extends DataFlow::Node, TSsaUseNode { private ControlFlowNode expr; From e784813c3b3e7e4123afa296486520be000de9ec Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 8 Oct 2024 16:26:03 +0200 Subject: [PATCH 317/514] JS: Make barrier guards work with use-use flow --- .../dataflow/internal/BarrierGuards.qll | 20 ++++++++++ .../dataflow/internal/DataFlowPrivate.qll | 3 +- .../internal/TaintTrackingPrivate.qll | 39 +++++++++++++++++++ .../dataflow/internal/sharedlib/Ssa.qll | 25 ++++++++++-- .../ql/test/library-tests/TripleDot/useuse.js | 31 +++++++++++++++ 5 files changed, 113 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll index 1235e05121a..ef6af64e79b 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll @@ -6,6 +6,8 @@ private import javascript private import semmle.javascript.dataflow.internal.AccessPaths +private import semmle.javascript.dataflow.internal.DataFlowPrivate as DataFlowPrivate +private import semmle.javascript.dataflow.internal.sharedlib.Ssa as Ssa2 private signature class BarrierGuardSig extends DataFlow::Node { /** @@ -282,6 +284,22 @@ module MakeStateBarrierGuard< ) } + private predicate ssa2GuardChecks( + Ssa2::SsaDataflowInput::Guard guard, Ssa2::SsaDataflowInput::Expr test, boolean branch, + FlowState state + ) { + exists(BarrierGuard g | + g.asExpr() = guard and + g.blocksExpr(branch, test, state) + ) + } + + private module Ssa2Barrier = Ssa2::BarrierGuardWithState; + + private predicate ssa2BlocksNode(DataFlow::Node node, FlowState state) { + node = DataFlowPrivate::getNodeFromSsa2(Ssa2Barrier::getABarrierNode(state)) + } + /** Holds if a barrier guard blocks uses of `ap` in basic blocks dominated by `cond`. */ pragma[nomagic] private predicate barrierGuardBlocksAccessPathIn( @@ -323,6 +341,8 @@ module MakeStateBarrierGuard< barrierGuardBlocksAccessPathUse(use, state) and nd = DataFlow::valueNode(use) ) + or + ssa2BlocksNode(nd, state) } /** diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index d561ab6eeb3..008e22b3554 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1062,7 +1062,8 @@ private predicate samePhi(SsaPhiNode legacyPhi, Ssa2::PhiNode newPhi) { ) } -private Node getNodeFromSsa2(Ssa2::Node node) { +cached +Node getNodeFromSsa2(Ssa2::Node node) { result = TSsaUseNode(node.(Ssa2::ExprNode).getExpr()) or result = TExprPostUpdateNode(node.(Ssa2::ExprPostUpdateNode).getExpr()) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index a16da33664d..0f9780ab69b 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -5,6 +5,7 @@ private import semmle.javascript.dataflow.internal.Contents::Public private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as FlowSummaryImpl private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate private import semmle.javascript.dataflow.internal.BarrierGuards +private import semmle.javascript.dataflow.internal.sharedlib.Ssa as Ssa2 cached predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { @@ -44,6 +45,43 @@ private class SanitizerGuardAdapter extends DataFlow::Node instanceof TaintTrack predicate blocksExpr(boolean outcome, Expr e) { super.sanitizes(outcome, e) } } +bindingset[node] +pragma[inline_late] +private BasicBlock getBasicBlockFromSsa2(Ssa2::Node node) { + result = node.(Ssa2::ExprNode).getExpr().getBasicBlock() + or + node.(Ssa2::SsaInputNode).isInputInto(_, result) +} + +/** + * Holds if `node` should act as a taint barrier, as it occurs after a variable has been checked to be falsy. + * + * For example: + * ```js + * if (!x) { + * use(x); // <-- 'x' is a varAccessBarrier + * } + * ``` + * + * This is particularly important for ensuring that query-specific barrier guards work when they + * occur after a truthiness-check: + * ```js + * if (x && !isSafe(x)) { + * throw new Error() + * } + * use(x); // both inputs to the phi-read for 'x' are blocked (one by varAccessBarrier, one by isSafe(x)) + * ``` + */ +private predicate varAccessBarrier(DataFlow::Node node) { + exists(ConditionGuardNode guard, Ssa2::ExprNode nodeFrom, Ssa2::Node nodeTo | + guard.getOutcome() = false and + guard.getTest().(VarAccess) = nodeFrom.getExpr() and + Ssa2::localFlowStep(_, nodeFrom, nodeTo, true) and + guard.dominates(getBasicBlockFromSsa2(nodeTo)) and + node = getNodeFromSsa2(nodeTo) + ) +} + /** * Holds if `node` should be a sanitizer in all global taint flow configurations * but not in local taint. @@ -51,6 +89,7 @@ private class SanitizerGuardAdapter extends DataFlow::Node instanceof TaintTrack cached predicate defaultTaintSanitizer(DataFlow::Node node) { node instanceof DataFlow::VarAccessBarrier or + varAccessBarrier(node) or node = MakeBarrierGuard::getABarrierNode() } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll index c2f3696a7ba..8f5b0003fb0 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll @@ -53,7 +53,7 @@ module SsaConfig implements InputSig { import Make -private module SsaDataflowInput implements DataFlowIntegrationInputSig { +module SsaDataflowInput implements DataFlowIntegrationInputSig { class Expr extends js::ControlFlowNode { Expr() { this = any(SsaConfig::SourceVariable v).getAUse() } @@ -66,11 +66,28 @@ private module SsaDataflowInput implements DataFlowIntegrationInputSig { predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) { none() } // Not handled here - abstract class Guard extends Expr { } // empty class + class Guard extends js::ControlFlowNode { + Guard() { this = any(js::ConditionGuardNode g).getTest() } - predicate guardControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) { none() } + predicate hasCfgNode(js::BasicBlock bb, int i) { this = bb.getNode(i) } + } - js::BasicBlock getAConditionalBasicBlockSuccessor(js::BasicBlock bb, boolean branch) { none() } + pragma[inline] + predicate guardControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) { + exists(js::ConditionGuardNode g | + g.getTest() = guard and + g.dominates(bb) and + branch = g.getOutcome() + ) + } + + js::BasicBlock getAConditionalBasicBlockSuccessor(js::BasicBlock bb, boolean branch) { + exists(js::ConditionGuardNode g | + bb = g.getTest().getBasicBlock() and + result = g.getBasicBlock() and + branch = g.getOutcome() + ) + } } import DataFlowIntegration diff --git a/javascript/ql/test/library-tests/TripleDot/useuse.js b/javascript/ql/test/library-tests/TripleDot/useuse.js index 05b17dfb72b..f6a6470e284 100644 --- a/javascript/ql/test/library-tests/TripleDot/useuse.js +++ b/javascript/ql/test/library-tests/TripleDot/useuse.js @@ -111,3 +111,34 @@ function t7() { const c = new Sub(source('t7.1')); sink(c.field); // $ hasTaintFlow=t7.1 } + +function t8() { + function foo(x) { + const obj = {}; + obj.field = x; + + sink(obj.field); // $ hasTaintFlow=t8.1 + + if (obj) { + sink(obj.field); // $ hasTaintFlow=t8.1 + } else { + sink(obj.field); + } + + if (!obj) { + sink(obj.field); + } else { + sink(obj.field); // $ hasTaintFlow=t8.1 + } + + if (!obj || !obj) { + sink(obj.field); + } else { + sink(obj.field); // $ hasTaintFlow=t8.1 + } + } + + // The guards used above are specific to taint-tracking, to ensure only taint flows in + const taint = source('t8.1') + ' taint'; + foo(taint); +} From 958602e43e9eaf2440f927009de069383e704bc8 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 27 Sep 2024 11:30:47 +0200 Subject: [PATCH 318/514] JS: Cache getARead (as per instructions in the SSA library) --- .../javascript/dataflow/internal/sharedlib/Ssa.qll | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll index 8f5b0003fb0..73ed86d195c 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll @@ -66,6 +66,16 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig { predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) { none() } // Not handled here + cached + Expr getARead(Definition def) { + // Copied from implementation so we can cache it here + exists(SsaConfig::SourceVariable v, js::BasicBlock bb, int i | + ssaDefReachesRead(v, def, bb, i) and + SsaConfig::variableRead(bb, i, v, true) and + result.hasCfgNode(bb, i) + ) + } + class Guard extends js::ControlFlowNode { Guard() { this = any(js::ConditionGuardNode g).getTest() } From 16b08b74ebdc4152ce046479d99dff1d555247fc Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 27 Sep 2024 14:13:09 +0200 Subject: [PATCH 319/514] JS: Add test showing potential for FPs when handling refinement guards --- .../ql/test/library-tests/TripleDot/useuse.js | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/javascript/ql/test/library-tests/TripleDot/useuse.js b/javascript/ql/test/library-tests/TripleDot/useuse.js index f6a6470e284..0f057edbe5a 100644 --- a/javascript/ql/test/library-tests/TripleDot/useuse.js +++ b/javascript/ql/test/library-tests/TripleDot/useuse.js @@ -142,3 +142,34 @@ function t8() { const taint = source('t8.1') + ' taint'; foo(taint); } + +function t9() { // same as t8 but with a SanitizerGuard that isn't just a variable access + function foo(x) { + const obj = {}; + obj.field = x; + + sink(obj.field); // $ hasTaintFlow=t9.1 + + if (typeof obj !== "undefined") { + sink(obj.field); // $ hasTaintFlow=t9.1 + } else { + sink(obj.field); + } + + if (typeof obj === "undefined") { + sink(obj.field); + } else { + sink(obj.field); // $ hasTaintFlow=t9.1 + } + + if (typeof obj === "undefined" || typeof obj === "undefined") { + sink(obj.field); // $ SPURIOUS: hasTaintFlow=t9.1 + } else { + sink(obj.field); // $ hasTaintFlow=t9.1 + } + } + + // The guards used above are specific to taint-tracking, to ensure only taint flows in + const taint = source('t9.1') + ' taint'; + foo(taint); +} From e05e077b335c9b603c672c157762c9828d635346 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 30 Sep 2024 12:16:42 +0200 Subject: [PATCH 320/514] JS: Block jump steps through 'this' now that the capture lib handles 'this' --- .../dataflow/internal/DataFlowPrivate.qll | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 008e22b3554..5465857d174 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1032,6 +1032,23 @@ private predicate isBlockedLegacyNode(Node node) { legacyBarrier(node) } +/** + * Holds if `thisNode` represents a value of `this` that is being tracked by the + * variable capture library. + * + * In this case we need to suppress the default flow steps between `thisNode` and + * the `ThisExpr` nodes; especially those that would become jump steps. + * + * Note that local uses of `this` are sometimes tracked by the local SSA library, but we should + * not block local def-use flow, since we only switch to use-use flow after a post-update. + */ +pragma[nomagic] +private predicate isThisNodeTrackedByVariableCapture(DataFlow::ThisNode thisNode) { + exists(StmtContainer container | thisNode = TThisNode(container) | + any(VariableCaptureConfig::CapturedVariable v).asThisContainer() = container + ) +} + /** * Holds if there is a value-preserving steps `node1` -> `node2` that might * be cross function boundaries. @@ -1039,7 +1056,8 @@ private predicate isBlockedLegacyNode(Node node) { private predicate valuePreservingStep(Node node1, Node node2) { node1.getASuccessor() = node2 and not isBlockedLegacyNode(node1) and - not isBlockedLegacyNode(node2) + not isBlockedLegacyNode(node2) and + not isThisNodeTrackedByVariableCapture(node1) or FlowSteps::propertyFlowStep(node1, node2) or From bd94fe1574f30077a97a5379e533849f57faf94d Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 8 Oct 2024 09:04:06 +0200 Subject: [PATCH 321/514] JS: Explain false positive in test case --- javascript/ql/test/library-tests/TripleDot/useuse.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/javascript/ql/test/library-tests/TripleDot/useuse.js b/javascript/ql/test/library-tests/TripleDot/useuse.js index 0f057edbe5a..eb862d0f7b7 100644 --- a/javascript/ql/test/library-tests/TripleDot/useuse.js +++ b/javascript/ql/test/library-tests/TripleDot/useuse.js @@ -163,6 +163,8 @@ function t9() { // same as t8 but with a SanitizerGuard that isn't just a variab } if (typeof obj === "undefined" || typeof obj === "undefined") { + // The shared SSA library expects short-circuiting operators be pre-order in the CFG, + // but in JS they are post-order (as per evaluation order). sink(obj.field); // $ SPURIOUS: hasTaintFlow=t9.1 } else { sink(obj.field); // $ hasTaintFlow=t9.1 From cb874945bf339bdf1bf4b525a6a153ef2ee844bb Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 10 Oct 2024 13:27:41 +0200 Subject: [PATCH 322/514] Test updates from introduction of implicit 'this' --- .../test/library-tests/DataFlow/tests.expected | 6 ++++-- .../test/library-tests/PropWrite/tests.expected | 8 ++++---- .../frameworks/ReactJS/tests.expected | 17 +++++++++-------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/javascript/ql/test/library-tests/DataFlow/tests.expected b/javascript/ql/test/library-tests/DataFlow/tests.expected index 8d333f1b9e0..3637927d0e2 100644 --- a/javascript/ql/test/library-tests/DataFlow/tests.expected +++ b/javascript/ql/test/library-tests/DataFlow/tests.expected @@ -999,7 +999,7 @@ flowStep | tst2.ts:13:26:13:29 | List | tst2.ts:13:26:13:37 | List | | tst2.ts:13:39:13:38 | args | tst2.ts:13:39:13:38 | args | | tst2.ts:13:39:13:38 | args | tst2.ts:13:39:13:38 | args | -| tst2.ts:13:39:13:38 | this | tst2.ts:13:39:13:38 | implicit 'this' argument of super(...args) | +| tst2.ts:13:39:13:38 | this | tst2.ts:13:39:13:38 | implicit 'this' | | tst2.ts:15:11:15:13 | A.x | tst2.ts:15:11:15:30 | A.x satisfies number | | tst.js:1:1:1:1 | x | tst.js:3:5:3:5 | x | | tst.js:1:10:1:11 | fs | tst.js:1:10:1:11 | fs | @@ -1080,7 +1080,7 @@ flowStep | tst.js:46:10:46:11 | "" | tst.js:46:1:46:11 | global = "" | | tst.js:49:1:54:1 | A | tst.js:55:1:55:1 | A | | tst.js:49:1:54:1 | class A ... `\\n }\\n} | tst.js:49:1:54:1 | A | -| tst.js:50:14:50:13 | this | tst.js:51:5:51:13 | implicit 'this' argument of super(42) | +| tst.js:50:14:50:13 | this | tst.js:51:5:51:9 | implicit 'this' | | tst.js:64:1:67:1 | functio ... lysed\\n} | tst.js:64:11:64:11 | h | | tst.js:64:11:64:11 | h | tst.js:68:12:68:12 | h | | tst.js:68:5:68:14 | iter | tst.js:69:1:69:4 | iter | @@ -1187,6 +1187,7 @@ getImmediatePredecessor | tst2.ts:13:26:13:29 | List | tst2.ts:13:26:13:37 | List | | tst2.ts:13:39:13:38 | args | tst2.ts:13:39:13:38 | args | | tst2.ts:13:39:13:38 | args | tst2.ts:13:39:13:38 | args | +| tst2.ts:13:39:13:38 | this | tst2.ts:13:39:13:38 | implicit 'this' | | tst2.ts:15:11:15:13 | A.x | tst2.ts:15:11:15:30 | A.x satisfies number | | tst.js:1:10:1:11 | fs | tst.js:1:10:1:11 | fs | | tst.js:1:10:1:11 | fs | tst.js:7:1:7:2 | fs | @@ -1249,6 +1250,7 @@ getImmediatePredecessor | tst.js:46:10:46:11 | "" | tst.js:46:1:46:11 | global = "" | | tst.js:49:1:54:1 | A | tst.js:55:1:55:1 | A | | tst.js:49:1:54:1 | class A ... `\\n }\\n} | tst.js:49:1:54:1 | A | +| tst.js:50:14:50:13 | this | tst.js:51:5:51:9 | implicit 'this' | | tst.js:64:1:67:1 | functio ... lysed\\n} | tst.js:64:11:64:11 | h | | tst.js:64:11:64:11 | h | tst.js:68:12:68:12 | h | | tst.js:68:5:68:14 | iter | tst.js:69:1:69:4 | iter | diff --git a/javascript/ql/test/library-tests/PropWrite/tests.expected b/javascript/ql/test/library-tests/PropWrite/tests.expected index 0fc9e672baf..c1b7e1e7b56 100644 --- a/javascript/ql/test/library-tests/PropWrite/tests.expected +++ b/javascript/ql/test/library-tests/PropWrite/tests.expected @@ -67,10 +67,10 @@ test_PropWriteRhs | tst.js:41:18:41:24 | ...arr3 | tst.js:41:18:41:24 | ...arr3 | | tst.js:41:27:41:29 | "d" | tst.js:41:27:41:29 | "d" | test_PropWriteBase -| classes.ts:4:3:4:24 | instanc ... foo(); | classes.ts:3:21:3:20 | this | -| classes.ts:8:15:8:35 | public ... erField | classes.ts:8:3:8:2 | this | -| classes.ts:12:17:12:37 | public ... erField | classes.ts:12:5:12:4 | this | -| classes.ts:16:17:16:37 | public ... erField | classes.ts:16:5:16:4 | this | +| classes.ts:4:3:4:24 | instanc ... foo(); | classes.ts:4:3:4:24 | implicit 'this' | +| classes.ts:8:15:8:35 | public ... erField | classes.ts:8:15:8:35 | implicit 'this' | +| classes.ts:12:17:12:37 | public ... erField | classes.ts:12:17:12:37 | implicit 'this' | +| classes.ts:16:17:16:37 | public ... erField | classes.ts:16:17:16:37 | implicit 'this' | | tst.js:2:5:2:8 | x: 4 | tst.js:1:11:9:1 | {\\n x ... }\\n} | | tst.js:3:5:5:5 | func: f ... ;\\n } | tst.js:1:11:9:1 | {\\n x ... }\\n} | | tst.js:6:5:8:5 | f() {\\n ... ;\\n } | tst.js:1:11:9:1 | {\\n x ... }\\n} | diff --git a/javascript/ql/test/library-tests/frameworks/ReactJS/tests.expected b/javascript/ql/test/library-tests/frameworks/ReactJS/tests.expected index e3b226f74f9..4804e30b6f7 100644 --- a/javascript/ql/test/library-tests/frameworks/ReactJS/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/ReactJS/tests.expected @@ -100,7 +100,7 @@ test_ReactComponent_ref | es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | | es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | es5.js:19:11:19:10 | this | | es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | es5.js:20:24:20:27 | this | -| es6.js:1:1:8:1 | class H ... ;\\n }\\n} | es6.js:1:37:1:36 | implicit 'this' argument of super(...args) | +| es6.js:1:1:8:1 | class H ... ;\\n }\\n} | es6.js:1:37:1:36 | implicit 'this' | | es6.js:1:1:8:1 | class H ... ;\\n }\\n} | es6.js:1:37:1:36 | this | | es6.js:1:1:8:1 | class H ... ;\\n }\\n} | es6.js:2:9:2:8 | this | | es6.js:1:1:8:1 | class H ... ;\\n }\\n} | es6.js:3:24:3:27 | this | @@ -111,31 +111,31 @@ test_ReactComponent_ref | es6.js:14:1:20:1 | class H ... }\\n} | es6.js:18:9:18:12 | this | | exportedComponent.jsx:1:8:3:1 | functio ... r}}/>\\n} | exportedComponent.jsx:1:8:1:7 | this | | importedComponent.jsx:3:8:5:1 | functio ... or}/>\\n} | importedComponent.jsx:3:8:3:7 | this | -| namedImport.js:3:1:3:28 | class C ... nent {} | namedImport.js:3:27:3:26 | implicit 'this' argument of super(...args) | +| namedImport.js:3:1:3:28 | class C ... nent {} | namedImport.js:3:27:3:26 | implicit 'this' | | namedImport.js:3:1:3:28 | class C ... nent {} | namedImport.js:3:27:3:26 | this | -| namedImport.js:5:1:5:20 | class D extends C {} | namedImport.js:5:19:5:18 | implicit 'this' argument of super(...args) | +| namedImport.js:5:1:5:20 | class D extends C {} | namedImport.js:5:19:5:18 | implicit 'this' | | namedImport.js:5:1:5:20 | class D extends C {} | namedImport.js:5:19:5:18 | this | | plainfn.js:1:1:3:1 | functio ... div>;\\n} | plainfn.js:1:1:1:0 | this | | plainfn.js:5:1:7:1 | functio ... iv");\\n} | plainfn.js:5:1:5:0 | this | | plainfn.js:9:1:12:1 | functio ... rn x;\\n} | plainfn.js:9:1:9:0 | this | | plainfn.js:20:1:24:1 | functio ... n 42;\\n} | plainfn.js:20:1:20:0 | this | -| preact.js:1:1:7:1 | class H ... }\\n} | preact.js:1:38:1:37 | implicit 'this' argument of super(...args) | +| preact.js:1:1:7:1 | class H ... }\\n} | preact.js:1:38:1:37 | implicit 'this' | | preact.js:1:1:7:1 | class H ... }\\n} | preact.js:1:38:1:37 | this | | preact.js:1:1:7:1 | class H ... }\\n} | preact.js:2:11:2:10 | this | -| preact.js:9:1:11:1 | class H ... nt {\\n\\n} | preact.js:9:38:9:37 | implicit 'this' argument of super(...args) | +| preact.js:9:1:11:1 | class H ... nt {\\n\\n} | preact.js:9:38:9:37 | implicit 'this' | | preact.js:9:1:11:1 | class H ... nt {\\n\\n} | preact.js:9:38:9:37 | this | -| probably-a-component.js:1:1:6:1 | class H ... }\\n} | probably-a-component.js:1:31:1:30 | implicit 'this' argument of super(...args) | +| probably-a-component.js:1:1:6:1 | class H ... }\\n} | probably-a-component.js:1:31:1:30 | implicit 'this' | | probably-a-component.js:1:1:6:1 | class H ... }\\n} | probably-a-component.js:1:31:1:30 | this | | probably-a-component.js:1:1:6:1 | class H ... }\\n} | probably-a-component.js:2:11:2:10 | this | | probably-a-component.js:1:1:6:1 | class H ... }\\n} | probably-a-component.js:3:9:3:12 | this | -| props.js:2:5:3:5 | class C ... {\\n } | props.js:2:37:2:36 | implicit 'this' argument of super(...args) | +| props.js:2:5:3:5 | class C ... {\\n } | props.js:2:37:2:36 | implicit 'this' | | props.js:2:5:3:5 | class C ... {\\n } | props.js:2:37:2:36 | this | | props.js:2:5:3:5 | class C ... {\\n } | props.js:9:5:9:55 | new C({ ... ctor"}) | | props.js:13:31:17:5 | {\\n ... }\\n } | props.js:13:31:17:5 | {\\n ... }\\n } | | props.js:13:31:17:5 | {\\n ... }\\n } | props.js:14:24:14:23 | this | | props.js:26:5:28:5 | functio ... ;\\n } | props.js:26:5:26:4 | this | | props.js:26:5:28:5 | functio ... ;\\n } | props.js:34:5:34:55 | new C({ ... ctor"}) | -| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:1:33:1:32 | implicit 'this' argument of super(...args) | +| rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:1:33:1:32 | implicit 'this' | | rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:1:33:1:32 | this | | rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:2:36:2:35 | this | | rare-lifecycle-methods.js:1:1:11:1 | class C ... }\\n} | rare-lifecycle-methods.js:5:26:5:25 | this | @@ -155,6 +155,7 @@ test_ReactComponent_ref | statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:18:9:18:11 | cmp | | statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:22:9:22:11 | cmp | | statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:25:20:25:19 | this | +| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:31:5:33:6 | implicit 'this' | | statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | | statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | statePropertyWrites.js:37:11:37:10 | this | | statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | statePropertyWrites.js:38:24:38:27 | this | From 4473e6d977be3a5f95cbf71cd50338bf8b54e399 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 11 Oct 2024 08:50:26 +0200 Subject: [PATCH 323/514] JS: Update test with some post-update consistency checks gone For a constructor call, the return value acts as the post-update node for the 'this' argument. The fact that constructor calls are sometimes PostUpdateNodes causes some of these harmless alerts. The warnings have disappeared in some cases because we no longer target getALocalSource() so the target is no longer the constructor call. --- .../FlowSummary/DataFlowConsistency.expected | 8 -------- 1 file changed, 8 deletions(-) diff --git a/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected b/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected index 892f306f30e..6cbebc43ea9 100644 --- a/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected +++ b/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected @@ -33,14 +33,6 @@ postWithInFlow | file://:0:0:0:0 | [summary] to write: Argument[this] in Array#forEach / Map#forEach / Set#forEach | PostUpdateNode should not be the target of local flow. | | file://:0:0:0:0 | [summary] to write: Argument[this] in Array#map | PostUpdateNode should not be the target of local flow. | | file://:0:0:0:0 | [summary] to write: Argument[this] in Array#reduce / Array#reduceRight | PostUpdateNode should not be the target of local flow. | -| tst.js:97:24:97:74 | new Pro ... rce())) | PostUpdateNode should not be the target of local flow. | -| tst.js:100:3:100:53 | new Pro ... rce())) | PostUpdateNode should not be the target of local flow. | -| tst.js:101:3:101:53 | new Pro ... rce())) | PostUpdateNode should not be the target of local flow. | -| tst.js:102:3:102:52 | new Pro ... rce())) | PostUpdateNode should not be the target of local flow. | -| tst.js:103:3:103:52 | new Pro ... rce())) | PostUpdateNode should not be the target of local flow. | -| tst.js:250:15:250:23 | new Map() | PostUpdateNode should not be the target of local flow. | -| tst.js:258:16:258:24 | new Map() | PostUpdateNode should not be the target of local flow. | -| tst.js:264:16:264:24 | new Map() | PostUpdateNode should not be the target of local flow. | viableImplInCallContextTooLarge uniqueParameterNodeAtPosition uniqueParameterNodePosition From c0997c28cb07dde4640182dd00d2bdf4ef038b73 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 17 Oct 2024 09:51:57 +0200 Subject: [PATCH 324/514] JS: Reveal issue with immutable.js test Fixed in the next commit --- .../ql/test/library-tests/frameworks/Immutable/immutable.js | 4 ++-- .../ql/test/library-tests/frameworks/Immutable/tests.expected | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/javascript/ql/test/library-tests/frameworks/Immutable/immutable.js b/javascript/ql/test/library-tests/frameworks/Immutable/immutable.js index 78104b6a20a..a80c804edb0 100644 --- a/javascript/ql/test/library-tests/frameworks/Immutable/immutable.js +++ b/javascript/ql/test/library-tests/frameworks/Immutable/immutable.js @@ -14,7 +14,7 @@ sink(map2.get("b")); // OK - but still flagged [INCONSISTENCY] const map3 = map2.set("d", source("d")); sink(map1.get("d")); // OK -sink(map3.get("d")); // NOT OK +sink(map3.get("d")); // NOT OK [INCONSISTENCY] sink(map3.toJS()["a"]); // NOT OK @@ -34,7 +34,7 @@ List(["safe"]).push(source()).forEach(x => sink(x)); // NOT OK const map4 = OrderedMap({}).set("f", source()); -sink(map4.get("f")); // NOT OK +sink(map4.get("f")); // NOT OK [INCONSISTENCY] const map5 = Record({a: source(), b: null, c: null})({b: source()}); sink(map5.get("a")); // NOT OK diff --git a/javascript/ql/test/library-tests/frameworks/Immutable/tests.expected b/javascript/ql/test/library-tests/frameworks/Immutable/tests.expected index e071504bfcf..594ea252d52 100644 --- a/javascript/ql/test/library-tests/frameworks/Immutable/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/Immutable/tests.expected @@ -1,4 +1,6 @@ legacyDataFlowDifference +| immutable.js:15:28:15:38 | source("d") | immutable.js:17:6:17:18 | map3.get("d") | only flow with OLD data flow library | +| immutable.js:36:38:36:45 | source() | immutable.js:37:6:37:18 | map4.get("f") | only flow with OLD data flow library | dataFlow | immutable.js:1:16:1:26 | source("a") | immutable.js:2:6:2:13 | obj["a"] | | immutable.js:1:16:1:26 | source("a") | immutable.js:11:6:11:18 | map1.get("a") | @@ -6,13 +8,11 @@ dataFlow | immutable.js:1:16:1:26 | source("a") | immutable.js:20:6:20:21 | map3.toJS()["a"] | | immutable.js:1:32:1:43 | source("b1") | immutable.js:8:6:8:18 | map1.get("b") | | immutable.js:1:32:1:43 | source("b1") | immutable.js:13:6:13:18 | map2.get("b") | -| immutable.js:15:28:15:38 | source("d") | immutable.js:17:6:17:18 | map3.get("d") | | immutable.js:22:19:22:29 | source("e") | immutable.js:22:6:22:40 | fromJS( ... et("e") | | immutable.js:24:18:24:25 | source() | immutable.js:25:22:25:22 | x | | immutable.js:29:25:29:32 | source() | immutable.js:29:53:29:53 | x | | immutable.js:31:7:31:14 | source() | immutable.js:31:75:31:75 | x | | immutable.js:33:21:33:28 | source() | immutable.js:33:49:33:49 | x | -| immutable.js:36:38:36:45 | source() | immutable.js:37:6:37:18 | map4.get("f") | | immutable.js:39:25:39:32 | source() | immutable.js:40:6:40:18 | map5.get("a") | | immutable.js:39:58:39:65 | source() | immutable.js:41:6:41:18 | map5.get("b") | | immutable.js:44:40:44:47 | source() | immutable.js:45:6:45:18 | map6.get("a") | From ad52b71922e63b0061786aab0aa4895b6f6d22dd Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 17 Oct 2024 09:59:41 +0200 Subject: [PATCH 325/514] JS: Update immutable.js test to clarify why it stopped working The Immutable model uses the 'd' and 'f' properties to model Map content, but the test doesn't actually mention those properties, so they were missing from the PropertyName class. The flow was previously found spuriously by the regular Map model, which also adds flow through the get/set calls. This flow is however no longer found since it relied on a step from post-update back to getALocalSource which is no longer present. --- .../test/library-tests/frameworks/Immutable/immutable.js | 9 ++++++--- .../library-tests/frameworks/Immutable/tests.expected | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/javascript/ql/test/library-tests/frameworks/Immutable/immutable.js b/javascript/ql/test/library-tests/frameworks/Immutable/immutable.js index a80c804edb0..7a6e87753a9 100644 --- a/javascript/ql/test/library-tests/frameworks/Immutable/immutable.js +++ b/javascript/ql/test/library-tests/frameworks/Immutable/immutable.js @@ -14,7 +14,7 @@ sink(map2.get("b")); // OK - but still flagged [INCONSISTENCY] const map3 = map2.set("d", source("d")); sink(map1.get("d")); // OK -sink(map3.get("d")); // NOT OK [INCONSISTENCY] +sink(map3.get("d")); // NOT OK sink(map3.toJS()["a"]); // NOT OK @@ -34,7 +34,7 @@ List(["safe"]).push(source()).forEach(x => sink(x)); // NOT OK const map4 = OrderedMap({}).set("f", source()); -sink(map4.get("f")); // NOT OK [INCONSISTENCY] +sink(map4.get("f")); // NOT OK const map5 = Record({a: source(), b: null, c: null})({b: source()}); sink(map5.get("a")); // NOT OK @@ -55,4 +55,7 @@ Set.of(source()).filter(x => true).toList().forEach(x => sink(x)); // NOT OK Set([source()]).filter(x => true).toList().forEach(x => sink(x)); // NOT OK -OrderedSet([source()]).filter(x => true).toList().forEach(x => sink(x)); // NOT OK \ No newline at end of file +OrderedSet([source()]).filter(x => true).toList().forEach(x => sink(x)); // NOT OK + +x.d; // ensure 'd' property exists +x.f; // ensure 'f' property exists diff --git a/javascript/ql/test/library-tests/frameworks/Immutable/tests.expected b/javascript/ql/test/library-tests/frameworks/Immutable/tests.expected index 594ea252d52..e071504bfcf 100644 --- a/javascript/ql/test/library-tests/frameworks/Immutable/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/Immutable/tests.expected @@ -1,6 +1,4 @@ legacyDataFlowDifference -| immutable.js:15:28:15:38 | source("d") | immutable.js:17:6:17:18 | map3.get("d") | only flow with OLD data flow library | -| immutable.js:36:38:36:45 | source() | immutable.js:37:6:37:18 | map4.get("f") | only flow with OLD data flow library | dataFlow | immutable.js:1:16:1:26 | source("a") | immutable.js:2:6:2:13 | obj["a"] | | immutable.js:1:16:1:26 | source("a") | immutable.js:11:6:11:18 | map1.get("a") | @@ -8,11 +6,13 @@ dataFlow | immutable.js:1:16:1:26 | source("a") | immutable.js:20:6:20:21 | map3.toJS()["a"] | | immutable.js:1:32:1:43 | source("b1") | immutable.js:8:6:8:18 | map1.get("b") | | immutable.js:1:32:1:43 | source("b1") | immutable.js:13:6:13:18 | map2.get("b") | +| immutable.js:15:28:15:38 | source("d") | immutable.js:17:6:17:18 | map3.get("d") | | immutable.js:22:19:22:29 | source("e") | immutable.js:22:6:22:40 | fromJS( ... et("e") | | immutable.js:24:18:24:25 | source() | immutable.js:25:22:25:22 | x | | immutable.js:29:25:29:32 | source() | immutable.js:29:53:29:53 | x | | immutable.js:31:7:31:14 | source() | immutable.js:31:75:31:75 | x | | immutable.js:33:21:33:28 | source() | immutable.js:33:49:33:49 | x | +| immutable.js:36:38:36:45 | source() | immutable.js:37:6:37:18 | map4.get("f") | | immutable.js:39:25:39:32 | source() | immutable.js:40:6:40:18 | map5.get("a") | | immutable.js:39:58:39:65 | source() | immutable.js:41:6:41:18 | map5.get("b") | | immutable.js:44:40:44:47 | source() | immutable.js:45:6:45:18 | map6.get("a") | From 1efef2ca3c6362d5325099b7c3ecc1c373e9fbeb Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 18 Oct 2024 11:52:48 +0200 Subject: [PATCH 326/514] JS: Change rule for getPostUpdateForStore This causes less wobbles in test outputs --- .../dataflow/internal/DataFlowPrivate.qll | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 5465857d174..43aebf0b7b5 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1314,17 +1314,18 @@ predicate readStep(Node node1, ContentSet c, Node node2) { /** Gets the post-update node for which `node` is the corresponding pre-update node. */ private Node getPostUpdateForStore(Node base) { - // Some nodes have post-update nodes but should not be targeted by a PropWrite store. - // Notably, an object literal can have a post-update node it if is an argument to a call, - // but in this case, we should not target the post-update node, as this would prevent data from - // flowing into the call. exists(Expr expr | base = TValueNode(expr) and result = TExprPostUpdateNode(expr) | - expr instanceof PropAccess or - expr instanceof VarAccess or - expr instanceof ThisExpr + // When object/array literal appears as an argument to a call, we would generally need two post-update nodes: + // - one for the stores coming from the properties or array elements (which happen before the call and must flow into the call) + // - one for the argument position, to propagate the updates that happened during the call + // + // However, the first post-update is not actually needed since we are storing into a brand new object, so in the first case + // we just target the expression directly. In the second case we use the ExprPostUpdateNode. + not expr instanceof ObjectExpr and + not expr instanceof ArrayExpr ) or exists(ImplicitThisUse use | From d557c7689c398b6f4efe0260dd2bec5136a4d3db Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 23 Oct 2024 10:24:33 +0200 Subject: [PATCH 327/514] JS: Update a test that now has more precise output --- .../library-tests/TaintTracking/BasicTaintTracking.expected | 2 +- javascript/ql/test/library-tests/TaintTracking/tst.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index ff2c1a61750..483d539d7b5 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -36,6 +36,7 @@ legacyDataFlowDifference | sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | only flow with NEW data flow library | | spread.js:4:15:4:22 | source() | spread.js:18:8:18:8 | y | only flow with NEW data flow library | | spread.js:4:15:4:22 | source() | spread.js:24:8:24:8 | y | only flow with NEW data flow library | +| tst.js:2:13:2:20 | source() | tst.js:17:10:17:10 | a | only flow with OLD data flow library | | use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:15:10:15:10 | x | only flow with NEW data flow library | consistencyIssue | nested-props.js:20 | expected an alert, but found none | NOT OK - but not found | Consistency | @@ -280,7 +281,6 @@ flow | tst.js:2:13:2:20 | source() | tst.js:4:10:4:10 | x | | tst.js:2:13:2:20 | source() | tst.js:5:10:5:22 | "/" + x + "!" | | tst.js:2:13:2:20 | source() | tst.js:14:10:14:17 | x.sort() | -| tst.js:2:13:2:20 | source() | tst.js:17:10:17:10 | a | | tst.js:2:13:2:20 | source() | tst.js:19:10:19:10 | a | | tst.js:2:13:2:20 | source() | tst.js:23:10:23:10 | b | | tst.js:2:13:2:20 | source() | tst.js:25:10:25:16 | x.pop() | diff --git a/javascript/ql/test/library-tests/TaintTracking/tst.js b/javascript/ql/test/library-tests/TaintTracking/tst.js index dd9829c9e0b..dcd0af62dbc 100644 --- a/javascript/ql/test/library-tests/TaintTracking/tst.js +++ b/javascript/ql/test/library-tests/TaintTracking/tst.js @@ -14,7 +14,7 @@ function test() { sink(x.sort()); // NOT OK var a = []; - sink(a); // NOT OK (flow-insensitive treatment of `a`) + sink(a); // OK a.push(x); sink(a); // NOT OK From 1b85feb1fadc6ab95d363774dd00071e32c2f563 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 23 Oct 2024 11:01:46 +0200 Subject: [PATCH 328/514] JS: Add imprecise post-update steps for when a captured var/this is not tracked precisely With the capture library we sometimes bails out of handling certain functions for scalability reasons. This means we have a notion of "captured but imprecisely-tracked" variables and 'this'. In these cases we go back to propagating flow from a post-update node to the local source. --- .../dataflow/internal/DataFlowPrivate.qll | 24 +++++++++++++++++++ .../TaintTracking/BasicTaintTracking.expected | 6 ++--- .../TaintTracking/DataFlowTracking.expected | 4 ++-- .../TaintTracking/capture-flow.js | 6 ++--- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 43aebf0b7b5..a7f123b9f02 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1049,6 +1049,28 @@ private predicate isThisNodeTrackedByVariableCapture(DataFlow::ThisNode thisNode ) } +/** + * Holds if there should be flow from `postUpdate` to `target` because of a variable/this value + * that is captured but not tracked precisely by the variable-capture library. + */ +pragma[nomagic] +private predicate imprecisePostUpdateStep(DataFlow::PostUpdateNode postUpdate, DataFlow::Node target) { + exists(LocalVariableOrThis var, DataFlow::Node use | + // 'var' is captured but not tracked precisely + var.isCaptured() and + not var instanceof VariableCaptureConfig::CapturedVariable and + ( + use = TValueNode(var.asLocalVariable().getAnAccess()) + or + use = TValueNode(var.getAThisExpr()) + or + use = TImplicitThisUse(var.getAThisUse(), false) + ) and + postUpdate.getPreUpdateNode() = use and + target = use.getALocalSource() + ) +} + /** * Holds if there is a value-preserving steps `node1` -> `node2` that might * be cross function boundaries. @@ -1059,6 +1081,8 @@ private predicate valuePreservingStep(Node node1, Node node2) { not isBlockedLegacyNode(node2) and not isThisNodeTrackedByVariableCapture(node1) or + imprecisePostUpdateStep(node1, node2) + or FlowSteps::propertyFlowStep(node1, node2) or FlowSteps::globalFlowStep(node1, node2) diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 483d539d7b5..2d3c12597b9 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -17,9 +17,6 @@ legacyDataFlowDifference | callbacks.js:44:17:44:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | | capture-flow.js:89:13:89:20 | source() | capture-flow.js:89:6:89:21 | test3c(source()) | only flow with NEW data flow library | | capture-flow.js:101:12:101:19 | source() | capture-flow.js:102:6:102:20 | test5("safe")() | only flow with OLD data flow library | -| capture-flow.js:274:33:274:40 | source() | capture-flow.js:272:10:272:17 | this.foo | only flow with OLD data flow library | -| capture-flow.js:274:33:274:40 | source() | capture-flow.js:274:6:274:45 | new Cap ... ()).foo | only flow with OLD data flow library | -| capture-flow.js:283:34:283:41 | source() | capture-flow.js:284:6:284:44 | new Cap ... e').foo | only flow with NEW data flow library | | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:40:8:40:14 | e.taint | only flow with NEW data flow library | | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:44:8:44:19 | f_safe.taint | only flow with NEW data flow library | | constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:39:8:39:14 | e.param | only flow with NEW data flow library | @@ -126,8 +123,9 @@ flow | capture-flow.js:259:23:259:30 | source() | capture-flow.js:252:14:252:36 | objectW ... s.field | | capture-flow.js:259:23:259:30 | source() | capture-flow.js:253:14:253:23 | this.field | | capture-flow.js:262:16:262:23 | source() | capture-flow.js:264:14:264:21 | this.foo | +| capture-flow.js:274:33:274:40 | source() | capture-flow.js:272:10:272:17 | this.foo | +| capture-flow.js:274:33:274:40 | source() | capture-flow.js:274:6:274:45 | new Cap ... ()).foo | | capture-flow.js:283:34:283:41 | source() | capture-flow.js:283:6:283:46 | new Cap ... ()).foo | -| capture-flow.js:283:34:283:41 | source() | capture-flow.js:284:6:284:44 | new Cap ... e').foo | | captured-sanitizer.js:25:3:25:10 | source() | captured-sanitizer.js:15:10:15:10 | x | | case.js:2:16:2:23 | source() | case.js:5:8:5:35 | changeC ... source) | | case.js:2:16:2:23 | source() | case.js:8:8:8:24 | camelCase(source) | diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected index c2ff238141b..7e083f53550 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected @@ -11,8 +11,6 @@ legacyDataFlowDifference | callbacks.js:44:17:44:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | | capture-flow.js:89:13:89:20 | source() | capture-flow.js:89:6:89:21 | test3c(source()) | only flow with NEW data flow library | | capture-flow.js:101:12:101:19 | source() | capture-flow.js:102:6:102:20 | test5("safe")() | only flow with OLD data flow library | -| capture-flow.js:274:33:274:40 | source() | capture-flow.js:272:10:272:17 | this.foo | only flow with OLD data flow library | -| capture-flow.js:274:33:274:40 | source() | capture-flow.js:274:6:274:45 | new Cap ... ()).foo | only flow with OLD data flow library | | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:40:8:40:14 | e.taint | only flow with NEW data flow library | | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:44:8:44:19 | f_safe.taint | only flow with NEW data flow library | | constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:39:8:39:14 | e.param | only flow with NEW data flow library | @@ -100,6 +98,8 @@ flow | capture-flow.js:259:23:259:30 | source() | capture-flow.js:252:14:252:36 | objectW ... s.field | | capture-flow.js:259:23:259:30 | source() | capture-flow.js:253:14:253:23 | this.field | | capture-flow.js:262:16:262:23 | source() | capture-flow.js:264:14:264:21 | this.foo | +| capture-flow.js:274:33:274:40 | source() | capture-flow.js:272:10:272:17 | this.foo | +| capture-flow.js:274:33:274:40 | source() | capture-flow.js:274:6:274:45 | new Cap ... ()).foo | | capture-flow.js:283:34:283:41 | source() | capture-flow.js:283:6:283:46 | new Cap ... ()).foo | | captured-sanitizer.js:25:3:25:10 | source() | captured-sanitizer.js:15:10:15:10 | x | | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:24:8:24:14 | c.taint | diff --git a/javascript/ql/test/library-tests/TaintTracking/capture-flow.js b/javascript/ql/test/library-tests/TaintTracking/capture-flow.js index baa6c6c95d2..20e654da6d0 100644 --- a/javascript/ql/test/library-tests/TaintTracking/capture-flow.js +++ b/javascript/ql/test/library-tests/TaintTracking/capture-flow.js @@ -269,9 +269,9 @@ function CaptureThisWithoutJump(x) { [1].forEach(() => { this.foo = x; }); - sink(this.foo); // NOT OK [INCONSISTENCY] + sink(this.foo); // NOT OK } -sink(new CaptureThisWithoutJump(source()).foo); // NOT OK [INCONSISTENCY] +sink(new CaptureThisWithoutJump(source()).foo); // NOT OK sink(new CaptureThisWithoutJump('safe').foo); // OK function CaptureThisWithoutJump2(x) { @@ -281,4 +281,4 @@ function CaptureThisWithoutJump2(x) { return y; } sink(new CaptureThisWithoutJump2(source()).foo); // NOT OK -sink(new CaptureThisWithoutJump2('safe').foo); // OK [INCONSISTENCY] +sink(new CaptureThisWithoutJump2('safe').foo); // OK From d3e70c1e970fceeb239422a7ed5f70b7bee06d07 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 23 Oct 2024 13:11:54 +0200 Subject: [PATCH 329/514] JS: Add in-barrier to XSS query This is a bit of a bandaid to cover issues with the push() method on next/router being treated as an array push, which causes it to flow into other taint sources. --- .../security/dataflow/DomBasedXssQuery.qll | 2 ++ .../Security/CWE-079/DomBasedXss/Xss.expected | 20 +++---------------- .../XssWithAdditionalSources.expected | 20 +++---------------- 3 files changed, 8 insertions(+), 34 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll index 9c326c4f389..d8e38456b8f 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll @@ -83,6 +83,8 @@ module DomBasedXssConfig implements DataFlow::StateConfigSig { node = DataFlow::MakeLabeledBarrierGuard::getABarrierNode(lbl) } + predicate isBarrierIn(DataFlow::Node node, DataFlow::FlowLabel label) { isSource(node, label) } + predicate isAdditionalFlowStep( DataFlow::Node node1, DataFlow::FlowLabel state1, DataFlow::Node node2, DataFlow::FlowLabel state2 diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 3d5623ff3f2..25651d7e060 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -258,10 +258,6 @@ nodes | react-use-router.js:8:21:8:39 | router.query.foobar | semmle.label | router.query.foobar | | react-use-router.js:11:24:11:35 | router.query | semmle.label | router.query | | react-use-router.js:11:24:11:42 | router.query.foobar | semmle.label | router.query.foobar | -| react-use-router.js:23:31:23:36 | [post update] router | semmle.label | [post update] router | -| react-use-router.js:23:31:23:36 | [post update] router [ArrayElement] | semmle.label | [post update] router [ArrayElement] | -| react-use-router.js:23:43:23:48 | router | semmle.label | router | -| react-use-router.js:23:43:23:48 | router [ArrayElement] | semmle.label | router [ArrayElement] | | react-use-router.js:23:43:23:54 | router.query | semmle.label | router.query | | react-use-router.js:23:43:23:61 | router.query.foobar | semmle.label | router.query.foobar | | react-use-router.js:33:21:33:32 | router.query | semmle.label | router.query | @@ -501,8 +497,6 @@ nodes | tst.js:371:16:371:39 | documen ... .search | semmle.label | documen ... .search | | tst.js:374:18:374:23 | target | semmle.label | target | | tst.js:381:7:381:39 | target | semmle.label | target | -| tst.js:381:7:381:39 | target [taint3] | semmle.label | target [taint3] | -| tst.js:381:7:381:39 | target [taint8] | semmle.label | target [taint8] | | tst.js:381:16:381:39 | documen ... .search | semmle.label | documen ... .search | | tst.js:384:18:384:23 | target | semmle.label | target | | tst.js:386:18:386:23 | target | semmle.label | target | @@ -824,13 +818,7 @@ edges | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | provenance | | | react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | provenance | | | react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | provenance | | -| react-use-router.js:23:31:23:36 | [post update] router | react-use-router.js:23:43:23:48 | router | provenance | | -| react-use-router.js:23:31:23:36 | [post update] router [ArrayElement] | react-use-router.js:23:43:23:48 | router [ArrayElement] | provenance | | -| react-use-router.js:23:43:23:48 | router | react-use-router.js:23:43:23:54 | router.query | provenance | | -| react-use-router.js:23:43:23:48 | router [ArrayElement] | react-use-router.js:23:43:23:54 | router.query | provenance | | | react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | provenance | | -| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:31:23:36 | [post update] router | provenance | | -| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:31:23:36 | [post update] router [ArrayElement] | provenance | | | react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | provenance | | | react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | provenance | | | react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:9:4:49 | state | provenance | | @@ -1025,17 +1013,15 @@ edges | tst.js:381:7:381:39 | target | tst.js:397:18:397:23 | target | provenance | | | tst.js:381:7:381:39 | target | tst.js:406:18:406:23 | target | provenance | | | tst.js:381:7:381:39 | target | tst.js:408:19:408:24 | target | provenance | | -| tst.js:381:7:381:39 | target [taint3] | tst.js:392:18:392:23 | target [taint3] | provenance | | -| tst.js:381:7:381:39 | target [taint8] | tst.js:408:19:408:24 | target [taint8] | provenance | | -| tst.js:381:7:381:39 | target [taint8] | tst.js:409:18:409:23 | target [taint8] | provenance | | | tst.js:381:16:381:39 | documen ... .search | tst.js:381:7:381:39 | target | provenance | | | tst.js:386:18:386:23 | target | tst.js:386:18:386:29 | target.taint | provenance | | -| tst.js:391:3:391:8 | [post update] target [taint3] | tst.js:381:7:381:39 | target [taint3] | provenance | | +| tst.js:391:3:391:8 | [post update] target [taint3] | tst.js:392:18:392:23 | target [taint3] | provenance | | | tst.js:391:19:391:42 | documen ... .search | tst.js:391:3:391:8 | [post update] target [taint3] | provenance | | | tst.js:392:18:392:23 | target [taint3] | tst.js:392:18:392:30 | target.taint3 | provenance | | | tst.js:397:18:397:23 | target | tst.js:397:18:397:30 | target.taint5 | provenance | | | tst.js:406:18:406:23 | target | tst.js:406:18:406:30 | target.taint7 | provenance | | -| tst.js:408:3:408:8 | [post update] target [taint8] | tst.js:381:7:381:39 | target [taint8] | provenance | | +| tst.js:408:3:408:8 | [post update] target [taint8] | tst.js:408:19:408:24 | target [taint8] | provenance | | +| tst.js:408:3:408:8 | [post update] target [taint8] | tst.js:409:18:409:23 | target [taint8] | provenance | | | tst.js:408:19:408:24 | target | tst.js:408:19:408:31 | target.taint8 | provenance | | | tst.js:408:19:408:24 | target [taint8] | tst.js:408:19:408:31 | target.taint8 | provenance | | | tst.js:408:19:408:31 | target.taint8 | tst.js:408:3:408:8 | [post update] target [taint8] | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index e9d44d1ee0e..a3c256a1b72 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -263,10 +263,6 @@ nodes | react-use-router.js:8:21:8:39 | router.query.foobar | semmle.label | router.query.foobar | | react-use-router.js:11:24:11:35 | router.query | semmle.label | router.query | | react-use-router.js:11:24:11:42 | router.query.foobar | semmle.label | router.query.foobar | -| react-use-router.js:23:31:23:36 | [post update] router | semmle.label | [post update] router | -| react-use-router.js:23:31:23:36 | [post update] router [ArrayElement] | semmle.label | [post update] router [ArrayElement] | -| react-use-router.js:23:43:23:48 | router | semmle.label | router | -| react-use-router.js:23:43:23:48 | router [ArrayElement] | semmle.label | router [ArrayElement] | | react-use-router.js:23:43:23:54 | router.query | semmle.label | router.query | | react-use-router.js:23:43:23:61 | router.query.foobar | semmle.label | router.query.foobar | | react-use-router.js:33:21:33:32 | router.query | semmle.label | router.query | @@ -506,8 +502,6 @@ nodes | tst.js:371:16:371:39 | documen ... .search | semmle.label | documen ... .search | | tst.js:374:18:374:23 | target | semmle.label | target | | tst.js:381:7:381:39 | target | semmle.label | target | -| tst.js:381:7:381:39 | target [taint3] | semmle.label | target [taint3] | -| tst.js:381:7:381:39 | target [taint8] | semmle.label | target [taint8] | | tst.js:381:16:381:39 | documen ... .search | semmle.label | documen ... .search | | tst.js:384:18:384:23 | target | semmle.label | target | | tst.js:386:18:386:23 | target | semmle.label | target | @@ -848,13 +842,7 @@ edges | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | provenance | | | react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | provenance | | | react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | provenance | | -| react-use-router.js:23:31:23:36 | [post update] router | react-use-router.js:23:43:23:48 | router | provenance | | -| react-use-router.js:23:31:23:36 | [post update] router [ArrayElement] | react-use-router.js:23:43:23:48 | router [ArrayElement] | provenance | | -| react-use-router.js:23:43:23:48 | router | react-use-router.js:23:43:23:54 | router.query | provenance | | -| react-use-router.js:23:43:23:48 | router [ArrayElement] | react-use-router.js:23:43:23:54 | router.query | provenance | | | react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | provenance | | -| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:31:23:36 | [post update] router | provenance | | -| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:31:23:36 | [post update] router [ArrayElement] | provenance | | | react-use-router.js:33:21:33:32 | router.query | react-use-router.js:33:21:33:39 | router.query.foobar | provenance | | | react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state | provenance | | | react-use-state.js:4:38:4:48 | window.name | react-use-state.js:4:9:4:49 | state | provenance | | @@ -1049,17 +1037,15 @@ edges | tst.js:381:7:381:39 | target | tst.js:397:18:397:23 | target | provenance | | | tst.js:381:7:381:39 | target | tst.js:406:18:406:23 | target | provenance | | | tst.js:381:7:381:39 | target | tst.js:408:19:408:24 | target | provenance | | -| tst.js:381:7:381:39 | target [taint3] | tst.js:392:18:392:23 | target [taint3] | provenance | | -| tst.js:381:7:381:39 | target [taint8] | tst.js:408:19:408:24 | target [taint8] | provenance | | -| tst.js:381:7:381:39 | target [taint8] | tst.js:409:18:409:23 | target [taint8] | provenance | | | tst.js:381:16:381:39 | documen ... .search | tst.js:381:7:381:39 | target | provenance | | | tst.js:386:18:386:23 | target | tst.js:386:18:386:29 | target.taint | provenance | | -| tst.js:391:3:391:8 | [post update] target [taint3] | tst.js:381:7:381:39 | target [taint3] | provenance | | +| tst.js:391:3:391:8 | [post update] target [taint3] | tst.js:392:18:392:23 | target [taint3] | provenance | | | tst.js:391:19:391:42 | documen ... .search | tst.js:391:3:391:8 | [post update] target [taint3] | provenance | | | tst.js:392:18:392:23 | target [taint3] | tst.js:392:18:392:30 | target.taint3 | provenance | | | tst.js:397:18:397:23 | target | tst.js:397:18:397:30 | target.taint5 | provenance | | | tst.js:406:18:406:23 | target | tst.js:406:18:406:30 | target.taint7 | provenance | | -| tst.js:408:3:408:8 | [post update] target [taint8] | tst.js:381:7:381:39 | target [taint8] | provenance | | +| tst.js:408:3:408:8 | [post update] target [taint8] | tst.js:408:19:408:24 | target [taint8] | provenance | | +| tst.js:408:3:408:8 | [post update] target [taint8] | tst.js:409:18:409:23 | target [taint8] | provenance | | | tst.js:408:19:408:24 | target | tst.js:408:19:408:31 | target.taint8 | provenance | | | tst.js:408:19:408:24 | target [taint8] | tst.js:408:19:408:31 | target.taint8 | provenance | | | tst.js:408:19:408:31 | target.taint8 | tst.js:408:3:408:8 | [post update] target [taint8] | provenance | | From 18b39460f593667101fe97b3f0d247367cec339c Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 23 Oct 2024 13:15:21 +0200 Subject: [PATCH 330/514] JS: Add regained results in UnsafeJQueryPlugin These were marked as 'NOT OK' in the test file, but weren't previously flagged for some reason --- .../UnsafeJQueryPlugin.expected | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/UnsafeJQueryPlugin.expected b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/UnsafeJQueryPlugin.expected index cf7af63c122..f246b00d787 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/UnsafeJQueryPlugin.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/UnsafeJQueryPlugin.expected @@ -17,10 +17,26 @@ edges | unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:60:6:60:11 | target | provenance | | | unsafe-jquery-plugin.js:11:16:11:22 | options | unsafe-jquery-plugin.js:11:16:11:29 | options.target | provenance | | | unsafe-jquery-plugin.js:11:16:11:29 | options.target | unsafe-jquery-plugin.js:11:7:11:29 | target | provenance | | +| unsafe-jquery-plugin.js:65:47:65:53 | options | unsafe-jquery-plugin.js:67:37:67:43 | options | provenance | | +| unsafe-jquery-plugin.js:67:3:67:6 | [post update] this [options] | unsafe-jquery-plugin.js:68:7:68:10 | this [options] | provenance | | +| unsafe-jquery-plugin.js:67:24:67:44 | $.exten ... ptions) | unsafe-jquery-plugin.js:67:3:67:6 | [post update] this [options] | provenance | | +| unsafe-jquery-plugin.js:67:37:67:43 | options | unsafe-jquery-plugin.js:67:24:67:44 | $.exten ... ptions) | provenance | | +| unsafe-jquery-plugin.js:68:7:68:10 | this [options] | unsafe-jquery-plugin.js:68:7:68:18 | this.options | provenance | | +| unsafe-jquery-plugin.js:68:7:68:18 | this.options | unsafe-jquery-plugin.js:68:7:68:25 | this.options.parent | provenance | | +| unsafe-jquery-plugin.js:68:7:68:25 | this.options.parent | unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | provenance | Config | | unsafe-jquery-plugin.js:71:38:71:44 | options | unsafe-jquery-plugin.js:72:5:72:11 | options | provenance | | | unsafe-jquery-plugin.js:72:5:72:11 | options | unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | provenance | | | unsafe-jquery-plugin.js:76:38:76:44 | options | unsafe-jquery-plugin.js:77:17:77:23 | options | provenance | | | unsafe-jquery-plugin.js:77:17:77:23 | options | unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | provenance | | +| unsafe-jquery-plugin.js:84:38:84:44 | options | unsafe-jquery-plugin.js:92:5:92:11 | options | provenance | | +| unsafe-jquery-plugin.js:85:14:85:14 | o | unsafe-jquery-plugin.js:86:26:86:26 | o | provenance | | +| unsafe-jquery-plugin.js:86:4:86:7 | [post update] this [o] | unsafe-jquery-plugin.js:87:12:87:15 | this [o] | provenance | | +| unsafe-jquery-plugin.js:86:13:86:27 | $.extend({}, o) | unsafe-jquery-plugin.js:86:4:86:7 | [post update] this [o] | provenance | | +| unsafe-jquery-plugin.js:86:26:86:26 | o | unsafe-jquery-plugin.js:86:13:86:27 | $.extend({}, o) | provenance | | +| unsafe-jquery-plugin.js:87:8:87:24 | t | unsafe-jquery-plugin.js:90:6:90:6 | t | provenance | | +| unsafe-jquery-plugin.js:87:12:87:15 | this [o] | unsafe-jquery-plugin.js:87:12:87:17 | this.o | provenance | | +| unsafe-jquery-plugin.js:87:12:87:17 | this.o | unsafe-jquery-plugin.js:87:8:87:24 | t | provenance | | +| unsafe-jquery-plugin.js:92:5:92:11 | options | unsafe-jquery-plugin.js:85:14:85:14 | o | provenance | | | unsafe-jquery-plugin.js:101:38:101:44 | options | unsafe-jquery-plugin.js:105:6:105:12 | options | provenance | | | unsafe-jquery-plugin.js:102:3:105:13 | options | unsafe-jquery-plugin.js:107:5:107:11 | options | provenance | | | unsafe-jquery-plugin.js:102:13:105:13 | $.exten ... ptions) | unsafe-jquery-plugin.js:102:3:105:13 | options | provenance | | @@ -75,12 +91,30 @@ nodes | unsafe-jquery-plugin.js:48:6:48:11 | target | semmle.label | target | | unsafe-jquery-plugin.js:52:6:52:11 | target | semmle.label | target | | unsafe-jquery-plugin.js:60:6:60:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:65:47:65:53 | options | semmle.label | options | +| unsafe-jquery-plugin.js:67:3:67:6 | [post update] this [options] | semmle.label | [post update] this [options] | +| unsafe-jquery-plugin.js:67:24:67:44 | $.exten ... ptions) | semmle.label | $.exten ... ptions) | +| unsafe-jquery-plugin.js:67:37:67:43 | options | semmle.label | options | +| unsafe-jquery-plugin.js:68:7:68:10 | this [options] | semmle.label | this [options] | +| unsafe-jquery-plugin.js:68:7:68:18 | this.options | semmle.label | this.options | +| unsafe-jquery-plugin.js:68:7:68:25 | this.options.parent | semmle.label | this.options.parent | +| unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | semmle.label | this.options.parent | | unsafe-jquery-plugin.js:71:38:71:44 | options | semmle.label | options | | unsafe-jquery-plugin.js:72:5:72:11 | options | semmle.label | options | | unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | semmle.label | options.foo.bar.baz | | unsafe-jquery-plugin.js:76:38:76:44 | options | semmle.label | options | | unsafe-jquery-plugin.js:77:17:77:23 | options | semmle.label | options | | unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | semmle.label | options.foo.bar.baz | +| unsafe-jquery-plugin.js:84:38:84:44 | options | semmle.label | options | +| unsafe-jquery-plugin.js:85:14:85:14 | o | semmle.label | o | +| unsafe-jquery-plugin.js:86:4:86:7 | [post update] this [o] | semmle.label | [post update] this [o] | +| unsafe-jquery-plugin.js:86:13:86:27 | $.extend({}, o) | semmle.label | $.extend({}, o) | +| unsafe-jquery-plugin.js:86:26:86:26 | o | semmle.label | o | +| unsafe-jquery-plugin.js:87:8:87:24 | t | semmle.label | t | +| unsafe-jquery-plugin.js:87:12:87:15 | this [o] | semmle.label | this [o] | +| unsafe-jquery-plugin.js:87:12:87:17 | this.o | semmle.label | this.o | +| unsafe-jquery-plugin.js:90:6:90:6 | t | semmle.label | t | +| unsafe-jquery-plugin.js:92:5:92:11 | options | semmle.label | options | | unsafe-jquery-plugin.js:101:38:101:44 | options | semmle.label | options | | unsafe-jquery-plugin.js:102:3:105:13 | options | semmle.label | options | | unsafe-jquery-plugin.js:102:13:105:13 | $.exten ... ptions) | semmle.label | $.exten ... ptions) | @@ -135,8 +169,10 @@ subpaths | unsafe-jquery-plugin.js:48:6:48:11 | target | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:48:6:48:11 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:2:19:63:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:52:6:52:11 | target | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:52:6:52:11 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:2:19:63:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:60:6:60:11 | target | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:60:6:60:11 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:2:19:63:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin | +| unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | unsafe-jquery-plugin.js:65:47:65:53 | options | unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:65:19:69:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | unsafe-jquery-plugin.js:71:38:71:44 | options | unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:71:19:74:2 | functio ... / OK\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | unsafe-jquery-plugin.js:76:38:76:44 | options | unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:76:19:78:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin | +| unsafe-jquery-plugin.js:90:6:90:6 | t | unsafe-jquery-plugin.js:84:38:84:44 | options | unsafe-jquery-plugin.js:90:6:90:6 | t | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:84:19:93:2 | functio ... ns);\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:107:5:107:18 | options.target | unsafe-jquery-plugin.js:101:38:101:44 | options | unsafe-jquery-plugin.js:107:5:107:18 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:101:19:108:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:117:5:117:18 | options.target | unsafe-jquery-plugin.js:114:38:114:44 | options | unsafe-jquery-plugin.js:117:5:117:18 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:114:19:118:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:122:5:122:18 | options.target | unsafe-jquery-plugin.js:121:40:121:46 | options | unsafe-jquery-plugin.js:122:5:122:18 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:121:21:123:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin | From 12431888257bbef0fc6cd75309decea023ac11e2 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 23 Oct 2024 13:20:34 +0200 Subject: [PATCH 331/514] JS: Update CleartextLogging with fixed FP --- .../Security/CWE-312/CleartextLogging.expected | 8 -------- .../ql/test/query-tests/Security/CWE-312/passwords.js | 4 ++-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index 26871214fd0..a5273e05758 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -9,9 +9,6 @@ edges | passwords.js:23:9:25:5 | obj2 [x] | passwords.js:26:17:26:20 | obj2 | provenance | | | passwords.js:23:16:25:5 | {\\n ... d\\n } [x] | passwords.js:23:9:25:5 | obj2 [x] | provenance | | | passwords.js:24:12:24:19 | password | passwords.js:23:16:25:5 | {\\n ... d\\n } [x] | provenance | | -| passwords.js:28:9:28:17 | obj3 [x] | passwords.js:29:17:29:20 | obj3 | provenance | | -| passwords.js:30:5:30:8 | [post update] obj3 [x] | passwords.js:28:9:28:17 | obj3 [x] | provenance | | -| passwords.js:30:14:30:21 | password | passwords.js:30:5:30:8 | [post update] obj3 [x] | provenance | | | passwords.js:77:9:77:55 | temp [encryptedPassword] | passwords.js:78:17:78:20 | temp [encryptedPassword] | provenance | | | passwords.js:77:16:77:55 | { encry ... sword } [encryptedPassword] | passwords.js:77:9:77:55 | temp [encryptedPassword] | provenance | | | passwords.js:77:37:77:53 | req.body.password | passwords.js:77:16:77:55 | { encry ... sword } [encryptedPassword] | provenance | | @@ -97,10 +94,6 @@ nodes | passwords.js:23:16:25:5 | {\\n ... d\\n } [x] | semmle.label | {\\n ... d\\n } [x] | | passwords.js:24:12:24:19 | password | semmle.label | password | | passwords.js:26:17:26:20 | obj2 | semmle.label | obj2 | -| passwords.js:28:9:28:17 | obj3 [x] | semmle.label | obj3 [x] | -| passwords.js:29:17:29:20 | obj3 | semmle.label | obj3 | -| passwords.js:30:5:30:8 | [post update] obj3 [x] | semmle.label | [post update] obj3 [x] | -| passwords.js:30:14:30:21 | password | semmle.label | password | | passwords.js:77:9:77:55 | temp [encryptedPassword] | semmle.label | temp [encryptedPassword] | | passwords.js:77:16:77:55 | { encry ... sword } [encryptedPassword] | semmle.label | { encry ... sword } [encryptedPassword] | | passwords.js:77:37:77:53 | req.body.password | semmle.label | req.body.password | @@ -192,7 +185,6 @@ subpaths | passwords.js:16:17:16:38 | `${name ... sword}` | passwords.js:16:29:16:36 | password | passwords.js:16:17:16:38 | `${name ... sword}` | This logs sensitive data returned by $@ as clear text. | passwords.js:16:29:16:36 | password | an access to password | | passwords.js:21:17:21:20 | obj1 | passwords.js:19:19:19:19 | x | passwords.js:21:17:21:20 | obj1 | This logs sensitive data returned by $@ as clear text. | passwords.js:19:19:19:19 | x | an access to password | | passwords.js:26:17:26:20 | obj2 | passwords.js:24:12:24:19 | password | passwords.js:26:17:26:20 | obj2 | This logs sensitive data returned by $@ as clear text. | passwords.js:24:12:24:19 | password | an access to password | -| passwords.js:29:17:29:20 | obj3 | passwords.js:30:14:30:21 | password | passwords.js:29:17:29:20 | obj3 | This logs sensitive data returned by $@ as clear text. | passwords.js:30:14:30:21 | password | an access to password | | passwords.js:78:17:78:38 | temp.en ... assword | passwords.js:77:37:77:53 | req.body.password | passwords.js:78:17:78:38 | temp.en ... assword | This logs sensitive data returned by $@ as clear text. | passwords.js:77:37:77:53 | req.body.password | an access to password | | passwords.js:81:17:81:31 | `pw: ${secret}` | passwords.js:80:18:80:25 | password | passwords.js:81:17:81:31 | `pw: ${secret}` | This logs sensitive data returned by $@ as clear text. | passwords.js:80:18:80:25 | password | an access to password | | passwords.js:93:21:93:46 | "Passwo ... assword | passwords.js:93:39:93:46 | password | passwords.js:93:21:93:46 | "Passwo ... assword | This logs sensitive data returned by $@ as clear text. | passwords.js:93:39:93:46 | password | an access to password | diff --git a/javascript/ql/test/query-tests/Security/CWE-312/passwords.js b/javascript/ql/test/query-tests/Security/CWE-312/passwords.js index 370cf5d5af8..9617de14bdb 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/passwords.js +++ b/javascript/ql/test/query-tests/Security/CWE-312/passwords.js @@ -26,7 +26,7 @@ console.log(obj2); // NOT OK var obj3 = {}; - console.log(obj3); // OK - but still flagged due to flow-insensitive field-analysis. [INCONSISTENCY] + console.log(obj3); // OK obj3.x = password; var fixed_password = "123"; @@ -174,4 +174,4 @@ const debug = require('debug')('test'); const myPasscode = foo(); console.log(myPasscode); // NOT OK -}); \ No newline at end of file +}); From 52ba91a7f8997977a2fc0d49bfa4d424149ad7e1 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 23 Oct 2024 13:21:15 +0200 Subject: [PATCH 332/514] JS: Updates to nodes/edges in tests Only changes to nodes/edges for various reasons, no actual result changes --- .../UntrustedDataToExternalAPI.expected | 24 ++++++------ .../CommandInjection.expected | 4 +- .../UnsafeShellCommandConstruction.expected | 16 ++------ .../ReflectedXss/ReflectedXss.expected | 23 +++-------- .../CWE-089/untyped/SqlInjection.expected | 8 +--- .../ImproperCodeSanitization.expected | 8 +--- .../CWE-200/FileAccessToHttp.expected | 20 +++------- .../Security/CWE-201/PostMessageStar.expected | 6 +-- .../CWE-312/BuildArtifactLeak.expected | 39 ++----------------- .../PrototypePollutingMergeCall.expected | 8 +--- 10 files changed, 40 insertions(+), 116 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected b/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected index c7a61da6e36..60423f3d667 100644 --- a/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected +++ b/javascript/ql/test/query-tests/Security/CWE-020/UntrustedDataToExternalAPI/UntrustedDataToExternalAPI.expected @@ -16,15 +16,15 @@ edges | tst-UntrustedDataToExternalAPI.js:10:19:10:27 | untrusted | tst-UntrustedDataToExternalAPI.js:10:13:10:33 | ['x', u ... d, 'y'] | provenance | | | tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } [z] | tst-UntrustedDataToExternalAPI.js:13:8:17:5 | {\\n ... }\\n } | provenance | | | tst-UntrustedDataToExternalAPI.js:15:16:15:24 | untrusted | tst-UntrustedDataToExternalAPI.js:14:12:16:9 | {\\n ... } [z] | provenance | | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [x] | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | provenance | | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [x] | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | provenance | | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [y] | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | provenance | | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [y] | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | provenance | | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [z] | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | provenance | | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [z] | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | provenance | | -| tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [x] | provenance | | -| tst-UntrustedDataToExternalAPI.js:43:8:43:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [y] | provenance | | -| tst-UntrustedDataToExternalAPI.js:44:8:44:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [z] | provenance | | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} [x] | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | provenance | | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} [y] | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | provenance | | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} [z] | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | provenance | | +| tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | provenance | | +| tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} [x] | provenance | | +| tst-UntrustedDataToExternalAPI.js:43:8:43:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | provenance | | +| tst-UntrustedDataToExternalAPI.js:43:8:43:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} [y] | provenance | | +| tst-UntrustedDataToExternalAPI.js:44:8:44:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | provenance | | +| tst-UntrustedDataToExternalAPI.js:44:8:44:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} [z] | provenance | | nodes | tst-UntrustedDataToExternalAPI.js:3:5:3:27 | untrusted | semmle.label | untrusted | | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | semmle.label | window.name | @@ -42,10 +42,10 @@ nodes | tst-UntrustedDataToExternalAPI.js:33:14:33:22 | untrusted | semmle.label | untrusted | | tst-UntrustedDataToExternalAPI.js:34:34:34:42 | untrusted | semmle.label | untrusted | | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | semmle.label | {} | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [x] | semmle.label | [post update] {\\n x ... usted\\n} [x] | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [y] | semmle.label | [post update] {\\n x ... usted\\n} [y] | -| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | [post update] {\\n x ... usted\\n} [z] | semmle.label | [post update] {\\n x ... usted\\n} [z] | | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | semmle.label | {\\n x ... usted\\n} | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} [x] | semmle.label | {\\n x ... usted\\n} [x] | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} [y] | semmle.label | {\\n x ... usted\\n} [y] | +| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} [z] | semmle.label | {\\n x ... usted\\n} [z] | | tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted | semmle.label | untrusted | | tst-UntrustedDataToExternalAPI.js:43:8:43:16 | untrusted | semmle.label | untrusted | | tst-UntrustedDataToExternalAPI.js:44:8:44:16 | untrusted | semmle.label | untrusted | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected index ad14af14118..e8d95064b8e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected @@ -27,8 +27,7 @@ edges | child_process-test.js:6:15:6:49 | url.par ... ry.path | child_process-test.js:6:9:6:49 | cmd | provenance | | | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:6:15:6:38 | url.par ... , true) | provenance | | | child_process-test.js:25:21:25:23 | cmd | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | provenance | | -| child_process-test.js:46:9:46:17 | args [1] | child_process-test.js:49:15:49:18 | args [1] | provenance | | -| child_process-test.js:48:5:48:8 | [post update] args [1] | child_process-test.js:46:9:46:17 | args [1] | provenance | | +| child_process-test.js:48:5:48:8 | [post update] args [1] | child_process-test.js:49:15:49:18 | args [1] | provenance | | | child_process-test.js:48:15:48:17 | cmd | child_process-test.js:48:5:48:8 | [post update] args [1] | provenance | | | child_process-test.js:49:15:49:18 | args [1] | child_process-test.js:66:19:66:22 | args | provenance | | | child_process-test.js:56:46:56:57 | ["bar", cmd] [1] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | provenance | | @@ -121,7 +120,6 @@ nodes | child_process-test.js:25:21:25:23 | cmd | semmle.label | cmd | | child_process-test.js:39:26:39:28 | cmd | semmle.label | cmd | | child_process-test.js:43:15:43:17 | cmd | semmle.label | cmd | -| child_process-test.js:46:9:46:17 | args [1] | semmle.label | args [1] | | child_process-test.js:48:5:48:8 | [post update] args [1] | semmle.label | [post update] args [1] | | child_process-test.js:48:15:48:17 | cmd | semmle.label | cmd | | child_process-test.js:48:15:48:17 | cmd | semmle.label | cmd | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected index 786c18cb8da..9585663d11a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected @@ -89,10 +89,8 @@ edges | lib/lib.js:414:40:414:43 | name | lib/lib.js:426:11:426:14 | name | provenance | | | lib/lib.js:414:40:414:43 | name | lib/lib.js:426:11:426:14 | name | provenance | | | lib/lib.js:414:40:414:43 | name | lib/lib.js:428:36:428:39 | name | provenance | | -| lib/lib.js:425:6:425:13 | arr | lib/lib.js:427:14:427:16 | arr | provenance | | -| lib/lib.js:425:6:425:13 | arr [ArrayElement] | lib/lib.js:427:14:427:16 | arr | provenance | | -| lib/lib.js:426:2:426:4 | [post update] arr | lib/lib.js:425:6:425:13 | arr | provenance | | -| lib/lib.js:426:2:426:4 | [post update] arr [ArrayElement] | lib/lib.js:425:6:425:13 | arr [ArrayElement] | provenance | | +| lib/lib.js:426:2:426:4 | [post update] arr | lib/lib.js:427:14:427:16 | arr | provenance | | +| lib/lib.js:426:2:426:4 | [post update] arr [ArrayElement] | lib/lib.js:427:14:427:16 | arr | provenance | | | lib/lib.js:426:11:426:14 | name | lib/lib.js:426:2:426:4 | [post update] arr | provenance | | | lib/lib.js:426:11:426:14 | name | lib/lib.js:426:2:426:4 | [post update] arr [ArrayElement] | provenance | | | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:428:14:428:58 | build(" ... + '-') | provenance | | @@ -100,10 +98,8 @@ edges | lib/lib.js:428:36:428:39 | name | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | provenance | | | lib/lib.js:431:23:431:26 | last | lib/lib.js:436:19:436:22 | last | provenance | | | lib/lib.js:431:23:431:26 | last | lib/lib.js:436:19:436:22 | last | provenance | | -| lib/lib.js:432:6:432:13 | arr | lib/lib.js:437:9:437:11 | arr | provenance | | -| lib/lib.js:432:6:432:13 | arr [ArrayElement] | lib/lib.js:437:9:437:11 | arr [ArrayElement] | provenance | | -| lib/lib.js:436:10:436:12 | [post update] arr | lib/lib.js:432:6:432:13 | arr | provenance | | -| lib/lib.js:436:10:436:12 | [post update] arr [ArrayElement] | lib/lib.js:432:6:432:13 | arr [ArrayElement] | provenance | | +| lib/lib.js:436:10:436:12 | [post update] arr | lib/lib.js:437:9:437:11 | arr | provenance | | +| lib/lib.js:436:10:436:12 | [post update] arr [ArrayElement] | lib/lib.js:437:9:437:11 | arr [ArrayElement] | provenance | | | lib/lib.js:436:19:436:22 | last | lib/lib.js:436:10:436:12 | [post update] arr | provenance | | | lib/lib.js:436:19:436:22 | last | lib/lib.js:436:10:436:12 | [post update] arr [ArrayElement] | provenance | | | lib/lib.js:441:39:441:42 | name | lib/lib.js:442:24:442:27 | name | provenance | | @@ -272,8 +268,6 @@ nodes | lib/lib.js:419:32:419:35 | name | semmle.label | name | | lib/lib.js:420:29:420:32 | name | semmle.label | name | | lib/lib.js:424:24:424:27 | name | semmle.label | name | -| lib/lib.js:425:6:425:13 | arr | semmle.label | arr | -| lib/lib.js:425:6:425:13 | arr [ArrayElement] | semmle.label | arr [ArrayElement] | | lib/lib.js:426:2:426:4 | [post update] arr | semmle.label | [post update] arr | | lib/lib.js:426:2:426:4 | [post update] arr [ArrayElement] | semmle.label | [post update] arr [ArrayElement] | | lib/lib.js:426:11:426:14 | name | semmle.label | name | @@ -283,8 +277,6 @@ nodes | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | semmle.label | (name ? ... ) + '-' | | lib/lib.js:428:36:428:39 | name | semmle.label | name | | lib/lib.js:431:23:431:26 | last | semmle.label | last | -| lib/lib.js:432:6:432:13 | arr | semmle.label | arr | -| lib/lib.js:432:6:432:13 | arr [ArrayElement] | semmle.label | arr [ArrayElement] | | lib/lib.js:436:10:436:12 | [post update] arr | semmle.label | [post update] arr | | lib/lib.js:436:10:436:12 | [post update] arr [ArrayElement] | semmle.label | [post update] arr [ArrayElement] | | lib/lib.js:436:19:436:22 | last | semmle.label | last | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected index ac9d399bd96..682a0694ce4 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected @@ -44,15 +44,13 @@ edges | ReflectedXssGood3.js:68:22:68:26 | value | ReflectedXssGood3.js:105:18:105:22 | value | provenance | | | ReflectedXssGood3.js:77:7:77:37 | parts | ReflectedXssGood3.js:108:10:108:14 | parts | provenance | | | ReflectedXssGood3.js:77:7:77:37 | parts [0] | ReflectedXssGood3.js:108:10:108:14 | parts [0] | provenance | | -| ReflectedXssGood3.js:77:7:77:37 | parts [ArrayElement] | ReflectedXssGood3.js:108:10:108:14 | parts [ArrayElement] | provenance | | | ReflectedXssGood3.js:77:15:77:37 | [value. ... (0, i)] [0] | ReflectedXssGood3.js:77:7:77:37 | parts [0] | provenance | | | ReflectedXssGood3.js:77:16:77:20 | value | ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | provenance | | | ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | ReflectedXssGood3.js:77:7:77:37 | parts | provenance | | | ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | ReflectedXssGood3.js:77:15:77:37 | [value. ... (0, i)] [0] | provenance | | | ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | provenance | | -| ReflectedXssGood3.js:105:7:105:11 | [post update] parts | ReflectedXssGood3.js:77:7:77:37 | parts | provenance | | -| ReflectedXssGood3.js:105:7:105:11 | [post update] parts | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | provenance | | -| ReflectedXssGood3.js:105:7:105:11 | [post update] parts [ArrayElement] | ReflectedXssGood3.js:77:7:77:37 | parts [ArrayElement] | provenance | | +| ReflectedXssGood3.js:105:7:105:11 | [post update] parts | ReflectedXssGood3.js:108:10:108:14 | parts | provenance | | +| ReflectedXssGood3.js:105:7:105:11 | [post update] parts [ArrayElement] | ReflectedXssGood3.js:108:10:108:14 | parts [ArrayElement] | provenance | | | ReflectedXssGood3.js:105:18:105:22 | value | ReflectedXssGood3.js:105:18:105:38 | value.s ... g(j, i) | provenance | | | ReflectedXssGood3.js:105:18:105:38 | value.s ... g(j, i) | ReflectedXssGood3.js:105:7:105:11 | [post update] parts | provenance | | | ReflectedXssGood3.js:105:18:105:38 | value.s ... g(j, i) | ReflectedXssGood3.js:105:7:105:11 | [post update] parts [ArrayElement] | provenance | | @@ -103,8 +101,7 @@ edges | tst2.js:30:7:30:24 | p | tst2.js:33:11:33:11 | p | provenance | | | tst2.js:30:7:30:24 | p | tst2.js:36:12:36:12 | p | provenance | | | tst2.js:30:9:30:9 | p | tst2.js:30:7:30:24 | p | provenance | | -| tst2.js:32:7:32:14 | obj [p] | tst2.js:34:21:34:23 | obj [p] | provenance | | -| tst2.js:33:3:33:5 | [post update] obj [p] | tst2.js:32:7:32:14 | obj [p] | provenance | | +| tst2.js:33:3:33:5 | [post update] obj [p] | tst2.js:34:21:34:23 | obj [p] | provenance | | | tst2.js:33:11:33:11 | p | tst2.js:33:3:33:5 | [post update] obj [p] | provenance | | | tst2.js:34:7:34:24 | other [p] | tst2.js:37:12:37:16 | other [p] | provenance | | | tst2.js:34:15:34:24 | clone(obj) [p] | tst2.js:34:7:34:24 | other [p] | provenance | | @@ -118,8 +115,7 @@ edges | tst2.js:57:7:57:24 | p | tst2.js:60:11:60:11 | p | provenance | | | tst2.js:57:7:57:24 | p | tst2.js:63:12:63:12 | p | provenance | | | tst2.js:57:9:57:9 | p | tst2.js:57:7:57:24 | p | provenance | | -| tst2.js:59:7:59:14 | obj [p] | tst2.js:61:22:61:24 | obj [p] | provenance | | -| tst2.js:60:3:60:5 | [post update] obj [p] | tst2.js:59:7:59:14 | obj [p] | provenance | | +| tst2.js:60:3:60:5 | [post update] obj [p] | tst2.js:61:22:61:24 | obj [p] | provenance | | | tst2.js:60:11:60:11 | p | tst2.js:60:3:60:5 | [post update] obj [p] | provenance | | | tst2.js:61:7:61:25 | other [p] | tst2.js:64:12:64:16 | other [p] | provenance | | | tst2.js:61:15:61:25 | fclone(obj) [p] | tst2.js:61:7:61:25 | other [p] | provenance | | @@ -128,8 +124,7 @@ edges | tst2.js:69:7:69:24 | p | tst2.js:72:11:72:11 | p | provenance | | | tst2.js:69:7:69:24 | p | tst2.js:75:12:75:12 | p | provenance | | | tst2.js:69:9:69:9 | p | tst2.js:69:7:69:24 | p | provenance | | -| tst2.js:71:7:71:14 | obj [p] | tst2.js:73:40:73:42 | obj [p] | provenance | | -| tst2.js:72:3:72:5 | [post update] obj [p] | tst2.js:71:7:71:14 | obj [p] | provenance | | +| tst2.js:72:3:72:5 | [post update] obj [p] | tst2.js:73:40:73:42 | obj [p] | provenance | | | tst2.js:72:11:72:11 | p | tst2.js:72:3:72:5 | [post update] obj [p] | provenance | | | tst2.js:73:7:73:44 | other [p] | tst2.js:76:12:76:16 | other [p] | provenance | | | tst2.js:73:15:73:44 | jc.retr ... e(obj)) [p] | tst2.js:73:7:73:44 | other [p] | provenance | | @@ -139,8 +134,7 @@ edges | tst2.js:82:7:82:24 | p | tst2.js:85:11:85:11 | p | provenance | | | tst2.js:82:7:82:24 | p | tst2.js:88:12:88:12 | p | provenance | | | tst2.js:82:9:82:9 | p | tst2.js:82:7:82:24 | p | provenance | | -| tst2.js:84:7:84:14 | obj [p] | tst2.js:86:24:86:26 | obj [p] | provenance | | -| tst2.js:85:3:85:5 | [post update] obj [p] | tst2.js:84:7:84:14 | obj [p] | provenance | | +| tst2.js:85:3:85:5 | [post update] obj [p] | tst2.js:86:24:86:26 | obj [p] | provenance | | | tst2.js:85:11:85:11 | p | tst2.js:85:3:85:5 | [post update] obj [p] | provenance | | | tst2.js:86:7:86:27 | other [p] | tst2.js:89:12:89:16 | other [p] | provenance | | | tst2.js:86:15:86:27 | sortKeys(obj) [p] | tst2.js:86:7:86:27 | other [p] | provenance | | @@ -220,7 +214,6 @@ nodes | ReflectedXssGood3.js:68:22:68:26 | value | semmle.label | value | | ReflectedXssGood3.js:77:7:77:37 | parts | semmle.label | parts | | ReflectedXssGood3.js:77:7:77:37 | parts [0] | semmle.label | parts [0] | -| ReflectedXssGood3.js:77:7:77:37 | parts [ArrayElement] | semmle.label | parts [ArrayElement] | | ReflectedXssGood3.js:77:15:77:37 | [value. ... (0, i)] [0] | semmle.label | [value. ... (0, i)] [0] | | ReflectedXssGood3.js:77:16:77:20 | value | semmle.label | value | | ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | semmle.label | value.s ... g(0, i) | @@ -290,7 +283,6 @@ nodes | tst2.js:21:14:21:14 | p | semmle.label | p | | tst2.js:30:7:30:24 | p | semmle.label | p | | tst2.js:30:9:30:9 | p | semmle.label | p | -| tst2.js:32:7:32:14 | obj [p] | semmle.label | obj [p] | | tst2.js:33:3:33:5 | [post update] obj [p] | semmle.label | [post update] obj [p] | | tst2.js:33:11:33:11 | p | semmle.label | p | | tst2.js:34:7:34:24 | other [p] | semmle.label | other [p] | @@ -307,7 +299,6 @@ nodes | tst2.js:51:12:51:17 | unsafe | semmle.label | unsafe | | tst2.js:57:7:57:24 | p | semmle.label | p | | tst2.js:57:9:57:9 | p | semmle.label | p | -| tst2.js:59:7:59:14 | obj [p] | semmle.label | obj [p] | | tst2.js:60:3:60:5 | [post update] obj [p] | semmle.label | [post update] obj [p] | | tst2.js:60:11:60:11 | p | semmle.label | p | | tst2.js:61:7:61:25 | other [p] | semmle.label | other [p] | @@ -318,7 +309,6 @@ nodes | tst2.js:64:12:64:18 | other.p | semmle.label | other.p | | tst2.js:69:7:69:24 | p | semmle.label | p | | tst2.js:69:9:69:9 | p | semmle.label | p | -| tst2.js:71:7:71:14 | obj [p] | semmle.label | obj [p] | | tst2.js:72:3:72:5 | [post update] obj [p] | semmle.label | [post update] obj [p] | | tst2.js:72:11:72:11 | p | semmle.label | p | | tst2.js:73:7:73:44 | other [p] | semmle.label | other [p] | @@ -330,7 +320,6 @@ nodes | tst2.js:76:12:76:18 | other.p | semmle.label | other.p | | tst2.js:82:7:82:24 | p | semmle.label | p | | tst2.js:82:9:82:9 | p | semmle.label | p | -| tst2.js:84:7:84:14 | obj [p] | semmle.label | obj [p] | | tst2.js:85:3:85:5 | [post update] obj [p] | semmle.label | [post update] obj [p] | | tst2.js:85:11:85:11 | p | semmle.label | p | | tst2.js:86:7:86:27 | other [p] | semmle.label | other [p] | diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected index 1f9ea0d7817..8a50f15963b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected @@ -52,8 +52,6 @@ nodes | json-schema-validator.js:61:22:61:26 | query | semmle.label | query | | koarouter.js:5:11:5:33 | version | semmle.label | version | | koarouter.js:5:13:5:19 | version | semmle.label | version | -| koarouter.js:11:11:11:28 | conditions | semmle.label | conditions | -| koarouter.js:11:11:11:28 | conditions [ArrayElement] | semmle.label | conditions [ArrayElement] | | koarouter.js:14:9:14:18 | [post update] conditions | semmle.label | [post update] conditions | | koarouter.js:14:9:14:18 | [post update] conditions [ArrayElement] | semmle.label | [post update] conditions [ArrayElement] | | koarouter.js:14:25:14:46 | `versio ... rsion}` | semmle.label | `versio ... rsion}` | @@ -327,10 +325,8 @@ edges | json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) | provenance | Config | | koarouter.js:5:11:5:33 | version | koarouter.js:14:38:14:44 | version | provenance | | | koarouter.js:5:13:5:19 | version | koarouter.js:5:11:5:33 | version | provenance | | -| koarouter.js:11:11:11:28 | conditions | koarouter.js:17:52:17:61 | conditions | provenance | | -| koarouter.js:11:11:11:28 | conditions [ArrayElement] | koarouter.js:17:52:17:61 | conditions [ArrayElement] | provenance | | -| koarouter.js:14:9:14:18 | [post update] conditions | koarouter.js:11:11:11:28 | conditions | provenance | | -| koarouter.js:14:9:14:18 | [post update] conditions [ArrayElement] | koarouter.js:11:11:11:28 | conditions [ArrayElement] | provenance | | +| koarouter.js:14:9:14:18 | [post update] conditions | koarouter.js:17:52:17:61 | conditions | provenance | | +| koarouter.js:14:9:14:18 | [post update] conditions [ArrayElement] | koarouter.js:17:52:17:61 | conditions [ArrayElement] | provenance | | | koarouter.js:14:25:14:46 | `versio ... rsion}` | koarouter.js:14:9:14:18 | [post update] conditions | provenance | | | koarouter.js:14:25:14:46 | `versio ... rsion}` | koarouter.js:14:9:14:18 | [post update] conditions [ArrayElement] | provenance | | | koarouter.js:14:38:14:44 | version | koarouter.js:14:25:14:46 | `versio ... rsion}` | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/ImproperCodeSanitization.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/ImproperCodeSanitization.expected index 1600e99b12f..3b86bfb074d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/ImproperCodeSanitization.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/ImproperCodeSanitization.expected @@ -1,10 +1,8 @@ edges | bad-code-sanitization.js:2:12:2:90 | /^[_$a- ... key)}]` | bad-code-sanitization.js:7:31:7:43 | safeProp(key) | provenance | | | bad-code-sanitization.js:2:69:2:87 | JSON.stringify(key) | bad-code-sanitization.js:2:12:2:90 | /^[_$a- ... key)}]` | provenance | | -| bad-code-sanitization.js:6:11:6:25 | statements | bad-code-sanitization.js:8:27:8:36 | statements | provenance | | -| bad-code-sanitization.js:6:11:6:25 | statements [ArrayElement] | bad-code-sanitization.js:8:27:8:36 | statements [ArrayElement] | provenance | | -| bad-code-sanitization.js:7:5:7:14 | [post update] statements | bad-code-sanitization.js:6:11:6:25 | statements | provenance | | -| bad-code-sanitization.js:7:5:7:14 | [post update] statements [ArrayElement] | bad-code-sanitization.js:6:11:6:25 | statements [ArrayElement] | provenance | | +| bad-code-sanitization.js:7:5:7:14 | [post update] statements | bad-code-sanitization.js:8:27:8:36 | statements | provenance | | +| bad-code-sanitization.js:7:5:7:14 | [post update] statements [ArrayElement] | bad-code-sanitization.js:8:27:8:36 | statements [ArrayElement] | provenance | | | bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | bad-code-sanitization.js:7:5:7:14 | [post update] statements | provenance | | | bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | bad-code-sanitization.js:7:5:7:14 | [post update] statements [ArrayElement] | provenance | | | bad-code-sanitization.js:7:31:7:43 | safeProp(key) | bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | provenance | | @@ -15,8 +13,6 @@ edges nodes | bad-code-sanitization.js:2:12:2:90 | /^[_$a- ... key)}]` | semmle.label | /^[_$a- ... key)}]` | | bad-code-sanitization.js:2:69:2:87 | JSON.stringify(key) | semmle.label | JSON.stringify(key) | -| bad-code-sanitization.js:6:11:6:25 | statements | semmle.label | statements | -| bad-code-sanitization.js:6:11:6:25 | statements [ArrayElement] | semmle.label | statements [ArrayElement] | | bad-code-sanitization.js:7:5:7:14 | [post update] statements | semmle.label | [post update] statements | | bad-code-sanitization.js:7:5:7:14 | [post update] statements [ArrayElement] | semmle.label | [post update] statements [ArrayElement] | | bad-code-sanitization.js:7:21:7:70 | `${name ... key])}` | semmle.label | `${name ... key])}` | diff --git a/javascript/ql/test/query-tests/Security/CWE-200/FileAccessToHttp.expected b/javascript/ql/test/query-tests/Security/CWE-200/FileAccessToHttp.expected index c53df2b9abd..2aa2fcbe302 100644 --- a/javascript/ql/test/query-tests/Security/CWE-200/FileAccessToHttp.expected +++ b/javascript/ql/test/query-tests/Security/CWE-200/FileAccessToHttp.expected @@ -1,8 +1,7 @@ edges | FileAccessToHttp.js:4:5:4:47 | content | FileAccessToHttp.js:9:23:9:29 | content | provenance | | | FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | FileAccessToHttp.js:4:5:4:47 | content | provenance | | -| FileAccessToHttp.js:5:11:10:1 | [post update] {\\n hos ... ent }\\n} [headers, Referer] | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | provenance | | -| FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | FileAccessToHttp.js:5:11:10:1 | [post update] {\\n hos ... ent }\\n} [headers, Referer] | provenance | | +| FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | provenance | | | FileAccessToHttp.js:9:23:9:29 | content | FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | provenance | | | bufferRead.js:12:13:12:43 | buffer | bufferRead.js:13:21:13:26 | buffer | provenance | | | bufferRead.js:12:13:12:43 | buffer | bufferRead.js:13:32:13:37 | buffer | provenance | | @@ -20,11 +19,9 @@ edges | readStreamRead.js:13:13:13:35 | chunk | readStreamRead.js:30:19:30:23 | chunk | provenance | | | readStreamRead.js:13:21:13:35 | readable.read() | readStreamRead.js:13:13:13:35 | chunk | provenance | | | request.js:6:19:6:26 | jsonData | request.js:8:12:8:19 | jsonData | provenance | | -| request.js:8:11:8:20 | [post update] {jsonData} [jsonData] | request.js:8:11:8:20 | {jsonData} | provenance | | -| request.js:8:12:8:19 | jsonData | request.js:8:11:8:20 | [post update] {jsonData} [jsonData] | provenance | | +| request.js:8:12:8:19 | jsonData | request.js:8:11:8:20 | {jsonData} | provenance | | | request.js:13:18:13:24 | xmlData | request.js:22:11:22:17 | xmlData | provenance | | -| request.js:16:11:23:3 | [post update] {\\n u ... ody\\n } [body] | request.js:16:11:23:3 | {\\n u ... ody\\n } | provenance | | -| request.js:22:11:22:17 | xmlData | request.js:16:11:23:3 | [post update] {\\n u ... ody\\n } [body] | provenance | | +| request.js:22:11:22:17 | xmlData | request.js:16:11:23:3 | {\\n u ... ody\\n } | provenance | | | request.js:28:52:28:55 | data | request.js:35:14:35:17 | data | provenance | | | request.js:35:14:35:17 | data | request.js:6:19:6:26 | jsonData | provenance | | | request.js:43:51:43:54 | data | request.js:50:13:50:16 | data | provenance | | @@ -38,18 +35,15 @@ edges | sentAsHeaders.js:12:19:12:25 | content | sentAsHeaders.js:12:19:12:74 | content ... =", "") | provenance | | | sentAsHeaders.js:12:19:12:74 | content ... =", "") | sentAsHeaders.js:12:19:12:81 | content ... .trim() | provenance | | | sentAsHeaders.js:12:19:12:81 | content ... .trim() | sentAsHeaders.js:12:9:12:81 | content | provenance | | -| sentAsHeaders.js:14:20:19:9 | [post update] {\\n ... } [headers, Referer] | sentAsHeaders.js:14:20:19:9 | {\\n ... } | provenance | | -| sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } [Referer] | sentAsHeaders.js:14:20:19:9 | [post update] {\\n ... } [headers, Referer] | provenance | | +| sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } [Referer] | sentAsHeaders.js:14:20:19:9 | {\\n ... } | provenance | | | sentAsHeaders.js:18:31:18:53 | "http:/ ... content | sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } [Referer] | provenance | | | sentAsHeaders.js:18:47:18:53 | content | sentAsHeaders.js:18:31:18:53 | "http:/ ... content | provenance | | -| sentAsHeaders.js:20:20:25:9 | [post update] {\\n ... } [headers, Referer] | sentAsHeaders.js:20:20:25:9 | {\\n ... } | provenance | | -| sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } [Referer] | sentAsHeaders.js:20:20:25:9 | [post update] {\\n ... } [headers, Referer] | provenance | | +| sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } [Referer] | sentAsHeaders.js:20:20:25:9 | {\\n ... } | provenance | | | sentAsHeaders.js:24:31:24:53 | "http:/ ... content | sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } [Referer] | provenance | | | sentAsHeaders.js:24:47:24:53 | content | sentAsHeaders.js:24:31:24:53 | "http:/ ... content | provenance | | nodes | FileAccessToHttp.js:4:5:4:47 | content | semmle.label | content | | FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | semmle.label | fs.read ... "utf8") | -| FileAccessToHttp.js:5:11:10:1 | [post update] {\\n hos ... ent }\\n} [headers, Referer] | semmle.label | [post update] {\\n hos ... ent }\\n} [headers, Referer] | | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | semmle.label | {\\n hos ... ent }\\n} | | FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | semmle.label | { Referer: content } [Referer] | | FileAccessToHttp.js:9:23:9:29 | content | semmle.label | content | @@ -71,11 +65,9 @@ nodes | readStreamRead.js:13:21:13:35 | readable.read() | semmle.label | readable.read() | | readStreamRead.js:30:19:30:23 | chunk | semmle.label | chunk | | request.js:6:19:6:26 | jsonData | semmle.label | jsonData | -| request.js:8:11:8:20 | [post update] {jsonData} [jsonData] | semmle.label | [post update] {jsonData} [jsonData] | | request.js:8:11:8:20 | {jsonData} | semmle.label | {jsonData} | | request.js:8:12:8:19 | jsonData | semmle.label | jsonData | | request.js:13:18:13:24 | xmlData | semmle.label | xmlData | -| request.js:16:11:23:3 | [post update] {\\n u ... ody\\n } [body] | semmle.label | [post update] {\\n u ... ody\\n } [body] | | request.js:16:11:23:3 | {\\n u ... ody\\n } | semmle.label | {\\n u ... ody\\n } | | request.js:22:11:22:17 | xmlData | semmle.label | xmlData | | request.js:28:52:28:55 | data | semmle.label | data | @@ -90,12 +82,10 @@ nodes | sentAsHeaders.js:12:19:12:25 | content | semmle.label | content | | sentAsHeaders.js:12:19:12:74 | content ... =", "") | semmle.label | content ... =", "") | | sentAsHeaders.js:12:19:12:81 | content ... .trim() | semmle.label | content ... .trim() | -| sentAsHeaders.js:14:20:19:9 | [post update] {\\n ... } [headers, Referer] | semmle.label | [post update] {\\n ... } [headers, Referer] | | sentAsHeaders.js:14:20:19:9 | {\\n ... } | semmle.label | {\\n ... } | | sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } [Referer] | semmle.label | { Refer ... ntent } [Referer] | | sentAsHeaders.js:18:31:18:53 | "http:/ ... content | semmle.label | "http:/ ... content | | sentAsHeaders.js:18:47:18:53 | content | semmle.label | content | -| sentAsHeaders.js:20:20:25:9 | [post update] {\\n ... } [headers, Referer] | semmle.label | [post update] {\\n ... } [headers, Referer] | | sentAsHeaders.js:20:20:25:9 | {\\n ... } | semmle.label | {\\n ... } | | sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } [Referer] | semmle.label | { Refer ... ntent } [Referer] | | sentAsHeaders.js:24:31:24:53 | "http:/ ... content | semmle.label | "http:/ ... content | diff --git a/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected b/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected index 23f4ed0c9b6..bd939420ab3 100644 --- a/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected +++ b/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected @@ -1,12 +1,10 @@ edges -| PostMessageStar2.js:4:7:4:15 | data [foo] | PostMessageStar2.js:8:29:8:32 | data | provenance | | -| PostMessageStar2.js:4:7:4:15 | data [foo] | PostMessageStar2.js:9:29:9:32 | data [foo] | provenance | | -| PostMessageStar2.js:5:3:5:6 | [post update] data [foo] | PostMessageStar2.js:4:7:4:15 | data [foo] | provenance | | +| PostMessageStar2.js:5:3:5:6 | [post update] data [foo] | PostMessageStar2.js:8:29:8:32 | data | provenance | | +| PostMessageStar2.js:5:3:5:6 | [post update] data [foo] | PostMessageStar2.js:9:29:9:32 | data [foo] | provenance | | | PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:5:3:5:6 | [post update] data [foo] | provenance | | | PostMessageStar2.js:9:29:9:32 | data [foo] | PostMessageStar2.js:9:29:9:36 | data.foo | provenance | | nodes | PostMessageStar2.js:1:27:1:34 | password | semmle.label | password | -| PostMessageStar2.js:4:7:4:15 | data [foo] | semmle.label | data [foo] | | PostMessageStar2.js:5:3:5:6 | [post update] data [foo] | semmle.label | [post update] data [foo] | | PostMessageStar2.js:5:14:5:21 | password | semmle.label | password | | PostMessageStar2.js:8:29:8:32 | data | semmle.label | data | diff --git a/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected b/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected index f891e9e7a64..a5f0eb8e860 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/BuildArtifactLeak.expected @@ -1,89 +1,58 @@ edges -| build-leaks.js:4:39:6:1 | [post update] { // NO ... .env)\\n} [process.env] | build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | provenance | | -| build-leaks.js:5:20:5:46 | JSON.st ... ss.env) | build-leaks.js:4:39:6:1 | [post update] { // NO ... .env)\\n} [process.env] | provenance | | +| build-leaks.js:5:20:5:46 | JSON.st ... ss.env) | build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | provenance | | | build-leaks.js:5:35:5:45 | process.env | build-leaks.js:5:20:5:46 | JSON.st ... ss.env) | provenance | | | build-leaks.js:13:11:19:10 | raw | build-leaks.js:22:36:22:38 | raw | provenance | | | build-leaks.js:13:17:19:10 | Object. ... }) | build-leaks.js:13:11:19:10 | raw | provenance | | -| build-leaks.js:14:18:14:20 | env | build-leaks.js:16:20:16:22 | env | provenance | | -| build-leaks.js:14:18:14:20 | env | build-leaks.js:16:20:16:22 | env | provenance | | -| build-leaks.js:14:18:14:20 | env [Return] | build-leaks.js:17:12:19:9 | [post update] {\\n ... } | provenance | | -| build-leaks.js:15:13:15:15 | [post update] env | build-leaks.js:14:18:14:20 | env | provenance | | -| build-leaks.js:15:13:15:15 | [post update] env | build-leaks.js:14:18:14:20 | env [Return] | provenance | | +| build-leaks.js:15:13:15:15 | [post update] env | build-leaks.js:16:20:16:22 | env | provenance | | | build-leaks.js:15:24:15:34 | process.env | build-leaks.js:15:13:15:15 | [post update] env | provenance | Config | | build-leaks.js:16:20:16:22 | env | build-leaks.js:13:17:19:10 | Object. ... }) | provenance | | -| build-leaks.js:16:20:16:22 | env | build-leaks.js:14:18:14:20 | env | provenance | | | build-leaks.js:16:20:16:22 | env | build-leaks.js:22:49:22:51 | env | provenance | | -| build-leaks.js:17:12:19:9 | [post update] {\\n ... } | build-leaks.js:17:12:19:9 | {\\n ... } | provenance | | -| build-leaks.js:17:12:19:9 | {\\n ... } | build-leaks.js:13:17:19:10 | Object. ... }) | provenance | | -| build-leaks.js:17:12:19:9 | {\\n ... } | build-leaks.js:14:18:14:20 | env | provenance | | | build-leaks.js:21:11:26:5 | stringifed [process.env] | build-leaks.js:30:22:30:31 | stringifed [process.env] | provenance | | | build-leaks.js:21:24:26:5 | {\\n ... )\\n } [process.env] | build-leaks.js:21:11:26:5 | stringifed [process.env] | provenance | | | build-leaks.js:22:24:25:14 | Object. ... }, {}) | build-leaks.js:21:24:26:5 | {\\n ... )\\n } [process.env] | provenance | | | build-leaks.js:22:36:22:38 | raw | build-leaks.js:22:24:25:14 | Object. ... }, {}) | provenance | Config | | build-leaks.js:22:36:22:38 | raw | build-leaks.js:22:49:22:51 | env | provenance | Config | | build-leaks.js:22:36:22:38 | raw | build-leaks.js:23:39:23:41 | raw | provenance | | -| build-leaks.js:22:36:22:38 | raw | build-leaks.js:25:12:25:13 | [post update] {} | provenance | Config | | build-leaks.js:22:49:22:51 | env | build-leaks.js:24:20:24:22 | env | provenance | | -| build-leaks.js:22:49:22:51 | env | build-leaks.js:24:20:24:22 | env | provenance | | -| build-leaks.js:23:13:23:15 | [post update] env | build-leaks.js:22:49:22:51 | env | provenance | | -| build-leaks.js:23:13:23:15 | [post update] env | build-leaks.js:22:49:22:51 | env [Return] | provenance | | +| build-leaks.js:23:13:23:15 | [post update] env | build-leaks.js:24:20:24:22 | env | provenance | | | build-leaks.js:23:39:23:41 | raw | build-leaks.js:23:13:23:15 | [post update] env | provenance | Config | -| build-leaks.js:25:12:25:13 | [post update] {} | build-leaks.js:25:12:25:13 | {} | provenance | | -| build-leaks.js:25:12:25:13 | {} | build-leaks.js:22:24:25:14 | Object. ... }, {}) | provenance | | -| build-leaks.js:25:12:25:13 | {} | build-leaks.js:22:49:22:51 | env | provenance | | | build-leaks.js:28:12:31:5 | {\\n ... d\\n } [stringified, process.env] | build-leaks.js:34:26:34:45 | getEnv('production') [stringified, process.env] | provenance | | | build-leaks.js:30:22:30:31 | stringifed [process.env] | build-leaks.js:28:12:31:5 | {\\n ... d\\n } [stringified, process.env] | provenance | | | build-leaks.js:34:26:34:45 | getEnv('production') [stringified, process.env] | build-leaks.js:34:26:34:57 | getEnv( ... ngified | provenance | | | build-leaks.js:40:9:40:60 | pw | build-leaks.js:41:82:41:83 | pw | provenance | | | build-leaks.js:40:14:40:60 | url.par ... assword | build-leaks.js:40:9:40:60 | pw | provenance | | -| build-leaks.js:41:43:41:86 | [post update] { "proc ... y(pw) } [process.env.secret] | build-leaks.js:41:43:41:86 | { "proc ... y(pw) } | provenance | | -| build-leaks.js:41:67:41:84 | JSON.stringify(pw) | build-leaks.js:41:43:41:86 | [post update] { "proc ... y(pw) } [process.env.secret] | provenance | | +| build-leaks.js:41:67:41:84 | JSON.stringify(pw) | build-leaks.js:41:43:41:86 | { "proc ... y(pw) } | provenance | | | build-leaks.js:41:82:41:83 | pw | build-leaks.js:41:67:41:84 | JSON.stringify(pw) | provenance | | nodes -| build-leaks.js:4:39:6:1 | [post update] { // NO ... .env)\\n} [process.env] | semmle.label | [post update] { // NO ... .env)\\n} [process.env] | | build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | semmle.label | { // NO ... .env)\\n} | | build-leaks.js:5:20:5:46 | JSON.st ... ss.env) | semmle.label | JSON.st ... ss.env) | | build-leaks.js:5:35:5:45 | process.env | semmle.label | process.env | | build-leaks.js:13:11:19:10 | raw | semmle.label | raw | | build-leaks.js:13:17:19:10 | Object. ... }) | semmle.label | Object. ... }) | -| build-leaks.js:14:18:14:20 | env | semmle.label | env | -| build-leaks.js:14:18:14:20 | env | semmle.label | env | -| build-leaks.js:14:18:14:20 | env [Return] | semmle.label | env [Return] | | build-leaks.js:15:13:15:15 | [post update] env | semmle.label | [post update] env | | build-leaks.js:15:24:15:34 | process.env | semmle.label | process.env | | build-leaks.js:16:20:16:22 | env | semmle.label | env | -| build-leaks.js:16:20:16:22 | env | semmle.label | env | -| build-leaks.js:17:12:19:9 | [post update] {\\n ... } | semmle.label | [post update] {\\n ... } | -| build-leaks.js:17:12:19:9 | {\\n ... } | semmle.label | {\\n ... } | | build-leaks.js:21:11:26:5 | stringifed [process.env] | semmle.label | stringifed [process.env] | | build-leaks.js:21:24:26:5 | {\\n ... )\\n } [process.env] | semmle.label | {\\n ... )\\n } [process.env] | | build-leaks.js:22:24:25:14 | Object. ... }, {}) | semmle.label | Object. ... }, {}) | | build-leaks.js:22:36:22:38 | raw | semmle.label | raw | | build-leaks.js:22:49:22:51 | env | semmle.label | env | -| build-leaks.js:22:49:22:51 | env | semmle.label | env | -| build-leaks.js:22:49:22:51 | env [Return] | semmle.label | env [Return] | | build-leaks.js:23:13:23:15 | [post update] env | semmle.label | [post update] env | | build-leaks.js:23:39:23:41 | raw | semmle.label | raw | | build-leaks.js:24:20:24:22 | env | semmle.label | env | | build-leaks.js:24:20:24:22 | env | semmle.label | env | -| build-leaks.js:25:12:25:13 | [post update] {} | semmle.label | [post update] {} | -| build-leaks.js:25:12:25:13 | {} | semmle.label | {} | | build-leaks.js:28:12:31:5 | {\\n ... d\\n } [stringified, process.env] | semmle.label | {\\n ... d\\n } [stringified, process.env] | | build-leaks.js:30:22:30:31 | stringifed [process.env] | semmle.label | stringifed [process.env] | | build-leaks.js:34:26:34:45 | getEnv('production') [stringified, process.env] | semmle.label | getEnv('production') [stringified, process.env] | | build-leaks.js:34:26:34:57 | getEnv( ... ngified | semmle.label | getEnv( ... ngified | | build-leaks.js:40:9:40:60 | pw | semmle.label | pw | | build-leaks.js:40:14:40:60 | url.par ... assword | semmle.label | url.par ... assword | -| build-leaks.js:41:43:41:86 | [post update] { "proc ... y(pw) } [process.env.secret] | semmle.label | [post update] { "proc ... y(pw) } [process.env.secret] | | build-leaks.js:41:43:41:86 | { "proc ... y(pw) } | semmle.label | { "proc ... y(pw) } | | build-leaks.js:41:67:41:84 | JSON.stringify(pw) | semmle.label | JSON.stringify(pw) | | build-leaks.js:41:82:41:83 | pw | semmle.label | pw | subpaths -| build-leaks.js:17:12:19:9 | {\\n ... } | build-leaks.js:14:18:14:20 | env | build-leaks.js:16:20:16:22 | env | build-leaks.js:13:17:19:10 | Object. ... }) | | build-leaks.js:22:36:22:38 | raw | build-leaks.js:22:49:22:51 | env | build-leaks.js:24:20:24:22 | env | build-leaks.js:22:24:25:14 | Object. ... }, {}) | -| build-leaks.js:22:36:22:38 | raw | build-leaks.js:23:39:23:41 | raw | build-leaks.js:22:49:22:51 | env [Return] | build-leaks.js:25:12:25:13 | [post update] {} | | build-leaks.js:22:36:22:38 | raw | build-leaks.js:23:39:23:41 | raw | build-leaks.js:24:20:24:22 | env | build-leaks.js:22:24:25:14 | Object. ... }, {}) | -| build-leaks.js:25:12:25:13 | {} | build-leaks.js:22:49:22:51 | env | build-leaks.js:24:20:24:22 | env | build-leaks.js:22:24:25:14 | Object. ... }, {}) | #select | build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | build-leaks.js:5:35:5:45 | process.env | build-leaks.js:4:39:6:1 | { // NO ... .env)\\n} | This creates a build artifact that depends on $@. | build-leaks.js:5:35:5:45 | process.env | sensitive data returned byprocess environment | | build-leaks.js:34:26:34:57 | getEnv( ... ngified | build-leaks.js:15:24:15:34 | process.env | build-leaks.js:34:26:34:57 | getEnv( ... ngified | This creates a build artifact that depends on $@. | build-leaks.js:15:24:15:34 | process.env | sensitive data returned byprocess environment | diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected index 195a5fec4ec..f687007db4d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected @@ -4,13 +4,11 @@ nodes | 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: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: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 | @@ -32,14 +30,12 @@ edges | angularmerge.js:1:30:1:34 | event | angularmerge.js:2:32:2:36 | event | provenance | | | angularmerge.js:2:32:2:36 | event | angularmerge.js:2:32:2:41 | event.data | provenance | | | angularmerge.js:2:32:2:41 | event.data | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | provenance | Config | -| 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 } | provenance | | -| 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] | provenance | | +| src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } | provenance | | | src-vulnerable-lodash/tst.js:14:9:16:5 | opts [thing] | src-vulnerable-lodash/tst.js:18:16:18:19 | opts [thing] | provenance | | | src-vulnerable-lodash/tst.js:14:16:16:5 | {\\n ... e\\n } [thing] | src-vulnerable-lodash/tst.js:14:9:16:5 | opts [thing] | provenance | | | 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] | provenance | | -| 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 } | provenance | | | src-vulnerable-lodash/tst.js:18:16:18:19 | opts [thing] | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | provenance | | -| 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] | provenance | | +| src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | provenance | | | webix/webix.html:3:34:3:38 | event | webix/webix.html:4:37:4:41 | event | provenance | | | webix/webix.html:3:34:3:38 | event | webix/webix.html:5:35:5:39 | event | provenance | | | webix/webix.html:4:37:4:41 | event | webix/webix.html:4:37:4:46 | event.data | provenance | | From 1e9e57e46e2a3f0bcb318f8eab3fd66796518eed Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 28 Oct 2024 11:11:51 +0100 Subject: [PATCH 333/514] JS: Fix missing qldoc --- .../lib/semmle/javascript/dataflow/internal/VariableOrThis.qll | 3 +++ 1 file changed, 3 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableOrThis.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableOrThis.qll index 92a3ad24d81..8309c0d639c 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableOrThis.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableOrThis.qll @@ -88,10 +88,13 @@ abstract class ThisUse instanceof ControlFlowNode { /** Gets the container binding the `this` being accessed */ abstract StmtContainer getBindingContainer(); + /** Get the container in which `this` is being accessed. */ abstract StmtContainer getUseContainer(); + /** Gets a string representation of this element. */ string toString() { result = super.toString() } + /** Gets the location of this use of `this`. */ DbLocation getLocation() { result = super.getLocation() } } From 2fb108419c48a07531f9eed459fd8ead3ea52455 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 28 Oct 2024 14:12:45 +0100 Subject: [PATCH 334/514] JS: Only parameter-calls as lambda calls --- .../semmle/javascript/dataflow/internal/DataFlowPrivate.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index a7f123b9f02..5311e75e7be 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1530,7 +1530,9 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { call.isSummaryCall(_, receiver.(FlowSummaryNode).getSummaryNode()) and exists(kind) or - receiver = call.asOrdinaryCall().getCalleeNode() and exists(kind) + receiver = call.asOrdinaryCall().getCalleeNode() and + exists(kind) and + receiver.getALocalSource() instanceof DataFlow::ParameterNode } /** Extra data-flow steps needed for lambda flow analysis. */ From 637baabe370fadcb99afa422bf319b1485b17514 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 Nov 2024 11:23:35 +0100 Subject: [PATCH 335/514] JS: Clarify why there are no SSA definitions --- .../javascript/dataflow/internal/sharedlib/Ssa.qll | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll index 73ed86d195c..04607a5bd5b 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll @@ -60,11 +60,17 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig { predicate hasCfgNode(js::BasicBlock bb, int i) { this = bb.getNode(i) } } - predicate ssaDefAssigns(WriteDefinition def, Expr value) { none() } // Not handled here + predicate ssaDefAssigns(WriteDefinition def, Expr value) { + // This library only handles use-use flow after a post-update, there are no definitions, only uses. + none() + } class Parameter = js::Parameter; - predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) { none() } // Not handled here + predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) { + // This library only handles use-use flow after a post-update, there are no definitions, only uses. + none() + } cached Expr getARead(Definition def) { From 80ee372ddf88c1adfa4594d4e500fc751577fbfc Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 Nov 2024 11:24:17 +0100 Subject: [PATCH 336/514] JS: Replace an unused value with _ --- .../semmle/javascript/dataflow/internal/DataFlowPrivate.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 5311e75e7be..b33f908cc68 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1127,8 +1127,8 @@ Node getNodeFromSsa2(Ssa2::Node node) { } private predicate useUseFlow(Node node1, Node node2) { - exists(Ssa2::DefinitionExt def, Ssa2::Node ssa1, Ssa2::Node ssa2, boolean isUseStep | - Ssa2::localFlowStep(def, ssa1, ssa2, isUseStep) and + exists(Ssa2::DefinitionExt def, Ssa2::Node ssa1, Ssa2::Node ssa2 | + Ssa2::localFlowStep(def, ssa1, ssa2, _) and node1 = getNodeFromSsa2(ssa1) and node2 = getNodeFromSsa2(ssa2) and not node1.getTopLevel().isExterns() From 5ed362f7d63040c05da49304142b0479b753e7d5 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 4 Nov 2024 16:22:09 +0100 Subject: [PATCH 337/514] JS: Add exception test case --- .../library-tests/TripleDot/exceptions.js | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 javascript/ql/test/library-tests/TripleDot/exceptions.js diff --git a/javascript/ql/test/library-tests/TripleDot/exceptions.js b/javascript/ql/test/library-tests/TripleDot/exceptions.js new file mode 100644 index 00000000000..e52dda7500a --- /dev/null +++ b/javascript/ql/test/library-tests/TripleDot/exceptions.js @@ -0,0 +1,65 @@ +import 'dummy'; + +function e1() { + let array = [source('e1.1')]; + try { + array.forEach(x => { + throw x; + }); + array.forEach(x => { + throw source('e1.2'); + }); + } catch (err) { + sink(err); // $ hasValueFlow=e1.2 hasValueFlow=e1.1 + } +} + +function e2() { + let array = [source('e2.1')]; + try { + array.unknown(x => { + throw x; + }); + array.unknown(x => { + throw source('e2.2'); + }); + } catch (err) { + sink(err); // $ MISSING: hasValueFlow=e2.2 + } +} + +function e3() { + const events = getSomething(); + try { + events.addEventListener('click', () =>{ + throw source('e3.1'); + }); + events.addListener('click', () =>{ + throw source('e3.2'); + }); + events.on('click', () =>{ + throw source('e3.3'); + }); + events.unknownMethod('click', () =>{ + throw source('e3.4'); + }); + } catch (err) { + sink(err); // $ MISSING: hasValueFlow=e3.4 + } +} + +function e4() { + function thrower(array) { + array.forEach(x => { throw x }); + } + try { + thrower([source("e4.1")]); + } catch (e) { + sink(e); // $ hasValueFlow=e4.1 + } + try { + thrower(["safe"]); + } catch (e) { + sink(e); // $ SPURIOUS: hasValueFlow=e4.1 + } +} From 7acc5689cfdf16a438a29eea171128aca2a44eaa Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 22 Aug 2024 14:00:09 +0200 Subject: [PATCH 338/514] JS: Port exception steps to a universal summary --- .../lib/semmle/javascript/StandardLibrary.qll | 2 +- .../flow_summaries/AllFlowSummaries.qll | 1 + .../internal/flow_summaries/ExceptionFlow.qll | 32 +++++++++++++++++++ .../internal/flow_summaries/Promises.qll | 2 +- .../library-tests/TripleDot/exceptions.js | 8 ++--- 5 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll diff --git a/javascript/ql/lib/semmle/javascript/StandardLibrary.qll b/javascript/ql/lib/semmle/javascript/StandardLibrary.qll index dc856fbab4b..a9102577bc2 100644 --- a/javascript/ql/lib/semmle/javascript/StandardLibrary.qll +++ b/javascript/ql/lib/semmle/javascript/StandardLibrary.qll @@ -69,7 +69,7 @@ private class ArrayIterationCallbackAsPartialInvoke extends DataFlow::PartialInv * A flow step propagating the exception thrown from a callback to a method whose name coincides * a built-in Array iteration method, such as `forEach` or `map`. */ -private class IteratorExceptionStep extends DataFlow::SharedFlowStep { +private class IteratorExceptionStep extends DataFlow::LegacyFlowStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { exists(DataFlow::MethodCallNode call | call.getMethodName() = ["forEach", "each", "map", "filter", "some", "every", "fold", "reduce"] and diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll index 6094141cc40..5935fa8bfd6 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AllFlowSummaries.qll @@ -1,6 +1,7 @@ private import AmbiguousCoreMethods private import Arrays private import AsyncAwait +private import ExceptionFlow private import ForOfLoops private import Generators private import Iterators diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll new file mode 100644 index 00000000000..aee3be8a95b --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll @@ -0,0 +1,32 @@ +/** + * Contains a summary for propagating exceptions out of callbacks + */ + +private import javascript +private import FlowSummaryUtil +private import semmle.javascript.dataflow.internal.AdditionalFlowInternal +private import semmle.javascript.dataflow.FlowSummary +private import semmle.javascript.internal.flow_summaries.Promises + +/** + * Summary that propagates exceptions out of callbacks back to the caller. + */ +private class ExceptionFlowSummary extends SummarizedCallable { + ExceptionFlowSummary() { this = "Exception propagator" } + + override DataFlow::CallNode getACall() { + not exists(result.getACallee()) and + // Avoid a few common cases where the exception should not propagate back + not result.getCalleeName() = + ["then", "catch", "finally", "addEventListener", EventEmitter::on()] and + not result = promiseConstructorRef().getAnInvocation() and + // Restrict to cases where a callback is known to flow in, as lambda flow in DataFlowImplCommon blows up otherwise + exists(result.getABoundCallbackParameter(_, _)) + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + preservesValue = true and + input = "Argument[0..].ReturnValue[exception]" and + output = "ReturnValue[exception]" + } +} diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises.qll index fb2f05f17b7..aa9398f14bb 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises.qll @@ -6,7 +6,7 @@ private import javascript private import semmle.javascript.dataflow.FlowSummary private import FlowSummaryUtil -private DataFlow::SourceNode promiseConstructorRef() { +DataFlow::SourceNode promiseConstructorRef() { result = Promises::promiseConstructorRef() or result = DataFlow::moduleImport("bluebird") diff --git a/javascript/ql/test/library-tests/TripleDot/exceptions.js b/javascript/ql/test/library-tests/TripleDot/exceptions.js index e52dda7500a..dddd53a046e 100644 --- a/javascript/ql/test/library-tests/TripleDot/exceptions.js +++ b/javascript/ql/test/library-tests/TripleDot/exceptions.js @@ -10,7 +10,7 @@ function e1() { throw source('e1.2'); }); } catch (err) { - sink(err); // $ hasValueFlow=e1.2 hasValueFlow=e1.1 + sink(err); // $ hasValueFlow=e1.2 MISSING: hasValueFlow=e1.1 } } @@ -24,7 +24,7 @@ function e2() { throw source('e2.2'); }); } catch (err) { - sink(err); // $ MISSING: hasValueFlow=e2.2 + sink(err); // $ hasValueFlow=e2.2 } } @@ -55,11 +55,11 @@ function e4() { try { thrower([source("e4.1")]); } catch (e) { - sink(e); // $ hasValueFlow=e4.1 + sink(e); // $ MISSING: hasValueFlow=e4.1 } try { thrower(["safe"]); } catch (e) { - sink(e); // $ SPURIOUS: hasValueFlow=e4.1 + sink(e); } } From 7f2eae0966b01a633e8ffb5fedc597a6abed4112 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 18 Nov 2024 13:34:35 +0100 Subject: [PATCH 339/514] JS: Add test case for false flow through IIFEs We generate local flow steps into and out of IIFEs, but these come jump steps automatically, resulting in FPs. --- .../ql/test/library-tests/TripleDot/iife.js | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 javascript/ql/test/library-tests/TripleDot/iife.js diff --git a/javascript/ql/test/library-tests/TripleDot/iife.js b/javascript/ql/test/library-tests/TripleDot/iife.js new file mode 100644 index 00000000000..8da09f67c0a --- /dev/null +++ b/javascript/ql/test/library-tests/TripleDot/iife.js @@ -0,0 +1,43 @@ +function f1() { + function inner(x) { + return (function(p) { + return p; // argument to return + })(x); + } + sink(inner(source("f1.1"))); // $ hasValueFlow=f1.1 SPURIOUS: hasValueFlow=f1.2 + sink(inner(source("f1.2"))); // $ hasValueFlow=f1.2 SPURIOUS: hasValueFlow=f1.1 +} + +function f2() { + function inner(x) { + let y; + (function(p) { + y = p; // parameter to captured variable + })(x); + return y; + } + sink(inner(source("f2.1"))); // $ hasValueFlow=f2.1 SPURIOUS: hasValueFlow=f2.2 + sink(inner(source("f2.2"))); // $ hasValueFlow=f2.2 SPURIOUS: hasValueFlow=f2.1 +} + +function f3() { + function inner(x) { + return (function() { + return x; // captured variable to return + })(); + } + sink(inner(source("f3.1"))); // $ hasValueFlow=f3.1 SPURIOUS: hasValueFlow=f3.2 + sink(inner(source("f3.2"))); // $ hasValueFlow=f3.2 SPURIOUS: hasValueFlow=f3.1 +} + +function f4() { + function inner(x) { + let y; + (function() { + y = x; // captured variable to captured variable + })(); + return y; + } + sink(inner(source("f4.1"))); // $ hasValueFlow=f4.1 + sink(inner(source("f4.2"))); // $ hasValueFlow=f4.2 +} From 37676f41aab91cfd69623433c86f5f5ec0c85693 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 1 Nov 2024 09:17:35 +0100 Subject: [PATCH 340/514] JS: Remove jump steps from IIFE steps --- .../dataflow/internal/DataFlowPrivate.qll | 17 ++++++++++++++++- .../ql/test/library-tests/TripleDot/iife.js | 12 ++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index b33f908cc68..864b6f13d7e 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1217,6 +1217,20 @@ predicate simpleLocalFlowStep(Node node1, Node node2) { predicate localMustFlowStep(Node node1, Node node2) { node1 = node2.getImmediatePredecessor() } +/** + * Holds if `node1 -> node2` should be removed as a jump step. + * + * Currently this is done as a workaround for the local steps generated from IIFEs. + */ +private predicate excludedJumpStep(Node node1, Node node2) { + exists(ImmediatelyInvokedFunctionExpr iife | + iife.argumentPassing(node2.asExpr(), node1.asExpr()) + or + node1 = iife.getAReturnedExpr().flow() and + node2 = iife.getInvocation().flow() + ) +} + /** * Holds if data can flow from `node1` to `node2` through a non-local step * that does not follow a call edge. For example, a step through a global @@ -1224,7 +1238,8 @@ predicate localMustFlowStep(Node node1, Node node2) { node1 = node2.getImmediate */ predicate jumpStep(Node node1, Node node2) { valuePreservingStep(node1, node2) and - node1.getContainer() != node2.getContainer() + node1.getContainer() != node2.getContainer() and + not excludedJumpStep(node1, node2) or FlowSummaryPrivate::Steps::summaryJumpStep(node1.(FlowSummaryNode).getSummaryNode(), node2.(FlowSummaryNode).getSummaryNode()) diff --git a/javascript/ql/test/library-tests/TripleDot/iife.js b/javascript/ql/test/library-tests/TripleDot/iife.js index 8da09f67c0a..2dcf3213c42 100644 --- a/javascript/ql/test/library-tests/TripleDot/iife.js +++ b/javascript/ql/test/library-tests/TripleDot/iife.js @@ -4,8 +4,8 @@ function f1() { return p; // argument to return })(x); } - sink(inner(source("f1.1"))); // $ hasValueFlow=f1.1 SPURIOUS: hasValueFlow=f1.2 - sink(inner(source("f1.2"))); // $ hasValueFlow=f1.2 SPURIOUS: hasValueFlow=f1.1 + sink(inner(source("f1.1"))); // $ hasValueFlow=f1.1 + sink(inner(source("f1.2"))); // $ hasValueFlow=f1.2 } function f2() { @@ -16,8 +16,8 @@ function f2() { })(x); return y; } - sink(inner(source("f2.1"))); // $ hasValueFlow=f2.1 SPURIOUS: hasValueFlow=f2.2 - sink(inner(source("f2.2"))); // $ hasValueFlow=f2.2 SPURIOUS: hasValueFlow=f2.1 + sink(inner(source("f2.1"))); // $ MISSING: hasValueFlow=f2.1 + sink(inner(source("f2.2"))); // $ MISSING: hasValueFlow=f2.2 } function f3() { @@ -26,8 +26,8 @@ function f3() { return x; // captured variable to return })(); } - sink(inner(source("f3.1"))); // $ hasValueFlow=f3.1 SPURIOUS: hasValueFlow=f3.2 - sink(inner(source("f3.2"))); // $ hasValueFlow=f3.2 SPURIOUS: hasValueFlow=f3.1 + sink(inner(source("f3.1"))); // $ hasValueFlow=f3.1 + sink(inner(source("f3.2"))); // $ hasValueFlow=f3.2 } function f4() { From 023dcce400d58950315fc7858a6166fe9208fc54 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 1 Nov 2024 10:29:53 +0100 Subject: [PATCH 341/514] JS: Disable variable capture heuristic Bailing out can be more expensive as the resulting jump steps themselves cause perf issues. The limit of 100 variables per scope has also been added in the interim, which handles the cases that this needed to cover. --- .../dataflow/internal/VariableCapture.qll | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll index 247f7690894..413bdc1babb 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll @@ -23,35 +23,11 @@ module VariableCaptureConfig implements InputSig { or isTopLevelLike(container.(js::ImmediatelyInvokedFunctionExpr).getEnclosingContainer()) or - // Functions declared in a top-level with no parameters and can't generate flow-through, except through 'this' - // which we rule out with a few syntactic checks. In this case we treat its captured variables as singletons. - // NOTE: This was done to prevent a blow-up in fiddlesalad where a function called 'Runtime' captures 7381 variables but is only called once. - exists(js::Function fun | - container = fun and - fun.getNumParameter() = 0 and - isTopLevelLike(fun.getEnclosingContainer()) and - not mayHaveFlowThroughThisArgument(fun) - ) - or - // Container declaring >100 captured variables tend to be singletons and are too expensive anyway + // Containers declaring >100 captured variables tend to be singletons and are too expensive anyway strictcount(js::LocalVariable v | v.isCaptured() and v.getDeclaringContainer() = container) > 100 } - private predicate hasLocalConstructorCall(js::Function fun) { - fun = getLambdaFromVariable(any(js::NewExpr e).getCallee().(js::VarAccess).getVariable()) - } - - private predicate mayHaveFlowThroughThisArgument(js::Function fun) { - any(js::ThisExpr e).getBinder() = fun and - not hasLocalConstructorCall(fun) and // 'this' argument is assumed to be a fresh object - ( - exists(fun.getAReturnedExpr()) - or - exists(js::YieldExpr e | e.getContainer() = fun) - ) - } - class CapturedVariable extends LocalVariableOrThis { CapturedVariable() { DataFlowImplCommon::forceCachingInSameStage() and From d2daec4c66d048499eef7f71ec267d986fb07f12 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 19 Nov 2024 13:10:34 +0100 Subject: [PATCH 342/514] JS: Add tests explaining why the IIFE in f2 didn't work --- .../ql/test/library-tests/TripleDot/iife.js | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/javascript/ql/test/library-tests/TripleDot/iife.js b/javascript/ql/test/library-tests/TripleDot/iife.js index 2dcf3213c42..31899f21b75 100644 --- a/javascript/ql/test/library-tests/TripleDot/iife.js +++ b/javascript/ql/test/library-tests/TripleDot/iife.js @@ -41,3 +41,42 @@ function f4() { sink(inner(source("f4.1"))); // $ hasValueFlow=f4.1 sink(inner(source("f4.2"))); // $ hasValueFlow=f4.2 } + +function f5() { + function inner(x) { + let y; + function nested(p) { + y = p; + } + nested(x); + return y; + } + sink(inner(source("f5.1"))); // $ hasValueFlow=f5.1 + sink(inner(source("f5.2"))); // $ hasValueFlow=f5.2 +} + +function f6() { + function inner(x) { + let y; + function nested(p) { + y = p; + } + (nested)(x); // same as f5, except the callee is parenthesised here + return y; + } + sink(inner(source("f6.1"))); // $ MISSING: hasValueFlow=f6.1 + sink(inner(source("f6.2"))); // $ MISSING: hasValueFlow=f6.2 +} + +function f7() { + function inner(x) { + let y; + let nested = (function (p) { + y = p; + }); + nested(x); // same as f5, except the function definition is parenthesised + return y; + } + sink(inner(source("f7.1"))); // $ MISSING: hasValueFlow=f7.1 + sink(inner(source("f7.2"))); // $ MISSING: hasValueFlow=f7.2 +} From 80a5a5909e99c14bc0c00b010d4a3eb6098d8e03 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 19 Nov 2024 13:21:32 +0100 Subject: [PATCH 343/514] JS: Use getUnderlyingValue() a few places in VariableCapture --- .../javascript/dataflow/internal/VariableCapture.qll | 6 ++++-- javascript/ql/test/library-tests/TripleDot/iife.js | 12 ++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll index 413bdc1babb..6e381a792ef 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/VariableCapture.qll @@ -8,7 +8,7 @@ module VariableCaptureConfig implements InputSig { private js::Function getLambdaFromVariable(js::LocalVariable variable) { result.getVariable() = variable or - result = variable.getAnAssignedExpr() + result = variable.getAnAssignedExpr().getUnderlyingValue() or exists(js::ClassDeclStmt cls | result = cls.getConstructor().getBody() and @@ -148,9 +148,11 @@ module VariableCaptureConfig implements InputSig { predicate hasAliasedAccess(Expr e) { e = this or + e.(js::Expr).getUnderlyingValue() = this + or exists(js::LocalVariable variable | this = getLambdaFromVariable(variable) and - e = variable.getAnAccess() + e.(js::Expr).getUnderlyingValue() = variable.getAnAccess() ) } } diff --git a/javascript/ql/test/library-tests/TripleDot/iife.js b/javascript/ql/test/library-tests/TripleDot/iife.js index 31899f21b75..1697ce8d334 100644 --- a/javascript/ql/test/library-tests/TripleDot/iife.js +++ b/javascript/ql/test/library-tests/TripleDot/iife.js @@ -16,8 +16,8 @@ function f2() { })(x); return y; } - sink(inner(source("f2.1"))); // $ MISSING: hasValueFlow=f2.1 - sink(inner(source("f2.2"))); // $ MISSING: hasValueFlow=f2.2 + sink(inner(source("f2.1"))); // $ hasValueFlow=f2.1 + sink(inner(source("f2.2"))); // $ hasValueFlow=f2.2 } function f3() { @@ -64,8 +64,8 @@ function f6() { (nested)(x); // same as f5, except the callee is parenthesised here return y; } - sink(inner(source("f6.1"))); // $ MISSING: hasValueFlow=f6.1 - sink(inner(source("f6.2"))); // $ MISSING: hasValueFlow=f6.2 + sink(inner(source("f6.1"))); // $ hasValueFlow=f6.1 + sink(inner(source("f6.2"))); // $ hasValueFlow=f6.2 } function f7() { @@ -77,6 +77,6 @@ function f7() { nested(x); // same as f5, except the function definition is parenthesised return y; } - sink(inner(source("f7.1"))); // $ MISSING: hasValueFlow=f7.1 - sink(inner(source("f7.2"))); // $ MISSING: hasValueFlow=f7.2 + sink(inner(source("f7.1"))); // $ hasValueFlow=f7.1 + sink(inner(source("f7.2"))); // $ hasValueFlow=f7.2 } From 01669908f22c308d388beb42cef58dcf1a906c9f Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 1 Nov 2024 10:30:24 +0100 Subject: [PATCH 344/514] JS: Block InsecureRandomness flow into test files --- .../security/dataflow/InsecureRandomnessQuery.qll | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureRandomnessQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureRandomnessQuery.qll index b4804e8f464..bf095a63768 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureRandomnessQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureRandomnessQuery.qll @@ -11,6 +11,7 @@ import javascript private import semmle.javascript.security.SensitiveActions import InsecureRandomnessCustomizations::InsecureRandomness private import InsecureRandomnessCustomizations::InsecureRandomness as InsecureRandomness +private import semmle.javascript.filters.ClassifyFiles as ClassifyFiles /** * A taint tracking configuration for random values that are not cryptographically secure. @@ -20,7 +21,11 @@ module InsecureRandomnessConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + predicate isBarrier(DataFlow::Node node) { + node instanceof Sanitizer + or + ClassifyFiles::isTestFile(node.getFile()) + } predicate isBarrierOut(DataFlow::Node node) { // stop propagation at the sinks to avoid double reporting From d1c9e47d231834736824a4d615a38a041a37f50e Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 1 Nov 2024 13:18:32 +0100 Subject: [PATCH 345/514] JS: More aggressive test file classification --- javascript/ql/lib/semmle/javascript/filters/ClassifyFiles.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/filters/ClassifyFiles.qll b/javascript/ql/lib/semmle/javascript/filters/ClassifyFiles.qll index 5dd44226351..8d392bc0448 100644 --- a/javascript/ql/lib/semmle/javascript/filters/ClassifyFiles.qll +++ b/javascript/ql/lib/semmle/javascript/filters/ClassifyFiles.qll @@ -61,6 +61,8 @@ predicate isTestFile(File f) { ) or f.getAbsolutePath().regexpMatch(".*/__(mocks|tests)__/.*") + or + f.getBaseName().matches("%.test.%") } /** From b7dd455aff8f930a8df90fde3b8aaea1b795a90e Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 21 Nov 2024 09:21:36 +0100 Subject: [PATCH 346/514] JS: Add test case --- javascript/ql/test/library-tests/TripleDot/exceptions.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/javascript/ql/test/library-tests/TripleDot/exceptions.js b/javascript/ql/test/library-tests/TripleDot/exceptions.js index dddd53a046e..9d105fb8d56 100644 --- a/javascript/ql/test/library-tests/TripleDot/exceptions.js +++ b/javascript/ql/test/library-tests/TripleDot/exceptions.js @@ -9,8 +9,11 @@ function e1() { array.forEach(x => { throw source('e1.2'); }); + array.forEach(() => { + throw source('e1.3'); // Same as e1.2 but without callback parameters + }); } catch (err) { - sink(err); // $ hasValueFlow=e1.2 MISSING: hasValueFlow=e1.1 + sink(err); // $ hasValueFlow=e1.2 MISSING: hasValueFlow=e1.1 hasValueFlow=e1.3 } } From dcdb2e5133115b0bf4db0ddb954ab721d26cd2f8 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 21 Nov 2024 09:23:38 +0100 Subject: [PATCH 347/514] JS: Fix callback check so it works without parameters --- .../internal/flow_summaries/ExceptionFlow.qll | 13 ++++++++++++- .../ql/test/library-tests/TripleDot/exceptions.js | 4 ++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll index aee3be8a95b..04616e05dc6 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll @@ -8,6 +8,17 @@ private import semmle.javascript.dataflow.internal.AdditionalFlowInternal private import semmle.javascript.dataflow.FlowSummary private import semmle.javascript.internal.flow_summaries.Promises +private predicate isCallback(DataFlow::SourceNode node) { + node instanceof DataFlow::FunctionNode + or + node instanceof DataFlow::PartialInvokeNode + or + exists(DataFlow::SourceNode prev | + isCallback(prev) and + DataFlow::argumentPassingStep(_, prev.getALocalUse(), _, node) + ) +} + /** * Summary that propagates exceptions out of callbacks back to the caller. */ @@ -21,7 +32,7 @@ private class ExceptionFlowSummary extends SummarizedCallable { ["then", "catch", "finally", "addEventListener", EventEmitter::on()] and not result = promiseConstructorRef().getAnInvocation() and // Restrict to cases where a callback is known to flow in, as lambda flow in DataFlowImplCommon blows up otherwise - exists(result.getABoundCallbackParameter(_, _)) + isCallback(result.getAnArgument().getALocalSource()) } override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { diff --git a/javascript/ql/test/library-tests/TripleDot/exceptions.js b/javascript/ql/test/library-tests/TripleDot/exceptions.js index 9d105fb8d56..0bd472e120c 100644 --- a/javascript/ql/test/library-tests/TripleDot/exceptions.js +++ b/javascript/ql/test/library-tests/TripleDot/exceptions.js @@ -13,7 +13,7 @@ function e1() { throw source('e1.3'); // Same as e1.2 but without callback parameters }); } catch (err) { - sink(err); // $ hasValueFlow=e1.2 MISSING: hasValueFlow=e1.1 hasValueFlow=e1.3 + sink(err); // $ hasValueFlow=e1.2 hasValueFlow=e1.3 MISSING: hasValueFlow=e1.1 } } @@ -47,7 +47,7 @@ function e3() { throw source('e3.4'); }); } catch (err) { - sink(err); // $ MISSING: hasValueFlow=e3.4 + sink(err); // $ hasValueFlow=e3.4 } } From 948d21ca071dadb8b639a08fff65b1a586fbd8fa Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 21 Nov 2024 10:23:08 +0100 Subject: [PATCH 348/514] JS: Propagate exceptions from summarized callables by default --- .../dataflow/internal/DataFlowNode.qll | 3 ++ .../dataflow/internal/DataFlowPrivate.qll | 38 +++++++++++++++++++ .../library-tests/TripleDot/exceptions.js | 4 +- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll index 6d2be5a1537..26bff4fdf80 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowNode.qll @@ -100,6 +100,9 @@ private module Cached { // So it doesn't cause negative recursion but it might look a bit surprising. FlowSummaryPrivate::Steps::summaryStoreStep(sn, MkAwaited(), _) } or + TFlowSummaryDefaultExceptionalReturn(FlowSummaryImpl::Public::SummarizedCallable callable) { + not DataFlowPrivate::mentionsExceptionalReturn(callable) + } or TSynthCaptureNode(VariableCapture::VariableCaptureOutput::SynthesizedCaptureNode node) or TGenericSynthesizedNode(AstNode node, string tag, DataFlowPrivate::DataFlowCallable container) { any(AdditionalFlowInternal flow).needsSynthesizedNode(node, tag, container) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 864b6f13d7e..8c1f74ae535 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -112,6 +112,33 @@ class FlowSummaryIntermediateAwaitStoreNode extends DataFlow::Node, } } +predicate mentionsExceptionalReturn(FlowSummaryImpl::Public::SummarizedCallable callable) { + exists(FlowSummaryImpl::Private::SummaryNode node | node.getSummarizedCallable() = callable | + FlowSummaryImpl::Private::summaryReturnNode(node, MkExceptionalReturnKind()) + or + FlowSummaryImpl::Private::summaryOutNode(_, node, MkExceptionalReturnKind()) + ) +} + +/** + * Exceptional return node in a summarized callable whose summary does not mention `ReturnValue[exception]`. + * + * By default, every call inside such a callable will forward their exceptional return to the caller's + * exceptional return, i.e. exceptions are not caught. + */ +class FlowSummaryDefaultExceptionalReturn extends DataFlow::Node, + TFlowSummaryDefaultExceptionalReturn +{ + private FlowSummaryImpl::Public::SummarizedCallable callable; + + FlowSummaryDefaultExceptionalReturn() { this = TFlowSummaryDefaultExceptionalReturn(callable) } + + FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() { result = callable } + + cached + override string toString() { result = "[default exceptional return] " + callable } +} + class CaptureNode extends DataFlow::Node, TSynthCaptureNode { /** Gets the underlying node from the variable-capture library. */ VariableCaptureOutput::SynthesizedCaptureNode getNode() { @@ -296,6 +323,9 @@ private predicate returnNodeImpl(DataFlow::Node node, ReturnKind kind) { ) or FlowSummaryImpl::Private::summaryReturnNode(node.(FlowSummaryNode).getSummaryNode(), kind) + or + node instanceof FlowSummaryDefaultExceptionalReturn and + kind = MkExceptionalReturnKind() } private DataFlow::Node getAnOutNodeImpl(DataFlowCall call, ReturnKind kind) { @@ -311,6 +341,10 @@ private DataFlow::Node getAnOutNodeImpl(DataFlowCall call, ReturnKind kind) { or FlowSummaryImpl::Private::summaryOutNode(call.(SummaryCall).getReceiver(), result.(FlowSummaryNode).getSummaryNode(), kind) + or + kind = MkExceptionalReturnKind() and + result.(FlowSummaryDefaultExceptionalReturn).getSummarizedCallable() = + call.(SummaryCall).getSummarizedCallable() } class ReturnNode extends DataFlow::Node { @@ -505,6 +539,8 @@ DataFlowCallable nodeGetEnclosingCallable(Node node) { or result.asLibraryCallable() = node.(FlowSummaryIntermediateAwaitStoreNode).getSummarizedCallable() or + result.asLibraryCallable() = node.(FlowSummaryDefaultExceptionalReturn).getSummarizedCallable() + or node = TGenericSynthesizedNode(_, _, result) } @@ -865,6 +901,8 @@ class SummaryCall extends DataFlowCall, MkSummaryCall { /** Gets the receiver node. */ FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver } + + FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() { result = enclosingCallable } } /** diff --git a/javascript/ql/test/library-tests/TripleDot/exceptions.js b/javascript/ql/test/library-tests/TripleDot/exceptions.js index 0bd472e120c..8b4262e7a6b 100644 --- a/javascript/ql/test/library-tests/TripleDot/exceptions.js +++ b/javascript/ql/test/library-tests/TripleDot/exceptions.js @@ -13,7 +13,7 @@ function e1() { throw source('e1.3'); // Same as e1.2 but without callback parameters }); } catch (err) { - sink(err); // $ hasValueFlow=e1.2 hasValueFlow=e1.3 MISSING: hasValueFlow=e1.1 + sink(err); // $ hasValueFlow=e1.2 hasValueFlow=e1.3 hasValueFlow=e1.1 } } @@ -58,7 +58,7 @@ function e4() { try { thrower([source("e4.1")]); } catch (e) { - sink(e); // $ MISSING: hasValueFlow=e4.1 + sink(e); // $ hasValueFlow=e4.1 } try { thrower(["safe"]); From 84820adf3ca1a06b646d9dead9db6eda3354ac26 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 21 Nov 2024 10:57:07 +0100 Subject: [PATCH 349/514] Add test for exception flow out of finally() --- .../ql/test/library-tests/TripleDot/exceptions.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/javascript/ql/test/library-tests/TripleDot/exceptions.js b/javascript/ql/test/library-tests/TripleDot/exceptions.js index 8b4262e7a6b..241e6aca55d 100644 --- a/javascript/ql/test/library-tests/TripleDot/exceptions.js +++ b/javascript/ql/test/library-tests/TripleDot/exceptions.js @@ -66,3 +66,16 @@ function e4() { sink(e); } } + +async function e5() { + try { + Promise.resolve(0).finally(() => { + throw source("e5.1"); + }); + await Promise.resolve(0).finally(() => { + throw source("e5.2"); + }); + } catch (e) { + sink(e); // $ hasValueFlow=e5.2 + } +} From 4e62a512c53ca11eb3ba09faf63a2c750fcdba3a Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 21 Nov 2024 11:00:49 +0100 Subject: [PATCH 350/514] JS: Only apply exception propagator when no other summary applies Previously a few Promise-related methods were special-cased, which is no longer needed. --- .../dataflow/internal/DataFlowPrivate.qll | 19 ++++++++++++++++++- .../dataflow/internal/FlowSummaryPrivate.qll | 7 ++++++- .../internal/flow_summaries/ExceptionFlow.qll | 9 +++++---- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 8c1f74ae535..d71ea9ff832 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -438,6 +438,19 @@ abstract class LibraryCallable extends string { DataFlow::InvokeNode getACallSimple() { none() } } +/** Internal subclass of `LibraryCallable`, whose member predicates should not be visible on `SummarizedCallable`. */ +abstract class LibraryCallableInternal extends LibraryCallable { + bindingset[this] + LibraryCallableInternal() { any() } + + /** + * Gets a call to this library callable. + * + * Same as `getACall()` but is evaluated later and may depend negatively on `getACall()`. + */ + DataFlow::InvokeNode getACallStage2() { none() } +} + private predicate isParameterNodeImpl(Node p, DataFlowCallable c, ParameterPosition pos) { exists(Parameter parameter | parameter = c.asSourceCallable().(Function).getParameter(pos.asPositional()) and @@ -1014,7 +1027,11 @@ DataFlowCallable viableCallable(DataFlowCall node) { or exists(LibraryCallable callable | result = MkLibraryCallable(callable) and - node.asOrdinaryCall() = [callable.getACall(), callable.getACallSimple()] + node.asOrdinaryCall() = + [ + callable.getACall(), callable.getACallSimple(), + callable.(LibraryCallableInternal).getACallStage2() + ] ) or result.asSourceCallableNotExterns() = node.asImpliedLambdaCall() diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index 6ae42a90bd2..460a2be4f1d 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -9,6 +9,7 @@ private import sharedlib.DataFlowImplCommon private import sharedlib.FlowSummaryImpl::Private as Private private import sharedlib.FlowSummaryImpl::Public private import codeql.dataflow.internal.AccessPathSyntax as AccessPathSyntax +private import semmle.javascript.internal.flow_summaries.ExceptionFlow /** * A class of callables that are candidates for flow summary modeling. @@ -131,7 +132,11 @@ ReturnKind getStandardReturnValueKind() { result = MkNormalReturnKind() and Stag private module FlowSummaryStepInput implements Private::StepsInputSig { DataFlowCall getACall(SummarizedCallable sc) { exists(LibraryCallable callable | callable = sc | - result.asOrdinaryCall() = [callable.getACall(), callable.getACallSimple()] + result.asOrdinaryCall() = + [ + callable.getACall(), callable.getACallSimple(), + callable.(LibraryCallableInternal).getACallStage2() + ] ) } } diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll index 04616e05dc6..a1d82cbf608 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll @@ -5,6 +5,7 @@ private import javascript private import FlowSummaryUtil private import semmle.javascript.dataflow.internal.AdditionalFlowInternal +private import semmle.javascript.dataflow.internal.DataFlowPrivate private import semmle.javascript.dataflow.FlowSummary private import semmle.javascript.internal.flow_summaries.Promises @@ -22,14 +23,14 @@ private predicate isCallback(DataFlow::SourceNode node) { /** * Summary that propagates exceptions out of callbacks back to the caller. */ -private class ExceptionFlowSummary extends SummarizedCallable { +private class ExceptionFlowSummary extends SummarizedCallable, LibraryCallableInternal { ExceptionFlowSummary() { this = "Exception propagator" } - override DataFlow::CallNode getACall() { + override DataFlow::CallNode getACallStage2() { not exists(result.getACallee()) and + not exists(SummarizedCallable c | result = [c.getACall(), c.getACallSimple()]) and // Avoid a few common cases where the exception should not propagate back - not result.getCalleeName() = - ["then", "catch", "finally", "addEventListener", EventEmitter::on()] and + not result.getCalleeName() = ["addEventListener", EventEmitter::on()] and not result = promiseConstructorRef().getAnInvocation() and // Restrict to cases where a callback is known to flow in, as lambda flow in DataFlowImplCommon blows up otherwise isCallback(result.getAnArgument().getALocalSource()) From ce00bd2cc969a8532c3c7e851c84346b75ef8c20 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 21 Nov 2024 11:06:43 +0100 Subject: [PATCH 351/514] JS: More docs --- .../javascript/internal/flow_summaries/ExceptionFlow.qll | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll index a1d82cbf608..c81dadadfb6 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll @@ -22,6 +22,10 @@ private predicate isCallback(DataFlow::SourceNode node) { /** * Summary that propagates exceptions out of callbacks back to the caller. + * + * This summary only applies to calls that have no other call targets. + * See also `FlowSummaryDefaultExceptionalReturn`, which handles calls that have a summary target, + * but where the summary does not mention `ReturnValue[exception]`. */ private class ExceptionFlowSummary extends SummarizedCallable, LibraryCallableInternal { ExceptionFlowSummary() { this = "Exception propagator" } From 9dad2d62d76c40015376b585a09b9209c2b1358c Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 21 Nov 2024 12:54:11 +0100 Subject: [PATCH 352/514] JS: Update DataFlowConsistency --- .../javascript/dataflow/internal/DataFlowImplConsistency.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll index aa892c810db..e5ce83d86c8 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowImplConsistency.qll @@ -26,6 +26,8 @@ private module ConsistencyConfig implements InputSig { or n instanceof FlowSummaryDynamicParameterArrayNode or + n instanceof FlowSummaryDefaultExceptionalReturn + or n instanceof GenericSynthesizedNode or n = DataFlow::globalAccessPathRootPseudoNode() From 1ac7591fafe990c47f78f6f080b9a5291cab4d1e Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 21 Nov 2024 12:57:34 +0100 Subject: [PATCH 353/514] JS: Update missed flow in capture-flow.js We previously caught this flow because of a heuristic in capture flow. We'll have to fix it properly later. --- .../library-tests/TaintTracking/BasicTaintTracking.expected | 2 +- .../test/library-tests/TaintTracking/DataFlowTracking.expected | 2 +- javascript/ql/test/library-tests/TaintTracking/capture-flow.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 2d3c12597b9..069da0c2c6f 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -17,6 +17,7 @@ legacyDataFlowDifference | callbacks.js:44:17:44:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | | capture-flow.js:89:13:89:20 | source() | capture-flow.js:89:6:89:21 | test3c(source()) | only flow with NEW data flow library | | capture-flow.js:101:12:101:19 | source() | capture-flow.js:102:6:102:20 | test5("safe")() | only flow with OLD data flow library | +| capture-flow.js:126:25:126:32 | source() | capture-flow.js:123:14:123:26 | orderingTaint | only flow with OLD data flow library | | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:40:8:40:14 | e.taint | only flow with NEW data flow library | | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:44:8:44:19 | f_safe.taint | only flow with NEW data flow library | | constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:39:8:39:14 | e.param | only flow with NEW data flow library | @@ -109,7 +110,6 @@ flow | capture-flow.js:101:12:101:19 | source() | capture-flow.js:101:6:101:22 | test5(source())() | | capture-flow.js:110:12:110:19 | source() | capture-flow.js:106:14:106:14 | x | | capture-flow.js:118:37:118:44 | source() | capture-flow.js:114:14:114:14 | x | -| capture-flow.js:126:25:126:32 | source() | capture-flow.js:123:14:123:26 | orderingTaint | | capture-flow.js:126:25:126:32 | source() | capture-flow.js:129:14:129:26 | orderingTaint | | capture-flow.js:177:26:177:33 | source() | capture-flow.js:173:14:173:14 | x | | capture-flow.js:187:34:187:41 | source() | capture-flow.js:183:14:183:14 | x | diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected index 7e083f53550..1f4f69f0274 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected @@ -11,6 +11,7 @@ legacyDataFlowDifference | callbacks.js:44:17:44:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | | capture-flow.js:89:13:89:20 | source() | capture-flow.js:89:6:89:21 | test3c(source()) | only flow with NEW data flow library | | capture-flow.js:101:12:101:19 | source() | capture-flow.js:102:6:102:20 | test5("safe")() | only flow with OLD data flow library | +| capture-flow.js:126:25:126:32 | source() | capture-flow.js:123:14:123:26 | orderingTaint | only flow with OLD data flow library | | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:40:8:40:14 | e.taint | only flow with NEW data flow library | | constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:44:8:44:19 | f_safe.taint | only flow with NEW data flow library | | constructor-calls.js:20:15:20:22 | source() | constructor-calls.js:39:8:39:14 | e.param | only flow with NEW data flow library | @@ -84,7 +85,6 @@ flow | capture-flow.js:101:12:101:19 | source() | capture-flow.js:101:6:101:22 | test5(source())() | | capture-flow.js:110:12:110:19 | source() | capture-flow.js:106:14:106:14 | x | | capture-flow.js:118:37:118:44 | source() | capture-flow.js:114:14:114:14 | x | -| capture-flow.js:126:25:126:32 | source() | capture-flow.js:123:14:123:26 | orderingTaint | | capture-flow.js:126:25:126:32 | source() | capture-flow.js:129:14:129:26 | orderingTaint | | capture-flow.js:177:26:177:33 | source() | capture-flow.js:173:14:173:14 | x | | capture-flow.js:187:34:187:41 | source() | capture-flow.js:183:14:183:14 | x | diff --git a/javascript/ql/test/library-tests/TaintTracking/capture-flow.js b/javascript/ql/test/library-tests/TaintTracking/capture-flow.js index 20e654da6d0..ba792b889bf 100644 --- a/javascript/ql/test/library-tests/TaintTracking/capture-flow.js +++ b/javascript/ql/test/library-tests/TaintTracking/capture-flow.js @@ -120,7 +120,7 @@ global.doEscape(testEscapeViaReturn(source())); function ordering() { var orderingTaint; global.addEventListener('click', () => { - sink(orderingTaint); // NOT OK + sink(orderingTaint); // NOT OK [INCONSISTENCY] }); global.addEventListener('load', () => { orderingTaint = source(); From 7a7743202486615e8bbaca44d2de5e9d75b543ca Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 21 Nov 2024 13:33:10 +0100 Subject: [PATCH 354/514] JS: Update lost result in insecure-download The VariableCapture library consumes one component of the access path limit, which means we lose this result --- .../CWE-829/InsecureDownload.expected | 28 ------------------- .../Security/CWE-829/insecure-download.js | 4 +-- 2 files changed, 2 insertions(+), 30 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-829/InsecureDownload.expected b/javascript/ql/test/query-tests/Security/CWE-829/InsecureDownload.expected index d697f55bdd7..aa8290bac3b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-829/InsecureDownload.expected +++ b/javascript/ql/test/query-tests/Security/CWE-829/InsecureDownload.expected @@ -1,18 +1,4 @@ nodes -| insecure-download.js:4:28:4:36 | installer [url] | semmle.label | installer [url] | -| insecure-download.js:5:16:5:24 | installer [url] | semmle.label | installer [url] | -| insecure-download.js:5:16:5:28 | installer.url | semmle.label | installer.url | -| insecure-download.js:7:9:11:5 | constants [buildTools, installerUrl] | semmle.label | constants [buildTools, installerUrl] | -| insecure-download.js:7:21:11:5 | {\\n ... }\\n } [buildTools, installerUrl] | semmle.label | {\\n ... }\\n } [buildTools, installerUrl] | -| insecure-download.js:8:21:10:9 | {\\n ... } [installerUrl] | semmle.label | {\\n ... } [installerUrl] | -| insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | semmle.label | 'http:/ ... ll.exe' | -| insecure-download.js:13:15:13:47 | buildTools [installerUrl] | semmle.label | buildTools [installerUrl] | -| insecure-download.js:13:28:13:36 | constants [buildTools, installerUrl] | semmle.label | constants [buildTools, installerUrl] | -| insecure-download.js:13:28:13:47 | constants.buildTools [installerUrl] | semmle.label | constants.buildTools [installerUrl] | -| insecure-download.js:14:16:16:9 | {\\n ... } [url] | semmle.label | {\\n ... } [url] | -| insecure-download.js:15:18:15:27 | buildTools [installerUrl] | semmle.label | buildTools [installerUrl] | -| insecure-download.js:15:18:15:40 | buildTo ... llerUrl | semmle.label | buildTo ... llerUrl | -| insecure-download.js:19:19:19:46 | getBuil ... rPath() [url] | semmle.label | getBuil ... rPath() [url] | | insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | semmle.label | "http:/ ... fe.APK" | | insecure-download.js:36:9:36:45 | url | semmle.label | url | | insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | semmle.label | "http:/ ... fe.APK" | @@ -22,25 +8,11 @@ nodes | insecure-download.js:48:12:48:38 | "http:/ ... unsafe" | semmle.label | "http:/ ... unsafe" | | insecure-download.js:52:11:52:45 | "http:/ ... nknown" | semmle.label | "http:/ ... nknown" | edges -| insecure-download.js:4:28:4:36 | installer [url] | insecure-download.js:5:16:5:24 | installer [url] | provenance | | -| insecure-download.js:5:16:5:24 | installer [url] | insecure-download.js:5:16:5:28 | installer.url | provenance | | -| insecure-download.js:7:9:11:5 | constants [buildTools, installerUrl] | insecure-download.js:13:28:13:36 | constants [buildTools, installerUrl] | provenance | | -| insecure-download.js:7:21:11:5 | {\\n ... }\\n } [buildTools, installerUrl] | insecure-download.js:7:9:11:5 | constants [buildTools, installerUrl] | provenance | | -| insecure-download.js:8:21:10:9 | {\\n ... } [installerUrl] | insecure-download.js:7:21:11:5 | {\\n ... }\\n } [buildTools, installerUrl] | provenance | | -| insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | insecure-download.js:8:21:10:9 | {\\n ... } [installerUrl] | provenance | | -| insecure-download.js:13:15:13:47 | buildTools [installerUrl] | insecure-download.js:15:18:15:27 | buildTools [installerUrl] | provenance | | -| insecure-download.js:13:28:13:36 | constants [buildTools, installerUrl] | insecure-download.js:13:28:13:47 | constants.buildTools [installerUrl] | provenance | | -| insecure-download.js:13:28:13:47 | constants.buildTools [installerUrl] | insecure-download.js:13:15:13:47 | buildTools [installerUrl] | provenance | | -| insecure-download.js:14:16:16:9 | {\\n ... } [url] | insecure-download.js:19:19:19:46 | getBuil ... rPath() [url] | provenance | | -| insecure-download.js:15:18:15:27 | buildTools [installerUrl] | insecure-download.js:15:18:15:40 | buildTo ... llerUrl | provenance | | -| insecure-download.js:15:18:15:40 | buildTo ... llerUrl | insecure-download.js:14:16:16:9 | {\\n ... } [url] | provenance | | -| insecure-download.js:19:19:19:46 | getBuil ... rPath() [url] | insecure-download.js:4:28:4:36 | installer [url] | provenance | | | insecure-download.js:36:9:36:45 | url | insecure-download.js:37:23:37:25 | url | provenance | | | insecure-download.js:36:9:36:45 | url | insecure-download.js:39:26:39:28 | url | provenance | | | insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | insecure-download.js:36:9:36:45 | url | provenance | | subpaths #select -| insecure-download.js:5:16:5:28 | installer.url | insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | insecure-download.js:5:16:5:28 | installer.url | $@ of sensitive file from $@. | insecure-download.js:5:9:5:44 | nugget( ... => { }) | Download | insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | HTTP source | | insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | $@ of sensitive file from $@. | insecure-download.js:30:5:30:43 | nugget( ... e.APK") | Download | insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | HTTP source | | insecure-download.js:37:23:37:25 | url | insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | insecure-download.js:37:23:37:25 | url | $@ of sensitive file from $@. | insecure-download.js:37:5:37:42 | cp.exec ... () {}) | Download | insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | HTTP source | | insecure-download.js:39:26:39:28 | url | insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | insecure-download.js:39:26:39:28 | url | $@ of sensitive file from $@. | insecure-download.js:39:5:39:46 | cp.exec ... () {}) | Download | insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | HTTP source | diff --git a/javascript/ql/test/query-tests/Security/CWE-829/insecure-download.js b/javascript/ql/test/query-tests/Security/CWE-829/insecure-download.js index 4f662e8e1dd..9a62286218d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-829/insecure-download.js +++ b/javascript/ql/test/query-tests/Security/CWE-829/insecure-download.js @@ -2,7 +2,7 @@ const nugget = require('nugget'); function foo() { function downloadTools(installer) { - nugget(installer.url, {}, () => { }) // NOT OK + nugget(installer.url, {}, () => { }) // NOT OK [INCONSISTENCY] - access path too deep } var constants = { buildTools: { @@ -56,4 +56,4 @@ function test() { $.get("http://example.org/unsafe.unknown", function( data ) { writeFileAtomic('foo.safe', data, {}, function (err) {}); // OK }); -} \ No newline at end of file +} From 930a7b6e282be86bb7073e16a6f9af1fe4f7f6f5 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 21 Nov 2024 13:33:39 +0100 Subject: [PATCH 355/514] JS: Update output changes to nodes/edges/subpaths --- .../Security/CWE-079/DomBasedXss/Xss.expected | 45 +++++++++++++++---- .../XssWithAdditionalSources.expected | 45 +++++++++++++++---- 2 files changed, 72 insertions(+), 18 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 25651d7e060..868e9c0eedd 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -153,6 +153,9 @@ nodes | express.js:7:15:7:33 | req.param("wobble") | semmle.label | req.param("wobble") | | jquery.js:2:7:2:40 | tainted | semmle.label | tainted | | jquery.js:2:17:2:40 | documen ... .search | semmle.label | documen ... .search | +| jquery.js:4:5:4:11 | tainted | semmle.label | tainted | +| jquery.js:5:13:5:19 | tainted | semmle.label | tainted | +| jquery.js:6:11:6:17 | tainted | semmle.label | tainted | | jquery.js:7:5:7:34 | "
    " | semmle.label | "
    " | | jquery.js:7:20:7:26 | tainted | semmle.label | tainted | | jquery.js:8:18:8:34 | "XSS: " + tainted | semmle.label | "XSS: " + tainted | @@ -321,6 +324,9 @@ nodes | tooltip.jsx:6:20:6:30 | window.name | semmle.label | window.name | | tooltip.jsx:10:25:10:30 | source | semmle.label | source | | tooltip.jsx:11:25:11:30 | source | semmle.label | source | +| tooltip.jsx:17:11:17:33 | provide [source] | semmle.label | provide [source] | +| tooltip.jsx:17:21:17:33 | props.provide [source] | semmle.label | props.provide [source] | +| tooltip.jsx:18:51:18:57 | provide [source] | semmle.label | provide [source] | | tooltip.jsx:18:51:18:59 | provide() | semmle.label | provide() | | tooltip.jsx:22:11:22:30 | source | semmle.label | source | | tooltip.jsx:22:20:22:30 | window.name | semmle.label | window.name | @@ -491,6 +497,7 @@ nodes | tst.js:355:10:355:42 | target | semmle.label | target | | tst.js:355:19:355:42 | documen ... .search | semmle.label | documen ... .search | | tst.js:356:16:356:21 | target | semmle.label | target | +| tst.js:357:20:357:25 | target | semmle.label | target | | tst.js:360:21:360:26 | target | semmle.label | target | | tst.js:363:18:363:23 | target | semmle.label | target | | tst.js:371:7:371:39 | target | semmle.label | target | @@ -725,13 +732,20 @@ edges | dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | provenance | | | event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

    ' | provenance | | | event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

    ' | provenance | Config | +| jquery.js:2:7:2:40 | tainted | jquery.js:4:5:4:11 | tainted | provenance | | +| jquery.js:2:7:2:40 | tainted | jquery.js:5:13:5:19 | tainted | provenance | | +| jquery.js:2:7:2:40 | tainted | jquery.js:6:11:6:17 | tainted | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:7:20:7:26 | tainted | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:8:28:8:34 | tainted | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | provenance | | -| jquery.js:2:7:2:40 | tainted | jquery.js:37:31:37:37 | tainted | provenance | | | jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | provenance | | +| jquery.js:4:5:4:11 | tainted | jquery.js:5:13:5:19 | tainted | provenance | | +| jquery.js:5:13:5:19 | tainted | jquery.js:6:11:6:17 | tainted | provenance | | +| jquery.js:6:11:6:17 | tainted | jquery.js:7:20:7:26 | tainted | provenance | | | jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "
    " | provenance | Config | +| jquery.js:7:20:7:26 | tainted | jquery.js:8:28:8:34 | tainted | provenance | | | jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | provenance | | +| jquery.js:8:28:8:34 | tainted | jquery.js:36:25:36:31 | tainted | provenance | | | jquery.js:10:13:10:20 | location | jquery.js:10:13:10:31 | location.toString() | provenance | | | jquery.js:10:13:10:31 | location.toString() | jquery.js:10:5:10:40 | "" + ... "" | provenance | Config | | jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | provenance | | @@ -752,6 +766,7 @@ edges | jquery.js:27:5:27:8 | hash | jquery.js:27:5:27:25 | hash.re ... #', '') | provenance | Config | | jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | provenance | Config | | jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '' + ... '' | provenance | Config | +| jquery.js:36:25:36:31 | tainted | jquery.js:37:31:37:37 | tainted | provenance | | | jquery.js:37:31:37:37 | tainted | jquery.js:37:25:37:37 | () => tainted | provenance | Config | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:11:51:11:56 | locale | provenance | | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:19:56:19:61 | locale | provenance | | @@ -863,9 +878,12 @@ edges | tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | provenance | | | tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | provenance | | | tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source | provenance | | -| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:23:38:23:43 | source | provenance | | +| tooltip.jsx:17:11:17:33 | provide [source] | tooltip.jsx:18:51:18:57 | provide [source] | provenance | | +| tooltip.jsx:17:21:17:33 | props.provide [source] | tooltip.jsx:17:11:17:33 | provide [source] | provenance | | +| tooltip.jsx:18:51:18:57 | provide [source] | tooltip.jsx:18:51:18:59 | provide() | provenance | | +| tooltip.jsx:18:51:18:57 | provide [source] | tooltip.jsx:23:38:23:43 | source | provenance | | +| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:17:21:17:33 | props.provide [source] | provenance | | | tooltip.jsx:22:20:22:30 | window.name | tooltip.jsx:22:11:22:30 | source | provenance | | -| tooltip.jsx:23:38:23:43 | source | tooltip.jsx:18:51:18:59 | provide() | provenance | | | translate.js:6:7:6:39 | target | translate.js:7:42:7:47 | target | provenance | | | translate.js:6:16:6:39 | documen ... .search | translate.js:6:7:6:39 | target | provenance | | | translate.js:7:7:7:61 | searchParams | translate.js:9:27:9:38 | searchParams | provenance | | @@ -964,24 +982,30 @@ edges | tst.js:184:19:184:42 | documen ... .search | tst.js:184:9:184:42 | tainted | provenance | | | tst.js:197:9:197:42 | tainted | tst.js:199:67:199:73 | tainted | provenance | | | tst.js:197:9:197:42 | tainted | tst.js:200:67:200:73 | tainted | provenance | | -| tst.js:197:9:197:42 | tainted | tst.js:204:35:204:41 | tainted | provenance | | -| tst.js:197:9:197:42 | tainted | tst.js:206:46:206:52 | tainted | provenance | | -| tst.js:197:9:197:42 | tainted | tst.js:207:38:207:44 | tainted | provenance | | -| tst.js:197:9:197:42 | tainted | tst.js:208:35:208:41 | tainted | provenance | | | tst.js:197:9:197:42 | tainted | tst.js:236:35:236:41 | tainted | provenance | | | tst.js:197:9:197:42 | tainted | tst.js:238:20:238:26 | tainted | provenance | | | tst.js:197:9:197:42 | tainted | tst.js:240:23:240:29 | tainted | provenance | | | tst.js:197:9:197:42 | tainted | tst.js:241:23:241:29 | tainted | provenance | | | tst.js:197:9:197:42 | tainted | tst.js:255:23:255:29 | tainted | provenance | | | tst.js:197:19:197:42 | documen ... .search | tst.js:197:9:197:42 | tainted | provenance | | +| tst.js:199:67:199:73 | tainted | tst.js:200:67:200:73 | tainted | provenance | | +| tst.js:200:67:200:73 | tainted | tst.js:204:35:204:41 | tainted | provenance | | +| tst.js:200:67:200:73 | tainted | tst.js:206:46:206:52 | tainted | provenance | | +| tst.js:200:67:200:73 | tainted | tst.js:207:38:207:44 | tainted | provenance | | +| tst.js:200:67:200:73 | tainted | tst.js:208:35:208:41 | tainted | provenance | | +| tst.js:200:67:200:73 | tainted | tst.js:236:35:236:41 | tainted | provenance | | | tst.js:204:35:204:41 | tainted | tst.js:212:28:212:46 | this.state.tainted1 | provenance | | | tst.js:206:46:206:52 | tainted | tst.js:213:28:213:46 | this.state.tainted2 | provenance | | | tst.js:207:38:207:44 | tainted | tst.js:214:28:214:46 | this.state.tainted3 | provenance | | | tst.js:208:35:208:41 | tainted | tst.js:218:32:218:49 | prevState.tainted4 | provenance | | | tst.js:236:35:236:41 | tainted | tst.js:225:28:225:46 | this.props.tainted1 | provenance | | +| tst.js:236:35:236:41 | tainted | tst.js:238:20:238:26 | tainted | provenance | | | tst.js:238:20:238:26 | tainted | tst.js:226:28:226:46 | this.props.tainted2 | provenance | | +| tst.js:238:20:238:26 | tainted | tst.js:240:23:240:29 | tainted | provenance | | | tst.js:240:23:240:29 | tainted | tst.js:227:28:227:46 | this.props.tainted3 | provenance | | +| tst.js:240:23:240:29 | tainted | tst.js:241:23:241:29 | tainted | provenance | | | tst.js:241:23:241:29 | tainted | tst.js:231:32:231:49 | prevProps.tainted4 | provenance | | +| tst.js:241:23:241:29 | tainted | tst.js:255:23:255:29 | tainted | provenance | | | tst.js:247:39:247:55 | props.propTainted | tst.js:251:60:251:82 | this.st ... Tainted | provenance | | | tst.js:255:23:255:29 | tainted | tst.js:247:39:247:55 | props.propTainted | provenance | | | tst.js:285:9:285:29 | tainted | tst.js:288:59:288:65 | tainted | provenance | | @@ -1003,9 +1027,11 @@ edges | tst.js:348:7:348:39 | target | tst.js:349:12:349:17 | target | provenance | | | tst.js:348:16:348:39 | documen ... .search | tst.js:348:7:348:39 | target | provenance | | | tst.js:355:10:355:42 | target | tst.js:356:16:356:21 | target | provenance | | -| tst.js:355:10:355:42 | target | tst.js:360:21:360:26 | target | provenance | | -| tst.js:355:10:355:42 | target | tst.js:363:18:363:23 | target | provenance | | +| tst.js:355:10:355:42 | target | tst.js:357:20:357:25 | target | provenance | | | tst.js:355:19:355:42 | documen ... .search | tst.js:355:10:355:42 | target | provenance | | +| tst.js:356:16:356:21 | target | tst.js:357:20:357:25 | target | provenance | | +| tst.js:357:20:357:25 | target | tst.js:360:21:360:26 | target | provenance | | +| tst.js:357:20:357:25 | target | tst.js:363:18:363:23 | target | provenance | | | tst.js:371:7:371:39 | target | tst.js:374:18:374:23 | target | provenance | | | tst.js:371:16:371:39 | documen ... .search | tst.js:371:7:371:39 | target | provenance | | | tst.js:381:7:381:39 | target | tst.js:384:18:384:23 | target | provenance | | @@ -1116,6 +1142,7 @@ subpaths | optionalSanitizer.js:34:28:34:35 | tainted2 | optionalSanitizer.js:28:24:28:24 | x | optionalSanitizer.js:29:12:29:12 | x | optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | | optionalSanitizer.js:41:28:41:35 | tainted3 | optionalSanitizer.js:28:24:28:24 | x | optionalSanitizer.js:29:12:29:12 | x | optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | | optionalSanitizer.js:45:41:45:46 | target | optionalSanitizer.js:28:24:28:24 | x | optionalSanitizer.js:29:12:29:12 | x | optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | +| tooltip.jsx:18:51:18:57 | provide [source] | tooltip.jsx:23:38:23:43 | source | tooltip.jsx:23:38:23:43 | source | tooltip.jsx:18:51:18:59 | provide() | | tst.js:40:20:40:43 | documen ... .search | tst.js:36:14:36:14 | x | tst.js:37:10:37:10 | x | tst.js:40:16:40:44 | baz(doc ... search) | | tst.js:46:21:46:44 | documen ... .search | tst.js:42:15:42:15 | s | tst.js:43:10:43:31 | "
    " ...
    " | tst.js:46:16:46:45 | wrap(do ... search) | | tst.js:54:21:54:44 | documen ... .search | tst.js:48:15:48:15 | s | tst.js:50:12:50:22 | s.substr(1) | tst.js:54:16:54:45 | chop(do ... search) | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index a3c256a1b72..cef53b2b3f5 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -153,6 +153,9 @@ nodes | express.js:7:15:7:33 | req.param("wobble") | semmle.label | req.param("wobble") | | jquery.js:2:7:2:40 | tainted | semmle.label | tainted | | jquery.js:2:17:2:40 | documen ... .search | semmle.label | documen ... .search | +| jquery.js:4:5:4:11 | tainted | semmle.label | tainted | +| jquery.js:5:13:5:19 | tainted | semmle.label | tainted | +| jquery.js:6:11:6:17 | tainted | semmle.label | tainted | | jquery.js:7:5:7:34 | "
    " | semmle.label | "
    " | | jquery.js:7:20:7:26 | tainted | semmle.label | tainted | | jquery.js:8:18:8:34 | "XSS: " + tainted | semmle.label | "XSS: " + tainted | @@ -326,6 +329,9 @@ nodes | tooltip.jsx:6:20:6:30 | window.name | semmle.label | window.name | | tooltip.jsx:10:25:10:30 | source | semmle.label | source | | tooltip.jsx:11:25:11:30 | source | semmle.label | source | +| tooltip.jsx:17:11:17:33 | provide [source] | semmle.label | provide [source] | +| tooltip.jsx:17:21:17:33 | props.provide [source] | semmle.label | props.provide [source] | +| tooltip.jsx:18:51:18:57 | provide [source] | semmle.label | provide [source] | | tooltip.jsx:18:51:18:59 | provide() | semmle.label | provide() | | tooltip.jsx:22:11:22:30 | source | semmle.label | source | | tooltip.jsx:22:20:22:30 | window.name | semmle.label | window.name | @@ -496,6 +502,7 @@ nodes | tst.js:355:10:355:42 | target | semmle.label | target | | tst.js:355:19:355:42 | documen ... .search | semmle.label | documen ... .search | | tst.js:356:16:356:21 | target | semmle.label | target | +| tst.js:357:20:357:25 | target | semmle.label | target | | tst.js:360:21:360:26 | target | semmle.label | target | | tst.js:363:18:363:23 | target | semmle.label | target | | tst.js:371:7:371:39 | target | semmle.label | target | @@ -745,13 +752,20 @@ edges | dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | provenance | | | event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

    ' | provenance | | | event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

    ' | provenance | Config | +| jquery.js:2:7:2:40 | tainted | jquery.js:4:5:4:11 | tainted | provenance | | +| jquery.js:2:7:2:40 | tainted | jquery.js:5:13:5:19 | tainted | provenance | | +| jquery.js:2:7:2:40 | tainted | jquery.js:6:11:6:17 | tainted | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:7:20:7:26 | tainted | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:8:28:8:34 | tainted | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | provenance | | -| jquery.js:2:7:2:40 | tainted | jquery.js:37:31:37:37 | tainted | provenance | | | jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | provenance | | +| jquery.js:4:5:4:11 | tainted | jquery.js:5:13:5:19 | tainted | provenance | | +| jquery.js:5:13:5:19 | tainted | jquery.js:6:11:6:17 | tainted | provenance | | +| jquery.js:6:11:6:17 | tainted | jquery.js:7:20:7:26 | tainted | provenance | | | jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "
    " | provenance | Config | +| jquery.js:7:20:7:26 | tainted | jquery.js:8:28:8:34 | tainted | provenance | | | jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | provenance | | +| jquery.js:8:28:8:34 | tainted | jquery.js:36:25:36:31 | tainted | provenance | | | jquery.js:10:13:10:20 | location | jquery.js:10:13:10:31 | location.toString() | provenance | | | jquery.js:10:13:10:31 | location.toString() | jquery.js:10:5:10:40 | "" + ... "" | provenance | Config | | jquery.js:14:38:14:57 | window.location.hash | jquery.js:14:19:14:58 | decodeU ... n.hash) | provenance | | @@ -772,6 +786,7 @@ edges | jquery.js:27:5:27:8 | hash | jquery.js:27:5:27:25 | hash.re ... #', '') | provenance | Config | | jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | provenance | Config | | jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '' + ... '' | provenance | Config | +| jquery.js:36:25:36:31 | tainted | jquery.js:37:31:37:37 | tainted | provenance | | | jquery.js:37:31:37:37 | tainted | jquery.js:37:25:37:37 | () => tainted | provenance | Config | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:11:51:11:56 | locale | provenance | | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:19:56:19:61 | locale | provenance | | @@ -887,9 +902,12 @@ edges | tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source | provenance | | | tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source | provenance | | | tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source | provenance | | -| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:23:38:23:43 | source | provenance | | +| tooltip.jsx:17:11:17:33 | provide [source] | tooltip.jsx:18:51:18:57 | provide [source] | provenance | | +| tooltip.jsx:17:21:17:33 | props.provide [source] | tooltip.jsx:17:11:17:33 | provide [source] | provenance | | +| tooltip.jsx:18:51:18:57 | provide [source] | tooltip.jsx:18:51:18:59 | provide() | provenance | | +| tooltip.jsx:18:51:18:57 | provide [source] | tooltip.jsx:23:38:23:43 | source | provenance | | +| tooltip.jsx:22:11:22:30 | source | tooltip.jsx:17:21:17:33 | props.provide [source] | provenance | | | tooltip.jsx:22:20:22:30 | window.name | tooltip.jsx:22:11:22:30 | source | provenance | | -| tooltip.jsx:23:38:23:43 | source | tooltip.jsx:18:51:18:59 | provide() | provenance | | | translate.js:6:7:6:39 | target | translate.js:7:42:7:47 | target | provenance | | | translate.js:6:16:6:39 | documen ... .search | translate.js:6:7:6:39 | target | provenance | | | translate.js:7:7:7:61 | searchParams | translate.js:9:27:9:38 | searchParams | provenance | | @@ -988,24 +1006,30 @@ edges | tst.js:184:19:184:42 | documen ... .search | tst.js:184:9:184:42 | tainted | provenance | | | tst.js:197:9:197:42 | tainted | tst.js:199:67:199:73 | tainted | provenance | | | tst.js:197:9:197:42 | tainted | tst.js:200:67:200:73 | tainted | provenance | | -| tst.js:197:9:197:42 | tainted | tst.js:204:35:204:41 | tainted | provenance | | -| tst.js:197:9:197:42 | tainted | tst.js:206:46:206:52 | tainted | provenance | | -| tst.js:197:9:197:42 | tainted | tst.js:207:38:207:44 | tainted | provenance | | -| tst.js:197:9:197:42 | tainted | tst.js:208:35:208:41 | tainted | provenance | | | tst.js:197:9:197:42 | tainted | tst.js:236:35:236:41 | tainted | provenance | | | tst.js:197:9:197:42 | tainted | tst.js:238:20:238:26 | tainted | provenance | | | tst.js:197:9:197:42 | tainted | tst.js:240:23:240:29 | tainted | provenance | | | tst.js:197:9:197:42 | tainted | tst.js:241:23:241:29 | tainted | provenance | | | tst.js:197:9:197:42 | tainted | tst.js:255:23:255:29 | tainted | provenance | | | tst.js:197:19:197:42 | documen ... .search | tst.js:197:9:197:42 | tainted | provenance | | +| tst.js:199:67:199:73 | tainted | tst.js:200:67:200:73 | tainted | provenance | | +| tst.js:200:67:200:73 | tainted | tst.js:204:35:204:41 | tainted | provenance | | +| tst.js:200:67:200:73 | tainted | tst.js:206:46:206:52 | tainted | provenance | | +| tst.js:200:67:200:73 | tainted | tst.js:207:38:207:44 | tainted | provenance | | +| tst.js:200:67:200:73 | tainted | tst.js:208:35:208:41 | tainted | provenance | | +| tst.js:200:67:200:73 | tainted | tst.js:236:35:236:41 | tainted | provenance | | | tst.js:204:35:204:41 | tainted | tst.js:212:28:212:46 | this.state.tainted1 | provenance | | | tst.js:206:46:206:52 | tainted | tst.js:213:28:213:46 | this.state.tainted2 | provenance | | | tst.js:207:38:207:44 | tainted | tst.js:214:28:214:46 | this.state.tainted3 | provenance | | | tst.js:208:35:208:41 | tainted | tst.js:218:32:218:49 | prevState.tainted4 | provenance | | | tst.js:236:35:236:41 | tainted | tst.js:225:28:225:46 | this.props.tainted1 | provenance | | +| tst.js:236:35:236:41 | tainted | tst.js:238:20:238:26 | tainted | provenance | | | tst.js:238:20:238:26 | tainted | tst.js:226:28:226:46 | this.props.tainted2 | provenance | | +| tst.js:238:20:238:26 | tainted | tst.js:240:23:240:29 | tainted | provenance | | | tst.js:240:23:240:29 | tainted | tst.js:227:28:227:46 | this.props.tainted3 | provenance | | +| tst.js:240:23:240:29 | tainted | tst.js:241:23:241:29 | tainted | provenance | | | tst.js:241:23:241:29 | tainted | tst.js:231:32:231:49 | prevProps.tainted4 | provenance | | +| tst.js:241:23:241:29 | tainted | tst.js:255:23:255:29 | tainted | provenance | | | tst.js:247:39:247:55 | props.propTainted | tst.js:251:60:251:82 | this.st ... Tainted | provenance | | | tst.js:255:23:255:29 | tainted | tst.js:247:39:247:55 | props.propTainted | provenance | | | tst.js:285:9:285:29 | tainted | tst.js:288:59:288:65 | tainted | provenance | | @@ -1027,9 +1051,11 @@ edges | tst.js:348:7:348:39 | target | tst.js:349:12:349:17 | target | provenance | | | tst.js:348:16:348:39 | documen ... .search | tst.js:348:7:348:39 | target | provenance | | | tst.js:355:10:355:42 | target | tst.js:356:16:356:21 | target | provenance | | -| tst.js:355:10:355:42 | target | tst.js:360:21:360:26 | target | provenance | | -| tst.js:355:10:355:42 | target | tst.js:363:18:363:23 | target | provenance | | +| tst.js:355:10:355:42 | target | tst.js:357:20:357:25 | target | provenance | | | tst.js:355:19:355:42 | documen ... .search | tst.js:355:10:355:42 | target | provenance | | +| tst.js:356:16:356:21 | target | tst.js:357:20:357:25 | target | provenance | | +| tst.js:357:20:357:25 | target | tst.js:360:21:360:26 | target | provenance | | +| tst.js:357:20:357:25 | target | tst.js:363:18:363:23 | target | provenance | | | tst.js:371:7:371:39 | target | tst.js:374:18:374:23 | target | provenance | | | tst.js:371:16:371:39 | documen ... .search | tst.js:371:7:371:39 | target | provenance | | | tst.js:381:7:381:39 | target | tst.js:384:18:384:23 | target | provenance | | @@ -1152,6 +1178,7 @@ subpaths | optionalSanitizer.js:34:28:34:35 | tainted2 | optionalSanitizer.js:28:24:28:24 | x | optionalSanitizer.js:29:12:29:12 | x | optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | | optionalSanitizer.js:41:28:41:35 | tainted3 | optionalSanitizer.js:28:24:28:24 | x | optionalSanitizer.js:29:12:29:12 | x | optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | | optionalSanitizer.js:45:41:45:46 | target | optionalSanitizer.js:28:24:28:24 | x | optionalSanitizer.js:29:12:29:12 | x | optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | +| tooltip.jsx:18:51:18:57 | provide [source] | tooltip.jsx:23:38:23:43 | source | tooltip.jsx:23:38:23:43 | source | tooltip.jsx:18:51:18:59 | provide() | | tst.js:40:20:40:43 | documen ... .search | tst.js:36:14:36:14 | x | tst.js:37:10:37:10 | x | tst.js:40:16:40:44 | baz(doc ... search) | | tst.js:46:21:46:44 | documen ... .search | tst.js:42:15:42:15 | s | tst.js:43:10:43:31 | "
    " ...
    " | tst.js:46:16:46:45 | wrap(do ... search) | | tst.js:54:21:54:44 | documen ... .search | tst.js:48:15:48:15 | s | tst.js:50:12:50:22 | s.substr(1) | tst.js:54:16:54:45 | chop(do ... search) | From b4bd8e701ca082f621dd40800c4a21347b78b542 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 26 Nov 2024 12:33:39 +0100 Subject: [PATCH 356/514] JS: Add test for file classification change --- .../query-tests/filters/ClassifyFiles/ClassifyFiles.expected | 1 + .../test/query-tests/filters/ClassifyFiles/something.test.js | 4 ++++ 2 files changed, 5 insertions(+) create mode 100644 javascript/ql/test/query-tests/filters/ClassifyFiles/something.test.js diff --git a/javascript/ql/test/query-tests/filters/ClassifyFiles/ClassifyFiles.expected b/javascript/ql/test/query-tests/filters/ClassifyFiles/ClassifyFiles.expected index da235c205ee..5b896e958c5 100644 --- a/javascript/ql/test/query-tests/filters/ClassifyFiles/ClassifyFiles.expected +++ b/javascript/ql/test/query-tests/filters/ClassifyFiles/ClassifyFiles.expected @@ -35,6 +35,7 @@ | purs.js:0:0:0:0 | purs.js | generated | | short-variables.js:0:0:0:0 | short-variables.js | generated | | some-template.html:0:0:0:0 | some-template.html | template | +| something.test.js:0:0:0:0 | something.test.js | test | | templ.js:0:0:0:0 | templ.js | template | | textmate.html:0:0:0:0 | textmate.html | generated | | tmpl2.html:0:0:0:0 | tmpl2.html | template | diff --git a/javascript/ql/test/query-tests/filters/ClassifyFiles/something.test.js b/javascript/ql/test/query-tests/filters/ClassifyFiles/something.test.js new file mode 100644 index 00000000000..b396475247a --- /dev/null +++ b/javascript/ql/test/query-tests/filters/ClassifyFiles/something.test.js @@ -0,0 +1,4 @@ +// Deliberately avoid using known test frameworks in this file. +foo('bar', () => { + baz(); +}); From 65da9b41b513daa1d129c69a7e72a47f45f66aec Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 26 Nov 2024 13:43:24 +0100 Subject: [PATCH 357/514] JS: Add cross-file test in InsecureRandom --- .../Security/CWE-338/InsecureRandomness.expected | 8 ++++++++ javascript/ql/test/query-tests/Security/CWE-338/foo.js | 6 ++++++ .../ql/test/query-tests/Security/CWE-338/library1.js | 3 +++ .../ql/test/query-tests/Security/CWE-338/library2.js | 3 +++ 4 files changed, 20 insertions(+) create mode 100644 javascript/ql/test/query-tests/Security/CWE-338/foo.js create mode 100644 javascript/ql/test/query-tests/Security/CWE-338/library1.js create mode 100644 javascript/ql/test/query-tests/Security/CWE-338/library2.js diff --git a/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected b/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected index 122cb1ac876..d126ffeb123 100644 --- a/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected +++ b/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected @@ -1,4 +1,7 @@ edges +| foo.js:5:12:5:22 | getRandom() | library2.js:1:24:1:25 | pw | provenance | | +| library1.js:2:12:2:24 | Math.random() | foo.js:5:12:5:22 | getRandom() | provenance | | +| library2.js:1:24:1:25 | pw | library2.js:2:20:2:21 | pw | provenance | | | tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | provenance | Config | | tst.js:19:9:19:36 | suffix | tst.js:20:31:20:36 | suffix | provenance | | | tst.js:19:18:19:30 | Math.random() | tst.js:19:18:19:36 | Math.random() % 255 | provenance | Config | @@ -32,6 +35,10 @@ edges | tst.js:136:38:136:50 | Math.random() | tst.js:136:38:136:65 | Math.ra ... .length | provenance | Config | | tst.js:136:38:136:65 | Math.ra ... .length | tst.js:136:27:136:66 | Math.fl ... length) | provenance | Config | nodes +| foo.js:5:12:5:22 | getRandom() | semmle.label | getRandom() | +| library1.js:2:12:2:24 | Math.random() | semmle.label | Math.random() | +| library2.js:1:24:1:25 | pw | semmle.label | pw | +| library2.js:2:20:2:21 | pw | semmle.label | pw | | tst.js:2:20:2:32 | Math.random() | semmle.label | Math.random() | | tst.js:6:20:6:43 | "prefix ... andom() | semmle.label | "prefix ... andom() | | tst.js:6:31:6:43 | Math.random() | semmle.label | Math.random() | @@ -89,6 +96,7 @@ nodes | tst.js:136:38:136:65 | Math.ra ... .length | semmle.label | Math.ra ... .length | subpaths #select +| library2.js:2:20:2:21 | pw | library1.js:2:12:2:24 | Math.random() | library2.js:2:20:2:21 | pw | This uses a cryptographically insecure random number generated at $@ in a security context. | library1.js:2:12:2:24 | Math.random() | Math.random() | | tst.js:2:20:2:32 | Math.random() | tst.js:2:20:2:32 | Math.random() | tst.js:2:20:2:32 | Math.random() | This uses a cryptographically insecure random number generated at $@ in a security context. | tst.js:2:20:2:32 | Math.random() | Math.random() | | tst.js:6:20:6:43 | "prefix ... andom() | tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | This uses a cryptographically insecure random number generated at $@ in a security context. | tst.js:6:31:6:43 | Math.random() | Math.random() | | tst.js:10:20:10:32 | Math.random() | tst.js:10:20:10:32 | Math.random() | tst.js:10:20:10:32 | Math.random() | This uses a cryptographically insecure random number generated at $@ in a security context. | tst.js:10:20:10:32 | Math.random() | Math.random() | diff --git a/javascript/ql/test/query-tests/Security/CWE-338/foo.js b/javascript/ql/test/query-tests/Security/CWE-338/foo.js new file mode 100644 index 00000000000..9c898c649b4 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-338/foo.js @@ -0,0 +1,6 @@ +import { getRandom } from "./library1"; +import { doAuth } from "./library2"; + +function f() { + doAuth(getRandom()); +} diff --git a/javascript/ql/test/query-tests/Security/CWE-338/library1.js b/javascript/ql/test/query-tests/Security/CWE-338/library1.js new file mode 100644 index 00000000000..727eaa1a5da --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-338/library1.js @@ -0,0 +1,3 @@ +export function getRandom() { + return Math.random(); +} diff --git a/javascript/ql/test/query-tests/Security/CWE-338/library2.js b/javascript/ql/test/query-tests/Security/CWE-338/library2.js new file mode 100644 index 00000000000..08fa1695747 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-338/library2.js @@ -0,0 +1,3 @@ +export function doAuth(pw) { + var password = pw; +} From f073f3b7918e0ebf9faf158c48c2ac3e113a392b Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 26 Nov 2024 13:44:00 +0100 Subject: [PATCH 358/514] JS: Rename file to foo.test.js --- .../Security/CWE-338/InsecureRandomness.expected | 8 -------- .../query-tests/Security/CWE-338/{foo.js => foo.test.js} | 0 2 files changed, 8 deletions(-) rename javascript/ql/test/query-tests/Security/CWE-338/{foo.js => foo.test.js} (100%) diff --git a/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected b/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected index d126ffeb123..122cb1ac876 100644 --- a/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected +++ b/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected @@ -1,7 +1,4 @@ edges -| foo.js:5:12:5:22 | getRandom() | library2.js:1:24:1:25 | pw | provenance | | -| library1.js:2:12:2:24 | Math.random() | foo.js:5:12:5:22 | getRandom() | provenance | | -| library2.js:1:24:1:25 | pw | library2.js:2:20:2:21 | pw | provenance | | | tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | provenance | Config | | tst.js:19:9:19:36 | suffix | tst.js:20:31:20:36 | suffix | provenance | | | tst.js:19:18:19:30 | Math.random() | tst.js:19:18:19:36 | Math.random() % 255 | provenance | Config | @@ -35,10 +32,6 @@ edges | tst.js:136:38:136:50 | Math.random() | tst.js:136:38:136:65 | Math.ra ... .length | provenance | Config | | tst.js:136:38:136:65 | Math.ra ... .length | tst.js:136:27:136:66 | Math.fl ... length) | provenance | Config | nodes -| foo.js:5:12:5:22 | getRandom() | semmle.label | getRandom() | -| library1.js:2:12:2:24 | Math.random() | semmle.label | Math.random() | -| library2.js:1:24:1:25 | pw | semmle.label | pw | -| library2.js:2:20:2:21 | pw | semmle.label | pw | | tst.js:2:20:2:32 | Math.random() | semmle.label | Math.random() | | tst.js:6:20:6:43 | "prefix ... andom() | semmle.label | "prefix ... andom() | | tst.js:6:31:6:43 | Math.random() | semmle.label | Math.random() | @@ -96,7 +89,6 @@ nodes | tst.js:136:38:136:65 | Math.ra ... .length | semmle.label | Math.ra ... .length | subpaths #select -| library2.js:2:20:2:21 | pw | library1.js:2:12:2:24 | Math.random() | library2.js:2:20:2:21 | pw | This uses a cryptographically insecure random number generated at $@ in a security context. | library1.js:2:12:2:24 | Math.random() | Math.random() | | tst.js:2:20:2:32 | Math.random() | tst.js:2:20:2:32 | Math.random() | tst.js:2:20:2:32 | Math.random() | This uses a cryptographically insecure random number generated at $@ in a security context. | tst.js:2:20:2:32 | Math.random() | Math.random() | | tst.js:6:20:6:43 | "prefix ... andom() | tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | This uses a cryptographically insecure random number generated at $@ in a security context. | tst.js:6:31:6:43 | Math.random() | Math.random() | | tst.js:10:20:10:32 | Math.random() | tst.js:10:20:10:32 | Math.random() | tst.js:10:20:10:32 | Math.random() | This uses a cryptographically insecure random number generated at $@ in a security context. | tst.js:10:20:10:32 | Math.random() | Math.random() | diff --git a/javascript/ql/test/query-tests/Security/CWE-338/foo.js b/javascript/ql/test/query-tests/Security/CWE-338/foo.test.js similarity index 100% rename from javascript/ql/test/query-tests/Security/CWE-338/foo.js rename to javascript/ql/test/query-tests/Security/CWE-338/foo.test.js From bf62582f5305272b05ba272f939a54434f9a7ab7 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 20 Nov 2024 13:58:43 +0100 Subject: [PATCH 359/514] JS: Implement 'speculativeTaintStep' It is a mandatory part of the interface now; just providing a bare-bones implementation for rather than 'none()' --- .../dataflow/internal/TaintTrackingPrivate.qll | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index 0f9780ab69b..b182e945840 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -104,3 +104,12 @@ predicate defaultImplicitTaintRead(DataFlow::Node node, ContentSet c) { // Optional steps are added through isAdditionalFlowStep but we don't want the implicit reads not optionalStep(node, _, _) } + +predicate speculativeTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(DataFlow::CallNode call, DataFlowCall c | + not exists(viableCallable(c)) and + c.asOrdinaryCall() = call and + node1 = call.getAnArgument() and + node2 = call + ) +} From c94a01e6b659df5f9105cf9b4c9a0ed60d8bcc8b Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 21 Nov 2024 11:29:21 +0100 Subject: [PATCH 360/514] JS: Remove reference to argsParseStep This was removed as part of the PR that introduced threat models. --- .../security/dataflow/IndirectCommandInjectionQuery.qll | 4 ---- 1 file changed, 4 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/IndirectCommandInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/IndirectCommandInjectionQuery.qll index 75324e94b13..a0bb45e78ec 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/IndirectCommandInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/IndirectCommandInjectionQuery.qll @@ -26,10 +26,6 @@ module IndirectCommandInjectionConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { isSinkWithHighlight(sink, _) } predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } - - predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { - argsParseStep(pred, succ) - } } /** From 8818fcc20777ddf5c5bacfddf66e72a4cf268a55 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 26 Nov 2024 15:47:13 +0100 Subject: [PATCH 361/514] JS: Benign test output changes --- .../Security/CWE-918/SSRF.expected | 4 + .../library-tests/Arrays/DataFlow.expected | 3 + .../library-tests/Arrays/TaintFlow.expected | 3 + .../library-tests/Arrays/printAst.expected | 446 +++++++++++++----- .../FlowSummary/DataFlowConsistency.expected | 2 + .../TaintTracking/BasicTaintTracking.expected | 13 + .../CWE-022/TaintedPath/TaintedPath.expected | 11 + .../IndirectCommandInjection.expected | 21 +- .../local-threat-source/SqlInjection.expected | 21 +- .../Security/CWE-117/LogInjection.expected | 20 + 10 files changed, 405 insertions(+), 139 deletions(-) diff --git a/javascript/ql/test/experimental/Security/CWE-918/SSRF.expected b/javascript/ql/test/experimental/Security/CWE-918/SSRF.expected index b2b293a6ca9..da02dc24848 100644 --- a/javascript/ql/test/experimental/Security/CWE-918/SSRF.expected +++ b/javascript/ql/test/experimental/Security/CWE-918/SSRF.expected @@ -12,6 +12,7 @@ edges | check-regex.js:31:29:31:45 | req.query.tainted | check-regex.js:31:15:31:45 | "test.c ... tainted | provenance | | | check-regex.js:34:25:34:42 | req.params.tainted | check-regex.js:34:15:34:42 | baseURL ... tainted | provenance | | | check-regex.js:41:27:41:43 | req.query.tainted | check-regex.js:41:13:41:43 | "test.c ... tainted | provenance | | +| check-regex.js:61:25:61:42 | req.params.tainted | check-regex.js:61:15:61:42 | baseURL ... tainted | provenance | | | check-validator.js:15:29:15:45 | req.query.tainted | check-validator.js:15:15:15:45 | "test.c ... tainted | provenance | | | check-validator.js:27:29:27:45 | req.query.tainted | check-validator.js:27:15:27:45 | "test.c ... tainted | provenance | | | check-validator.js:50:29:50:45 | req.query.tainted | check-validator.js:50:15:50:45 | "test.c ... tainted | provenance | | @@ -47,6 +48,8 @@ nodes | check-regex.js:34:25:34:42 | req.params.tainted | semmle.label | req.params.tainted | | check-regex.js:41:13:41:43 | "test.c ... tainted | semmle.label | "test.c ... tainted | | check-regex.js:41:27:41:43 | req.query.tainted | semmle.label | req.query.tainted | +| check-regex.js:61:15:61:42 | baseURL ... tainted | semmle.label | baseURL ... tainted | +| check-regex.js:61:25:61:42 | req.params.tainted | semmle.label | req.params.tainted | | check-validator.js:15:15:15:45 | "test.c ... tainted | semmle.label | "test.c ... tainted | | check-validator.js:15:29:15:45 | req.query.tainted | semmle.label | req.query.tainted | | check-validator.js:27:15:27:45 | "test.c ... tainted | semmle.label | "test.c ... tainted | @@ -76,6 +79,7 @@ subpaths | check-regex.js:31:15:31:45 | "test.c ... tainted | check-regex.js:31:29:31:45 | req.query.tainted | check-regex.js:31:15:31:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. | | check-regex.js:34:15:34:42 | baseURL ... tainted | check-regex.js:34:25:34:42 | req.params.tainted | check-regex.js:34:15:34:42 | baseURL ... tainted | The URL of this request depends on a user-provided value. | | check-regex.js:41:13:41:43 | "test.c ... tainted | check-regex.js:41:27:41:43 | req.query.tainted | check-regex.js:41:13:41:43 | "test.c ... tainted | The URL of this request depends on a user-provided value. | +| check-regex.js:61:15:61:42 | baseURL ... tainted | check-regex.js:61:25:61:42 | req.params.tainted | check-regex.js:61:15:61:42 | baseURL ... tainted | The URL of this request depends on a user-provided value. | | check-validator.js:15:15:15:45 | "test.c ... tainted | check-validator.js:15:29:15:45 | req.query.tainted | check-validator.js:15:15:15:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. | | check-validator.js:27:15:27:45 | "test.c ... tainted | check-validator.js:27:29:27:45 | req.query.tainted | check-validator.js:27:15:27:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. | | check-validator.js:50:15:50:45 | "test.c ... tainted | check-validator.js:50:29:50:45 | req.query.tainted | check-validator.js:50:15:50:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. | diff --git a/javascript/ql/test/library-tests/Arrays/DataFlow.expected b/javascript/ql/test/library-tests/Arrays/DataFlow.expected index 35a04acc4a1..14116c4e257 100644 --- a/javascript/ql/test/library-tests/Arrays/DataFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/DataFlow.expected @@ -17,6 +17,7 @@ flow | arrays.js:2:16:2:23 | "source" | arrays.js:86:8:86:35 | arrayFi ... llback) | | arrays.js:2:16:2:23 | "source" | arrays.js:90:10:90:10 | x | | arrays.js:2:16:2:23 | "source" | arrays.js:93:8:93:17 | arr.at(-1) | +| arrays.js:2:16:2:23 | "source" | arrays.js:110:8:110:24 | arr8_spread.pop() | | arrays.js:18:22:18:29 | "source" | arrays.js:18:50:18:50 | e | | arrays.js:22:15:22:22 | "source" | arrays.js:23:8:23:17 | arr2.pop() | | arrays.js:25:15:25:22 | "source" | arrays.js:26:8:26:17 | arr3.pop() | @@ -28,3 +29,5 @@ flow | arrays.js:53:4:53:11 | "source" | arrays.js:54:10:54:18 | ary.pop() | | arrays.js:96:9:96:16 | "source" | arrays.js:96:8:96:40 | ["sourc ... ).pop() | | arrays.js:97:9:97:16 | "source" | arrays.js:97:8:97:42 | ["sourc ... ).pop() | +| arrays.js:100:31:100:38 | "source" | arrays.js:101:8:101:17 | arr8.pop() | +| arrays.js:104:55:104:62 | "source" | arrays.js:106:8:106:25 | arr8_variant.pop() | diff --git a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected index 70f5b29403d..be8aaf12b12 100644 --- a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected @@ -16,6 +16,7 @@ flow | arrays.js:2:16:2:23 | "source" | arrays.js:86:8:86:35 | arrayFi ... llback) | | arrays.js:2:16:2:23 | "source" | arrays.js:90:10:90:10 | x | | arrays.js:2:16:2:23 | "source" | arrays.js:93:8:93:17 | arr.at(-1) | +| arrays.js:2:16:2:23 | "source" | arrays.js:110:8:110:24 | arr8_spread.pop() | | arrays.js:18:22:18:29 | "source" | arrays.js:18:50:18:50 | e | | arrays.js:22:15:22:22 | "source" | arrays.js:23:8:23:17 | arr2.pop() | | arrays.js:25:15:25:22 | "source" | arrays.js:26:8:26:17 | arr3.pop() | @@ -29,3 +30,5 @@ flow | arrays.js:95:9:95:16 | "source" | arrays.js:95:8:95:17 | ["source"] | | arrays.js:96:9:96:16 | "source" | arrays.js:96:8:96:40 | ["sourc ... ).pop() | | arrays.js:97:9:97:16 | "source" | arrays.js:97:8:97:42 | ["sourc ... ).pop() | +| arrays.js:100:31:100:38 | "source" | arrays.js:101:8:101:17 | arr8.pop() | +| arrays.js:104:55:104:62 | "source" | arrays.js:106:8:106:25 | arr8_variant.pop() | diff --git a/javascript/ql/test/library-tests/Arrays/printAst.expected b/javascript/ql/test/library-tests/Arrays/printAst.expected index dbbeccd38a8..7d4c7285c70 100644 --- a/javascript/ql/test/library-tests/Arrays/printAst.expected +++ b/javascript/ql/test/library-tests/Arrays/printAst.expected @@ -1,9 +1,9 @@ nodes -| arrays.js:1:1:99:2 | [ParExpr] (functi ... OK }) | semmle.label | [ParExpr] (functi ... OK }) | -| arrays.js:1:1:99:3 | [ExprStmt] (functi ... OK }); | semmle.label | [ExprStmt] (functi ... OK }); | -| arrays.js:1:1:99:3 | [ExprStmt] (functi ... OK }); | semmle.order | 1 | -| arrays.js:1:2:99:1 | [FunctionExpr] functio ... T OK } | semmle.label | [FunctionExpr] functio ... T OK } | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | semmle.label | [BlockStmt] { let ... T OK } | +| arrays.js:1:1:111:2 | [ParExpr] (functi ... T OK }) | semmle.label | [ParExpr] (functi ... T OK }) | +| arrays.js:1:1:111:3 | [ExprStmt] (functi ... OK }); | semmle.label | [ExprStmt] (functi ... OK }); | +| arrays.js:1:1:111:3 | [ExprStmt] (functi ... OK }); | semmle.order | 1 | +| arrays.js:1:2:111:1 | [FunctionExpr] functio ... OT OK } | semmle.label | [FunctionExpr] functio ... OT OK } | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | semmle.label | [BlockStmt] { let ... OT OK } | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | [DeclStmt] let source = ... | | arrays.js:2:7:2:12 | [VarDecl] source | semmle.label | [VarDecl] source | | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.label | [VariableDeclarator] source = "source" | @@ -428,6 +428,82 @@ nodes | arrays.js:97:34:97:35 | [UnaryExpr] !x | semmle.label | [UnaryExpr] !x | | arrays.js:97:35:97:35 | [VarRef] x | semmle.label | [VarRef] x | | arrays.js:97:38:97:40 | [Label] pop | semmle.label | [Label] pop | +| arrays.js:99:3:99:16 | [DeclStmt] var arr8 = ... | semmle.label | [DeclStmt] var arr8 = ... | +| arrays.js:99:7:99:10 | [VarDecl] arr8 | semmle.label | [VarDecl] arr8 | +| arrays.js:99:7:99:15 | [VariableDeclarator] arr8 = [] | semmle.label | [VariableDeclarator] arr8 = [] | +| arrays.js:99:14:99:15 | [ArrayExpr] [] | semmle.label | [ArrayExpr] [] | +| arrays.js:100:3:100:6 | [VarRef] arr8 | semmle.label | [VarRef] arr8 | +| arrays.js:100:3:100:39 | [AssignExpr] arr8 = ... ource") | semmle.label | [AssignExpr] arr8 = ... ource") | +| arrays.js:100:3:100:40 | [ExprStmt] arr8 = ... urce"); | semmle.label | [ExprStmt] arr8 = ... urce"); | +| arrays.js:100:10:100:13 | [VarRef] arr8 | semmle.label | [VarRef] arr8 | +| arrays.js:100:10:100:23 | [DotExpr] arr8.toSpliced | semmle.label | [DotExpr] arr8.toSpliced | +| arrays.js:100:10:100:39 | [MethodCallExpr] arr8.to ... ource") | semmle.label | [MethodCallExpr] arr8.to ... ource") | +| arrays.js:100:15:100:23 | [Label] toSpliced | semmle.label | [Label] toSpliced | +| arrays.js:100:25:100:25 | [Literal] 0 | semmle.label | [Literal] 0 | +| arrays.js:100:28:100:28 | [Literal] 0 | semmle.label | [Literal] 0 | +| arrays.js:100:31:100:38 | [Literal] "source" | semmle.label | [Literal] "source" | +| arrays.js:101:3:101:6 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:101:3:101:18 | [CallExpr] sink(arr8.pop()) | semmle.label | [CallExpr] sink(arr8.pop()) | +| arrays.js:101:3:101:19 | [ExprStmt] sink(arr8.pop()); | semmle.label | [ExprStmt] sink(arr8.pop()); | +| arrays.js:101:8:101:11 | [VarRef] arr8 | semmle.label | [VarRef] arr8 | +| arrays.js:101:8:101:15 | [DotExpr] arr8.pop | semmle.label | [DotExpr] arr8.pop | +| arrays.js:101:8:101:17 | [MethodCallExpr] arr8.pop() | semmle.label | [MethodCallExpr] arr8.pop() | +| arrays.js:101:13:101:15 | [Label] pop | semmle.label | [Label] pop | +| arrays.js:103:3:103:24 | [DeclStmt] var arr8_variant = ... | semmle.label | [DeclStmt] var arr8_variant = ... | +| arrays.js:103:7:103:18 | [VarDecl] arr8_variant | semmle.label | [VarDecl] arr8_variant | +| arrays.js:103:7:103:23 | [VariableDeclarator] arr8_variant = [] | semmle.label | [VariableDeclarator] arr8_variant = [] | +| arrays.js:103:22:103:23 | [ArrayExpr] [] | semmle.label | [ArrayExpr] [] | +| arrays.js:104:3:104:14 | [VarRef] arr8_variant | semmle.label | [VarRef] arr8_variant | +| arrays.js:104:3:104:63 | [AssignExpr] arr8_va ... ource") | semmle.label | [AssignExpr] arr8_va ... ource") | +| arrays.js:104:3:104:64 | [ExprStmt] arr8_va ... urce"); | semmle.label | [ExprStmt] arr8_va ... urce"); | +| arrays.js:104:18:104:29 | [VarRef] arr8_variant | semmle.label | [VarRef] arr8_variant | +| arrays.js:104:18:104:39 | [DotExpr] arr8_va ... Spliced | semmle.label | [DotExpr] arr8_va ... Spliced | +| arrays.js:104:18:104:63 | [MethodCallExpr] arr8_va ... ource") | semmle.label | [MethodCallExpr] arr8_va ... ource") | +| arrays.js:104:31:104:39 | [Label] toSpliced | semmle.label | [Label] toSpliced | +| arrays.js:104:41:104:41 | [Literal] 0 | semmle.label | [Literal] 0 | +| arrays.js:104:44:104:44 | [Literal] 0 | semmle.label | [Literal] 0 | +| arrays.js:104:47:104:52 | [Literal] "safe" | semmle.label | [Literal] "safe" | +| arrays.js:104:55:104:62 | [Literal] "source" | semmle.label | [Literal] "source" | +| arrays.js:105:3:105:14 | [VarRef] arr8_variant | semmle.label | [VarRef] arr8_variant | +| arrays.js:105:3:105:18 | [DotExpr] arr8_variant.pop | semmle.label | [DotExpr] arr8_variant.pop | +| arrays.js:105:3:105:20 | [MethodCallExpr] arr8_variant.pop() | semmle.label | [MethodCallExpr] arr8_variant.pop() | +| arrays.js:105:3:105:21 | [ExprStmt] arr8_variant.pop(); | semmle.label | [ExprStmt] arr8_variant.pop(); | +| arrays.js:105:16:105:18 | [Label] pop | semmle.label | [Label] pop | +| arrays.js:106:3:106:6 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:106:3:106:26 | [CallExpr] sink(ar ... .pop()) | semmle.label | [CallExpr] sink(ar ... .pop()) | +| arrays.js:106:3:106:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | [ExprStmt] sink(ar ... pop()); | +| arrays.js:106:8:106:19 | [VarRef] arr8_variant | semmle.label | [VarRef] arr8_variant | +| arrays.js:106:8:106:23 | [DotExpr] arr8_variant.pop | semmle.label | [DotExpr] arr8_variant.pop | +| arrays.js:106:8:106:25 | [MethodCallExpr] arr8_variant.pop() | semmle.label | [MethodCallExpr] arr8_variant.pop() | +| arrays.js:106:21:106:23 | [Label] pop | semmle.label | [Label] pop | +| arrays.js:108:3:108:23 | [DeclStmt] var arr8_spread = ... | semmle.label | [DeclStmt] var arr8_spread = ... | +| arrays.js:108:7:108:17 | [VarDecl] arr8_spread | semmle.label | [VarDecl] arr8_spread | +| arrays.js:108:7:108:22 | [VariableDeclarator] arr8_spread = [] | semmle.label | [VariableDeclarator] arr8_spread = [] | +| arrays.js:108:21:108:22 | [ArrayExpr] [] | semmle.label | [ArrayExpr] [] | +| arrays.js:109:3:109:13 | [VarRef] arr8_spread | semmle.label | [VarRef] arr8_spread | +| arrays.js:109:3:109:51 | [AssignExpr] arr8_sp ... ...arr) | semmle.label | [AssignExpr] arr8_sp ... ...arr) | +| arrays.js:109:3:109:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.label | [ExprStmt] arr8_sp ... ..arr); | +| arrays.js:109:17:109:27 | [VarRef] arr8_spread | semmle.label | [VarRef] arr8_spread | +| arrays.js:109:17:109:37 | [DotExpr] arr8_sp ... Spliced | semmle.label | [DotExpr] arr8_sp ... Spliced | +| arrays.js:109:17:109:51 | [MethodCallExpr] arr8_sp ... ...arr) | semmle.label | [MethodCallExpr] arr8_sp ... ...arr) | +| arrays.js:109:29:109:37 | [Label] toSpliced | semmle.label | [Label] toSpliced | +| arrays.js:109:39:109:39 | [Literal] 0 | semmle.label | [Literal] 0 | +| arrays.js:109:42:109:42 | [Literal] 0 | semmle.label | [Literal] 0 | +| arrays.js:109:45:109:50 | [SpreadElement] ...arr | semmle.label | [SpreadElement] ...arr | +| arrays.js:109:48:109:50 | [VarRef] arr | semmle.label | [VarRef] arr | +| arrays.js:110:3:110:6 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:110:3:110:25 | [CallExpr] sink(ar ... .pop()) | semmle.label | [CallExpr] sink(ar ... .pop()) | +| arrays.js:110:3:110:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | [ExprStmt] sink(ar ... pop()); | +| arrays.js:110:8:110:18 | [VarRef] arr8_spread | semmle.label | [VarRef] arr8_spread | +| arrays.js:110:8:110:22 | [DotExpr] arr8_spread.pop | semmle.label | [DotExpr] arr8_spread.pop | +| arrays.js:110:8:110:24 | [MethodCallExpr] arr8_spread.pop() | semmle.label | [MethodCallExpr] arr8_spread.pop() | +| arrays.js:110:20:110:22 | [Label] pop | semmle.label | [Label] pop | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | @@ -488,110 +564,130 @@ nodes | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | edges -| arrays.js:1:1:99:2 | [ParExpr] (functi ... OK }) | arrays.js:1:2:99:1 | [FunctionExpr] functio ... T OK } | semmle.label | 1 | -| arrays.js:1:1:99:2 | [ParExpr] (functi ... OK }) | arrays.js:1:2:99:1 | [FunctionExpr] functio ... T OK } | semmle.order | 1 | -| arrays.js:1:1:99:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:99:2 | [ParExpr] (functi ... OK }) | semmle.label | 1 | -| arrays.js:1:1:99:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:99:2 | [ParExpr] (functi ... OK }) | semmle.order | 1 | -| arrays.js:1:2:99:1 | [FunctionExpr] functio ... T OK } | arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | semmle.label | 5 | -| arrays.js:1:2:99:1 | [FunctionExpr] functio ... T OK } | arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | semmle.order | 5 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | 1 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.order | 1 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.label | 2 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.order | 2 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.label | 3 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.order | 3 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.label | 4 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.order | 4 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.label | 5 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.order | 5 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.label | 6 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.order | 6 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.label | 7 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.order | 7 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.label | 8 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.order | 8 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.label | 9 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.order | 9 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.label | 10 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.order | 10 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.label | 11 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.order | 11 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.label | 12 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.order | 12 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.label | 13 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.order | 13 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.label | 14 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.order | 14 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.label | 15 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.order | 15 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.label | 16 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.order | 16 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.label | 17 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.order | 17 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.label | 18 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.order | 18 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.label | 19 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.order | 19 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.label | 20 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.order | 20 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 21 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 21 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.label | 22 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.order | 22 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.label | 23 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.order | 23 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 24 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 24 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.label | 25 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.order | 25 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.label | 26 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.order | 26 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.label | 27 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.order | 27 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.label | 28 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.order | 28 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.label | 29 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.order | 29 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.label | 30 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.order | 30 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.label | 31 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.order | 31 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.label | 32 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.order | 32 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.label | 33 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.order | 33 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.label | 34 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.order | 34 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.label | 35 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.order | 35 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.label | 36 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.order | 36 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.label | 37 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.order | 37 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.label | 38 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.order | 38 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.label | 39 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.order | 39 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.label | 40 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.order | 40 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.label | 41 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.order | 41 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.label | 42 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.order | 42 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.label | 43 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.order | 43 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.label | 44 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.order | 44 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.label | 45 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.order | 45 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.label | 46 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.order | 46 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:95:3:95:19 | [ExprStmt] sink(["source"]); | semmle.label | 47 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:95:3:95:19 | [ExprStmt] sink(["source"]); | semmle.order | 47 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:96:3:96:42 | [ExprStmt] sink([" ... pop()); | semmle.label | 48 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:96:3:96:42 | [ExprStmt] sink([" ... pop()); | semmle.order | 48 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:97:3:97:44 | [ExprStmt] sink([" ... pop()); | semmle.label | 49 | -| arrays.js:1:14:99:1 | [BlockStmt] { let ... T OK } | arrays.js:97:3:97:44 | [ExprStmt] sink([" ... pop()); | semmle.order | 49 | +| arrays.js:1:1:111:2 | [ParExpr] (functi ... T OK }) | arrays.js:1:2:111:1 | [FunctionExpr] functio ... OT OK } | semmle.label | 1 | +| arrays.js:1:1:111:2 | [ParExpr] (functi ... T OK }) | arrays.js:1:2:111:1 | [FunctionExpr] functio ... OT OK } | semmle.order | 1 | +| arrays.js:1:1:111:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:111:2 | [ParExpr] (functi ... T OK }) | semmle.label | 1 | +| arrays.js:1:1:111:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:111:2 | [ParExpr] (functi ... T OK }) | semmle.order | 1 | +| arrays.js:1:2:111:1 | [FunctionExpr] functio ... OT OK } | arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | semmle.label | 5 | +| arrays.js:1:2:111:1 | [FunctionExpr] functio ... OT OK } | arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | semmle.order | 5 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | 1 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.order | 1 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.label | 2 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.order | 2 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.label | 3 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.order | 3 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.label | 4 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.order | 4 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.label | 5 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.order | 5 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.label | 6 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.order | 6 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.label | 7 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.order | 7 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.label | 8 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.order | 8 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.label | 9 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.order | 9 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.label | 10 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.order | 10 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.label | 11 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.order | 11 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.label | 12 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.order | 12 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.label | 13 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.order | 13 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.label | 14 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.order | 14 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.label | 15 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.order | 15 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.label | 16 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.order | 16 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.label | 17 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.order | 17 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.label | 18 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.order | 18 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.label | 19 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.order | 19 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.label | 20 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.order | 20 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 21 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 21 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.label | 22 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.order | 22 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.label | 23 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.order | 23 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 24 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 24 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.label | 25 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.order | 25 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.label | 26 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.order | 26 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.label | 27 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.order | 27 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.label | 28 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.order | 28 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.label | 29 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.order | 29 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.label | 30 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.order | 30 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.label | 31 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.order | 31 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.label | 32 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.order | 32 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.label | 33 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.order | 33 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.label | 34 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.order | 34 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.label | 35 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.order | 35 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.label | 36 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.order | 36 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.label | 37 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.order | 37 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.label | 38 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.order | 38 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.label | 39 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.order | 39 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.label | 40 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.order | 40 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.label | 41 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.order | 41 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.label | 42 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.order | 42 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.label | 43 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.order | 43 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.label | 44 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.order | 44 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.label | 45 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.order | 45 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.label | 46 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.order | 46 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:95:3:95:19 | [ExprStmt] sink(["source"]); | semmle.label | 47 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:95:3:95:19 | [ExprStmt] sink(["source"]); | semmle.order | 47 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:96:3:96:42 | [ExprStmt] sink([" ... pop()); | semmle.label | 48 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:96:3:96:42 | [ExprStmt] sink([" ... pop()); | semmle.order | 48 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:97:3:97:44 | [ExprStmt] sink([" ... pop()); | semmle.label | 49 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:97:3:97:44 | [ExprStmt] sink([" ... pop()); | semmle.order | 49 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:99:3:99:16 | [DeclStmt] var arr8 = ... | semmle.label | 50 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:99:3:99:16 | [DeclStmt] var arr8 = ... | semmle.order | 50 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:100:3:100:40 | [ExprStmt] arr8 = ... urce"); | semmle.label | 51 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:100:3:100:40 | [ExprStmt] arr8 = ... urce"); | semmle.order | 51 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:101:3:101:19 | [ExprStmt] sink(arr8.pop()); | semmle.label | 52 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:101:3:101:19 | [ExprStmt] sink(arr8.pop()); | semmle.order | 52 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:103:3:103:24 | [DeclStmt] var arr8_variant = ... | semmle.label | 53 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:103:3:103:24 | [DeclStmt] var arr8_variant = ... | semmle.order | 53 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:104:3:104:64 | [ExprStmt] arr8_va ... urce"); | semmle.label | 54 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:104:3:104:64 | [ExprStmt] arr8_va ... urce"); | semmle.order | 54 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:105:3:105:21 | [ExprStmt] arr8_variant.pop(); | semmle.label | 55 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:105:3:105:21 | [ExprStmt] arr8_variant.pop(); | semmle.order | 55 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:106:3:106:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 56 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:106:3:106:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 56 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:108:3:108:23 | [DeclStmt] var arr8_spread = ... | semmle.label | 57 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:108:3:108:23 | [DeclStmt] var arr8_spread = ... | semmle.order | 57 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:109:3:109:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.label | 58 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:109:3:109:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.order | 58 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:110:3:110:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 59 | +| arrays.js:1:14:111:1 | [BlockStmt] { let ... OT OK } | arrays.js:110:3:110:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 59 | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.label | 1 | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.order | 1 | | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | arrays.js:2:7:2:12 | [VarDecl] source | semmle.label | 1 | @@ -1322,6 +1418,112 @@ edges | arrays.js:97:33:97:35 | [UnaryExpr] !!x | arrays.js:97:34:97:35 | [UnaryExpr] !x | semmle.order | 1 | | arrays.js:97:34:97:35 | [UnaryExpr] !x | arrays.js:97:35:97:35 | [VarRef] x | semmle.label | 1 | | arrays.js:97:34:97:35 | [UnaryExpr] !x | arrays.js:97:35:97:35 | [VarRef] x | semmle.order | 1 | +| arrays.js:99:3:99:16 | [DeclStmt] var arr8 = ... | arrays.js:99:7:99:15 | [VariableDeclarator] arr8 = [] | semmle.label | 1 | +| arrays.js:99:3:99:16 | [DeclStmt] var arr8 = ... | arrays.js:99:7:99:15 | [VariableDeclarator] arr8 = [] | semmle.order | 1 | +| arrays.js:99:7:99:15 | [VariableDeclarator] arr8 = [] | arrays.js:99:7:99:10 | [VarDecl] arr8 | semmle.label | 1 | +| arrays.js:99:7:99:15 | [VariableDeclarator] arr8 = [] | arrays.js:99:7:99:10 | [VarDecl] arr8 | semmle.order | 1 | +| arrays.js:99:7:99:15 | [VariableDeclarator] arr8 = [] | arrays.js:99:14:99:15 | [ArrayExpr] [] | semmle.label | 2 | +| arrays.js:99:7:99:15 | [VariableDeclarator] arr8 = [] | arrays.js:99:14:99:15 | [ArrayExpr] [] | semmle.order | 2 | +| arrays.js:100:3:100:39 | [AssignExpr] arr8 = ... ource") | arrays.js:100:3:100:6 | [VarRef] arr8 | semmle.label | 1 | +| arrays.js:100:3:100:39 | [AssignExpr] arr8 = ... ource") | arrays.js:100:3:100:6 | [VarRef] arr8 | semmle.order | 1 | +| arrays.js:100:3:100:39 | [AssignExpr] arr8 = ... ource") | arrays.js:100:10:100:39 | [MethodCallExpr] arr8.to ... ource") | semmle.label | 2 | +| arrays.js:100:3:100:39 | [AssignExpr] arr8 = ... ource") | arrays.js:100:10:100:39 | [MethodCallExpr] arr8.to ... ource") | semmle.order | 2 | +| arrays.js:100:3:100:40 | [ExprStmt] arr8 = ... urce"); | arrays.js:100:3:100:39 | [AssignExpr] arr8 = ... ource") | semmle.label | 1 | +| arrays.js:100:3:100:40 | [ExprStmt] arr8 = ... urce"); | arrays.js:100:3:100:39 | [AssignExpr] arr8 = ... ource") | semmle.order | 1 | +| arrays.js:100:10:100:23 | [DotExpr] arr8.toSpliced | arrays.js:100:10:100:13 | [VarRef] arr8 | semmle.label | 1 | +| arrays.js:100:10:100:23 | [DotExpr] arr8.toSpliced | arrays.js:100:10:100:13 | [VarRef] arr8 | semmle.order | 1 | +| arrays.js:100:10:100:23 | [DotExpr] arr8.toSpliced | arrays.js:100:15:100:23 | [Label] toSpliced | semmle.label | 2 | +| arrays.js:100:10:100:23 | [DotExpr] arr8.toSpliced | arrays.js:100:15:100:23 | [Label] toSpliced | semmle.order | 2 | +| arrays.js:100:10:100:39 | [MethodCallExpr] arr8.to ... ource") | arrays.js:100:10:100:23 | [DotExpr] arr8.toSpliced | semmle.label | 0 | +| arrays.js:100:10:100:39 | [MethodCallExpr] arr8.to ... ource") | arrays.js:100:10:100:23 | [DotExpr] arr8.toSpliced | semmle.order | 0 | +| arrays.js:100:10:100:39 | [MethodCallExpr] arr8.to ... ource") | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:100:10:100:39 | [MethodCallExpr] arr8.to ... ource") | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:101:3:101:18 | [CallExpr] sink(arr8.pop()) | arrays.js:101:3:101:6 | [VarRef] sink | semmle.label | 0 | +| arrays.js:101:3:101:18 | [CallExpr] sink(arr8.pop()) | arrays.js:101:3:101:6 | [VarRef] sink | semmle.order | 0 | +| arrays.js:101:3:101:18 | [CallExpr] sink(arr8.pop()) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:101:3:101:18 | [CallExpr] sink(arr8.pop()) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:101:3:101:19 | [ExprStmt] sink(arr8.pop()); | arrays.js:101:3:101:18 | [CallExpr] sink(arr8.pop()) | semmle.label | 1 | +| arrays.js:101:3:101:19 | [ExprStmt] sink(arr8.pop()); | arrays.js:101:3:101:18 | [CallExpr] sink(arr8.pop()) | semmle.order | 1 | +| arrays.js:101:8:101:15 | [DotExpr] arr8.pop | arrays.js:101:8:101:11 | [VarRef] arr8 | semmle.label | 1 | +| arrays.js:101:8:101:15 | [DotExpr] arr8.pop | arrays.js:101:8:101:11 | [VarRef] arr8 | semmle.order | 1 | +| arrays.js:101:8:101:15 | [DotExpr] arr8.pop | arrays.js:101:13:101:15 | [Label] pop | semmle.label | 2 | +| arrays.js:101:8:101:15 | [DotExpr] arr8.pop | arrays.js:101:13:101:15 | [Label] pop | semmle.order | 2 | +| arrays.js:101:8:101:17 | [MethodCallExpr] arr8.pop() | arrays.js:101:8:101:15 | [DotExpr] arr8.pop | semmle.label | 0 | +| arrays.js:101:8:101:17 | [MethodCallExpr] arr8.pop() | arrays.js:101:8:101:15 | [DotExpr] arr8.pop | semmle.order | 0 | +| arrays.js:103:3:103:24 | [DeclStmt] var arr8_variant = ... | arrays.js:103:7:103:23 | [VariableDeclarator] arr8_variant = [] | semmle.label | 1 | +| arrays.js:103:3:103:24 | [DeclStmt] var arr8_variant = ... | arrays.js:103:7:103:23 | [VariableDeclarator] arr8_variant = [] | semmle.order | 1 | +| arrays.js:103:7:103:23 | [VariableDeclarator] arr8_variant = [] | arrays.js:103:7:103:18 | [VarDecl] arr8_variant | semmle.label | 1 | +| arrays.js:103:7:103:23 | [VariableDeclarator] arr8_variant = [] | arrays.js:103:7:103:18 | [VarDecl] arr8_variant | semmle.order | 1 | +| arrays.js:103:7:103:23 | [VariableDeclarator] arr8_variant = [] | arrays.js:103:22:103:23 | [ArrayExpr] [] | semmle.label | 2 | +| arrays.js:103:7:103:23 | [VariableDeclarator] arr8_variant = [] | arrays.js:103:22:103:23 | [ArrayExpr] [] | semmle.order | 2 | +| arrays.js:104:3:104:63 | [AssignExpr] arr8_va ... ource") | arrays.js:104:3:104:14 | [VarRef] arr8_variant | semmle.label | 1 | +| arrays.js:104:3:104:63 | [AssignExpr] arr8_va ... ource") | arrays.js:104:3:104:14 | [VarRef] arr8_variant | semmle.order | 1 | +| arrays.js:104:3:104:63 | [AssignExpr] arr8_va ... ource") | arrays.js:104:18:104:63 | [MethodCallExpr] arr8_va ... ource") | semmle.label | 2 | +| arrays.js:104:3:104:63 | [AssignExpr] arr8_va ... ource") | arrays.js:104:18:104:63 | [MethodCallExpr] arr8_va ... ource") | semmle.order | 2 | +| arrays.js:104:3:104:64 | [ExprStmt] arr8_va ... urce"); | arrays.js:104:3:104:63 | [AssignExpr] arr8_va ... ource") | semmle.label | 1 | +| arrays.js:104:3:104:64 | [ExprStmt] arr8_va ... urce"); | arrays.js:104:3:104:63 | [AssignExpr] arr8_va ... ource") | semmle.order | 1 | +| arrays.js:104:18:104:39 | [DotExpr] arr8_va ... Spliced | arrays.js:104:18:104:29 | [VarRef] arr8_variant | semmle.label | 1 | +| arrays.js:104:18:104:39 | [DotExpr] arr8_va ... Spliced | arrays.js:104:18:104:29 | [VarRef] arr8_variant | semmle.order | 1 | +| arrays.js:104:18:104:39 | [DotExpr] arr8_va ... Spliced | arrays.js:104:31:104:39 | [Label] toSpliced | semmle.label | 2 | +| arrays.js:104:18:104:39 | [DotExpr] arr8_va ... Spliced | arrays.js:104:31:104:39 | [Label] toSpliced | semmle.order | 2 | +| arrays.js:104:18:104:63 | [MethodCallExpr] arr8_va ... ource") | arrays.js:104:18:104:39 | [DotExpr] arr8_va ... Spliced | semmle.label | 0 | +| arrays.js:104:18:104:63 | [MethodCallExpr] arr8_va ... ource") | arrays.js:104:18:104:39 | [DotExpr] arr8_va ... Spliced | semmle.order | 0 | +| arrays.js:104:18:104:63 | [MethodCallExpr] arr8_va ... ource") | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:104:18:104:63 | [MethodCallExpr] arr8_va ... ource") | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:105:3:105:18 | [DotExpr] arr8_variant.pop | arrays.js:105:3:105:14 | [VarRef] arr8_variant | semmle.label | 1 | +| arrays.js:105:3:105:18 | [DotExpr] arr8_variant.pop | arrays.js:105:3:105:14 | [VarRef] arr8_variant | semmle.order | 1 | +| arrays.js:105:3:105:18 | [DotExpr] arr8_variant.pop | arrays.js:105:16:105:18 | [Label] pop | semmle.label | 2 | +| arrays.js:105:3:105:18 | [DotExpr] arr8_variant.pop | arrays.js:105:16:105:18 | [Label] pop | semmle.order | 2 | +| arrays.js:105:3:105:20 | [MethodCallExpr] arr8_variant.pop() | arrays.js:105:3:105:18 | [DotExpr] arr8_variant.pop | semmle.label | 0 | +| arrays.js:105:3:105:20 | [MethodCallExpr] arr8_variant.pop() | arrays.js:105:3:105:18 | [DotExpr] arr8_variant.pop | semmle.order | 0 | +| arrays.js:105:3:105:21 | [ExprStmt] arr8_variant.pop(); | arrays.js:105:3:105:20 | [MethodCallExpr] arr8_variant.pop() | semmle.label | 1 | +| arrays.js:105:3:105:21 | [ExprStmt] arr8_variant.pop(); | arrays.js:105:3:105:20 | [MethodCallExpr] arr8_variant.pop() | semmle.order | 1 | +| arrays.js:106:3:106:26 | [CallExpr] sink(ar ... .pop()) | arrays.js:106:3:106:6 | [VarRef] sink | semmle.label | 0 | +| arrays.js:106:3:106:26 | [CallExpr] sink(ar ... .pop()) | arrays.js:106:3:106:6 | [VarRef] sink | semmle.order | 0 | +| arrays.js:106:3:106:26 | [CallExpr] sink(ar ... .pop()) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:106:3:106:26 | [CallExpr] sink(ar ... .pop()) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:106:3:106:27 | [ExprStmt] sink(ar ... pop()); | arrays.js:106:3:106:26 | [CallExpr] sink(ar ... .pop()) | semmle.label | 1 | +| arrays.js:106:3:106:27 | [ExprStmt] sink(ar ... pop()); | arrays.js:106:3:106:26 | [CallExpr] sink(ar ... .pop()) | semmle.order | 1 | +| arrays.js:106:8:106:23 | [DotExpr] arr8_variant.pop | arrays.js:106:8:106:19 | [VarRef] arr8_variant | semmle.label | 1 | +| arrays.js:106:8:106:23 | [DotExpr] arr8_variant.pop | arrays.js:106:8:106:19 | [VarRef] arr8_variant | semmle.order | 1 | +| arrays.js:106:8:106:23 | [DotExpr] arr8_variant.pop | arrays.js:106:21:106:23 | [Label] pop | semmle.label | 2 | +| arrays.js:106:8:106:23 | [DotExpr] arr8_variant.pop | arrays.js:106:21:106:23 | [Label] pop | semmle.order | 2 | +| arrays.js:106:8:106:25 | [MethodCallExpr] arr8_variant.pop() | arrays.js:106:8:106:23 | [DotExpr] arr8_variant.pop | semmle.label | 0 | +| arrays.js:106:8:106:25 | [MethodCallExpr] arr8_variant.pop() | arrays.js:106:8:106:23 | [DotExpr] arr8_variant.pop | semmle.order | 0 | +| arrays.js:108:3:108:23 | [DeclStmt] var arr8_spread = ... | arrays.js:108:7:108:22 | [VariableDeclarator] arr8_spread = [] | semmle.label | 1 | +| arrays.js:108:3:108:23 | [DeclStmt] var arr8_spread = ... | arrays.js:108:7:108:22 | [VariableDeclarator] arr8_spread = [] | semmle.order | 1 | +| arrays.js:108:7:108:22 | [VariableDeclarator] arr8_spread = [] | arrays.js:108:7:108:17 | [VarDecl] arr8_spread | semmle.label | 1 | +| arrays.js:108:7:108:22 | [VariableDeclarator] arr8_spread = [] | arrays.js:108:7:108:17 | [VarDecl] arr8_spread | semmle.order | 1 | +| arrays.js:108:7:108:22 | [VariableDeclarator] arr8_spread = [] | arrays.js:108:21:108:22 | [ArrayExpr] [] | semmle.label | 2 | +| arrays.js:108:7:108:22 | [VariableDeclarator] arr8_spread = [] | arrays.js:108:21:108:22 | [ArrayExpr] [] | semmle.order | 2 | +| arrays.js:109:3:109:51 | [AssignExpr] arr8_sp ... ...arr) | arrays.js:109:3:109:13 | [VarRef] arr8_spread | semmle.label | 1 | +| arrays.js:109:3:109:51 | [AssignExpr] arr8_sp ... ...arr) | arrays.js:109:3:109:13 | [VarRef] arr8_spread | semmle.order | 1 | +| arrays.js:109:3:109:51 | [AssignExpr] arr8_sp ... ...arr) | arrays.js:109:17:109:51 | [MethodCallExpr] arr8_sp ... ...arr) | semmle.label | 2 | +| arrays.js:109:3:109:51 | [AssignExpr] arr8_sp ... ...arr) | arrays.js:109:17:109:51 | [MethodCallExpr] arr8_sp ... ...arr) | semmle.order | 2 | +| arrays.js:109:3:109:52 | [ExprStmt] arr8_sp ... ..arr); | arrays.js:109:3:109:51 | [AssignExpr] arr8_sp ... ...arr) | semmle.label | 1 | +| arrays.js:109:3:109:52 | [ExprStmt] arr8_sp ... ..arr); | arrays.js:109:3:109:51 | [AssignExpr] arr8_sp ... ...arr) | semmle.order | 1 | +| arrays.js:109:17:109:37 | [DotExpr] arr8_sp ... Spliced | arrays.js:109:17:109:27 | [VarRef] arr8_spread | semmle.label | 1 | +| arrays.js:109:17:109:37 | [DotExpr] arr8_sp ... Spliced | arrays.js:109:17:109:27 | [VarRef] arr8_spread | semmle.order | 1 | +| arrays.js:109:17:109:37 | [DotExpr] arr8_sp ... Spliced | arrays.js:109:29:109:37 | [Label] toSpliced | semmle.label | 2 | +| arrays.js:109:17:109:37 | [DotExpr] arr8_sp ... Spliced | arrays.js:109:29:109:37 | [Label] toSpliced | semmle.order | 2 | +| arrays.js:109:17:109:51 | [MethodCallExpr] arr8_sp ... ...arr) | arrays.js:109:17:109:37 | [DotExpr] arr8_sp ... Spliced | semmle.label | 0 | +| arrays.js:109:17:109:51 | [MethodCallExpr] arr8_sp ... ...arr) | arrays.js:109:17:109:37 | [DotExpr] arr8_sp ... Spliced | semmle.order | 0 | +| arrays.js:109:17:109:51 | [MethodCallExpr] arr8_sp ... ...arr) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:109:17:109:51 | [MethodCallExpr] arr8_sp ... ...arr) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:109:45:109:50 | [SpreadElement] ...arr | arrays.js:109:48:109:50 | [VarRef] arr | semmle.label | 1 | +| arrays.js:109:45:109:50 | [SpreadElement] ...arr | arrays.js:109:48:109:50 | [VarRef] arr | semmle.order | 1 | +| arrays.js:110:3:110:25 | [CallExpr] sink(ar ... .pop()) | arrays.js:110:3:110:6 | [VarRef] sink | semmle.label | 0 | +| arrays.js:110:3:110:25 | [CallExpr] sink(ar ... .pop()) | arrays.js:110:3:110:6 | [VarRef] sink | semmle.order | 0 | +| arrays.js:110:3:110:25 | [CallExpr] sink(ar ... .pop()) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:110:3:110:25 | [CallExpr] sink(ar ... .pop()) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:110:3:110:26 | [ExprStmt] sink(ar ... pop()); | arrays.js:110:3:110:25 | [CallExpr] sink(ar ... .pop()) | semmle.label | 1 | +| arrays.js:110:3:110:26 | [ExprStmt] sink(ar ... pop()); | arrays.js:110:3:110:25 | [CallExpr] sink(ar ... .pop()) | semmle.order | 1 | +| arrays.js:110:8:110:22 | [DotExpr] arr8_spread.pop | arrays.js:110:8:110:18 | [VarRef] arr8_spread | semmle.label | 1 | +| arrays.js:110:8:110:22 | [DotExpr] arr8_spread.pop | arrays.js:110:8:110:18 | [VarRef] arr8_spread | semmle.order | 1 | +| arrays.js:110:8:110:22 | [DotExpr] arr8_spread.pop | arrays.js:110:20:110:22 | [Label] pop | semmle.label | 2 | +| arrays.js:110:8:110:22 | [DotExpr] arr8_spread.pop | arrays.js:110:20:110:22 | [Label] pop | semmle.order | 2 | +| arrays.js:110:8:110:24 | [MethodCallExpr] arr8_spread.pop() | arrays.js:110:8:110:22 | [DotExpr] arr8_spread.pop | semmle.label | 0 | +| arrays.js:110:8:110:24 | [MethodCallExpr] arr8_spread.pop() | arrays.js:110:8:110:22 | [DotExpr] arr8_spread.pop | semmle.order | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:5:8:5:14 | [DotExpr] obj.foo | semmle.label | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:5:8:5:14 | [DotExpr] obj.foo | semmle.order | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:8:12:8:17 | [VarRef] source | semmle.label | 0 | @@ -1442,6 +1644,32 @@ edges | file://:0:0:0:0 | (Arguments) | arrays.js:97:8:97:42 | [MethodCallExpr] ["sourc ... ).pop() | semmle.order | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:97:26:97:35 | [ArrowFunctionExpr] (x) => !!x | semmle.label | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:97:26:97:35 | [ArrowFunctionExpr] (x) => !!x | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:100:25:100:25 | [Literal] 0 | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:100:25:100:25 | [Literal] 0 | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:100:28:100:28 | [Literal] 0 | semmle.label | 1 | +| file://:0:0:0:0 | (Arguments) | arrays.js:100:28:100:28 | [Literal] 0 | semmle.order | 1 | +| file://:0:0:0:0 | (Arguments) | arrays.js:100:31:100:38 | [Literal] "source" | semmle.label | 2 | +| file://:0:0:0:0 | (Arguments) | arrays.js:100:31:100:38 | [Literal] "source" | semmle.order | 2 | +| file://:0:0:0:0 | (Arguments) | arrays.js:101:8:101:17 | [MethodCallExpr] arr8.pop() | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:101:8:101:17 | [MethodCallExpr] arr8.pop() | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:104:41:104:41 | [Literal] 0 | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:104:41:104:41 | [Literal] 0 | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:104:44:104:44 | [Literal] 0 | semmle.label | 1 | +| file://:0:0:0:0 | (Arguments) | arrays.js:104:44:104:44 | [Literal] 0 | semmle.order | 1 | +| file://:0:0:0:0 | (Arguments) | arrays.js:104:47:104:52 | [Literal] "safe" | semmle.label | 2 | +| file://:0:0:0:0 | (Arguments) | arrays.js:104:47:104:52 | [Literal] "safe" | semmle.order | 2 | +| file://:0:0:0:0 | (Arguments) | arrays.js:104:55:104:62 | [Literal] "source" | semmle.label | 3 | +| file://:0:0:0:0 | (Arguments) | arrays.js:104:55:104:62 | [Literal] "source" | semmle.order | 3 | +| file://:0:0:0:0 | (Arguments) | arrays.js:106:8:106:25 | [MethodCallExpr] arr8_variant.pop() | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:106:8:106:25 | [MethodCallExpr] arr8_variant.pop() | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:109:39:109:39 | [Literal] 0 | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:109:39:109:39 | [Literal] 0 | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:109:42:109:42 | [Literal] 0 | semmle.label | 1 | +| file://:0:0:0:0 | (Arguments) | arrays.js:109:42:109:42 | [Literal] 0 | semmle.order | 1 | +| file://:0:0:0:0 | (Arguments) | arrays.js:109:45:109:50 | [SpreadElement] ...arr | semmle.label | 2 | +| file://:0:0:0:0 | (Arguments) | arrays.js:109:45:109:50 | [SpreadElement] ...arr | semmle.order | 2 | +| file://:0:0:0:0 | (Arguments) | arrays.js:110:8:110:24 | [MethodCallExpr] arr8_spread.pop() | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:110:8:110:24 | [MethodCallExpr] arr8_spread.pop() | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:15:16:15:16 | [SimpleParameter] e | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:15:16:15:16 | [SimpleParameter] e | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:16:12:16:12 | [SimpleParameter] e | semmle.label | 0 | diff --git a/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected b/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected index 6cbebc43ea9..b654e9c8362 100644 --- a/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected +++ b/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected @@ -198,3 +198,5 @@ multipleArgumentCall | tst.js:266:3:266:6 | map3 | tst.js:266:3:266:14 | map3.forEach (as accessor call) | Multiple calls for argument node. | | tst.js:266:3:266:6 | map3 | tst.js:266:3:266:36 | map3.fo ... value)) | Multiple calls for argument node. | lambdaCallEnclosingCallableMismatch +speculativeStepAlreadyHasModel +| tst.js:223:39:223:44 | array4 | tst.js:223:12:223:45 | Array.p ... array4) | dispatch | diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 069da0c2c6f..2ee606c2e50 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -52,6 +52,11 @@ flow | array-mutation.js:31:33:31:40 | source() | array-mutation.js:32:8:32:8 | h | | array-mutation.js:35:36:35:43 | source() | array-mutation.js:36:8:36:8 | i | | array-mutation.js:39:17:39:24 | source() | array-mutation.js:40:8:40:8 | j | +| array-mutation.js:43:36:43:43 | source() | array-mutation.js:45:8:45:15 | kSpliced | +| array-mutation.js:48:25:48:32 | source() | array-mutation.js:49:8:49:8 | l | +| array-mutation.js:68:21:68:28 | source() | array-mutation.js:69:8:69:8 | q | +| array-mutation.js:72:39:72:46 | source() | array-mutation.js:73:8:73:15 | rSpliced | +| array-mutation.js:75:28:75:35 | source() | array-mutation.js:76:8:76:8 | r | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:17:8:17:13 | arr[1] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:22:8:22:13 | arr[6] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:28:8:28:13 | arr[1] | @@ -296,6 +301,14 @@ flow | 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) | | tst.js:2:13:2:20 | source() | tst.js:54:14:54:19 | unsafe | +| tst.js:2:13:2:20 | source() | tst.js:61:10:61:20 | x.reverse() | +| tst.js:2:13:2:20 | source() | tst.js:62:10:62:22 | x.toSpliced() | +| tst.js:2:13:2:20 | source() | tst.js:64:10:64:21 | x.toSorted() | +| tst.js:2:13:2:20 | source() | tst.js:66:10:66:16 | xSorted | +| tst.js:2:13:2:20 | source() | tst.js:68:10:68:23 | x.toReversed() | +| tst.js:2:13:2:20 | source() | tst.js:70:10:70:18 | xReversed | +| tst.js:2:13:2:20 | source() | tst.js:72:10:72:17 | x.with() | +| tst.js:2:13:2:20 | source() | tst.js:74:10:74:14 | xWith | | use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:8:10:8:17 | captured | | use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:15:10:15:10 | x | | xml.js:5:18:5:25 | source() | xml.js:8:14:8:17 | text | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected index bfff47f8391..7aa4dfd0bca 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected @@ -313,6 +313,11 @@ nodes | normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | semmle.label | pathMod ... t('/')) | | normalizedPaths.js:408:38:408:48 | req.query.x | semmle.label | req.query.x | | normalizedPaths.js:408:38:408:59 | req.que ... it('/') | semmle.label | req.que ... it('/') | +| normalizedPaths.js:412:7:412:46 | path | semmle.label | path | +| normalizedPaths.js:412:14:412:46 | pathMod ... uery.x) | semmle.label | pathMod ... uery.x) | +| normalizedPaths.js:412:35:412:45 | req.query.x | semmle.label | req.query.x | +| normalizedPaths.js:415:19:415:22 | path | semmle.label | path | +| normalizedPaths.js:426:21:426:24 | path | semmle.label | path | | other-fs-libraries.js:9:7:9:48 | path | semmle.label | path | | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | semmle.label | url.par ... , true) | | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | semmle.label | url.par ... ).query | @@ -760,6 +765,10 @@ edges | normalizedPaths.js:407:45:407:66 | req.que ... it('/') | normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | provenance | Config | | normalizedPaths.js:408:38:408:48 | req.query.x | normalizedPaths.js:408:38:408:59 | req.que ... it('/') | provenance | Config | | normalizedPaths.js:408:38:408:59 | req.que ... it('/') | normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | provenance | Config | +| normalizedPaths.js:412:7:412:46 | path | normalizedPaths.js:415:19:415:22 | path | provenance | | +| normalizedPaths.js:412:7:412:46 | path | normalizedPaths.js:426:21:426:24 | path | provenance | | +| normalizedPaths.js:412:14:412:46 | pathMod ... uery.x) | normalizedPaths.js:412:7:412:46 | path | provenance | | +| normalizedPaths.js:412:35:412:45 | req.query.x | normalizedPaths.js:412:14:412:46 | pathMod ... uery.x) | provenance | Config | | other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | provenance | | | other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | provenance | | | other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | provenance | | @@ -1023,6 +1032,8 @@ subpaths | normalizedPaths.js:399:21:399:24 | path | normalizedPaths.js:385:35:385:45 | req.query.x | normalizedPaths.js:399:21:399:24 | path | This path depends on a $@. | normalizedPaths.js:385:35:385:45 | req.query.x | user-provided value | | normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | normalizedPaths.js:407:45:407:55 | req.query.x | normalizedPaths.js:407:19:407:67 | pathMod ... t('/')) | This path depends on a $@. | normalizedPaths.js:407:45:407:55 | req.query.x | user-provided value | | normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | normalizedPaths.js:408:38:408:48 | req.query.x | normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | This path depends on a $@. | normalizedPaths.js:408:38:408:48 | req.query.x | user-provided value | +| normalizedPaths.js:415:19:415:22 | path | normalizedPaths.js:412:35:412:45 | req.query.x | normalizedPaths.js:415:19:415:22 | path | This path depends on a $@. | normalizedPaths.js:412:35:412:45 | req.query.x | user-provided value | +| normalizedPaths.js:426:21:426:24 | path | normalizedPaths.js:412:35:412:45 | req.query.x | normalizedPaths.js:426:21:426:24 | path | This path depends on a $@. | normalizedPaths.js:412:35:412:45 | req.query.x | user-provided value | | other-fs-libraries.js:11:19:11:22 | path | other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:11:19:11:22 | path | This path depends on a $@. | other-fs-libraries.js:9:24:9:30 | req.url | user-provided value | | other-fs-libraries.js:12:27:12:30 | path | other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:12:27:12:30 | path | This path depends on a $@. | other-fs-libraries.js:9:24:9:30 | req.url | user-provided value | | other-fs-libraries.js:13:24:13:27 | path | other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:13:24:13:27 | path | This path depends on a $@. | other-fs-libraries.js:9:24:9:30 | req.url | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected index 60a29847a10..b8ce07f4ca8 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected @@ -94,27 +94,19 @@ edges | command-line-parameter-command-injection.js:71:20:71:40 | require ... ').argv | command-line-parameter-command-injection.js:71:6:71:16 | [...taint4] | provenance | | | command-line-parameter-command-injection.js:72:22:72:27 | taint4 | command-line-parameter-command-injection.js:72:10:72:27 | "cmd.sh " + taint4 | provenance | | | command-line-parameter-command-injection.js:76:8:76:35 | argv | command-line-parameter-command-injection.js:79:31:79:34 | argv | provenance | | -| command-line-parameter-command-injection.js:76:8:76:35 | argv [ArrayElement] | command-line-parameter-command-injection.js:79:31:79:34 | argv [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:76:15:76:26 | process.argv | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | provenance | | -| command-line-parameter-command-injection.js:76:15:76:26 | process.argv | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | command-line-parameter-command-injection.js:76:8:76:35 | argv | provenance | | -| command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) [ArrayElement] | command-line-parameter-command-injection.js:76:8:76:35 | argv [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | command-line-parameter-command-injection.js:79:10:79:39 | "cmd.sh ... gv).foo | provenance | | -| command-line-parameter-command-injection.js:79:31:79:34 | argv | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | provenance | Config | -| command-line-parameter-command-injection.js:79:31:79:34 | argv [ArrayElement] | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | provenance | Config | +| command-line-parameter-command-injection.js:79:31:79:34 | argv | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | provenance | | | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | command-line-parameter-command-injection.js:82:10:82:54 | "cmd.sh ... 2)).foo | provenance | | | command-line-parameter-command-injection.js:82:29:82:40 | process.argv | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | provenance | | -| command-line-parameter-command-injection.js:82:29:82:40 | process.argv | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) [ArrayElement] | provenance | | -| command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | provenance | Config | -| command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) [ArrayElement] | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | provenance | Config | +| command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | provenance | | | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | command-line-parameter-command-injection.js:85:10:85:59 | "cmd.sh ... 2)).foo | provenance | | | command-line-parameter-command-injection.js:85:34:85:45 | process.argv | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | provenance | | -| command-line-parameter-command-injection.js:85:34:85:45 | process.argv | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) [ArrayElement] | provenance | | -| command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | provenance | Config | -| command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) [ArrayElement] | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | provenance | Config | +| command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | provenance | | | command-line-parameter-command-injection.js:88:6:88:37 | flags | command-line-parameter-command-injection.js:89:22:89:26 | flags | provenance | | | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | command-line-parameter-command-injection.js:88:6:88:37 | flags | provenance | | -| command-line-parameter-command-injection.js:88:25:88:36 | process.argv | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | provenance | Config | +| command-line-parameter-command-injection.js:88:25:88:36 | process.argv | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | provenance | | | command-line-parameter-command-injection.js:89:22:89:26 | flags | command-line-parameter-command-injection.js:89:10:89:30 | "cmd.sh ... ags.foo | provenance | | | command-line-parameter-command-injection.js:91:6:91:38 | flags | command-line-parameter-command-injection.js:92:22:92:26 | flags | provenance | | | command-line-parameter-command-injection.js:91:14:91:38 | require ... .spec}) | command-line-parameter-command-injection.js:91:6:91:38 | flags | provenance | | @@ -245,24 +237,19 @@ nodes | command-line-parameter-command-injection.js:72:10:72:27 | "cmd.sh " + taint4 | semmle.label | "cmd.sh " + taint4 | | command-line-parameter-command-injection.js:72:22:72:27 | taint4 | semmle.label | taint4 | | command-line-parameter-command-injection.js:76:8:76:35 | argv | semmle.label | argv | -| command-line-parameter-command-injection.js:76:8:76:35 | argv [ArrayElement] | semmle.label | argv [ArrayElement] | | command-line-parameter-command-injection.js:76:15:76:26 | process.argv | semmle.label | process.argv | | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | semmle.label | process ... lice(2) | -| command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) [ArrayElement] | semmle.label | process ... lice(2) [ArrayElement] | | command-line-parameter-command-injection.js:79:10:79:39 | "cmd.sh ... gv).foo | semmle.label | "cmd.sh ... gv).foo | | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | semmle.label | minimist(argv) | | command-line-parameter-command-injection.js:79:31:79:34 | argv | semmle.label | argv | -| command-line-parameter-command-injection.js:79:31:79:34 | argv [ArrayElement] | semmle.label | argv [ArrayElement] | | command-line-parameter-command-injection.js:82:10:82:54 | "cmd.sh ... 2)).foo | semmle.label | "cmd.sh ... 2)).foo | | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | semmle.label | subarg( ... ice(2)) | | command-line-parameter-command-injection.js:82:29:82:40 | process.argv | semmle.label | process.argv | | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | semmle.label | process ... lice(2) | -| command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) [ArrayElement] | semmle.label | process ... lice(2) [ArrayElement] | | command-line-parameter-command-injection.js:85:10:85:59 | "cmd.sh ... 2)).foo | semmle.label | "cmd.sh ... 2)).foo | | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | semmle.label | yargsPa ... ice(2)) | | command-line-parameter-command-injection.js:85:34:85:45 | process.argv | semmle.label | process.argv | | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | semmle.label | process ... lice(2) | -| command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) [ArrayElement] | semmle.label | process ... lice(2) [ArrayElement] | | command-line-parameter-command-injection.js:88:6:88:37 | flags | semmle.label | flags | | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | semmle.label | args.pa ... s.argv) | | command-line-parameter-command-injection.js:88:25:88:36 | process.argv | semmle.label | process.argv | diff --git a/javascript/ql/test/query-tests/Security/CWE-089/local-threat-source/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/local-threat-source/SqlInjection.expected index 05749a54c5b..3a4a7ef0481 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/local-threat-source/SqlInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/local-threat-source/SqlInjection.expected @@ -1,17 +1,12 @@ nodes -| test.js:4:5:4:29 | temp | -| test.js:4:12:4:22 | process.env | -| test.js:4:12:4:22 | process.env | -| test.js:4:12:4:29 | process.env['foo'] | -| test.js:7:14:7:61 | 'SELECT ... + temp | -| test.js:7:14:7:61 | 'SELECT ... + temp | -| test.js:7:58:7:61 | temp | +| test.js:4:5:4:29 | temp | semmle.label | temp | +| test.js:4:12:4:22 | process.env | semmle.label | process.env | +| test.js:7:14:7:61 | 'SELECT ... + temp | semmle.label | 'SELECT ... + temp | +| test.js:7:58:7:61 | temp | semmle.label | temp | edges -| test.js:4:5:4:29 | temp | test.js:7:58:7:61 | temp | -| test.js:4:12:4:22 | process.env | test.js:4:12:4:29 | process.env['foo'] | -| test.js:4:12:4:22 | process.env | test.js:4:12:4:29 | process.env['foo'] | -| test.js:4:12:4:29 | process.env['foo'] | test.js:4:5:4:29 | temp | -| test.js:7:58:7:61 | temp | test.js:7:14:7:61 | 'SELECT ... + temp | -| test.js:7:58:7:61 | temp | test.js:7:14:7:61 | 'SELECT ... + temp | +| test.js:4:5:4:29 | temp | test.js:7:58:7:61 | temp | provenance | | +| test.js:4:12:4:22 | process.env | test.js:4:5:4:29 | temp | provenance | | +| test.js:7:58:7:61 | temp | test.js:7:14:7:61 | 'SELECT ... + temp | provenance | | +subpaths #select | test.js:7:14:7:61 | 'SELECT ... + temp | test.js:4:12:4:22 | process.env | test.js:7:14:7:61 | 'SELECT ... + temp | This query string depends on a $@. | test.js:4:12:4:22 | process.env | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-117/LogInjection.expected b/javascript/ql/test/query-tests/Security/CWE-117/LogInjection.expected index 12bbd7feea9..786bbb5c0b9 100644 --- a/javascript/ql/test/query-tests/Security/CWE-117/LogInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-117/LogInjection.expected @@ -64,6 +64,14 @@ edges | logInjectionBad.js:87:5:94:5 | functio ... ;\\n } [username] | logInjectionBad.js:91:26:91:33 | username | provenance | | | logInjectionBad.js:96:5:103:5 | functio ... ;\\n } [username] | logInjectionBad.js:99:26:99:33 | username | provenance | | | logInjectionBad.js:105:5:118:5 | functio ... ;\\n } [username] | logInjectionBad.js:113:37:113:44 | username | provenance | | +| logInjectionBad.js:122:9:122:58 | username | logInjectionBad.js:123:20:123:27 | username | provenance | | +| logInjectionBad.js:122:20:122:43 | url.par ... , true) | logInjectionBad.js:122:9:122:58 | username | provenance | | +| logInjectionBad.js:122:30:122:36 | req.url | logInjectionBad.js:122:20:122:43 | url.par ... , true) | provenance | | +| logInjectionBad.js:123:9:123:46 | otherStr | logInjectionBad.js:124:17:124:24 | otherStr | provenance | | +| logInjectionBad.js:123:20:123:27 | username | logInjectionBad.js:123:20:123:43 | usernam ... (/.*/g) | provenance | | +| logInjectionBad.js:123:20:123:43 | usernam ... (/.*/g) | logInjectionBad.js:123:9:123:46 | otherStr | provenance | | +| logInjectionBad.js:128:20:128:43 | url.par ... , true) | logInjectionBad.js:129:42:129:50 | RegExp.$1 | provenance | | +| logInjectionBad.js:128:30:128:36 | req.url | logInjectionBad.js:128:20:128:43 | url.par ... , true) | provenance | | nodes | logInjectionBad.js:7:25:7:32 | username | semmle.label | username | | logInjectionBad.js:8:38:8:45 | username | semmle.label | username | @@ -134,6 +142,16 @@ nodes | logInjectionBad.js:99:26:99:33 | username | semmle.label | username | | logInjectionBad.js:105:5:118:5 | functio ... ;\\n } [username] | semmle.label | functio ... ;\\n } [username] | | logInjectionBad.js:113:37:113:44 | username | semmle.label | username | +| logInjectionBad.js:122:9:122:58 | username | semmle.label | username | +| logInjectionBad.js:122:20:122:43 | url.par ... , true) | semmle.label | url.par ... , true) | +| logInjectionBad.js:122:30:122:36 | req.url | semmle.label | req.url | +| logInjectionBad.js:123:9:123:46 | otherStr | semmle.label | otherStr | +| logInjectionBad.js:123:20:123:27 | username | semmle.label | username | +| logInjectionBad.js:123:20:123:43 | usernam ... (/.*/g) | semmle.label | usernam ... (/.*/g) | +| logInjectionBad.js:124:17:124:24 | otherStr | semmle.label | otherStr | +| logInjectionBad.js:128:20:128:43 | url.par ... , true) | semmle.label | url.par ... , true) | +| logInjectionBad.js:128:30:128:36 | req.url | semmle.label | req.url | +| logInjectionBad.js:129:42:129:50 | RegExp.$1 | semmle.label | RegExp.$1 | subpaths | logInjectionBad.js:28:24:28:31 | username | logInjectionBad.js:7:25:7:32 | username | logInjectionBad.js:8:38:8:45 | username | logInjectionBad.js:28:9:28:32 | exceptional return of check_u ... ername) | #select @@ -158,3 +176,5 @@ subpaths | logInjectionBad.js:91:26:91:33 | username | logInjectionBad.js:72:23:72:29 | req.url | logInjectionBad.js:91:26:91:33 | username | Log entry depends on a $@. | logInjectionBad.js:72:23:72:29 | req.url | user-provided value | | logInjectionBad.js:99:26:99:33 | username | logInjectionBad.js:72:23:72:29 | req.url | logInjectionBad.js:99:26:99:33 | username | Log entry depends on a $@. | logInjectionBad.js:72:23:72:29 | req.url | user-provided value | | logInjectionBad.js:113:37:113:44 | username | logInjectionBad.js:72:23:72:29 | req.url | logInjectionBad.js:113:37:113:44 | username | Log entry depends on a $@. | logInjectionBad.js:72:23:72:29 | req.url | user-provided value | +| logInjectionBad.js:124:17:124:24 | otherStr | logInjectionBad.js:122:30:122:36 | req.url | logInjectionBad.js:124:17:124:24 | otherStr | Log entry depends on a $@. | logInjectionBad.js:122:30:122:36 | req.url | user-provided value | +| logInjectionBad.js:129:42:129:50 | RegExp.$1 | logInjectionBad.js:128:30:128:36 | req.url | logInjectionBad.js:129:42:129:50 | RegExp.$1 | Log entry depends on a $@. | logInjectionBad.js:128:30:128:36 | req.url | user-provided value | From 805fd0b46eebf80d1e4dc4b788b7f98237290180 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 26 Nov 2024 15:56:56 +0100 Subject: [PATCH 362/514] JS: Refine speculative step definition --- .../internal/TaintTrackingPrivate.qll | 22 ++++++++++++++----- .../FlowSummary/DataFlowConsistency.expected | 1 - 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index b182e945840..0ca5de709ff 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -105,11 +105,21 @@ predicate defaultImplicitTaintRead(DataFlow::Node node, ContentSet c) { not optionalStep(node, _, _) } -predicate speculativeTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(DataFlow::CallNode call, DataFlowCall c | - not exists(viableCallable(c)) and - c.asOrdinaryCall() = call and - node1 = call.getAnArgument() and - node2 = call +private predicate isArgumentToResolvedCall(DataFlow::Node arg) { + exists(DataFlowCall c | + exists(viableCallable(c)) and + isArgumentNode(arg, c, _) + ) +} + +predicate speculativeTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(DataFlow::CallNode call | + node1 = call.getAnArgument() and + node2 = call and + // A given node can appear as argument in more than one call. For example `x` in `fn.call(x)` is + // is argument 0 of the `fn.call` call, but also the receiver of a reflective call to `fn`. + // It is thus not enough to check if `call` has a known target; we nede to ensure that none of the calls + // involving `node1` have a known target. + not isArgumentToResolvedCall(node1) ) } diff --git a/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected b/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected index b654e9c8362..da22cf7e778 100644 --- a/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected +++ b/javascript/ql/test/library-tests/FlowSummary/DataFlowConsistency.expected @@ -199,4 +199,3 @@ multipleArgumentCall | tst.js:266:3:266:6 | map3 | tst.js:266:3:266:36 | map3.fo ... value)) | Multiple calls for argument node. | lambdaCallEnclosingCallableMismatch speculativeStepAlreadyHasModel -| tst.js:223:39:223:44 | array4 | tst.js:223:12:223:45 | Array.p ... array4) | dispatch | From df12f255ac90599d0ee7c164f5a2aec5685d42fc Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 Nov 2024 13:49:11 +0100 Subject: [PATCH 363/514] JS: Rename propagatesFlowExt -> propagatesFlow --- .../javascript/dataflow/FlowSummary.qll | 5 +- .../flow_summaries/AmbiguousCoreMethods.qll | 14 +++--- .../internal/flow_summaries/Arrays.qll | 50 +++++++++---------- .../internal/flow_summaries/ExceptionFlow.qll | 2 +- .../internal/flow_summaries/Iterators.qll | 2 +- .../internal/flow_summaries/JsonStringify.qll | 2 +- .../internal/flow_summaries/Maps.qll | 6 +-- .../internal/flow_summaries/Promises.qll | 30 +++++------ .../internal/flow_summaries/Sets.qll | 4 +- .../internal/flow_summaries/Strings.qll | 8 +-- 10 files changed, 61 insertions(+), 62 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll b/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll index 9f619a3058e..1520ff22f88 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll @@ -11,19 +11,18 @@ abstract class SummarizedCallable extends LibraryCallable, Impl::Public::Summari bindingset[this] SummarizedCallable() { any() } - // TODO: rename 'propagatesFlowExt' and/or override 'propagatesFlow' directly /** * Holds if data may flow from `input` to `output` through this callable. * * `preservesValue` indicates whether this is a value-preserving step or a taint-step. */ pragma[nomagic] - predicate propagatesFlowExt(string input, string output, boolean preservesValue) { none() } + predicate propagatesFlow(string input, string output, boolean preservesValue) { none() } override predicate propagatesFlow( string input, string output, boolean preservesValue, string model ) { - this.propagatesFlowExt(input, output, preservesValue) and model = this + this.propagatesFlow(input, output, preservesValue) and model = this } /** diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AmbiguousCoreMethods.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AmbiguousCoreMethods.qll index 9c74cc7e33f..95981a6fb95 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AmbiguousCoreMethods.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/AmbiguousCoreMethods.qll @@ -31,7 +31,7 @@ class At extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = "at" } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[this].ArrayElement" and output = "ReturnValue" @@ -45,7 +45,7 @@ class Concat extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = "concat" } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[this,0..].ArrayElement" and output = "ReturnValue.ArrayElement" @@ -61,7 +61,7 @@ class Slice extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = "slice" } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[this].ArrayElement" and output = "ReturnValue.ArrayElement" @@ -80,7 +80,7 @@ class Entries extends SummarizedCallable { result.getNumArgument() = 0 } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[this]." + ["MapKey", "SetElement"] and @@ -97,7 +97,7 @@ class ForEach extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = "forEach" } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and /* * array.forEach(callbackfn, thisArg) @@ -128,7 +128,7 @@ class Keys extends SummarizedCallable { result.getNumArgument() = 0 } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[this]." + ["MapKey", "SetElement"] and output = "ReturnValue.IteratorElement" @@ -143,7 +143,7 @@ class Values extends SummarizedCallable { result.getNumArgument() = 0 } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[this]." + ["ArrayElement", "SetElement", "MapValue"] and output = "ReturnValue.IteratorElement" diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll index 9381ca98dd7..702936b46c3 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll @@ -99,7 +99,7 @@ class ArrayConstructorSummary extends SummarizedCallable { result = arrayConstructorRef().getAnInvocation() } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[0..]" and output = "ReturnValue.ArrayElement" @@ -123,7 +123,7 @@ class Join extends SummarizedCallable { result.getNumArgument() = [0, 1] } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = false and input = "Argument[this].ArrayElement" and output = "ReturnValue" @@ -135,7 +135,7 @@ class CopyWithin extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = "copyWithin" } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[this].WithArrayElement" and output = "ReturnValue" @@ -154,7 +154,7 @@ class FlowIntoCallback extends SummarizedCallable { result.getMethodName() = ["every", "findIndex", "findLastIndex", "some"] } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[this].ArrayElement" and @@ -171,7 +171,7 @@ class Filter extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = "filter" } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[this].ArrayElement" and @@ -198,7 +198,7 @@ class Fill extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = "fill" } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[0..]" and output = ["ReturnValue.ArrayElement", "Argument[this].ArrayElement"] @@ -210,7 +210,7 @@ class FindLike extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = ["find", "findLast"] } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[this].ArrayElement" and @@ -229,7 +229,7 @@ class FindLibrary extends SummarizedCallable { result = DataFlow::moduleImport(["array.prototype.find", "array-find"]).getACall() } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[0].ArrayElement" and @@ -257,7 +257,7 @@ class Flat extends SummarizedCallable { ) } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[this]" + concat(int n | n in [0 .. depth] | ".ArrayElement") @@ -277,7 +277,7 @@ class FlatMap extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = "flatMap" } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[this].ArrayElement" and @@ -309,7 +309,7 @@ class From1Arg extends SummarizedCallable { result = arrayFromCall() and result.getNumArgument() = 1 } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[0].WithArrayElement" and @@ -346,7 +346,7 @@ class FromManyArg extends SummarizedCallable { result.getNumArgument() > 1 } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[0]." + ["ArrayElement", "SetElement", "IteratorElement"] and @@ -380,7 +380,7 @@ class Map extends SummarizedCallable { result.getMethodName() = "map" } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[this].ArrayElement" and @@ -405,7 +405,7 @@ class Of extends SummarizedCallable { result = arrayConstructorRef().getAMemberCall("of") } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[0..]" and output = "ReturnValue.ArrayElement" @@ -417,7 +417,7 @@ class Pop extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = "pop" } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[this].ArrayElement" and output = "ReturnValue" @@ -429,7 +429,7 @@ class PushLike extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = ["push", "unshift"] } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[0..]" and output = "Argument[this].ArrayElement" @@ -441,7 +441,7 @@ class ReduceLike extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = ["reduce", "reduceRight"] } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and /* * Signatures: @@ -470,7 +470,7 @@ class Reverse extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = ["reverse", "toReversed"] } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[this].ArrayElement" and output = "ReturnValue.ArrayElement" @@ -482,7 +482,7 @@ class Shift extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = "shift" } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[this].ArrayElement[0]" and output = "ReturnValue" @@ -500,7 +500,7 @@ class Sort extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = ["sort", "toSorted"] } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[this].ArrayElement" and @@ -517,7 +517,7 @@ class Splice extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = "splice" } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[this].ArrayElement" and @@ -534,7 +534,7 @@ class ToSpliced extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = "toSpliced" } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[this].ArrayElement" and @@ -551,7 +551,7 @@ class ArrayCoercionPackage extends FunctionalPackageSummary { override string getAPackageName() { result = ["arrify", "array-ify"] } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[0].WithArrayElement" and @@ -573,7 +573,7 @@ class ArrayCopyingPackage extends FunctionalPackageSummary { override string getAPackageName() { result = ["array-union", "array-uniq", "uniq"] } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[0..].ArrayElement" and output = "ReturnValue.ArrayElement" @@ -587,7 +587,7 @@ class ArrayFlatteningPackage extends FunctionalPackageSummary { result = ["array-flatten", "arr-flatten", "flatten", "array.prototype.flat"] } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { // TODO: properly support these. For the moment we're just adding parity with the old model preservesValue = false and input = "Argument[0..]" and diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll index c81dadadfb6..252baab207b 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/ExceptionFlow.qll @@ -40,7 +40,7 @@ private class ExceptionFlowSummary extends SummarizedCallable, LibraryCallableIn isCallback(result.getAnArgument().getALocalSource()) } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[0..].ReturnValue[exception]" and output = "ReturnValue[exception]" diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Iterators.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Iterators.qll index 94afac52787..e9937363c01 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Iterators.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Iterators.qll @@ -16,7 +16,7 @@ class IteratorNext extends SummarizedCallable { result.getNumArgument() = 0 } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[this].IteratorElement" and diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/JsonStringify.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/JsonStringify.qll index 86779b8e7ec..ecd2dcdfc79 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/JsonStringify.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/JsonStringify.qll @@ -12,7 +12,7 @@ private class JsonStringifySummary extends SummarizedCallable { override DataFlow::InvokeNode getACall() { result instanceof JsonStringifyCall } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = false and input = ["Argument[0]", "Argument[0].AnyMemberDeep"] and output = "ReturnValue" diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Maps.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Maps.qll index c80bee19aaa..3adc145d1a1 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Maps.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Maps.qll @@ -15,7 +15,7 @@ class MapConstructor extends SummarizedCallable { result = mapConstructorRef().getAnInstantiation() } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[0]." + ["ArrayElement", "SetElement", "IteratorElement"] + ".Member[0]" and @@ -87,7 +87,7 @@ class MapGet extends SummarizedCallable { result.getNumArgument() = 1 } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[this].MapValue" and output = "ReturnValue" @@ -102,7 +102,7 @@ class MapSet extends SummarizedCallable { result.getNumArgument() = 2 } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = ["Argument[this].WithMapKey", "Argument[this].WithMapValue"] and output = "ReturnValue" diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises.qll index aa9398f14bb..33299a3f5c0 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises.qll @@ -29,7 +29,7 @@ private class PromiseConstructor extends SummarizedCallable { none() } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( // TODO: when FlowSummaryImpl.qll supports these summaries, remove the workaround in PromiseConstructorWorkaround @@ -58,7 +58,7 @@ module PromiseConstructorWorkaround { promiseConstructorRef().getAnInstantiation().getCallback(0).getParameter(0).getACall() } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[0]" and output = "Argument[function].Member[resolve-value]" @@ -73,7 +73,7 @@ module PromiseConstructorWorkaround { promiseConstructorRef().getAnInstantiation().getCallback(0).getParameter(1).getACall() } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[0]" and output = "Argument[function].Member[reject-value]" @@ -87,7 +87,7 @@ module PromiseConstructorWorkaround { result = promiseConstructorRef().getAnInstantiation() } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[0].Parameter[0].Member[resolve-value]" and @@ -111,7 +111,7 @@ private class PromiseThen2Arguments extends SummarizedCallable { result.getNumArgument() = 2 } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[0,1].ReturnValue" and output = "ReturnValue.Awaited" @@ -133,7 +133,7 @@ private class PromiseThen1Argument extends SummarizedCallable { result.getNumArgument() = 1 } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[0].ReturnValue" and output = "ReturnValue.Awaited" @@ -152,7 +152,7 @@ private class PromiseCatch extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = "catch" } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[0].ReturnValue" and output = "ReturnValue.Awaited" @@ -171,7 +171,7 @@ private class PromiseFinally extends SummarizedCallable { override InstanceCall getACallSimple() { result.getMethodName() = "finally" } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[0].ReturnValue.Awaited[error]" and output = "ReturnValue.Awaited[error]" @@ -190,7 +190,7 @@ private class PromiseResolve extends SummarizedCallable { result = promiseConstructorRef().getAMemberCall("resolve") } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[0]" and output = "ReturnValue.Awaited" @@ -204,7 +204,7 @@ private class PromiseReject extends SummarizedCallable { result = promiseConstructorRef().getAMemberCall("reject") } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[0]" and output = "ReturnValue.Awaited[error]" @@ -218,7 +218,7 @@ private class PromiseAll extends SummarizedCallable { result = promiseConstructorRef().getAMemberCall("all") } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and exists(string content | content = getAnArrayContent() | input = "Argument[0]." + content + ".Awaited" and @@ -242,7 +242,7 @@ private class PromiseAnyLike extends SummarizedCallable { result = promiseConstructorRef().getAMemberCall(["any", "race", "firstFulfilled"]) } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[0].ArrayElement" and output = "ReturnValue.Awaited" @@ -258,7 +258,7 @@ private class PromiseAllSettled extends SummarizedCallable { result = DataFlow::moduleImport("promise.allsettled").getACall() } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and exists(string content | content = getAnArrayContent() | input = "Argument[0]." + content + ".Awaited" and @@ -277,7 +277,7 @@ private class BluebirdMapSeries extends SummarizedCallable { result = promiseConstructorRef().getAMemberCall("mapSeries") } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[0].Awaited.ArrayElement.Awaited" and @@ -310,7 +310,7 @@ private class PromiseWithResolversLike extends SummarizedCallable { result = promiseConstructorRef().getAMemberCall(["withResolver", "withResolvers", "defer"]) } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( // TODO: not currently supported by FlowSummaryImpl.qll diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Sets.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Sets.qll index 1880eb569bf..34f7d222df8 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Sets.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Sets.qll @@ -15,7 +15,7 @@ class SetConstructor extends SummarizedCallable { result = setConstructorRef().getAnInstantiation() } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( input = "Argument[0]." + ["ArrayElement", "SetElement", "IteratorElement"] and @@ -38,7 +38,7 @@ class SetAdd extends SummarizedCallable { result.getNumArgument() = 1 } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and input = "Argument[0]" and output = "Argument[this].SetElement" diff --git a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll index 9267ab598fb..154668cde08 100644 --- a/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll +++ b/javascript/ql/lib/semmle/javascript/internal/flow_summaries/Strings.qll @@ -15,7 +15,7 @@ private class StringReplaceNoWildcard extends SummarizedCallable { override StringReplaceCall getACall() { not result.hasRegExpContainingWildcard() } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = false and ( input = "Argument[this]" and @@ -39,7 +39,7 @@ private class StringReplaceWithWildcard extends SummarizedCallable { override StringReplaceCall getACall() { result.hasRegExpContainingWildcard() } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = false and ( input = "Argument[this]" and @@ -60,7 +60,7 @@ class StringSplit extends SummarizedCallable { not result.getArgument(0).getStringValue() = ["#", "?"] } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = false and input = "Argument[this]" and output = "ReturnValue.ArrayElement" @@ -85,7 +85,7 @@ class StringSplitHashOrQuestionMark extends SummarizedCallable { result.getArgument(0).getStringValue() = ["#", "?"] } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = false and ( input = "Argument[this].OptionalBarrier[split-url-suffix]" and From e34064e3b541b43c7259b541c124772826bb4ffb Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 19 Nov 2024 14:43:18 +0100 Subject: [PATCH 364/514] JS: Initial instantiation of sumamry type tracking Instantiates the library without using it yet. --- javascript/ql/lib/qlpack.yml | 1 + .../internal/sharedlib/SummaryTypeTracker.qll | 73 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/SummaryTypeTracker.qll diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index a7baed0056b..78f26bc9870 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -12,6 +12,7 @@ dependencies: codeql/ssa: ${workspace} codeql/threat-models: ${workspace} codeql/tutorial: ${workspace} + codeql/typetracking: ${workspace} codeql/util: ${workspace} codeql/xml: ${workspace} codeql/yaml: ${workspace} diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/SummaryTypeTracker.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/SummaryTypeTracker.qll new file mode 100644 index 00000000000..09d992dcea7 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/SummaryTypeTracker.qll @@ -0,0 +1,73 @@ +private import semmle.javascript.Locations +private import codeql.typetracking.internal.SummaryTypeTracker +private import semmle.javascript.dataflow.internal.DataFlowPrivate as DataFlowPrivate +private import semmle.javascript.dataflow.FlowSummary as FlowSummary +private import FlowSummaryImpl as FlowSummaryImpl +private import DataFlowArg + +private module SummaryFlowConfig implements Input { + import JSDataFlow + import FlowSummaryImpl::Public + import FlowSummaryImpl::Private + import FlowSummaryImpl::Private::SummaryComponent + + class Content = DataFlow::ContentSet; + + class ContentFilter extends Unit { + ContentFilter() { none() } + } + + ContentFilter getFilterFromWithoutContentStep(Content content) { none() } + + ContentFilter getFilterFromWithContentStep(Content content) { none() } + + predicate singleton = SummaryComponentStack::singleton/1; + + predicate push = SummaryComponentStack::push/2; + + SummaryComponent return() { + result = SummaryComponent::return(DataFlowPrivate::MkNormalReturnKind()) + } + + Node argumentOf(Node call, SummaryComponent arg, boolean isPostUpdate) { + exists(ArgumentPosition apos, ParameterPosition ppos, Node argNode | + arg = argument(ppos) and + parameterMatch(ppos, apos) and + isArgumentNode(argNode, any(DataFlowCall c | c.asOrdinaryCall() = call), apos) + | + isPostUpdate = true and result = argNode.getPostUpdateNode() + or + isPostUpdate = false and result = argNode + ) + } + + Node parameterOf(Node callable, SummaryComponent param) { + exists(ArgumentPosition apos, ParameterPosition ppos, Function function | + param = parameter(apos) and + parameterMatch(ppos, apos) and + callable = function.flow() and + isParameterNode(result, any(DataFlowCallable c | c.asSourceCallable() = function), ppos) + ) + } + + Node returnOf(Node callable, SummaryComponent return) { + return = return() and + result = callable.(DataFlow::FunctionNode).getReturnNode() + } + + class SummarizedCallable instanceof SummarizedCallableImpl { + predicate propagatesFlow( + SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue + ) { + super.propagatesFlow(input, output, preservesValue, _) + } + + string toString() { result = super.toString() } + } + + Node callTo(SummarizedCallable callable) { + result = callable.(FlowSummary::SummarizedCallable).getACallSimple() + } +} + +import SummaryFlow From 6349903110238106549b8911bb6ee334474adcef Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 19 Nov 2024 14:57:59 +0100 Subject: [PATCH 365/514] JS: Move FlowSummary/Summaries.qll into testUtilities --- javascript/ql/test/library-tests/FlowSummary/test.ql | 2 +- .../Summaries.qll => testUtilities/InlineSummaries.qll} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename javascript/ql/test/{library-tests/FlowSummary/Summaries.qll => testUtilities/InlineSummaries.qll} (86%) diff --git a/javascript/ql/test/library-tests/FlowSummary/test.ql b/javascript/ql/test/library-tests/FlowSummary/test.ql index 3b300bbe19b..7d0d0db7ee2 100644 --- a/javascript/ql/test/library-tests/FlowSummary/test.ql +++ b/javascript/ql/test/library-tests/FlowSummary/test.ql @@ -1,6 +1,6 @@ import javascript import testUtilities.ConsistencyChecking -import Summaries +import testUtilities.InlineSummaries DataFlow::CallNode getACall(string name) { result.getCalleeName() = name diff --git a/javascript/ql/test/library-tests/FlowSummary/Summaries.qll b/javascript/ql/test/testUtilities/InlineSummaries.qll similarity index 86% rename from javascript/ql/test/library-tests/FlowSummary/Summaries.qll rename to javascript/ql/test/testUtilities/InlineSummaries.qll index e6037cb814b..559f1360977 100644 --- a/javascript/ql/test/library-tests/FlowSummary/Summaries.qll +++ b/javascript/ql/test/testUtilities/InlineSummaries.qll @@ -11,11 +11,11 @@ class MkSummary extends SummarizedCallable { mkSummary.getLocation().getStartLine() } - override DataFlow::InvokeNode getACall() { + override DataFlow::InvokeNode getACallSimple() { result = mkSummary.flow().(DataFlow::CallNode).getAnInvocation() } - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + override predicate propagatesFlow(string input, string output, boolean preservesValue) { preservesValue = true and ( // mkSummary(input, output) From 440cbb7f0aed6b373917c2efad61bb86a7c83abb Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 19 Nov 2024 15:16:53 +0100 Subject: [PATCH 366/514] JS: Add inline-expectation test for type tracking --- .../library-tests/TypeTracking2/summaries.js | 45 +++++++++++++++++++ .../library-tests/TypeTracking2/test.expected | 2 + .../test/library-tests/TypeTracking2/test.ql | 39 ++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 javascript/ql/test/library-tests/TypeTracking2/summaries.js create mode 100644 javascript/ql/test/library-tests/TypeTracking2/test.expected create mode 100644 javascript/ql/test/library-tests/TypeTracking2/test.ql diff --git a/javascript/ql/test/library-tests/TypeTracking2/summaries.js b/javascript/ql/test/library-tests/TypeTracking2/summaries.js new file mode 100644 index 00000000000..0223801fbaf --- /dev/null +++ b/javascript/ql/test/library-tests/TypeTracking2/summaries.js @@ -0,0 +1,45 @@ +function m0() { + const x = source("m0.1"); + sink(x); // $ track=m0.1 +} + +function m1() { + const fn = mkSummary("Argument[0]", "ReturnValue"); + const obj = source("m1.1"); + sink(fn(obj)); // $ MISSING: track=m1.1 + sink(fn(obj.p)); + sink(fn(obj).p); + sink(fn({ p: obj })); + sink(fn({ p: obj }).q); +} + +function m2() { + const fn = mkSummary("Argument[0].Member[p]", "ReturnValue"); + const obj = source("m2.1"); + sink(fn(obj)); + sink(fn(obj.p)); + sink(fn(obj).p); + sink(fn({ p: obj })); // $ MISSING: track=m2.1 + sink(fn({ p: obj }).q); +} + +function m3() { + const fn = mkSummary("Argument[0]", "ReturnValue.Member[p]"); + const obj = source("m3.1"); + sink(fn(obj)); + sink(fn(obj.p)); + sink(fn(obj).p); // $ MISSING: track=m3.1 + sink(fn({ p: obj })); + sink(fn({ p: obj }).q); +} + + +function m4() { + const fn = mkSummary("Argument[0].Member[p]", "ReturnValue.Member[q]"); + const obj = source("m4.1"); + sink(fn(obj)); + sink(fn(obj.p)); + sink(fn(obj).p); + sink(fn({ p: obj })); + sink(fn({ p: obj }).q); // $ MISSING: track=m4.1 +} diff --git a/javascript/ql/test/library-tests/TypeTracking2/test.expected b/javascript/ql/test/library-tests/TypeTracking2/test.expected new file mode 100644 index 00000000000..8ec8033d086 --- /dev/null +++ b/javascript/ql/test/library-tests/TypeTracking2/test.expected @@ -0,0 +1,2 @@ +testFailures +failures diff --git a/javascript/ql/test/library-tests/TypeTracking2/test.ql b/javascript/ql/test/library-tests/TypeTracking2/test.ql new file mode 100644 index 00000000000..dcc3ff1b57b --- /dev/null +++ b/javascript/ql/test/library-tests/TypeTracking2/test.ql @@ -0,0 +1,39 @@ +import javascript +import testUtilities.InlineSummaries +import testUtilities.InlineExpectationsTest + +private DataFlow::SourceNode typeTrack(DataFlow::TypeTracker t, string name) { + t.start() and + exists(DataFlow::CallNode call | + call.getCalleeName() = "source" and + name = call.getArgument(0).getStringValue() and + result = call + ) + or + exists(DataFlow::TypeTracker t2 | result = typeTrack(t2, name).track(t2, t)) +} + +DataFlow::SourceNode typeTrack(string name) { + result = typeTrack(DataFlow::TypeTracker::end(), name) +} + +module TestConfig implements TestSig { + string getARelevantTag() { result = "track" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + element = "" and + tag = "track" and + exists(DataFlow::CallNode call, DataFlow::Node arg | + call.getCalleeName() = "sink" and + arg = call.getArgument(0) and + typeTrack(value).flowsTo(arg) and + location = arg.getLocation() + ) + } + + predicate hasOptionalResult(Location location, string element, string tag, string value) { + none() + } +} + +import MakeTest From 2f0c80a98bb658ecb98b07e9f6a935dcc75f8ea0 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 19 Nov 2024 22:18:01 +0100 Subject: [PATCH 367/514] JS: Include summary steps in type tracking --- .../dataflow/internal/StepSummary.qll | 22 +++++++++++++++++++ .../library-tests/TypeTracking2/summaries.js | 8 +++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/StepSummary.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/StepSummary.qll index 435d4d82ed5..792fbbcc927 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/StepSummary.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/StepSummary.qll @@ -1,6 +1,7 @@ import javascript private import semmle.javascript.dataflow.TypeTracking private import semmle.javascript.internal.CachedStages +private import sharedlib.SummaryTypeTracker as SummaryTypeTracker private import FlowSteps cached @@ -46,6 +47,12 @@ private module Cached { LoadStoreStep(PropertyName fromProp, PropertyName toProp) { SharedTypeTrackingStep::loadStoreStep(_, _, fromProp, toProp) or + exists(DataFlow::ContentSet loadContent, DataFlow::ContentSet storeContent | + SummaryTypeTracker::basicLoadStoreStep(_, _, loadContent, storeContent) and + fromProp = loadContent.asPropertyName() and + toProp = storeContent.asPropertyName() + ) + or summarizedLoadStoreStep(_, _, fromProp, toProp) } or WithoutPropStep(PropertySet props) { SharedTypeTrackingStep::withoutPropStep(_, _, props) } @@ -205,6 +212,21 @@ private module Cached { succ = getACallbackSource(parameter).getParameter(i) and summary = ReturnStep() ) + or + SummaryTypeTracker::levelStepNoCall(pred, succ) and summary = LevelStep() + or + exists(DataFlow::ContentSet content | + SummaryTypeTracker::basicLoadStep(pred, succ, content) and + summary = LoadStep(content.asPropertyName()) + or + SummaryTypeTracker::basicStoreStep(pred, succ, content) and + summary = StoreStep(content.asPropertyName()) + ) + or + exists(DataFlow::ContentSet loadContent, DataFlow::ContentSet storeContent | + SummaryTypeTracker::basicLoadStoreStep(pred, succ, loadContent, storeContent) and + summary = LoadStoreStep(loadContent.asPropertyName(), storeContent.asPropertyName()) + ) } } diff --git a/javascript/ql/test/library-tests/TypeTracking2/summaries.js b/javascript/ql/test/library-tests/TypeTracking2/summaries.js index 0223801fbaf..416495a167e 100644 --- a/javascript/ql/test/library-tests/TypeTracking2/summaries.js +++ b/javascript/ql/test/library-tests/TypeTracking2/summaries.js @@ -6,7 +6,7 @@ function m0() { function m1() { const fn = mkSummary("Argument[0]", "ReturnValue"); const obj = source("m1.1"); - sink(fn(obj)); // $ MISSING: track=m1.1 + sink(fn(obj)); // $ track=m1.1 sink(fn(obj.p)); sink(fn(obj).p); sink(fn({ p: obj })); @@ -19,7 +19,7 @@ function m2() { sink(fn(obj)); sink(fn(obj.p)); sink(fn(obj).p); - sink(fn({ p: obj })); // $ MISSING: track=m2.1 + sink(fn({ p: obj })); // $ track=m2.1 sink(fn({ p: obj }).q); } @@ -28,7 +28,7 @@ function m3() { const obj = source("m3.1"); sink(fn(obj)); sink(fn(obj.p)); - sink(fn(obj).p); // $ MISSING: track=m3.1 + sink(fn(obj).p); // $ track=m3.1 sink(fn({ p: obj })); sink(fn({ p: obj }).q); } @@ -41,5 +41,5 @@ function m4() { sink(fn(obj.p)); sink(fn(obj).p); sink(fn({ p: obj })); - sink(fn({ p: obj }).q); // $ MISSING: track=m4.1 + sink(fn({ p: obj }).q); // $ track=m4.1 } From 9c6b6981e2722673d516a55297ac5c248a85bd5f Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 29 Nov 2024 10:45:10 +0100 Subject: [PATCH 368/514] JS: Add test to restrict dependencies --- .../DependencyRestriction.expected | 1 + .../TypeTracking2/DependencyRestriction.ql | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 javascript/ql/test/library-tests/TypeTracking2/DependencyRestriction.expected create mode 100644 javascript/ql/test/library-tests/TypeTracking2/DependencyRestriction.ql diff --git a/javascript/ql/test/library-tests/TypeTracking2/DependencyRestriction.expected b/javascript/ql/test/library-tests/TypeTracking2/DependencyRestriction.expected new file mode 100644 index 00000000000..e1481d55a80 --- /dev/null +++ b/javascript/ql/test/library-tests/TypeTracking2/DependencyRestriction.expected @@ -0,0 +1 @@ +| pass | diff --git a/javascript/ql/test/library-tests/TypeTracking2/DependencyRestriction.ql b/javascript/ql/test/library-tests/TypeTracking2/DependencyRestriction.ql new file mode 100644 index 00000000000..51ed46ac655 --- /dev/null +++ b/javascript/ql/test/library-tests/TypeTracking2/DependencyRestriction.ql @@ -0,0 +1,19 @@ +/** + * Test that fails with a compilation error if `getACallSimple` depends on the call graph. + * To do this, we add a negative dependency from the call graph to `getACallSimple`. + */ + +import javascript +import semmle.javascript.dataflow.internal.StepSummary +import semmle.javascript.dataflow.FlowSummary + +class NegativeDependency extends DataFlow::SharedTypeTrackingStep { + override predicate step(DataFlow::Node node1, DataFlow::Node node2) { + exists(SummarizedCallable callable | + not exists(callable.getACallSimple()) and + node1 = node2 + ) + } +} + +select "pass" From cab8a40d004ae5750e8dea397638b5b03c7a5d23 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 29 Nov 2024 11:01:19 +0100 Subject: [PATCH 369/514] JS: Fix accidental recursion --- .../internal/sharedlib/SummaryTypeTracker.qll | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/SummaryTypeTracker.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/SummaryTypeTracker.qll index 09d992dcea7..c9acd77db1a 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/SummaryTypeTracker.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/SummaryTypeTracker.qll @@ -30,10 +30,16 @@ private module SummaryFlowConfig implements Input { } Node argumentOf(Node call, SummaryComponent arg, boolean isPostUpdate) { + // Note: we cannot rely on DataFlowPrivate::DataFlowCall here because that depends on the call graph. exists(ArgumentPosition apos, ParameterPosition ppos, Node argNode | arg = argument(ppos) and parameterMatch(ppos, apos) and - isArgumentNode(argNode, any(DataFlowCall c | c.asOrdinaryCall() = call), apos) + ( + argNode = call.(DataFlow::InvokeNode).getArgument(apos.asPositional()) + or + apos.isThis() and + argNode = call.(DataFlow::CallNode).getReceiver() + ) | isPostUpdate = true and result = argNode.getPostUpdateNode() or @@ -42,11 +48,15 @@ private module SummaryFlowConfig implements Input { } Node parameterOf(Node callable, SummaryComponent param) { - exists(ArgumentPosition apos, ParameterPosition ppos, Function function | + exists(ArgumentPosition apos, ParameterPosition ppos, DataFlow::FunctionNode function | param = parameter(apos) and parameterMatch(ppos, apos) and - callable = function.flow() and - isParameterNode(result, any(DataFlowCallable c | c.asSourceCallable() = function), ppos) + callable = function + | + result = function.getParameter(ppos.asPositional()) + or + ppos.isThis() and + result = function.getReceiver() ) } From 32f020ee6faa57ba5160b3f69373c75f2050d2ba Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 11:55:26 +0100 Subject: [PATCH 370/514] JS: Port tutorial query1 --- .../Global data flow/query1.ql | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query1.ql b/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query1.ql index 68828b0005d..3d0ed69b89d 100644 --- a/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query1.ql +++ b/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query1.ql @@ -1,17 +1,17 @@ import javascript -class CommandLineFileNameConfiguration extends TaintTracking::Configuration { - CommandLineFileNameConfiguration() { this = "CommandLineFileNameConfiguration" } - - override predicate isSource(DataFlow::Node source) { +module CommandLineFileNameConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { DataFlow::globalVarRef("process").getAPropertyRead("argv").getAPropertyRead() = source } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { DataFlow::moduleMember("fs", "readFile").getACall().getArgument(0) = sink } } -from CommandLineFileNameConfiguration cfg, DataFlow::Node source, DataFlow::Node sink -where cfg.hasFlow(source, sink) +module CommandLineFileNameFlow = TaintTracking::Global; + +from DataFlow::Node source, DataFlow::Node sink +where CommandLineFileNameFlow::flow(source, sink) select source, sink From 3319870d0035b85eacf2ba9725f91add9e5c80ae Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 11:56:44 +0100 Subject: [PATCH 371/514] JS: Port tutorial query2 --- .../Global data flow/query2.ql | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query2.ql b/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query2.ql index f94ae08309f..d436670a7ab 100644 --- a/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query2.ql +++ b/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query2.ql @@ -1,21 +1,19 @@ import javascript -class CommandLineFileNameConfiguration extends TaintTracking::Configuration { - CommandLineFileNameConfiguration() { this = "CommandLineFileNameConfiguration" } - - override predicate isSource(DataFlow::Node source) { +module CommandLineFileNameConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { DataFlow::globalVarRef("process").getAPropertyRead("argv").getAPropertyRead() = source } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { DataFlow::moduleMember("fs", "readFile").getACall().getArgument(0) = sink } - override predicate isSanitizer(DataFlow::Node nd) { - nd.(DataFlow::CallNode).getCalleeName() = "checkPath" - } + predicate isBarrier(DataFlow::Node nd) { nd.(DataFlow::CallNode).getCalleeName() = "checkPath" } } -from CommandLineFileNameConfiguration cfg, DataFlow::Node source, DataFlow::Node sink -where cfg.hasFlow(source, sink) +module CommandLineFileNameFlow = TaintTracking::Global; + +from DataFlow::Node source, DataFlow::Node sink +where CommandLineFileNameFlow::flow(source, sink) select source, sink From 1f6335f9ba42c309c65e84c82d253c998ed0ff87 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 11:58:27 +0100 Subject: [PATCH 372/514] JS: Port tutorial query3 --- .../Global data flow/query3.ql | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query3.ql b/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query3.ql index 54855983a84..70a490ead45 100644 --- a/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query3.ql +++ b/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query3.ql @@ -1,30 +1,30 @@ import javascript -class CheckPathSanitizerGuard extends TaintTracking::SanitizerGuardNode, DataFlow::CallNode { +class CheckPathSanitizerGuard extends DataFlow::CallNode { CheckPathSanitizerGuard() { this.getCalleeName() = "checkPath" } - override predicate sanitizes(boolean outcome, Expr e) { + predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = this.getArgument(0).asExpr() } } -class CommandLineFileNameConfiguration extends TaintTracking::Configuration { - CommandLineFileNameConfiguration() { this = "CommandLineFileNameConfiguration" } - - override predicate isSource(DataFlow::Node source) { +module CommandLineFileNameConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { DataFlow::globalVarRef("process").getAPropertyRead("argv").getAPropertyRead() = source } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { DataFlow::moduleMember("fs", "readFile").getACall().getArgument(0) = sink } - override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode nd) { - nd instanceof CheckPathSanitizerGuard + predicate isBarrier(DataFlow::Node node) { + node = DataFlow::MakeBarrierGuard::getABarrierNode() } } -from CommandLineFileNameConfiguration cfg, DataFlow::Node source, DataFlow::Node sink -where cfg.hasFlow(source, sink) +module CommandLineFileNameFlow = TaintTracking::Global; + +from DataFlow::Node source, DataFlow::Node sink +where CommandLineFileNameFlow::flow(source, sink) select source, sink From 02c5e49de8d084d6c977f958726332feeab2cad1 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 11:59:45 +0100 Subject: [PATCH 373/514] JS: Port tutorial query4 --- .../Global data flow/query4.ql | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query4.ql b/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query4.ql index 3a224bab804..dff069d72e2 100644 --- a/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query4.ql +++ b/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query4.ql @@ -1,17 +1,15 @@ import javascript -class CommandLineFileNameConfiguration extends TaintTracking::Configuration { - CommandLineFileNameConfiguration() { this = "CommandLineFileNameConfiguration" } - - override predicate isSource(DataFlow::Node source) { +module CommandLineFileNameConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { DataFlow::globalVarRef("process").getAPropertyRead("argv").getAPropertyRead() = source } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { DataFlow::moduleMember("fs", "readFile").getACall().getArgument(0) = sink } - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { exists(DataFlow::CallNode c | c = DataFlow::moduleImport("resolve-symlinks").getACall() and pred = c.getArgument(0) and @@ -20,6 +18,8 @@ class CommandLineFileNameConfiguration extends TaintTracking::Configuration { } } -from CommandLineFileNameConfiguration cfg, DataFlow::Node source, DataFlow::Node sink -where cfg.hasFlow(source, sink) +module CommandLineFileNameFlow = TaintTracking::Global; + +from DataFlow::Node source, DataFlow::Node sink +where CommandLineFileNameFlow::flow(source, sink) select source, sink From 103a6ea8a69d6921245ee0f14059040c2b75bcc1 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 12:02:15 +0100 Subject: [PATCH 374/514] JS: Port tutorial query5 --- .../Global data flow/query5.ql | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query5.ql b/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query5.ql index 6d9261b9786..8f88190a3ff 100644 --- a/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query5.ql +++ b/javascript/ql/test/tutorials/Analyzing data flow in JavaScript/Global data flow/query5.ql @@ -10,18 +10,18 @@ class StepThroughResolveSymlinks extends TaintTracking::SharedTaintStep { } } -class CommandLineFileNameConfiguration extends TaintTracking::Configuration { - CommandLineFileNameConfiguration() { this = "CommandLineFileNameConfiguration" } - - override predicate isSource(DataFlow::Node source) { +module CommandLineFileNameConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { DataFlow::globalVarRef("process").getAPropertyRead("argv").getAPropertyRead() = source } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { DataFlow::moduleMember("fs", "readFile").getACall().getArgument(0) = sink } } -from CommandLineFileNameConfiguration cfg, DataFlow::Node source, DataFlow::Node sink -where cfg.hasFlow(source, sink) +module CommandLineFileNameFlow = TaintTracking::Global; + +from DataFlow::Node source, DataFlow::Node sink +where CommandLineFileNameFlow::flow(source, sink) select source, sink From 2722c45737bcade9c420c0329a33184e29dffbff Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 13:13:58 +0100 Subject: [PATCH 375/514] JS: Update global data flow tutorial .rst file --- ...data-flow-in-javascript-and-typescript.rst | 127 ++++++++---------- 1 file changed, 57 insertions(+), 70 deletions(-) diff --git a/docs/codeql/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript.rst b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript.rst index 1dfcd0b713b..55c8d4dc3a8 100644 --- a/docs/codeql/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript.rst +++ b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript.rst @@ -204,58 +204,45 @@ data flow solver that can check whether there is (global) data flow from a sourc Optionally, configurations may specify extra data flow edges to be added to the data flow graph, and may also specify `barriers`. Barriers are data flow nodes or edges through which data should not be tracked for the purposes of this analysis. -To define a configuration, extend the class ``DataFlow::Configuration`` as follows: +To define a configuration, add a module that implements the signature ``DataFlow::ConfigSig`` and pass it to ``DataFlow::Global`` as follows: .. code-block:: ql - class MyDataFlowConfiguration extends DataFlow::Configuration { - MyDataFlowConfiguration() { this = "MyDataFlowConfiguration" } + module MyAnalysisConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { /* ... */ } - override predicate isSource(DataFlow::Node source) { /* ... */ } + predicate isSink(DataFlow::Node sink) { /* ... */ } - override predicate isSink(DataFlow::Node sink) { /* ... */ } - - // optional overrides: - override predicate isBarrier(DataFlow::Node nd) { /* ... */ } - override predicate isBarrierEdge(DataFlow::Node pred, DataFlow::Node succ) { /* ... */ } - override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { /* ... */ } + // optional predicates: + predicate isBarrier(DataFlow::Node nd) { /* ... */ } + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { /* ... */ } } -The characteristic predicate ``MyDataFlowConfiguration()`` defines the name of the configuration, so ``"MyDataFlowConfiguration"`` should be replaced by a suitable -name describing your particular analysis configuration. + module MyAnalysisFlow = DataFlow::Global -The data flow analysis is performed using the predicate ``hasFlow(source, sink)``: +The data flow analysis is performed using the predicate ``MyAnalysisFlow::flow(source, sink)``: .. code-block:: ql - from MyDataFlowConfiguration dataflow, DataFlow::Node source, DataFlow::Node sink - where dataflow.hasFlow(source, sink) + from DataFlow::Node source, DataFlow::Node sink + where MyAnalysisFlow::flow(source, sink) select source, "Data flow from $@ to $@.", source, source.toString(), sink, sink.toString() Using global taint tracking ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Global taint tracking extends global data flow with additional non-value-preserving steps, such as flow through string-manipulating operations. To use it, simply extend -``TaintTracking::Configuration`` instead of ``DataFlow::Configuration``: +Global taint tracking extends global data flow with additional non-value-preserving steps, such as flow through string-manipulating operations. To use it, simply +use ``TaintTracking::Global<...>`` instead of ``DataFlow::Global<...>``: .. code-block:: ql - class MyTaintTrackingConfiguration extends TaintTracking::Configuration { - MyTaintTrackingConfiguration() { this = "MyTaintTrackingConfiguration" } - - override predicate isSource(DataFlow::Node source) { /* ... */ } - - override predicate isSink(DataFlow::Node sink) { /* ... */ } + module MyAnalysisConfig implements DataFlow::ConfigSig { + /* ... */ } -Analogous to ``isAdditionalFlowStep``, there is a predicate ``isAdditionalTaintStep`` that you can override to specify custom flow steps to consider in the analysis. -Instead of the ``isBarrier`` and ``isBarrierEdge`` predicates, the taint tracking configuration includes ``isSanitizer`` and ``isSanitizerEdge`` predicates that specify -data flow nodes or edges that act as taint sanitizers and hence stop flow from a source to a sink. + module MyAnalysisFlow = TaintTracking::Global -Similar to global data flow, the characteristic predicate ``MyTaintTrackingConfiguration()`` defines the unique name of the configuration, so ``"MyTaintTrackingConfiguration"`` -should be replaced by an appropriate descriptive name. - -The taint tracking analysis is again performed using the predicate ``hasFlow(source, sink)``. +The taint tracking analysis is again performed using the predicate ``MyAnalysisFlow::flow(source, sink)``. Examples ~~~~~~~~ @@ -267,20 +254,20 @@ time using global taint tracking. import javascript - class CommandLineFileNameConfiguration extends TaintTracking::Configuration { - CommandLineFileNameConfiguration() { this = "CommandLineFileNameConfiguration" } - - override predicate isSource(DataFlow::Node source) { + module CommandLineFileNameConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { DataFlow::globalVarRef("process").getAPropertyRead("argv").getAPropertyRead() = source } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { DataFlow::moduleMember("fs", "readFile").getACall().getArgument(0) = sink } } - from CommandLineFileNameConfiguration cfg, DataFlow::Node source, DataFlow::Node sink - where cfg.hasFlow(source, sink) + module CommandLineFileNameFlow = TaintTracking::Global; + + from DataFlow::Node source, DataFlow::Node sink + where CommandLineFileNameFlow::flow(source, sink) select source, sink This query will now find flows that involve inter-procedural steps, like in the following example (where the individual steps have been marked with comments @@ -325,15 +312,15 @@ with an error if it does not. We could then use that function in ``readFileHelpe } For the purposes of our above analysis, ``checkPath`` is a `sanitizer`: its output is always untainted, even if its input is tainted. To model this -we can add an override of ``isSanitizer`` to our taint-tracking configuration like this: +we can add an ``isBarrier`` predicate to our taint-tracking configuration like this: .. code-block:: ql - class CommandLineFileNameConfiguration extends TaintTracking::Configuration { + module CommandLineFileNameConfig implements DataFlow::ConfigSig { // ... - override predicate isSanitizer(DataFlow::Node nd) { + predicate isBarrier(DataFlow::Node nd) { nd.(DataFlow::CallNode).getCalleeName() = "checkPath" } } @@ -359,36 +346,36 @@ Note that ``checkPath`` is now no longer a sanitizer in the sense described abov through ``checkPath`` any more. The flow is, however, `guarded` by ``checkPath`` in the sense that the expression ``checkPath(p)`` has to evaluate to ``true`` (or, more precisely, to a truthy value) in order for the flow to happen. -Such sanitizer guards can be supported by defining a new subclass of ``TaintTracking::SanitizerGuardNode`` and overriding the predicate -``isSanitizerGuard`` in the taint-tracking configuration class to add all instances of this class as sanitizer guards to the configuration. +Such sanitizer guards can be supported by defining a class with a ``blocksExpr`` predicate and using the `DataFlow::MakeBarrierGuard`` module +to implement the ``isBarrier`` predicate. -For our above example, we would begin by defining a subclass of ``SanitizerGuardNode`` that identifies guards of the form ``checkPath(...)``: +For our above example, we would begin by defining a subclass of ``DataFlow::CallNode`` that identifies guards of the form ``checkPath(...)``: .. code-block:: ql - class CheckPathSanitizerGuard extends TaintTracking::SanitizerGuardNode, DataFlow::CallNode { + class CheckPathSanitizerGuard extends DataFlow::CallNode { CheckPathSanitizerGuard() { this.getCalleeName() = "checkPath" } - override predicate sanitizes(boolean outcome, Expr e) { + predicate blocksExpr(boolean outcome, Expr e) { outcome = true and - e = getArgument(0).asExpr() + e = this.getArgument(0).asExpr() } } -The characteristic predicate of this class checks that the sanitizer guard is a call to a function named ``checkPath``. The overriding definition -of ``sanitizes`` says such a call sanitizes its first argument (that is, ``getArgument(0)``) if it evaluates to ``true`` (or rather, a truthy +The characteristic predicate of this class checks that the sanitizer guard is a call to a function named ``checkPath``. The definition +of ``blocksExpr`` says such a call sanitizes its first argument (that is, ``getArgument(0)``) if it evaluates to ``true`` (or rather, a truthy value). -Now we can override ``isSanitizerGuard`` to add these sanitizer guards to our configuration: +Now we can implement ``isBarrier`` to add this sanitizer guards to our configuration: .. code-block:: ql - class CommandLineFileNameConfiguration extends TaintTracking::Configuration { + module CommandLineFileNameConfig implements DataFlow::ConfigSig { // ... - override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode nd) { - nd instanceof CheckPathSanitizerGuard + predicate isBarrier(DataFlow::Node node) { + node = DataFlow::MakeBarrierGuard::getABarrierNode() } } @@ -399,7 +386,7 @@ reach there if ``checkPath(p)`` evaluates to a truthy value. Consequently, there Additional taint steps ~~~~~~~~~~~~~~~~~~~~~~ -Sometimes the default data flow and taint steps provided by ``DataFlow::Configuration`` and ``TaintTracking::Configuration`` are not sufficient +Sometimes the default data flow and taint steps provided by the data flow library are not sufficient and we need to add additional flow or taint steps to our configuration to make it find the expected flow. For example, this can happen because the analyzed program uses a function from an external library whose source code is not available to the analysis, or because it uses a function that is too difficult to analyze. @@ -420,16 +407,16 @@ to resolve any symlinks in the path ``p`` before passing it to ``readFile``: Resolving symlinks does not make an unsafe path any safer, so we would still like our query to flag this, but since the standard library does not have a model of ``resolve-symlinks`` it will no longer return any results. -We can fix this quite easily by adding an overriding definition of the ``isAdditionalTaintStep`` predicate to our configuration, introducing an +We can fix this quite easily by adding a definition of the ``isAdditionalFlowStep`` predicate to our configuration, introducing an additional taint step from the first argument of ``resolveSymlinks`` to its result: .. code-block:: ql - class CommandLineFileNameConfiguration extends TaintTracking::Configuration { + module CommandLineFileNameConfig implements DataFlow::ConfigSig { // ... - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { exists(DataFlow::CallNode c | c = DataFlow::moduleImport("resolve-symlinks").getACall() and pred = c.getArgument(0) and @@ -494,18 +481,18 @@ Exercise 2 import javascript - class HardCodedTagNameConfiguration extends DataFlow::Configuration { - HardCodedTagNameConfiguration() { this = "HardCodedTagNameConfiguration" } + module HardCodedTagNameConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr() instanceof ConstantString } - override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof ConstantString } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink = DataFlow::globalVarRef("document").getAMethodCall("createElement").getArgument(0) } } - from HardCodedTagNameConfiguration cfg, DataFlow::Node source, DataFlow::Node sink - where cfg.hasFlow(source, sink) + module HardCodedTagNameFlow = DataFlow::Global; + + from DataFlow::Node source, DataFlow::Node sink + where HardCodedTagNameFlow::flow(source, sink) select source, sink Exercise 3 @@ -540,18 +527,18 @@ Exercise 4 } } - class HardCodedTagNameConfiguration extends DataFlow::Configuration { - HardCodedTagNameConfiguration() { this = "HardCodedTagNameConfiguration" } + module HardCodedTagNameConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof ArrayEntryCallResult } - override predicate isSource(DataFlow::Node source) { source instanceof ArrayEntryCallResult } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink = DataFlow::globalVarRef("document").getAMethodCall("createElement").getArgument(0) } } - from HardCodedTagNameConfiguration cfg, DataFlow::Node source, DataFlow::Node sink - where cfg.hasFlow(source, sink) + module HardCodedTagNameFlow = DataFlow::Global; + + from DataFlow::Node source, DataFlow::Node sink + where HardCodedTagNameFlow::flow(source, sink) select source, sink Further reading From 2db89c1b0295828262aa5d9d5382bb79d146b713 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 29 Nov 2024 09:47:34 +0100 Subject: [PATCH 376/514] JS: Update query17 from intro tutorial --- .../codeql-library-for-javascript.rst | 45 +++++++------------ .../query17.qll | 25 +++++------ 2 files changed, 28 insertions(+), 42 deletions(-) diff --git a/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst index 6742dfa8e76..d39da11411a 100644 --- a/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst @@ -700,19 +700,16 @@ The data flow graph-based analyses described so far are all intraprocedural: the We distinguish here between data flow proper, and *taint tracking*: the latter not only considers value-preserving flow (such as from variable definitions to uses), but also cases where one value influences ("taints") another without determining it entirely. For example, in the assignment ``s2 = s1.substring(i)``, the value of ``s1`` influences the value of ``s2``, because ``s2`` is assigned a substring of ``s1``. In general, ``s2`` will not be assigned ``s1`` itself, so there is no data flow from ``s1`` to ``s2``, but ``s1`` still taints ``s2``. -It is a common pattern that we wish to specify data flow or taint analysis in terms of its *sources* (where flow starts), *sinks* (where it should be tracked), and *barriers* or *sanitizers* (where flow is interrupted). Sanitizers they are very common in security analyses: for example, an analysis that tracks the flow of untrusted user input into, say, a SQL query has to keep track of code that validates the input, thereby making it safe to use. Such a validation step is an example of a sanitizer. +It is a common pattern that we wish to specify data flow or taint analysis in terms of its *sources* (where flow starts), *sinks* (where it should be tracked), and *barriers* (also called *sanitizers*) where flow is interrupted. Sanitizers they are very common in security analyses: for example, an analysis that tracks the flow of untrusted user input into, say, a SQL query has to keep track of code that validates the input, thereby making it safe to use. Such a validation step is an example of a sanitizer. -The classes ``DataFlow::Configuration`` and ``TaintTracking::Configuration`` allow specifying a data flow or taint analysis, respectively, by overriding the following predicates: +A module implementing the signature `DataFlow::ConfigSig` may specify a data flow or taint analysis by implementing the following predicates: - ``isSource(DataFlow::Node nd)`` selects all nodes ``nd`` from where flow tracking starts. - ``isSink(DataFlow::Node nd)`` selects all nodes ``nd`` to which the flow is tracked. -- ``isBarrier(DataFlow::Node nd)`` selects all nodes ``nd`` that act as a barrier for data flow; ``isSanitizer`` is the corresponding predicate for taint tracking configurations. -- ``isBarrierEdge(DataFlow::Node src, DataFlow::Node trg)`` is a variant of ``isBarrier(nd)`` that allows specifying barrier *edges* in addition to barrier nodes; again, ``isSanitizerEdge`` is the corresponding predicate for taint tracking; +- ``isBarrier(DataFlow::Node nd)`` selects all nodes ``nd`` that act as a barrier/sanitizer for data flow. - ``isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg)`` allows specifying custom additional flow steps for this analysis; ``isAdditionalTaintStep`` is the corresponding predicate for taint tracking configurations. -Since for technical reasons both ``Configuration`` classes are subtypes of ``string``, you have to choose a unique name for each flow configuration and equate ``this`` with it in the characteristic predicate (as in the example below). - -The predicate ``Configuration.hasFlow`` performs the actual flow tracking, starting at a source and looking for flow to a sink that does not pass through a barrier node or edge. +Such a module can be passed to ``DataFlow::Global<...>``. This will produce a module with a ``flow`` predicate that performs the actual flow tracking, starting at a source and looking for flow to a sink that does not pass through a barrier node. For example, suppose that we are developing an analysis to find hard-coded passwords. We might write a simple query that looks for string constants flowing into variables named ``"password"``. @@ -720,35 +717,27 @@ For example, suppose that we are developing an analysis to find hard-coded passw import javascript - class PasswordTracker extends DataFlow::Configuration { - PasswordTracker() { - // unique identifier for this configuration - this = "PasswordTracker" - } + module PasswordConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node nd) { nd.asExpr() instanceof StringLiteral } - override predicate isSource(DataFlow::Node nd) { - nd.asExpr() instanceof StringLiteral - } - - override predicate isSink(DataFlow::Node nd) { - passwordVarAssign(_, nd) - } - - predicate passwordVarAssign(Variable v, DataFlow::Node nd) { - v.getAnAssignedExpr() = nd.asExpr() and - v.getName().toLowerCase() = "password" - } + predicate isSink(DataFlow::Node nd) { passwordVarAssign(_, nd) } } -Now we can rephrase our query to use ``Configuration.hasFlow``: + predicate passwordVarAssign(Variable v, DataFlow::Node nd) { + v.getAnAssignedExpr() = nd.asExpr() and + v.getName().toLowerCase() = "password" + } + + module PasswordFlow = DataFlow::Global; + +Now we can rephrase our query to use ``PasswordFlow::flow``: .. code-block:: ql - from PasswordTracker pt, DataFlow::Node source, DataFlow::Node sink, Variable v - where pt.hasFlow(source, sink) and pt.passwordVarAssign(v, sink) + from DataFlow::Node source, DataFlow::Node sink, Variable v + where PasswordFlow::flow(_, sink) and passwordVarAssign(v, sink) select sink, "Password variable " + v + " is assigned a constant string." - Syntax errors ~~~~~~~~~~~~~ diff --git a/javascript/ql/test/tutorials/Introducing the JavaScript libraries/query17.qll b/javascript/ql/test/tutorials/Introducing the JavaScript libraries/query17.qll index 1de380f710b..e6dff623e97 100644 --- a/javascript/ql/test/tutorials/Introducing the JavaScript libraries/query17.qll +++ b/javascript/ql/test/tutorials/Introducing the JavaScript libraries/query17.qll @@ -1,23 +1,20 @@ import javascript -class PasswordTracker extends DataFlow::Configuration { - PasswordTracker() { - // unique identifier for this configuration - this = "PasswordTracker" - } +module PasswordConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node nd) { nd.asExpr() instanceof StringLiteral } - override predicate isSource(DataFlow::Node nd) { nd.asExpr() instanceof StringLiteral } - - override predicate isSink(DataFlow::Node nd) { this.passwordVarAssign(_, nd) } - - predicate passwordVarAssign(Variable v, DataFlow::Node nd) { - v.getAnAssignedExpr() = nd.asExpr() and - v.getName().toLowerCase() = "password" - } + predicate isSink(DataFlow::Node nd) { passwordVarAssign(_, nd) } } +predicate passwordVarAssign(Variable v, DataFlow::Node nd) { + v.getAnAssignedExpr() = nd.asExpr() and + v.getName().toLowerCase() = "password" +} + +module PasswordFlow = DataFlow::Global; + query predicate test_query17(DataFlow::Node sink, string res) { - exists(PasswordTracker pt, Variable v | pt.hasFlow(_, sink) and pt.passwordVarAssign(v, sink) | + exists(Variable v | PasswordFlow::flow(_, sink) and passwordVarAssign(v, sink) | res = "Password variable " + v.toString() + " is assigned a constant string." ) } From 628f60d2e3afb70dec6594e4285cf30ec896cdf2 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 29 Nov 2024 15:08:34 +0100 Subject: [PATCH 377/514] JS: Update flow label tutorial --- ...-labels-for-precise-data-flow-analysis.rst | 254 ++++++++---------- 1 file changed, 116 insertions(+), 138 deletions(-) diff --git a/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst index 8e5d3c4285b..2dece8cdf28 100644 --- a/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst +++ b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst @@ -1,9 +1,9 @@ .. _using-flow-labels-for-precise-data-flow-analysis: -Using flow labels for precise data flow analysis +Using flow state for precise data flow analysis ================================================ -You can associate flow labels with each value tracked by the flow analysis to determine whether the flow contains potential vulnerabilities. +You can associate a flow state with each value tracked by the flow analysis to determine whether the flow contains potential vulnerabilities. Overview -------- @@ -16,9 +16,9 @@ program, and associates a flag with every data value telling us whether it might source node. In some cases, you may want to track more detailed information about data values. This can be done -by associating flow labels with data values, as shown in this tutorial. We will first discuss the -general idea behind flow labels and then show how to use them in practice. Finally, we will give an -overview of the API involved and provide some pointers to standard queries that use flow labels. +by associating flow states with data values, as shown in this tutorial. We will first discuss the +general idea behind flow states and then show how to use them in practice. Finally, we will give an +overview of the API involved and provide some pointers to standard queries that use flow states. Limitations of basic data-flow analysis --------------------------------------- @@ -47,22 +47,21 @@ contain ``..`` components. Untrusted user input has both bits set initially, ind off individual bits, and if a value that has at least one bit set is interpreted as a path, a potential vulnerability is flagged. -Using flow labels +Using flow states ----------------- -You can handle these cases and others like them by associating a set of `flow labels` (sometimes -also referred to as `taint kinds`) with each value being tracked by the analysis. Value-preserving +You can handle these cases and others like them by associating a set of `flow states` (sometimes +also referred to as `flow labels` or `taint kinds`) with each value being tracked by the analysis. Value-preserving data-flow steps (such as flow steps from writes to a variable to its reads) preserve the set of flow -labels, but other steps may add or remove flow labels. Sanitizers, in particular, are simply flow -steps that remove some or all flow labels. The initial set of flow labels for a value is determined +states, but other steps may add or remove flow states. The initial set of flow states for a value is determined by the source node that gives rise to it. Similarly, sink nodes can specify that an incoming value -needs to have a certain flow label (or one of a set of flow labels) in order for the flow to be +needs to have a certain flow state (or one of a set of flow states) in order for the flow to be flagged as a potential vulnerability. Example ------- -As an example of using flow labels, we will show how to write a query that flags property accesses +As an example of using flow state, we will show how to write a query that flags property accesses on JSON values that come from user-controlled input where we have not checked whether the value is ``null``, so that the property access may cause a runtime exception. @@ -88,8 +87,8 @@ This code, on the other hand, should not be flagged: } } -We will first try to write a query to find this kind of problem without flow labels, and use the -difficulties we encounter as a motivation for bringing flow labels into play, which will make the +We will first try to write a query to find this kind of problem without flow state, and use the +difficulties we encounter as a motivation for bringing flow state into play, which will make the query much easier to implement. To get started, let's write a query that simply flags any flow from ``JSON.parse`` into the base of @@ -99,24 +98,24 @@ a property access: import javascript - class JsonTrackingConfig extends DataFlow::Configuration { - JsonTrackingConfig() { this = "JsonTrackingConfig" } - - override predicate isSource(DataFlow::Node nd) { + module JsonTrackingConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node nd) { exists(JsonParserCall jpc | nd = jpc.getOutput() ) } - override predicate isSink(DataFlow::Node nd) { + predicate isSink(DataFlow::Node nd) { exists(DataFlow::PropRef pr | nd = pr.getBase() ) } } - from JsonTrackingConfig cfg, DataFlow::Node source, DataFlow::Node sink - where cfg.hasFlow(source, sink) + module JsonTrackingFlow = DataFlow::Global; + + from DataFlow::Node source, DataFlow::Node sink + where JsonTrackingFlow::flow(source, sink) select sink, "Property access on JSON value originating $@.", source, "here" Note that we use the ``JsonParserCall`` class from the standard library to model various JSON @@ -139,29 +138,29 @@ is a barrier guard blocking flow through the use of ``data`` on the right-hand s At this point we know that ``data`` has evaluated to a truthy value, so it cannot be ``null`` anymore. -Implementing this additional condition is easy. We implement a subclass of ``DataFlow::BarrierGuardNode``: +Implementing this additional condition is easy. We implement a class with a predicate called ``blocksExpr``: .. code-block:: ql - class TruthinessCheck extends DataFlow::BarrierGuardNode, DataFlow::ValueNode { + class TruthinessCheck extends DataFlow::Node, DataFlow::ValueNode { SsaVariable v; TruthinessCheck() { astNode = v.getAUse() } - override predicate blocks(boolean outcome, Expr e) { + predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = astNode } } -and then use it to override predicate ``isBarrierGuard`` in our configuration class: +and then use it to implement the predicate ``isBarrier`` in our configuration module: .. code-block:: ql - override predicate isBarrierGuard(DataFlow::BarrierGuardNode guard) { - guard instanceof TruthinessCheck + predicate isBarrier(DataFlow::Node node) { + node = DataFlow::MakeBarrierGuard::getABarrierNode() } With this change, we now flag the problematic case and don't flag the unproblematic case above. @@ -182,11 +181,11 @@ checked for null-guardedness: } } -We could try to remedy the situation by overriding ``isAdditionalFlowStep`` in our configuration class to track values through property reads: +We could try to remedy the situation by adding ``isAdditionalFlowStep`` in our configuration module to track values through property reads: .. code-block:: ql - override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { succ.(DataFlow::PropRead).getBase() = pred } @@ -199,79 +198,86 @@ altogether, it should simply record the fact that ``root`` itself is known to be Any property read from ``root``, on the other hand, may well be null and needs to be checked separately. -We can achieve this by introducing two different flow labels, ``json`` and ``maybe-null``. The former +We can achieve this by introducing two different flow states, ``json`` and ``maybe-null``. The former means that the value we are dealing with comes from a JSON object, the latter that it may be -``null``. The result of any call to ``JSON.parse`` has both labels. A property read from a value -with label ``json`` also has both labels. Checking truthiness removes the ``maybe-null`` label. -Accessing a property on a value that has the ``maybe-null`` label should be flagged. +``null``. The result of any call to ``JSON.parse`` has both states. A property read from a value +with state ``json`` also results in a value with both states. Checking truthiness removes the ``maybe-null`` state. +Accessing a property on a value that has the ``maybe-null`` state should be flagged. -To implement this, we start by defining two new subclasses of the class ``DataFlow::FlowLabel``: +To implement this, we first change the signature of our configuration module to ``DataFlow::StateConfigSig``, and +replace ``DataFlow::Global<...>`` with ``DataFlow::GlobalWithState<...>``: .. code-block:: ql - class JsonLabel extends DataFlow::FlowLabel { - JsonLabel() { - this = "json" - } + module JsonTrackingConfig implements DataFlow::StateConfigSig { + /* ... */ } - class MaybeNullLabel extends DataFlow::FlowLabel { - MaybeNullLabel() { - this = "maybe-null" - } - } + module JsonTrackingFlow = DataFlow::GlobalWithState; -Then we extend our ``isSource`` predicate from above to track flow labels by overriding the two-argument version instead of the one-argument version: +We then add a class called ``FlowState`` which has one value for each flow state: .. code-block:: ql - override predicate isSource(DataFlow::Node nd, DataFlow::FlowLabel lbl) { + module JsonTrackingConfig implements DataFlow::StateConfigSig { + class FlowState extends string { + FlowState() { + this = ["json", "maybe-null"] + } + } + + /* ... */ + } + +Then we extend our ``isSource`` predicate with an additional parameter to specify the flow state: + +.. code-block:: ql + + predicate isSource(DataFlow::Node nd, FlowState state) { exists(JsonParserCall jpc | nd = jpc.getOutput() and - (lbl instanceof JsonLabel or lbl instanceof MaybeNullLabel) + state = ["json", "maybe-null"] // start in either state ) } -Similarly, we make ``isSink`` flow-label aware and require the base of the property read to have the ``maybe-null`` label: +Similarly, we update ``isSink`` and require the base of the property read to have the ``maybe-null`` state: .. code-block:: ql - override predicate isSink(DataFlow::Node nd, DataFlow::FlowLabel lbl) { + predicate isSink(DataFlow::Node nd, FlowState state) { exists(DataFlow::PropRef pr | nd = pr.getBase() and - lbl instanceof MaybeNullLabel + state = "maybe-null" ) } -Our overriding definition of ``isAdditionalFlowStep`` now needs to specify two flow labels, a -predecessor label ``predlbl`` and a successor label ``succlbl``. In addition to specifying flow from -the predecessor node ``pred`` to the successor node ``succ``, it requires that ``pred`` has label -``predlbl``, and adds label ``succlbl`` to ``succ``. In our case, we use this to add both the -``json`` label and the ``maybe-null`` label to any property read from a value labeled with ``json`` -(no matter whether it has the ``maybe-null`` label): +Our definition of ``isAdditionalFlowStep`` now needs to specify two flow state, a +predecessor state ``predState`` and a successor state ``succState``. In addition to specifying flow from +the predecessor node ``pred`` to the successor node ``succ``, it requires that ``pred`` has state +``state1``, and adds state ``succState`` to ``succ``. In our case, we use this to add both the +``json`` state and the ``maybe-null`` state to any property read from a value in the ``json`` state +(no matter whether it has the ``maybe-null`` state): .. code-block:: ql - override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ, - DataFlow::FlowLabel predlbl, DataFlow::FlowLabel succlbl) { + predicate isAdditionalFlowStep(DataFlow::Node pred, FlowState predState, + DataFlow::Node succ, FlowState succState) { succ.(DataFlow::PropRead).getBase() = pred and - predlbl instanceof JsonLabel and - (succlbl instanceof JsonLabel or succlbl instanceof MaybeNullLabel) + predState = "json" and + succState = ["json", "maybe-null"] } -Finally, we turn ``TruthinessCheck`` from a ``BarrierGuardNode`` into a ``LabeledBarrierGuardNode``, -specifying that it only removes the ``maybe-null`` label (but not the ``json`` label) from the -sanitized value: +Finally, we add an additional parameter to the ``isBarrier`` predicate to specify the flow state +to block at the ``TruthinessCheck`` barrier. .. code-block:: ql - class TruthinessCheck extends DataFlow::LabeledBarrierGuardNode, DataFlow::ValueNode { - ... + module JsonTrackingConfig implements DataFlow::StateConfigSig { + /* ... */ - override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { - outcome = true and - e = astNode and - lbl instanceof MaybeNullLabel + predicate isBarrier(DataFlow::Node node, FlowState state) { + node = DataFlow::MakeBarrierGuard::getABarrierNode() and + state = "maybe-null" } } @@ -283,66 +289,60 @@ step by step in the UI: /** @kind path-problem */ import javascript - import DataFlow::PathGraph - class JsonLabel extends DataFlow::FlowLabel { - JsonLabel() { - this = "json" - } - } - - class MaybeNullLabel extends DataFlow::FlowLabel { - MaybeNullLabel() { - this = "maybe-null" - } - } - - class TruthinessCheck extends DataFlow::LabeledBarrierGuardNode, DataFlow::ValueNode { + class TruthinessCheck extends DataFlow::Node, DataFlow::ValueNode { SsaVariable v; TruthinessCheck() { astNode = v.getAUse() } - override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { + predicate blocksExpr(boolean outcome, Expr e, JsonTrackingConfig::FlowState state) { outcome = true and e = astNode and - lbl instanceof MaybeNullLabel + state = "maybe-null" } } - class JsonTrackingConfig extends DataFlow::Configuration { - JsonTrackingConfig() { this = "JsonTrackingConfig" } + module JsonTrackingConfig implements DataFlow::StateConfigSig { + class FlowState extends string { + FlowState() { + this = ["json", "maybe-null"] + } + } - override predicate isSource(DataFlow::Node nd, DataFlow::FlowLabel lbl) { + predicate isSource(DataFlow::Node nd, FlowState state) { exists(JsonParserCall jpc | nd = jpc.getOutput() and - (lbl instanceof JsonLabel or lbl instanceof MaybeNullLabel) + state = ["json", "maybe-null"] // start in either state ) } - override predicate isSink(DataFlow::Node nd, DataFlow::FlowLabel lbl) { + predicate isSink(DataFlow::Node nd, FlowState state) { exists(DataFlow::PropRef pr | nd = pr.getBase() and - lbl instanceof MaybeNullLabel + state = "maybe-null" ) } - override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ, - DataFlow::FlowLabel predlbl, DataFlow::FlowLabel succlbl) { + predicate isAdditionalFlowStep(DataFlow::Node pred, FlowState predState, + DataFlow::Node succ, FlowState succState) { succ.(DataFlow::PropRead).getBase() = pred and - predlbl instanceof JsonLabel and - (succlbl instanceof JsonLabel or succlbl instanceof MaybeNullLabel) + predState = "json" and + succState = ["json", "maybe-null"] } - override predicate isBarrierGuard(DataFlow::BarrierGuardNode guard) { - guard instanceof TruthinessCheck + predicate isBarrier(DataFlow::Node node, FlowState state) { + node = DataFlow::MakeBarrierGuard::getABarrierNode() and + state = "maybe-null" } } - from JsonTrackingConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink - where cfg.hasFlowPath(source, sink) - select sink, source, sink, "Property access on JSON value originating $@.", source, "here" + module JsonTrackingFlow = DataFlow::GlobalWithState; + + from DataFlow::Node source, DataFlow::Node sink + where JsonTrackingFlow::flow(source, sink) + select sink, "Property access on JSON value originating $@.", source, "here" We ran this query on the https://github.com/finos/plexus-interop repository. Many of the results were false positives since the query does not currently model many ways in which we can check @@ -354,52 +354,30 @@ this tutorial. API --- -Plain data-flow configurations implicitly use a single flow label "data", which indicates that a -data value originated from a source. You can use the predicate ``DataFlow::FlowLabel::data()``, -which returns this flow label, as a symbolic name for it. +Flow state can be used in modules implementing the ``DataFlow::StateConfigSig`` signature. Compared to a ``DataFlow::ConfigSig`` the main differences are: -Taint-tracking configurations add a second flow label "taint" (``DataFlow::FlowLabel::taint()``), -which is similar to "data", but includes values that have passed through non-value preserving steps -such as string operations. +- The module must be passed to ``DataFlow::GlobalWithState<...>`` or ``TaintTracking::GlobalWithState<...>``. + instead of ``DataFlow::Global<...>`` or ``TaintTracking::Global<...>``. +- The module must contain a type named ``FlowState``. +- ``isSource`` expects an additional parameter specifying the flow state. +- ``isSink`` optionally can take an additional parameter specifying the flow state. + If omitted, the sinks are in effect for all flow states. +- ``isAdditionalFlowStep`` optionally can take two additional parameters specifying the predecessor and successor flow states. + If omitted, the generated steps apply for any flow state and preserve the current flow state. +- ``isBarrier`` optionally can take an additional parameter specifying the flow state to block. + If omitted, the barriers block all flow states. -Each of the three member predicates ``isSource``, ``isSink`` and -``isAdditionalFlowStep``/``isAdditionalTaintStep`` has one version that uses the default flow -labels, and one version that allows specifying custom flow labels through additional arguments. - -For ``isSource``, there is one additional argument specifying which flow label(s) should be -associated with values originating from this source. If multiple flow labels are specified, each -value is associated with `all` of them. - -For ``isSink``, the additional argument specifies which flow label(s) a value that flows into this -source may be associated with. If multiple flow labels are specified, then any value that is -associated with `at least one` of them will be considered by the configuration. - -For ``isAdditionalFlowStep`` there are two additional arguments ``predlbl`` and ``succlbl``, which -allow flow steps to act as flow label transformers. If a value associated with ``predlbl`` arrives -at the start node of the additional step, it is propagated to the end node and associated with -``succlbl``. Of course, ``predlbl`` and ``succlbl`` may be the same, indicating that the flow step -preserves this label. There can also be multiple values of ``succlbl`` for a single ``predlbl`` or -vice versa. - -Note that if you do not restrict ``succlbl`` then it will be allowed to range over all flow labels. -This may cause labels that were previously blocked on a path to reappear, which is not usually what -you want. - -The flow label-aware version of ``isBarrier`` is called ``isLabeledBarrier``: unlike ``isBarrier``, -which prevents any flow past the given node, it only blocks flow of values associated with one of -the specified flow labels. - -Standard queries using flow labels +Standard queries using flow state ---------------------------------- -Some of our standard security queries use flow labels. You can look at their implementation -to get a feeling for how to use flow labels in practice. +Some of our standard security queries use flow state. You can look at their implementation +to get a feeling for how to use flow state in practice. In particular, both of the examples mentioned in the section on limitations of basic data flow above -are from standard security queries that use flow labels. The `Prototype-polluting merge call -`_ query uses two flow labels to distinguish completely +are from standard security queries that use flow state. The `Prototype-polluting merge call +`_ query uses two flow states to distinguish completely tainted objects from partially tainted objects. The `Uncontrolled data used in path expression -`_ query uses four flow labels to track whether a user-controlled +`_ query uses four flow states to track whether a user-controlled string may be an absolute path and whether it may contain ``..`` components. Further reading From 422c089a39fb474caf57f414e229462b41eacf24 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 2 Dec 2024 13:26:37 +0100 Subject: [PATCH 378/514] JS: Remove redundant base class in TruthinessCheck --- .../using-flow-labels-for-precise-data-flow-analysis.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst index 2dece8cdf28..149a1244df7 100644 --- a/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst +++ b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst @@ -142,7 +142,7 @@ Implementing this additional condition is easy. We implement a class with a pred .. code-block:: ql - class TruthinessCheck extends DataFlow::Node, DataFlow::ValueNode { + class TruthinessCheck extends DataFlow::ValueNode { SsaVariable v; TruthinessCheck() { @@ -290,7 +290,7 @@ step by step in the UI: import javascript - class TruthinessCheck extends DataFlow::Node, DataFlow::ValueNode { + class TruthinessCheck extends DataFlow::ValueNode { SsaVariable v; TruthinessCheck() { From 404b0f24f25755b91d4221c3af4a5de661a2e083 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 2 Dec 2024 13:29:52 +0100 Subject: [PATCH 379/514] JS: Fix another stray reference to BarrierGuardNode/SanitizerGuardNode --- .../using-flow-labels-for-precise-data-flow-analysis.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst index 149a1244df7..2fb5896f645 100644 --- a/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst +++ b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst @@ -126,8 +126,7 @@ introduced any sanitizers yet. There are many ways of checking for nullness directly or indirectly. Since this is not the main focus of this tutorial, we will only show how to model one specific case: if some variable ``v`` is -known to be truthy, it cannot be ``null``. This kind of condition is easily expressed using a -``BarrierGuardNode`` (or its counterpart ``SanitizerGuardNode`` for taint-tracking configurations). +known to be truthy, it cannot be ``null``. This kind of condition is expressed using a "barrier guard". A barrier guard node is a data-flow node ``b`` that blocks flow through some other node ``nd``, provided that some condition checked at ``b`` is known to hold, that is, evaluate to a truthy value. From 8bca66493f0c0bd95450ca788f8d65315c2c52d3 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Dec 2024 09:57:02 +0100 Subject: [PATCH 380/514] JS: Add test showing lack of inclusion in PropertyName --- .../ql/test/library-tests/TypeTracking2/summaries.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/javascript/ql/test/library-tests/TypeTracking2/summaries.js b/javascript/ql/test/library-tests/TypeTracking2/summaries.js index 416495a167e..7c0f31e3607 100644 --- a/javascript/ql/test/library-tests/TypeTracking2/summaries.js +++ b/javascript/ql/test/library-tests/TypeTracking2/summaries.js @@ -43,3 +43,13 @@ function m4() { sink(fn({ p: obj })); sink(fn({ p: obj }).q); // $ track=m4.1 } + +function m5() { + // Store and read to a property that isn't mentioned anywhere in the source code. + const store = mkSummary("Argument[0]", "ReturnValue.Member[propOnlyMentionedInSummary]"); + const read = mkSummary("Argument[0].Member[propOnlyMentionedInSummary]", "ReturnValue"); + sink(read(store(source("m5.1")))); // $ MISSING: track=m5.1 + sink(read(source("m5.1"))); + sink(store(source("m5.1"))); + sink(store(read(source("m5.1")))); +} From 054558d7b564515bc479ea7a5596681308bf725a Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Dec 2024 09:58:54 +0100 Subject: [PATCH 381/514] JS: Include content properties in type-tracker properties Reminder: we have two PropertyName classes because the one in Contents.qll can't depend on DataFlow::Node. --- .../ql/lib/semmle/javascript/dataflow/internal/StepSummary.qll | 3 +++ javascript/ql/test/library-tests/TypeTracking2/summaries.js | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/StepSummary.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/StepSummary.qll index 792fbbcc927..2bcd89130a9 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/StepSummary.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/StepSummary.qll @@ -1,6 +1,7 @@ import javascript private import semmle.javascript.dataflow.TypeTracking private import semmle.javascript.internal.CachedStages +private import semmle.javascript.dataflow.internal.Contents as Contents private import sharedlib.SummaryTypeTracker as SummaryTypeTracker private import FlowSteps @@ -30,6 +31,8 @@ private module Cached { SharedTypeTrackingStep::loadStoreStep(_, _, _, this) or this = DataFlow::PseudoProperties::arrayLikeElement() + or + this instanceof Contents::Private::PropertyName } } diff --git a/javascript/ql/test/library-tests/TypeTracking2/summaries.js b/javascript/ql/test/library-tests/TypeTracking2/summaries.js index 7c0f31e3607..1550ded19f4 100644 --- a/javascript/ql/test/library-tests/TypeTracking2/summaries.js +++ b/javascript/ql/test/library-tests/TypeTracking2/summaries.js @@ -48,7 +48,7 @@ function m5() { // Store and read to a property that isn't mentioned anywhere in the source code. const store = mkSummary("Argument[0]", "ReturnValue.Member[propOnlyMentionedInSummary]"); const read = mkSummary("Argument[0].Member[propOnlyMentionedInSummary]", "ReturnValue"); - sink(read(store(source("m5.1")))); // $ MISSING: track=m5.1 + sink(read(store(source("m5.1")))); // $ track=m5.1 sink(read(source("m5.1"))); sink(store(source("m5.1"))); sink(store(read(source("m5.1")))); From 5e272574053adc13e1702a84347ab72eb855cf15 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Dec 2024 11:49:22 +0100 Subject: [PATCH 382/514] Update docs/codeql/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript.rst Co-authored-by: Erik Krogh Kristensen --- .../analyzing-data-flow-in-javascript-and-typescript.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript.rst b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript.rst index 55c8d4dc3a8..44da0912d4a 100644 --- a/docs/codeql/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript.rst +++ b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript.rst @@ -366,7 +366,7 @@ The characteristic predicate of this class checks that the sanitizer guard is a of ``blocksExpr`` says such a call sanitizes its first argument (that is, ``getArgument(0)``) if it evaluates to ``true`` (or rather, a truthy value). -Now we can implement ``isBarrier`` to add this sanitizer guards to our configuration: +Now we can implement ``isBarrier`` to add this sanitizer guard to our configuration: .. code-block:: ql From 89849fae87365dc836d75dd380714f9ec0d63b7f Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Dec 2024 11:49:34 +0100 Subject: [PATCH 383/514] Update docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst Co-authored-by: Erik Krogh Kristensen --- .../using-flow-labels-for-precise-data-flow-analysis.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst index 2fb5896f645..aa40f32fcf0 100644 --- a/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst +++ b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst @@ -250,7 +250,7 @@ Similarly, we update ``isSink`` and require the base of the property read to hav ) } -Our definition of ``isAdditionalFlowStep`` now needs to specify two flow state, a +Our definition of ``isAdditionalFlowStep`` now needs to specify two flow states, a predecessor state ``predState`` and a successor state ``succState``. In addition to specifying flow from the predecessor node ``pred`` to the successor node ``succ``, it requires that ``pred`` has state ``state1``, and adds state ``succState`` to ``succ``. In our case, we use this to add both the From 935e1c065a1ca9bd6be57cc70f5d2b532bed4a68 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Dec 2024 11:49:45 +0100 Subject: [PATCH 384/514] Update docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst Co-authored-by: Erik Krogh Kristensen --- .../using-flow-labels-for-precise-data-flow-analysis.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst index aa40f32fcf0..e85132bf3d9 100644 --- a/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst +++ b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst @@ -253,7 +253,7 @@ Similarly, we update ``isSink`` and require the base of the property read to hav Our definition of ``isAdditionalFlowStep`` now needs to specify two flow states, a predecessor state ``predState`` and a successor state ``succState``. In addition to specifying flow from the predecessor node ``pred`` to the successor node ``succ``, it requires that ``pred`` has state -``state1``, and adds state ``succState`` to ``succ``. In our case, we use this to add both the +``predState``, and adds state ``succState`` to ``succ``. In our case, we use this to add both the ``json`` state and the ``maybe-null`` state to any property read from a value in the ``json`` state (no matter whether it has the ``maybe-null`` state): From 89463d73f5c4490fce41129e1a6a677ec3e83478 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Dec 2024 11:51:46 +0100 Subject: [PATCH 385/514] JS: Remove mention of isAdditionalTaintStep --- .../codeql-language-guides/codeql-library-for-javascript.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst index d39da11411a..aeaf68aeee4 100644 --- a/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst @@ -707,7 +707,7 @@ A module implementing the signature `DataFlow::ConfigSig` may specify a data flo - ``isSource(DataFlow::Node nd)`` selects all nodes ``nd`` from where flow tracking starts. - ``isSink(DataFlow::Node nd)`` selects all nodes ``nd`` to which the flow is tracked. - ``isBarrier(DataFlow::Node nd)`` selects all nodes ``nd`` that act as a barrier/sanitizer for data flow. -- ``isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg)`` allows specifying custom additional flow steps for this analysis; ``isAdditionalTaintStep`` is the corresponding predicate for taint tracking configurations. +- ``isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg)`` allows specifying custom additional flow steps for this analysis. Such a module can be passed to ``DataFlow::Global<...>``. This will produce a module with a ``flow`` predicate that performs the actual flow tracking, starting at a source and looking for flow to a sink that does not pass through a barrier node. From 27e61a1f3d74156769714b8b2ec7c46219726a5f Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 3 Dec 2024 12:00:30 +0100 Subject: [PATCH 386/514] JS: Also update cheat sheet --- .../data-flow-cheat-sheet-for-javascript.rst | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/codeql/codeql-language-guides/data-flow-cheat-sheet-for-javascript.rst b/docs/codeql/codeql-language-guides/data-flow-cheat-sheet-for-javascript.rst index 60d66ba1644..9ac89996d40 100644 --- a/docs/codeql/codeql-language-guides/data-flow-cheat-sheet-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/data-flow-cheat-sheet-for-javascript.rst @@ -16,18 +16,17 @@ Use the following template to create a taint tracking path query: * @kind path-problem */ import javascript - import DataFlow - import DataFlow::PathGraph - class MyConfig extends TaintTracking::Configuration { - MyConfig() { this = "MyConfig" } - override predicate isSource(Node node) { ... } - override predicate isSink(Node node) { ... } - override predicate isAdditionalTaintStep(Node pred, Node succ) { ... } + module MyConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { ... } + predicate isSink(DataFlow::Node node) { ... } + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { ... } } - from MyConfig cfg, PathNode source, PathNode sink - where cfg.hasFlowPath(source, sink) + module MyFlow = TaintTracking::Global; + + from MyFlow::PathNode source, MyFlow::PathNode sink + where MyFlow::flowPath(source, sink) select sink.getNode(), source, sink, "taint from $@.", source.getNode(), "here" This query reports flow paths which: From 0cd2e3f9eb4660032f3dccb074c4b479fca2fec2 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 6 Nov 2024 11:34:56 +0100 Subject: [PATCH 387/514] JS: Deprecate old data flow library, except some guard-related nodes --- .../javascript/dataflow/Configuration.qll | 200 ++++++++++-------- .../javascript/dataflow/TaintTracking.qll | 28 +-- .../dataflow/internal/BarrierGuards.qll | 6 +- .../dataflow/internal/FlowSteps.qll | 2 +- .../internal/TaintTrackingPrivate.qll | 12 +- .../javascript/internal/CachedStages.qll | 4 +- 6 files changed, 142 insertions(+), 110 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index 3d62ca33a66..a9bc65cc0bc 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -85,7 +85,7 @@ private import AdditionalFlowSteps * define additional edges beyond the standard data flow edges (`isAdditionalFlowStep`) * and prohibit intermediate flow nodes and edges (`isBarrier`). */ -abstract class Configuration extends string { +abstract deprecated class Configuration extends string { bindingset[this] Configuration() { any() } @@ -281,7 +281,9 @@ abstract class Configuration extends string { * `isBarrierGuard` or `AdditionalBarrierGuardNode`. */ pragma[nomagic] -private predicate isBarrierGuardInternal(Configuration cfg, BarrierGuardNodeInternal guard) { +deprecated private predicate isBarrierGuardInternal( + Configuration cfg, BarrierGuardNodeInternal guard +) { cfg.isBarrierGuard(guard) or guard.(AdditionalBarrierGuardNode).appliesTo(cfg) @@ -330,12 +332,12 @@ abstract class FlowLabel extends string { * * This is an alias of `FlowLabel`, so the two types can be used interchangeably. */ -class TaintKind = FlowLabel; +deprecated class TaintKind = FlowLabel; /** * A standard flow label, that is, either `FlowLabel::data()` or `FlowLabel::taint()`. */ -class StandardFlowLabel extends FlowLabel { +deprecated class StandardFlowLabel extends FlowLabel { StandardFlowLabel() { this = "data" or this = "taint" } } @@ -366,6 +368,7 @@ abstract private class BarrierGuardNodeInternal extends DataFlow::Node { } * implementations of `blocks` will _both_ apply to any configuration that includes either of them. */ abstract class BarrierGuardNode extends BarrierGuardNodeInternal { + // TODO: deprecate this class; currently requires too much refactoring /** * Holds if this node blocks expression `e` provided it evaluates to `outcome`. * @@ -382,8 +385,8 @@ abstract class BarrierGuardNode extends BarrierGuardNodeInternal { /** * Barrier guards derived from other barrier guards. */ -abstract private class DerivedBarrierGuardNode extends BarrierGuardNodeInternal { - abstract predicate appliesTo(Configuration cfg); +abstract deprecated private class DerivedBarrierGuardNode extends BarrierGuardNodeInternal { + abstract deprecated predicate appliesTo(Configuration cfg); /** * Holds if this node blocks expression `e` from flow of type `label`, provided it evaluates to `outcome`. @@ -396,7 +399,7 @@ abstract private class DerivedBarrierGuardNode extends BarrierGuardNodeInternal /** * Barrier guards derived from `AdditionalSanitizerGuard` */ -private class BarrierGuardNodeFromAdditionalSanitizerGuard extends BarrierGuardNodeInternal instanceof TaintTracking::AdditionalSanitizerGuardNode +deprecated private class BarrierGuardNodeFromAdditionalSanitizerGuard extends BarrierGuardNodeInternal instanceof TaintTracking::AdditionalSanitizerGuardNode { } /** @@ -405,7 +408,7 @@ private class BarrierGuardNodeFromAdditionalSanitizerGuard extends BarrierGuardN * `label` is bound to the blocked label, or the empty string if all labels should be blocked. */ pragma[nomagic] -private predicate barrierGuardBlocksExpr( +deprecated private predicate barrierGuardBlocksExpr( BarrierGuardNodeInternal guard, boolean outcome, Expr test, string label ) { guard.(BarrierGuardNode).blocks(outcome, test) and label = "" @@ -423,7 +426,7 @@ private predicate barrierGuardBlocksExpr( * Holds if `guard` may block the flow of a value reachable through exploratory flow. */ pragma[nomagic] -private predicate barrierGuardIsRelevant(BarrierGuardNodeInternal guard) { +deprecated private predicate barrierGuardIsRelevant(BarrierGuardNodeInternal guard) { exists(Expr e | barrierGuardBlocksExpr(guard, _, e, _) and isRelevantForward(e.flow(), _) @@ -437,7 +440,7 @@ private predicate barrierGuardIsRelevant(BarrierGuardNodeInternal guard) { * `label` is bound to the blocked label, or the empty string if all labels should be blocked. */ pragma[nomagic] -private predicate barrierGuardBlocksAccessPath( +deprecated private predicate barrierGuardBlocksAccessPath( BarrierGuardNodeInternal guard, boolean outcome, AccessPath ap, string label ) { barrierGuardIsRelevant(guard) and @@ -450,7 +453,7 @@ private predicate barrierGuardBlocksAccessPath( * This predicate is outlined to give the optimizer a hint about the join ordering. */ pragma[nomagic] -private predicate barrierGuardBlocksSsaRefinement( +deprecated private predicate barrierGuardBlocksSsaRefinement( BarrierGuardNodeInternal guard, boolean outcome, SsaRefinementNode ref, string label ) { barrierGuardIsRelevant(guard) and @@ -466,7 +469,7 @@ private predicate barrierGuardBlocksSsaRefinement( * `outcome` is bound to the outcome of `cond` for join-ordering purposes. */ pragma[nomagic] -private predicate barrierGuardUsedInCondition( +deprecated private predicate barrierGuardUsedInCondition( BarrierGuardNodeInternal guard, ConditionGuardNode cond, boolean outcome ) { barrierGuardIsRelevant(guard) and @@ -485,7 +488,7 @@ private predicate barrierGuardUsedInCondition( * `label` is bound to the blocked label, or the empty string if all labels should be blocked. */ pragma[nomagic] -private predicate barrierGuardBlocksNode( +deprecated private predicate barrierGuardBlocksNode( BarrierGuardNodeInternal guard, DataFlow::Node nd, string label ) { // 1) `nd` is a use of a refinement node that blocks its input variable @@ -510,7 +513,7 @@ private predicate barrierGuardBlocksNode( * `label` is bound to the blocked label, or the empty string if all labels should be blocked. */ pragma[nomagic] -private predicate barrierGuardBlocksEdge( +deprecated private predicate barrierGuardBlocksEdge( BarrierGuardNodeInternal guard, DataFlow::Node pred, DataFlow::Node succ, string label ) { exists( @@ -531,7 +534,9 @@ private predicate barrierGuardBlocksEdge( * This predicate exists to get a better join-order for the `barrierGuardBlocksEdge` predicate above. */ pragma[noinline] -private BasicBlock getADominatedBasicBlock(BarrierGuardNodeInternal guard, ConditionGuardNode cond) { +deprecated private BasicBlock getADominatedBasicBlock( + BarrierGuardNodeInternal guard, ConditionGuardNode cond +) { barrierGuardIsRelevant(guard) and guard.getEnclosingExpr() = cond.getTest() and cond.dominates(result) @@ -543,7 +548,9 @@ private BasicBlock getADominatedBasicBlock(BarrierGuardNodeInternal guard, Condi * * Only holds for barriers that should apply to all flow labels. */ -private predicate isBarrierEdgeRaw(Configuration cfg, DataFlow::Node pred, DataFlow::Node succ) { +deprecated private predicate isBarrierEdgeRaw( + Configuration cfg, DataFlow::Node pred, DataFlow::Node succ +) { cfg.isBarrierEdge(pred, succ) or exists(BarrierGuardNodeInternal guard | @@ -559,7 +566,9 @@ private predicate isBarrierEdgeRaw(Configuration cfg, DataFlow::Node pred, DataF * Only holds for barriers that should apply to all flow labels. */ pragma[inline] -private predicate isBarrierEdge(Configuration cfg, DataFlow::Node pred, DataFlow::Node succ) { +deprecated private predicate isBarrierEdge( + Configuration cfg, DataFlow::Node pred, DataFlow::Node succ +) { isBarrierEdgeRaw(cfg, pred, succ) or cfg.isBarrierOut(pred) @@ -571,7 +580,7 @@ private predicate isBarrierEdge(Configuration cfg, DataFlow::Node pred, DataFlow * Holds if there is a labeled barrier edge `pred -> succ` in `cfg` either through an explicit barrier edge * or one implied by a barrier guard. */ -private predicate isLabeledBarrierEdgeRaw( +deprecated private predicate isLabeledBarrierEdgeRaw( Configuration cfg, DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel label ) { cfg.isBarrierEdge(pred, succ, label) @@ -587,7 +596,7 @@ private predicate isLabeledBarrierEdgeRaw( * or one implied by a barrier guard, or by an out/in barrier for `pred` or `succ`, respectively. */ pragma[inline] -private predicate isLabeledBarrierEdge( +deprecated private predicate isLabeledBarrierEdge( Configuration cfg, DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel label ) { isLabeledBarrierEdgeRaw(cfg, pred, succ, label) @@ -600,7 +609,7 @@ private predicate isLabeledBarrierEdge( /** * A guard node that only blocks specific labels. */ -abstract class LabeledBarrierGuardNode extends BarrierGuardNode { +abstract deprecated class LabeledBarrierGuardNode extends BarrierGuardNode { override predicate blocks(boolean outcome, Expr e) { none() } } @@ -699,7 +708,7 @@ module PseudoProperties { * A data flow node that should be considered a source for some specific configuration, * in addition to any other sources that configuration may recognize. */ -abstract class AdditionalSource extends DataFlow::Node { +abstract deprecated class AdditionalSource extends DataFlow::Node { /** * Holds if this data flow node should be considered a source node for * configuration `cfg`. @@ -717,7 +726,7 @@ abstract class AdditionalSource extends DataFlow::Node { * A data flow node that should be considered a sink for some specific configuration, * in addition to any other sinks that configuration may recognize. */ -abstract class AdditionalSink extends DataFlow::Node { +abstract deprecated class AdditionalSink extends DataFlow::Node { /** * Holds if this data flow node should be considered a sink node for * configuration `cfg`. @@ -751,7 +760,7 @@ private class FlowStepThroughImport extends SharedFlowStep { * Summary steps through function calls are not taken into account. */ pragma[inline] -private predicate basicFlowStepNoBarrier( +deprecated private predicate basicFlowStepNoBarrier( DataFlow::Node pred, DataFlow::Node succ, PathSummary summary, DataFlow::Configuration cfg ) { // Local flow @@ -790,7 +799,7 @@ private predicate basicFlowStepNoBarrier( * and hence should only be used for purposes of approximation. */ pragma[noinline] -private predicate exploratoryFlowStep( +deprecated private predicate exploratoryFlowStep( DataFlow::Node pred, DataFlow::Node succ, DataFlow::Configuration cfg ) { isRelevantForward(pred, cfg) and @@ -809,7 +818,7 @@ private predicate exploratoryFlowStep( /** * Holds if `nd` is a source node for configuration `cfg`. */ -private predicate isSource(DataFlow::Node nd, DataFlow::Configuration cfg, FlowLabel lbl) { +deprecated private predicate isSource(DataFlow::Node nd, DataFlow::Configuration cfg, FlowLabel lbl) { (cfg.isSource(nd) or nd.(AdditionalSource).isSourceFor(cfg)) and lbl = cfg.getDefaultSourceLabel() or @@ -821,7 +830,7 @@ private predicate isSource(DataFlow::Node nd, DataFlow::Configuration cfg, FlowL /** * Holds if `nd` is a sink node for configuration `cfg`. */ -private predicate isSink(DataFlow::Node nd, DataFlow::Configuration cfg, FlowLabel lbl) { +deprecated private predicate isSink(DataFlow::Node nd, DataFlow::Configuration cfg, FlowLabel lbl) { (cfg.isSink(nd) or nd.(AdditionalSink).isSinkFor(cfg)) and lbl = any(StandardFlowLabel f) or @@ -834,7 +843,7 @@ private predicate isSink(DataFlow::Node nd, DataFlow::Configuration cfg, FlowLab * Holds if there exists a load-step from `pred` to `succ` under configuration `cfg`, * and the forwards exploratory flow has found a relevant store-step with the same property as the load-step. */ -private predicate exploratoryLoadStep( +deprecated private predicate exploratoryLoadStep( DataFlow::Node pred, DataFlow::Node succ, DataFlow::Configuration cfg ) { exists(string prop | prop = getAForwardRelevantLoadProperty(cfg) | @@ -851,7 +860,7 @@ private predicate exploratoryLoadStep( * This private predicate is only used in `exploratoryLoadStep`, and exists as a separate predicate to give the compiler a hint about join-ordering. */ pragma[noinline] -private string getAForwardRelevantLoadProperty(DataFlow::Configuration cfg) { +deprecated private string getAForwardRelevantLoadProperty(DataFlow::Configuration cfg) { exists(DataFlow::Node previous | isRelevantForward(previous, cfg) | basicStoreStep(previous, _, result) or isAdditionalStoreStep(previous, _, result, cfg) @@ -865,7 +874,7 @@ private string getAForwardRelevantLoadProperty(DataFlow::Configuration cfg) { * * The properties from this predicate are used as a white-list of properties for load/store steps that should always be considered in the exploratory flow. */ -private string getAPropertyUsedInLoadStore(DataFlow::Configuration cfg) { +deprecated private string getAPropertyUsedInLoadStore(DataFlow::Configuration cfg) { exists(string loadProp, string storeProp | isAdditionalLoadStoreStep(_, _, loadProp, storeProp, cfg) and storeProp != loadProp and @@ -878,7 +887,7 @@ private string getAPropertyUsedInLoadStore(DataFlow::Configuration cfg) { * and somewhere in the program there exists a load-step that could possibly read the stored value. */ pragma[noinline] -private predicate exploratoryForwardStoreStep( +deprecated private predicate exploratoryForwardStoreStep( DataFlow::Node pred, DataFlow::Node succ, DataFlow::Configuration cfg ) { exists(string prop | @@ -896,7 +905,7 @@ private predicate exploratoryForwardStoreStep( * and `succ` has been found to be relevant during the backwards exploratory flow, * and the backwards exploratory flow has found a relevant load-step with the same property as the store-step. */ -private predicate exploratoryBackwardStoreStep( +deprecated private predicate exploratoryBackwardStoreStep( DataFlow::Node pred, DataFlow::Node succ, DataFlow::Configuration cfg ) { exists(string prop | prop = getABackwardsRelevantStoreProperty(cfg) | @@ -912,7 +921,7 @@ private predicate exploratoryBackwardStoreStep( * This private predicate is only used in `exploratoryBackwardStoreStep`, and exists as a separate predicate to give the compiler a hint about join-ordering. */ pragma[noinline] -private string getABackwardsRelevantStoreProperty(DataFlow::Configuration cfg) { +deprecated private string getABackwardsRelevantStoreProperty(DataFlow::Configuration cfg) { exists(DataFlow::Node mid | isRelevant(mid, cfg) | basicLoadStep(mid, _, result) or isAdditionalLoadStep(mid, _, result, cfg) @@ -926,7 +935,7 @@ private string getABackwardsRelevantStoreProperty(DataFlow::Configuration cfg) { * * No call/return matching is done, so this is a relatively coarse over-approximation. */ -private predicate isRelevantForward(DataFlow::Node nd, DataFlow::Configuration cfg) { +deprecated private predicate isRelevantForward(DataFlow::Node nd, DataFlow::Configuration cfg) { isSource(nd, cfg, _) and isLive() or exists(DataFlow::Node mid | @@ -942,7 +951,7 @@ private predicate isRelevantForward(DataFlow::Node nd, DataFlow::Configuration c * * No call/return matching is done, so this is a relatively coarse over-approximation. */ -private predicate isRelevant(DataFlow::Node nd, DataFlow::Configuration cfg) { +deprecated private predicate isRelevant(DataFlow::Node nd, DataFlow::Configuration cfg) { isRelevantForward(nd, cfg) and isSink(nd, cfg, _) or exists(DataFlow::Node mid | isRelevant(mid, cfg) | isRelevantBackStep(mid, nd, cfg)) @@ -951,7 +960,7 @@ private predicate isRelevant(DataFlow::Node nd, DataFlow::Configuration cfg) { /** * Holds if there is backwards data-flow step from `mid` to `nd` under `cfg`. */ -private predicate isRelevantBackStep( +deprecated private predicate isRelevantBackStep( DataFlow::Node mid, DataFlow::Node nd, DataFlow::Configuration cfg ) { exploratoryFlowStep(nd, mid, cfg) @@ -965,7 +974,7 @@ private predicate isRelevantBackStep( * either `pred` is an argument of `f` and `succ` the corresponding parameter, or * `pred` is a variable definition whose value is captured by `f` at `succ`. */ -private predicate callInputStep( +deprecated private predicate callInputStep( Function f, DataFlow::Node invk, DataFlow::Node pred, DataFlow::Node succ, DataFlow::Configuration cfg ) { @@ -995,7 +1004,7 @@ private predicate callInputStep( * into account. */ pragma[nomagic] -private predicate reachableFromInput( +deprecated private predicate reachableFromInput( Function f, DataFlow::Node invk, DataFlow::Node input, DataFlow::Node nd, DataFlow::Configuration cfg, PathSummary summary ) { @@ -1014,7 +1023,7 @@ private predicate reachableFromInput( * to a path represented by `oldSummary` yielding a path represented by `newSummary`. */ pragma[noinline] -private predicate appendStep( +deprecated private predicate appendStep( DataFlow::Node pred, DataFlow::Configuration cfg, PathSummary oldSummary, DataFlow::Node succ, PathSummary newSummary ) { @@ -1030,7 +1039,7 @@ private predicate appendStep( * which is either an argument or a definition captured by the function, flows under * configuration `cfg`, possibly through callees. */ -private predicate flowThroughCall( +deprecated private predicate flowThroughCall( DataFlow::Node input, DataFlow::Node output, DataFlow::Configuration cfg, PathSummary summary ) { exists(Function f, DataFlow::FunctionReturnNode ret | @@ -1076,7 +1085,7 @@ private predicate flowThroughCall( * along a path summarized by `summary`. */ pragma[nomagic] -private predicate storeStep( +deprecated private predicate storeStep( DataFlow::Node pred, DataFlow::Node succ, string prop, DataFlow::Configuration cfg, PathSummary summary ) { @@ -1114,7 +1123,7 @@ private predicate storeStep( /** * Gets a dataflow-node for the operand of the await-expression `await`. */ -private DataFlow::Node getAwaitOperand(DataFlow::Node await) { +deprecated private DataFlow::Node getAwaitOperand(DataFlow::Node await) { exists(AwaitExpr awaitExpr | result = awaitExpr.getOperand().getUnderlyingValue().flow() and await.asExpr() = awaitExpr @@ -1124,7 +1133,7 @@ private DataFlow::Node getAwaitOperand(DataFlow::Node await) { /** * Holds if property `prop` of `arg` is read inside a function and returned to the call `succ`. */ -private predicate parameterPropRead( +deprecated private predicate parameterPropRead( DataFlow::Node arg, string prop, DataFlow::Node succ, DataFlow::Configuration cfg, PathSummary summary ) { @@ -1136,7 +1145,7 @@ private predicate parameterPropRead( // all the non-recursive parts of parameterPropRead outlined into a precomputed predicate pragma[noinline] -private predicate parameterPropReadStep( +deprecated private predicate parameterPropReadStep( DataFlow::SourceNode parm, DataFlow::Node read, string prop, DataFlow::Configuration cfg, DataFlow::Node arg, DataFlow::Node invk, Function f, DataFlow::Node succ ) { @@ -1160,7 +1169,7 @@ private predicate parameterPropReadStep( * Holds if `read` may flow into a return statement of `f` under configuration `cfg` * (possibly through callees) along a path summarized by `summary`. */ -private predicate reachesReturn( +deprecated private predicate reachesReturn( Function f, DataFlow::Node read, DataFlow::Configuration cfg, PathSummary summary ) { isRelevant(read, cfg) and @@ -1178,7 +1187,7 @@ private predicate reachesReturn( // used in `getARelevantProp`, outlined for performance pragma[noinline] -private string getARelevantStoreProp(DataFlow::Configuration cfg) { +deprecated private string getARelevantStoreProp(DataFlow::Configuration cfg) { exists(DataFlow::Node previous | isRelevant(previous, cfg) | basicStoreStep(previous, _, result) or isAdditionalStoreStep(previous, _, result, cfg) @@ -1187,7 +1196,7 @@ private string getARelevantStoreProp(DataFlow::Configuration cfg) { // used in `getARelevantProp`, outlined for performance pragma[noinline] -private string getARelevantLoadProp(DataFlow::Configuration cfg) { +deprecated private string getARelevantLoadProp(DataFlow::Configuration cfg) { exists(DataFlow::Node previous | isRelevant(previous, cfg) | basicLoadStep(previous, _, result) or isAdditionalLoadStep(previous, _, result, cfg) @@ -1196,7 +1205,7 @@ private string getARelevantLoadProp(DataFlow::Configuration cfg) { /** Gets the name of a property that is both loaded and stored according to the exploratory analysis. */ pragma[noinline] -private string getARelevantProp(DataFlow::Configuration cfg) { +deprecated private string getARelevantProp(DataFlow::Configuration cfg) { result = getARelevantStoreProp(cfg) and result = getARelevantLoadProp(cfg) or @@ -1206,7 +1215,7 @@ private string getARelevantProp(DataFlow::Configuration cfg) { /** * Holds if the property `prop` of the object `pred` should be loaded into `succ`. */ -private predicate isAdditionalLoadStep( +deprecated private predicate isAdditionalLoadStep( DataFlow::Node pred, DataFlow::Node succ, string prop, DataFlow::Configuration cfg ) { LegacyFlowStep::loadStep(pred, succ, prop) @@ -1217,7 +1226,7 @@ private predicate isAdditionalLoadStep( /** * Holds if `pred` should be stored in the object `succ` under the property `prop`. */ -private predicate isAdditionalStoreStep( +deprecated private predicate isAdditionalStoreStep( DataFlow::Node pred, DataFlow::Node succ, string prop, DataFlow::Configuration cfg ) { LegacyFlowStep::storeStep(pred, succ, prop) @@ -1228,7 +1237,7 @@ private predicate isAdditionalStoreStep( /** * Holds if the property `loadProp` should be copied from the object `pred` to the property `storeProp` of object `succ`. */ -private predicate isAdditionalLoadStoreStep( +deprecated private predicate isAdditionalLoadStoreStep( DataFlow::Node pred, DataFlow::Node succ, string loadProp, string storeProp, DataFlow::Configuration cfg ) { @@ -1248,7 +1257,7 @@ private predicate isAdditionalLoadStoreStep( * Holds if property `prop` of `pred` may flow into `succ` along a path summarized by * `summary`. */ -private predicate loadStep( +deprecated private predicate loadStep( DataFlow::Node pred, DataFlow::Node succ, string prop, DataFlow::Configuration cfg, PathSummary summary ) { @@ -1270,7 +1279,7 @@ private predicate loadStep( * the flow that originally reached `base.startProp` used a call edge. */ pragma[noopt] -private predicate reachableFromStoreBase( +deprecated private predicate reachableFromStoreBase( string startProp, string endProp, DataFlow::Node base, DataFlow::Node nd, DataFlow::Configuration cfg, TPathSummary summary, boolean onlyRelevantInCall ) { @@ -1310,7 +1319,7 @@ private predicate reachableFromStoreBase( ) } -private boolean hasCall(PathSummary summary) { result = summary.hasCall() } +deprecated private boolean hasCall(PathSummary summary) { result = summary.hasCall() } /** * Holds if the value of `pred` is written to a property of some base object, and that base @@ -1320,7 +1329,7 @@ private boolean hasCall(PathSummary summary) { result = summary.hasCall() } * In other words, `pred` may flow to `succ` through a property. */ pragma[noinline] -private predicate flowThroughProperty( +deprecated private predicate flowThroughProperty( DataFlow::Node pred, DataFlow::Node succ, DataFlow::Configuration cfg, PathSummary summary ) { exists(PathSummary oldSummary, PathSummary newSummary | @@ -1336,7 +1345,7 @@ private predicate flowThroughProperty( * by `oldSummary`. */ pragma[noinline] -private predicate storeToLoad( +deprecated private predicate storeToLoad( DataFlow::Node pred, DataFlow::Node succ, DataFlow::Configuration cfg, PathSummary oldSummary, PathSummary newSummary ) { @@ -1358,7 +1367,7 @@ private predicate storeToLoad( * All of this is done under configuration `cfg`, and `arg` flows along a path * summarized by `summary`, while `cb` is only tracked locally. */ -private predicate summarizedHigherOrderCall( +deprecated private predicate summarizedHigherOrderCall( DataFlow::Node arg, DataFlow::Node cb, int i, DataFlow::Configuration cfg, PathSummary summary ) { exists( @@ -1388,7 +1397,7 @@ private predicate summarizedHigherOrderCall( * @see `summarizedHigherOrderCall`. */ pragma[noinline] -private predicate summarizedHigherOrderCallAux( +deprecated private predicate summarizedHigherOrderCallAux( Function f, DataFlow::Node arg, DataFlow::Node innerArg, DataFlow::Configuration cfg, PathSummary oldSummary, DataFlow::SourceNode cbParm, DataFlow::InvokeNode inner, int j, DataFlow::Node cb @@ -1426,7 +1435,7 @@ private predicate summarizedHigherOrderCallAux( * invocation of the callback. */ pragma[nomagic] -private predicate higherOrderCall( +deprecated private predicate higherOrderCall( DataFlow::Node arg, DataFlow::SourceNode callback, int i, DataFlow::Configuration cfg, PathSummary summary ) { @@ -1462,7 +1471,7 @@ private predicate higherOrderCall( * All of this is done under configuration `cfg`, and `arg` flows along a path * summarized by `summary`, while `cb` is only tracked locally. */ -private predicate flowIntoHigherOrderCall( +deprecated private predicate flowIntoHigherOrderCall( DataFlow::Node pred, DataFlow::Node succ, DataFlow::Configuration cfg, PathSummary summary ) { exists(DataFlow::FunctionNode cb, int i, PathSummary oldSummary | @@ -1485,7 +1494,7 @@ private predicate flowIntoHigherOrderCall( * Holds if there is a flow step from `pred` to `succ` described by `summary` * under configuration `cfg`. */ -private predicate flowStep( +deprecated private predicate flowStep( DataFlow::Node pred, DataFlow::Configuration cfg, DataFlow::Node succ, PathSummary summary ) { ( @@ -1513,7 +1522,7 @@ private predicate flowStep( * in zero or more steps. */ pragma[nomagic] -private predicate flowsTo( +deprecated private predicate flowsTo( PathNode flowsource, DataFlow::Node source, SinkPathNode flowsink, DataFlow::Node sink, DataFlow::Configuration cfg ) { @@ -1527,7 +1536,7 @@ private predicate flowsTo( * `summary`. */ pragma[nomagic] -private predicate reachableFromSource( +deprecated private predicate reachableFromSource( DataFlow::Node nd, DataFlow::Configuration cfg, PathSummary summary ) { exists(FlowLabel lbl | @@ -1548,7 +1557,9 @@ private predicate reachableFromSource( * Holds if `nd` can be reached from a source under `cfg`, and in turn a sink is * reachable from `nd`, where the path from the source to `nd` is summarized by `summary`. */ -private predicate onPath(DataFlow::Node nd, DataFlow::Configuration cfg, PathSummary summary) { +deprecated private predicate onPath( + DataFlow::Node nd, DataFlow::Configuration cfg, PathSummary summary +) { reachableFromSource(nd, cfg, summary) and isSink(nd, cfg, summary.getEndLabel()) and not cfg.isBarrier(nd) and @@ -1567,7 +1578,7 @@ private predicate onPath(DataFlow::Node nd, DataFlow::Configuration cfg, PathSum * This predicate has been outlined from `onPath` to give the optimizer a hint about join-ordering. */ pragma[noinline] -private predicate onPathStep( +deprecated private predicate onPathStep( DataFlow::Node nd, DataFlow::Configuration cfg, PathSummary summary, PathSummary stepSummary, DataFlow::Node mid ) { @@ -1579,26 +1590,30 @@ private predicate onPathStep( * Holds if there is a configuration that has at least one source and at least one sink. */ pragma[noinline] -private predicate isLive() { +deprecated private predicate isLive() { exists(DataFlow::Configuration cfg | isSource(_, cfg, _) and isSink(_, cfg, _)) } /** * A data flow node on an inter-procedural path from a source. */ -private newtype TPathNode = - MkSourceNode(DataFlow::Node nd, DataFlow::Configuration cfg) { isSourceNode(nd, cfg, _) } or - MkMidNode(DataFlow::Node nd, DataFlow::Configuration cfg, PathSummary summary) { +deprecated private newtype TPathNode = + deprecated MkSourceNode(DataFlow::Node nd, DataFlow::Configuration cfg) { + isSourceNode(nd, cfg, _) + } or + deprecated MkMidNode(DataFlow::Node nd, DataFlow::Configuration cfg, PathSummary summary) { isLive() and onPath(nd, cfg, summary) } or - MkSinkNode(DataFlow::Node nd, DataFlow::Configuration cfg) { isSinkNode(nd, cfg, _) } + deprecated MkSinkNode(DataFlow::Node nd, DataFlow::Configuration cfg) { isSinkNode(nd, cfg, _) } /** * Holds if `nd` is a source node for configuration `cfg`, and there is a path from `nd` to a sink * with the given `summary`. */ -private predicate isSourceNode(DataFlow::Node nd, DataFlow::Configuration cfg, PathSummary summary) { +deprecated private predicate isSourceNode( + DataFlow::Node nd, DataFlow::Configuration cfg, PathSummary summary +) { exists(FlowLabel lbl | summary = PathSummary::level(lbl) | isSource(nd, cfg, lbl) and isLive() and @@ -1610,7 +1625,9 @@ private predicate isSourceNode(DataFlow::Node nd, DataFlow::Configuration cfg, P * Holds if `nd` is a sink node for configuration `cfg`, and there is a path from a source to `nd` * with the given `summary`. */ -private predicate isSinkNode(DataFlow::Node nd, DataFlow::Configuration cfg, PathSummary summary) { +deprecated private predicate isSinkNode( + DataFlow::Node nd, DataFlow::Configuration cfg, PathSummary summary +) { isSink(nd, cfg, summary.getEndLabel()) and isLive() and onPath(nd, cfg, summary) @@ -1623,7 +1640,9 @@ private predicate isSinkNode(DataFlow::Node nd, DataFlow::Configuration cfg, Pat * from computing a cross-product of all path nodes belonging to the same configuration. */ bindingset[cfg, result] -private DataFlow::Configuration id(DataFlow::Configuration cfg) { result >= cfg and cfg >= result } +deprecated private DataFlow::Configuration id(DataFlow::Configuration cfg) { + result >= cfg and cfg >= result +} /** * A data-flow node on an inter-procedural path from a source to a sink. @@ -1641,7 +1660,7 @@ private DataFlow::Configuration id(DataFlow::Configuration cfg) { result >= cfg * some source to the node with the given summary that can be extended to a path to some sink node, * all under the configuration. */ -class PathNode extends TPathNode { +deprecated class PathNode extends TPathNode { DataFlow::Node nd; Configuration cfg; @@ -1697,7 +1716,7 @@ class PathNode extends TPathNode { } /** Gets the mid node corresponding to `src`. */ -private MidPathNode initialMidNode(SourcePathNode src) { +deprecated private MidPathNode initialMidNode(SourcePathNode src) { exists(DataFlow::Node nd, Configuration cfg, PathSummary summary | result.wraps(nd, cfg, summary) and src = MkSourceNode(nd, cfg) and @@ -1706,7 +1725,7 @@ private MidPathNode initialMidNode(SourcePathNode src) { } /** Gets the mid node corresponding to `snk`. */ -private MidPathNode finalMidNode(SinkPathNode snk) { +deprecated private MidPathNode finalMidNode(SinkPathNode snk) { exists(DataFlow::Node nd, Configuration cfg, PathSummary summary | result.wraps(nd, cfg, summary) and snk = MkSinkNode(nd, cfg) and @@ -1721,7 +1740,7 @@ private MidPathNode finalMidNode(SinkPathNode snk) { * This helper predicate exists to clarify the intended join order in `getASuccessor` below. */ pragma[noinline] -private predicate midNodeStep( +deprecated private predicate midNodeStep( PathNode nd, DataFlow::Node predNd, Configuration cfg, PathSummary summary, DataFlow::Node succNd, PathSummary newSummary ) { @@ -1732,7 +1751,7 @@ private predicate midNodeStep( /** * Gets a node to which data from `nd` may flow in one step. */ -private PathNode getASuccessor(PathNode nd) { +deprecated private PathNode getASuccessor(PathNode nd) { // source node to mid node result = initialMidNode(nd) or @@ -1746,7 +1765,7 @@ private PathNode getASuccessor(PathNode nd) { nd = finalMidNode(result) } -private PathNode getASuccessorIfHidden(PathNode nd) { +deprecated private PathNode getASuccessorIfHidden(PathNode nd) { nd.(MidPathNode).isHidden() and result = getASuccessor(nd) } @@ -1758,7 +1777,7 @@ private PathNode getASuccessorIfHidden(PathNode nd) { * is a configuration such that `nd` is on a path from a source to a sink under `cfg` * summarized by `summary`. */ -class MidPathNode extends PathNode, MkMidNode { +deprecated class MidPathNode extends PathNode, MkMidNode { PathSummary summary; MidPathNode() { this = MkMidNode(nd, cfg, summary) } @@ -1779,6 +1798,7 @@ class MidPathNode extends PathNode, MkMidNode { module PathNode { /** Holds if `nd` should be hidden in data flow paths. */ predicate shouldNodeBeHidden(DataFlow::Node nd) { + // TODO: move to DataFlowPrivate // Skip phi, refinement, and capture nodes nd.(DataFlow::SsaDefinitionNode).getSsaVariable().getDefinition() instanceof SsaImplicitDefinition @@ -1809,21 +1829,21 @@ module PathNode { /** * A path node corresponding to a flow source. */ -class SourcePathNode extends PathNode, MkSourceNode { +deprecated class SourcePathNode extends PathNode, MkSourceNode { SourcePathNode() { this = MkSourceNode(nd, cfg) } } /** * A path node corresponding to a flow sink. */ -class SinkPathNode extends PathNode, MkSinkNode { +deprecated class SinkPathNode extends PathNode, MkSinkNode { SinkPathNode() { this = MkSinkNode(nd, cfg) } } /** * Provides the query predicates needed to include a graph in a path-problem query. */ -module PathGraph { +deprecated module PathGraph { /** Holds if `nd` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode nd) { not nd.(MidPathNode).isHidden() } @@ -1877,7 +1897,7 @@ module PathGraph { /** * Gets a logical `and` expression, or parenthesized expression, that contains `guard`. */ -private Expr getALogicalAndParent(BarrierGuardNodeInternal guard) { +deprecated private Expr getALogicalAndParent(BarrierGuardNodeInternal guard) { barrierGuardIsRelevant(guard) and result = guard.asExpr() or result.(LogAndExpr).getAnOperand() = getALogicalAndParent(guard) @@ -1888,7 +1908,7 @@ private Expr getALogicalAndParent(BarrierGuardNodeInternal guard) { /** * Gets a logical `or` expression, or parenthesized expression, that contains `guard`. */ -private Expr getALogicalOrParent(BarrierGuardNodeInternal guard) { +deprecated private Expr getALogicalOrParent(BarrierGuardNodeInternal guard) { barrierGuardIsRelevant(guard) and result = guard.asExpr() or result.(LogOrExpr).getAnOperand() = getALogicalOrParent(guard) @@ -1904,14 +1924,14 @@ private Expr getALogicalOrParent(BarrierGuardNodeInternal guard) { * of the standard library. Override `Configuration::isBarrierGuard` * for analysis-specific barrier guards. */ -abstract class AdditionalBarrierGuardNode extends BarrierGuardNode { +abstract deprecated class AdditionalBarrierGuardNode extends BarrierGuardNode { abstract predicate appliesTo(Configuration cfg); } /** * A function that returns the result of a barrier guard. */ -private class BarrierGuardFunction extends Function { +deprecated private class BarrierGuardFunction extends Function { DataFlow::ParameterNode sanitizedParameter; BarrierGuardNodeInternal guard; boolean guardOutcome; @@ -1963,7 +1983,9 @@ private class BarrierGuardFunction extends Function { /** * A call that sanitizes an argument. */ -private class AdditionalBarrierGuardCall extends DerivedBarrierGuardNode, DataFlow::CallNode { +deprecated private class AdditionalBarrierGuardCall extends DerivedBarrierGuardNode, + DataFlow::CallNode +{ BarrierGuardFunction f; AdditionalBarrierGuardCall() { f.isBarrierCall(this, _, _, _) } @@ -1984,7 +2006,7 @@ private class AdditionalBarrierGuardCall extends DerivedBarrierGuardNode, DataFl * } * ``` */ -private class CallAgainstEqualityCheck extends DerivedBarrierGuardNode { +deprecated private class CallAgainstEqualityCheck extends DerivedBarrierGuardNode { BarrierGuardNodeInternal prev; boolean polarity; @@ -2026,7 +2048,7 @@ class VarAccessBarrier extends DataFlow::Node { /** * Holds if there is a path without unmatched return steps from `source` to `sink`. */ -predicate hasPathWithoutUnmatchedReturn(SourcePathNode source, SinkPathNode sink) { +deprecated predicate hasPathWithoutUnmatchedReturn(SourcePathNode source, SinkPathNode sink) { exists(MidPathNode mid | source.getASuccessor*() = mid and sink = mid.getASuccessor() and diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 409465b3ffa..ac108524cde 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -33,7 +33,7 @@ module TaintTracking { * If a different set of flow edges is desired, extend this class and override * `isAdditionalTaintStep`. */ - abstract class Configuration extends DataFlow::Configuration { + abstract deprecated class Configuration extends DataFlow::Configuration { bindingset[this] Configuration() { any() } @@ -183,6 +183,7 @@ module TaintTracking { */ cached abstract class AdditionalSanitizerGuardNode extends DataFlow::Node { + // TODO: deprecate this class; currently requires too much refactoring // For backwards compatibility, this contains a copy of the SanitizerGuard interface, // but is does not inherit from it as that would cause re-evaluation of cached barriers. /** @@ -219,7 +220,7 @@ module TaintTracking { * Holds if this guard applies to the flow in `cfg`. */ cached - abstract predicate appliesTo(Configuration cfg); + abstract deprecated predicate appliesTo(Configuration cfg); } /** @@ -235,6 +236,7 @@ module TaintTracking { * them. */ abstract class SanitizerGuardNode extends DataFlow::BarrierGuardNode { + // TODO: deprecate this class; currently requires too much refactoring override predicate blocks(boolean outcome, Expr e) { none() } /** @@ -259,7 +261,9 @@ module TaintTracking { /** * A sanitizer guard node that only blocks specific flow labels. */ - abstract class LabeledSanitizerGuardNode extends SanitizerGuardNode, DataFlow::BarrierGuardNode { + abstract deprecated class LabeledSanitizerGuardNode extends SanitizerGuardNode, + DataFlow::BarrierGuardNode + { override predicate sanitizes(boolean outcome, Expr e) { none() } } @@ -813,7 +817,7 @@ module TaintTracking { e = expr } - override predicate appliesTo(Configuration cfg) { any() } + deprecated override predicate appliesTo(Configuration cfg) { any() } } /** @@ -839,7 +843,7 @@ module TaintTracking { ) } - override predicate appliesTo(Configuration cfg) { any() } + deprecated override predicate appliesTo(Configuration cfg) { any() } } /** @@ -877,7 +881,7 @@ module TaintTracking { e = astNode.getLeftOperand() } - override predicate appliesTo(Configuration cfg) { any() } + deprecated override predicate appliesTo(Configuration cfg) { any() } } /** A check of the form `if(o[x] != undefined)`, which sanitizes `x` in its "then" branch. */ @@ -902,7 +906,7 @@ module TaintTracking { e = x } - override predicate appliesTo(Configuration cfg) { any() } + deprecated override predicate appliesTo(Configuration cfg) { any() } } /** A check of the form `type x === "undefined"`, which sanitized `x` in its "then" branch. */ @@ -917,7 +921,7 @@ module TaintTracking { e = x } - override predicate appliesTo(Configuration cfg) { any() } + deprecated override predicate appliesTo(Configuration cfg) { any() } } /** @@ -994,7 +998,7 @@ module TaintTracking { override predicate sanitizes(boolean outcome, Expr e) { polarity = outcome and e = operand } - override predicate appliesTo(Configuration cfg) { any() } + deprecated override predicate appliesTo(Configuration cfg) { any() } } /** @@ -1009,7 +1013,7 @@ module TaintTracking { candidate = e.flow() and candidate.getTestPolarity() = outcome } - override predicate appliesTo(Configuration cfg) { any() } + deprecated override predicate appliesTo(Configuration cfg) { any() } } /** @@ -1035,7 +1039,7 @@ module TaintTracking { e = indexOf.getArgument(0) } - override predicate appliesTo(Configuration cfg) { any() } + deprecated override predicate appliesTo(Configuration cfg) { any() } } /** @@ -1064,7 +1068,7 @@ module TaintTracking { e = event } - override predicate appliesTo(Configuration cfg) { any() } + deprecated override predicate appliesTo(Configuration cfg) { any() } } import internal.sharedlib.TaintTracking diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll index ef6af64e79b..b7a20acfcad 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll @@ -63,13 +63,13 @@ module MakeLabeledBarrierGuard { } } -private signature predicate isBarrierGuardSig(DataFlow::BarrierGuardNode node); +deprecated private signature predicate isBarrierGuardSig(DataFlow::BarrierGuardNode node); /** * Converts a labeled barrier guard class to a set of nodes to include in an implementation of `isBarrier(node)` and `isBarrier(node, label)` * in a `DataFlow::StateConfigSig` implementation. */ -module MakeLegacyBarrierGuardLabeled { +deprecated module MakeLegacyBarrierGuardLabeled { final private class FinalNode = DataFlow::Node; private class Adapter extends FinalNode instanceof DataFlow::BarrierGuardNode { @@ -100,7 +100,7 @@ module MakeLegacyBarrierGuardLabeled { /** * Converts a barrier guard class to a set of nodes to include in an implementation of `isBarrier(node)` in a `DataFlow::ConfigSig` implementation. */ -module MakeLegacyBarrierGuard { +deprecated module MakeLegacyBarrierGuard { final private class FinalNode = DataFlow::Node; private class Adapter extends FinalNode instanceof DataFlow::BarrierGuardNode { diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll index 2ee04b8dbf5..b6152bcf3c3 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll @@ -49,7 +49,7 @@ private predicate legacyPostUpdateStep(DataFlow::Node pred, DataFlow::Node succ) * additional steps from the configuration into account. */ pragma[inline] -predicate localFlowStep( +deprecated predicate localFlowStep( DataFlow::Node pred, DataFlow::Node succ, DataFlow::Configuration configuration, FlowLabel predlbl, FlowLabel succlbl ) { diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index 0ca5de709ff..fc4f85a751e 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -39,10 +39,16 @@ predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2, defaultAdditionalTaintStep(node1, node2) and model = "" // TODO: set model } -private class SanitizerGuardAdapter extends DataFlow::Node instanceof TaintTracking::AdditionalSanitizerGuardNode -{ +abstract private class SanitizerGuardAdapter extends DataFlow::Node { // Note: avoid depending on DataFlow::FlowLabel here as it will cause these barriers to be re-evaluated - predicate blocksExpr(boolean outcome, Expr e) { super.sanitizes(outcome, e) } + abstract predicate blocksExpr(boolean outcome, Expr e); +} + +deprecated private class SanitizerGuardAdapterImpl extends SanitizerGuardAdapter instanceof TaintTracking::AdditionalSanitizerGuardNode +{ + // TODO: reverse this relationship, so the sanitizer guards are implemented with the new interface, and the AdditionalSanitizerGuardNode + // takes its values from the new implementations + override predicate blocksExpr(boolean outcome, Expr e) { super.sanitizes(outcome, e) } } bindingset[node] diff --git a/javascript/ql/lib/semmle/javascript/internal/CachedStages.qll b/javascript/ql/lib/semmle/javascript/internal/CachedStages.qll index 8f77419d638..e8846b58dca 100644 --- a/javascript/ql/lib/semmle/javascript/internal/CachedStages.qll +++ b/javascript/ql/lib/semmle/javascript/internal/CachedStages.qll @@ -344,7 +344,7 @@ module Stages { or any(RegExpTerm t).isUsedAsRegExp() or - any(TaintTracking::AdditionalSanitizerGuardNode e).appliesTo(_) + any(TaintTracking::AdditionalSanitizerGuardNode e).blocks(_, _) } cached @@ -353,7 +353,7 @@ module Stages { DummySanitizer() { none() } cached - override predicate appliesTo(TaintTracking::Configuration cfg) { none() } + deprecated override predicate appliesTo(TaintTracking::Configuration cfg) { none() } cached override predicate sanitizes(boolean outcome, Expr e) { none() } From bc7753de29c8a38cfc076685a67a3d9b5c08a258 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 6 Nov 2024 10:30:46 +0100 Subject: [PATCH 388/514] JS: Remove non-deprecated reference to AdditionalBarrierGuardNode --- .../javascript/dataflow/internal/DataFlowPrivate.qll | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index d71ea9ff832..72de0f5c045 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -1055,10 +1055,14 @@ private predicate sameContainerAsEnclosingContainer(Node node, Function fun) { node.getContainer() = fun.getEnclosingContainer() } -private class BarrierGuardAdapter extends DataFlow::Node instanceof DataFlow::AdditionalBarrierGuardNode -{ +abstract private class BarrierGuardAdapter extends DataFlow::Node { // Note: avoid depending on DataFlow::FlowLabel here as it will cause these barriers to be re-evaluated - predicate blocksExpr(boolean outcome, Expr e) { super.blocks(outcome, e) } + predicate blocksExpr(boolean outcome, Expr e) { none() } +} + +deprecated private class BarrierGuardAdapterSubclass extends BarrierGuardAdapter instanceof DataFlow::AdditionalBarrierGuardNode +{ + override predicate blocksExpr(boolean outcome, Expr e) { super.blocks(outcome, e) } } /** From 82682d9a62b1f762b0e411fc05446c022d0ab7d0 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 6 Nov 2024 10:35:32 +0100 Subject: [PATCH 389/514] JS: Remove a non-deprecated reference to SanitizerGuardNode --- .../ql/lib/semmle/javascript/dataflow/TaintTracking.qll | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index ac108524cde..106f5f97c6a 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -853,15 +853,13 @@ module TaintTracking { * * This sanitizer is not enabled by default. */ - class AdHocWhitelistCheckSanitizer extends SanitizerGuardNode, DataFlow::CallNode { + class AdHocWhitelistCheckSanitizer extends DataFlow::CallNode { AdHocWhitelistCheckSanitizer() { this.getCalleeName() .regexpMatch("(?i).*((?; From c2abb0fbd0c982f17857cdecbff1d5f4fa07af67 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 6 Nov 2024 12:43:04 +0100 Subject: [PATCH 390/514] JS: Remove reference to AdditionalSanitizerGuard from CachedStages --- .../semmle/javascript/internal/CachedStages.qll | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/internal/CachedStages.qll b/javascript/ql/lib/semmle/javascript/internal/CachedStages.qll index e8846b58dca..470435ce23c 100644 --- a/javascript/ql/lib/semmle/javascript/internal/CachedStages.qll +++ b/javascript/ql/lib/semmle/javascript/internal/CachedStages.qll @@ -25,6 +25,7 @@ private import StmtContainers private import semmle.javascript.dataflow.internal.PreCallGraphStep private import semmle.javascript.dataflow.internal.FlowSteps private import semmle.javascript.dataflow.internal.AccessPaths +private import semmle.javascript.dataflow.internal.TaintTrackingPrivate as TaintTrackingPrivate /** * Contains a `cached module` for each stage. @@ -344,19 +345,7 @@ module Stages { or any(RegExpTerm t).isUsedAsRegExp() or - any(TaintTracking::AdditionalSanitizerGuardNode e).blocks(_, _) - } - - cached - class DummySanitizer extends TaintTracking::AdditionalSanitizerGuardNode { - cached - DummySanitizer() { none() } - - cached - deprecated override predicate appliesTo(TaintTracking::Configuration cfg) { none() } - - cached - override predicate sanitizes(boolean outcome, Expr e) { none() } + TaintTrackingPrivate::defaultTaintSanitizer(_) } } } From 0b1e859e707cadc81f71b4b3c97074594457d310 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 6 Nov 2024 14:26:38 +0100 Subject: [PATCH 391/514] JS: Remove uses of AdditionalSanitizerGuardNode --- .../javascript/dataflow/TaintTracking.qll | 92 +++++++++++-------- .../internal/TaintTrackingPrivate.qll | 14 +-- 2 files changed, 57 insertions(+), 49 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 106f5f97c6a..23d91b80ccb 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -173,6 +173,44 @@ module TaintTracking { override DataFlow::FlowLabel getDefaultSourceLabel() { result.isTaint() } } + /** + * A barrier guard that applies to all taint-tracking configurations. + * + * Note: For performance reasons, all subclasses of this class should be part + * of the standard library. To define a query-specific barrier guard, instead override + * `isBarrier` and use the `DataFlow::MakeBarrierGuard` module. For example: + * ```codeql + * module MyConfig implements DataFlow::ConfigSig { + * predicate isBarrier(DataFlow::Node node) { + * node = DataFlow::MakeBarrierGuard + * } + * } + * class MyGuard extends DataFlow::Node { + * MyGuard() { ... } + * predicate blocksExpr(boolean outcome, Expr e) { ... } + * } + */ + abstract class AdditionalBarrierGuard extends DataFlow::Node { + /** + * Holds if this node blocks expression `e`, provided it evaluates to `outcome`. + */ + abstract predicate blocksExpr(boolean outcome, Expr e); + } + + /** + * Internal barrier guard class that populates both the new `AdditionalBarrierGuard` class + * and the legacy `AdditionalSanitizerGuardNode` class. + * + * It exposes the member predicates of `AdditionalSanitizerGuardNode` for backwards compatibility. + */ + abstract private class LegacyAdditionalBarrierGuard extends AdditionalBarrierGuard, + AdditionalSanitizerGuardNode + { + override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + deprecated override predicate appliesTo(Configuration cfg) { any() } + } + /** * A `SanitizerGuardNode` that controls which taint tracking * configurations it is used in. @@ -779,7 +817,7 @@ module TaintTracking { * A conditional checking a tainted string against a regular expression, which is * considered to be a sanitizer for all configurations. */ - class SanitizingRegExpTest extends AdditionalSanitizerGuardNode, DataFlow::ValueNode { + class SanitizingRegExpTest extends LegacyAdditionalBarrierGuard, DataFlow::ValueNode { Expr expr; boolean sanitizedOutcome; @@ -812,12 +850,10 @@ module TaintTracking { private boolean getSanitizedOutcome() { result = sanitizedOutcome } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { outcome = sanitizedOutcome and e = expr } - - deprecated override predicate appliesTo(Configuration cfg) { any() } } /** @@ -827,14 +863,14 @@ module TaintTracking { * * Note that the `includes` method is covered by `MembershipTestSanitizer`. */ - class WhitelistContainmentCallSanitizer extends AdditionalSanitizerGuardNode, + class WhitelistContainmentCallSanitizer extends LegacyAdditionalBarrierGuard, DataFlow::MethodCallNode { WhitelistContainmentCallSanitizer() { this.getMethodName() = ["contains", "has", "hasOwnProperty", "hasOwn"] } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { exists(int propertyIndex | if this.getMethodName() = "hasOwn" then propertyIndex = 1 else propertyIndex = 0 | @@ -842,8 +878,6 @@ module TaintTracking { e = this.getArgument(propertyIndex).asExpr() ) } - - deprecated override predicate appliesTo(Configuration cfg) { any() } } /** @@ -876,19 +910,17 @@ module TaintTracking { module AdHocWhitelistCheckSanitizer = DataFlow::MakeBarrierGuard; /** A check of the form `if(x in o)`, which sanitizes `x` in its "then" branch. */ - class InSanitizer extends AdditionalSanitizerGuardNode, DataFlow::ValueNode { + class InSanitizer extends LegacyAdditionalBarrierGuard, DataFlow::ValueNode { override InExpr astNode; - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = astNode.getLeftOperand() } - - deprecated override predicate appliesTo(Configuration cfg) { any() } } /** A check of the form `if(o[x] != undefined)`, which sanitizes `x` in its "then" branch. */ - class UndefinedCheckSanitizer extends AdditionalSanitizerGuardNode, DataFlow::ValueNode { + class UndefinedCheckSanitizer extends LegacyAdditionalBarrierGuard, DataFlow::ValueNode { Expr x; override EqualityTest astNode; @@ -904,27 +936,23 @@ module TaintTracking { ) } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { outcome = astNode.getPolarity().booleanNot() and e = x } - - deprecated override predicate appliesTo(Configuration cfg) { any() } } /** A check of the form `type x === "undefined"`, which sanitized `x` in its "then" branch. */ - class TypeOfUndefinedSanitizer extends AdditionalSanitizerGuardNode, DataFlow::ValueNode { + class TypeOfUndefinedSanitizer extends LegacyAdditionalBarrierGuard, DataFlow::ValueNode { Expr x; override EqualityTest astNode; TypeOfUndefinedSanitizer() { isTypeofGuard(astNode, x, "undefined") } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { outcome = astNode.getPolarity() and e = x } - - deprecated override predicate appliesTo(Configuration cfg) { any() } } /** @@ -985,7 +1013,7 @@ module TaintTracking { /** * A test of form `x.length === "0"`, preventing `x` from being tainted. */ - class IsEmptyGuard extends AdditionalSanitizerGuardNode, DataFlow::ValueNode { + class IsEmptyGuard extends LegacyAdditionalBarrierGuard, DataFlow::ValueNode { override EqualityTest astNode; boolean polarity; Expr operand; @@ -999,24 +1027,20 @@ module TaintTracking { ) } - override predicate sanitizes(boolean outcome, Expr e) { polarity = outcome and e = operand } - - deprecated override predicate appliesTo(Configuration cfg) { any() } + override predicate blocksExpr(boolean outcome, Expr e) { polarity = outcome and e = operand } } /** * A check of the form `whitelist.includes(x)` or equivalent, which sanitizes `x` in its "then" branch. */ - class MembershipTestSanitizer extends AdditionalSanitizerGuardNode { + class MembershipTestSanitizer extends LegacyAdditionalBarrierGuard { MembershipCandidate candidate; MembershipTestSanitizer() { this = candidate.getTest() } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { candidate = e.flow() and candidate.getTestPolarity() = outcome } - - deprecated override predicate appliesTo(Configuration cfg) { any() } } /** @@ -1024,7 +1048,7 @@ module TaintTracking { * * The more typical case of `x.indexOf(y) >= 0` is covered by `MembershipTestSanitizer`. */ - class PositiveIndexOfSanitizer extends AdditionalSanitizerGuardNode, DataFlow::ValueNode { + class PositiveIndexOfSanitizer extends LegacyAdditionalBarrierGuard, DataFlow::ValueNode { MethodCallExpr indexOf; override RelationalComparison astNode; @@ -1037,19 +1061,17 @@ module TaintTracking { ) } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = indexOf.getArgument(0) } - - deprecated override predicate appliesTo(Configuration cfg) { any() } } /** * An equality test on `e.origin` or `e.source` where `e` is a `postMessage` event object, * considered as a sanitizer for `e`. */ - private class PostMessageEventSanitizer extends AdditionalSanitizerGuardNode { + private class PostMessageEventSanitizer extends LegacyAdditionalBarrierGuard { VarAccess event; boolean polarity; @@ -1066,12 +1088,10 @@ module TaintTracking { ) } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { outcome = polarity and e = event } - - deprecated override predicate appliesTo(Configuration cfg) { any() } } import internal.sharedlib.TaintTracking diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index fc4f85a751e..5f290b557fe 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -39,18 +39,6 @@ predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2, defaultAdditionalTaintStep(node1, node2) and model = "" // TODO: set model } -abstract private class SanitizerGuardAdapter extends DataFlow::Node { - // Note: avoid depending on DataFlow::FlowLabel here as it will cause these barriers to be re-evaluated - abstract predicate blocksExpr(boolean outcome, Expr e); -} - -deprecated private class SanitizerGuardAdapterImpl extends SanitizerGuardAdapter instanceof TaintTracking::AdditionalSanitizerGuardNode -{ - // TODO: reverse this relationship, so the sanitizer guards are implemented with the new interface, and the AdditionalSanitizerGuardNode - // takes its values from the new implementations - override predicate blocksExpr(boolean outcome, Expr e) { super.sanitizes(outcome, e) } -} - bindingset[node] pragma[inline_late] private BasicBlock getBasicBlockFromSsa2(Ssa2::Node node) { @@ -96,7 +84,7 @@ cached predicate defaultTaintSanitizer(DataFlow::Node node) { node instanceof DataFlow::VarAccessBarrier or varAccessBarrier(node) or - node = MakeBarrierGuard::getABarrierNode() + node = MakeBarrierGuard::getABarrierNode() } /** From 988fa9c0ef2e510ca774ca7626885d8b7ed7699d Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 6 Nov 2024 14:31:34 +0100 Subject: [PATCH 392/514] JS: Deprecate AdditionalSanitizerGuardNode We're deprecating the class through an alias, but it is still the base class for a non-deprecated class, for backwards compatibility. For this reason we're also deprecating all of its member predicates so we can remove those in the future. --- .../javascript/dataflow/TaintTracking.qll | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 23d91b80ccb..48aaca1a36f 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -204,44 +204,41 @@ module TaintTracking { * It exposes the member predicates of `AdditionalSanitizerGuardNode` for backwards compatibility. */ abstract private class LegacyAdditionalBarrierGuard extends AdditionalBarrierGuard, - AdditionalSanitizerGuardNode + AdditionalSanitizerGuardNodeDeprecated { - override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + deprecated override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } deprecated override predicate appliesTo(Configuration cfg) { any() } } /** - * A `SanitizerGuardNode` that controls which taint tracking - * configurations it is used in. - * - * Note: For performance reasons, all subclasses of this class should be part - * of the standard library. Override `Configuration::isSanitizerGuard` - * for analysis-specific taint sanitizer guards. + * DEPRECATED. This class was part of the old data flow library which is now deprecated. + * Use `TaintTracking::AdditionalBarrierGuard` instead. */ + deprecated class AdditionalSanitizerGuardNode = AdditionalSanitizerGuardNodeDeprecated; + cached - abstract class AdditionalSanitizerGuardNode extends DataFlow::Node { - // TODO: deprecate this class; currently requires too much refactoring + abstract private class AdditionalSanitizerGuardNodeDeprecated extends DataFlow::Node { // For backwards compatibility, this contains a copy of the SanitizerGuard interface, // but is does not inherit from it as that would cause re-evaluation of cached barriers. /** * Holds if this node blocks expression `e`, provided it evaluates to `outcome`. */ cached - predicate blocks(boolean outcome, Expr e) { none() } + deprecated predicate blocks(boolean outcome, Expr e) { none() } /** * Holds if this node sanitizes expression `e`, provided it evaluates * to `outcome`. */ cached - abstract predicate sanitizes(boolean outcome, Expr e); + abstract deprecated predicate sanitizes(boolean outcome, Expr e); /** * Holds if this node blocks expression `e` from flow of type `label`, provided it evaluates to `outcome`. */ cached - predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel label) { + deprecated predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel label) { this.sanitizes(outcome, e) and label.isTaint() or this.sanitizes(outcome, e, label) @@ -252,7 +249,7 @@ module TaintTracking { * to `outcome`. */ cached - predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { none() } + deprecated predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { none() } /** * Holds if this guard applies to the flow in `cfg`. From 13ee5978481c07e95ace264da8122fbc17a5ba14 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 Nov 2024 14:28:39 +0100 Subject: [PATCH 393/514] JS: Add some proper documentation to SummarizedCallable --- .../javascript/dataflow/FlowSummary.qll | 47 ++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll b/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll index 1520ff22f88..c4a6e12b210 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/FlowSummary.qll @@ -6,7 +6,49 @@ private import semmle.javascript.dataflow.internal.FlowSummaryPrivate private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon private import semmle.javascript.dataflow.internal.DataFlowPrivate -/** A callable with a flow summary, identified by a unique string. */ +/** + * A model for a function that can propagate data flow. + * + * This class makes it possible to model flow through functions, using the same mechanism as + * `summaryModel` as described in the [library customization docs](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-javascript). + * + * Extend this class to define summary models directly in CodeQL. + * Data extensions and `summaryModel` are usually preferred; but there are a few cases where direct use of this class may be needed: + * + * - The relevant call sites cannot be matched by the access path syntax, and require the full power of CodeQL. + * For example, complex overloading patterns might require more local reasoning at the call site. + * - The input/output behaviour cannot be described statically in the access path syntax, but the relevant access paths + * can be generated dynamically in CodeQL, based on the usages found in the codebase. + * + * Subclasses should bind `this` to a unique identifier for the function being modelled. There is no special + * interpreation of the `this` value, it should just not clash with the `this`-value used by other classes. + * + * For example, this models flow through calls such as `require("my-library").myFunction()`: + * ```codeql + * class MyFunction extends SummarizedCallable { + * MyFunction() { this = "MyFunction" } + * + * override predicate propagatesFlow(string input, string output, boolean preservesValues) { + * input = "Argument[0]" and + * output = "ReturnValue" and + * preservesValue = false + * } + * + * override DataFlow::InvokeNode getACall() { + * result = API::moduleImport("my-library").getMember("myFunction").getACall() + * } + * } + * ``` + * This would be equivalent to the following model written as a data extension: + * ```yaml + * extensions: + * - addsTo: + * pack: codeql/javascript-all + * extensible: summaryModel + * data: + * - ["my-library", "Member[myFunction]", "Argument[0]", "ReturnValue", "taint"] + * ``` + */ abstract class SummarizedCallable extends LibraryCallable, Impl::Public::SummarizedCallable { bindingset[this] SummarizedCallable() { any() } @@ -15,6 +57,9 @@ abstract class SummarizedCallable extends LibraryCallable, Impl::Public::Summari * Holds if data may flow from `input` to `output` through this callable. * * `preservesValue` indicates whether this is a value-preserving step or a taint-step. + * + * See the [library customization docs](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-javascript) for + * the syntax of the `input` and `output` parameters. */ pragma[nomagic] predicate propagatesFlow(string input, string output, boolean preservesValue) { none() } From 249104b8ae20d566f64b1ad1b7148b019be5d527 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 Nov 2024 14:40:36 +0100 Subject: [PATCH 394/514] JS: Update comments referring to old `Configuration` style Also avoid the term "analysis-specific" because it's not a term we use anywhere else. --- .../ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll | 3 +-- .../ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll b/javascript/ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll index d3935d463f1..457d5892675 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll @@ -29,8 +29,7 @@ private import semmle.javascript.internal.CachedStages * This class is a singleton, and thus subclasses do not need to specify a characteristic predicate. * * Note: For performance reasons, all subclasses of this class should be part - * of the standard library. Override `Configuration::isAdditionalFlowStep` - * for analysis-specific flow steps. + * of the standard library. Use `isAdditionalFlowStep` for query-specific flow steps. */ class AdditionalFlowStep extends Unit { /** diff --git a/javascript/ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll b/javascript/ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll index 86eb6078a72..37742a26c40 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll @@ -12,8 +12,7 @@ private import semmle.javascript.internal.CachedStages * This class is a singleton, and thus subclasses do not need to specify a characteristic predicate. * * Note: For performance reasons, all subclasses of this class should be part - * of the standard library. Override `Configuration::isAdditionalTaintStep` - * for analysis-specific taint steps. + * of the standard library. Use `isAdditionalFlowStep` for query-specific taint steps. */ class AdditionalTaintStep extends Unit { /** From f758b67d303b8861ae72cefb481b4cfc1ecb3a9b Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 Nov 2024 14:50:27 +0100 Subject: [PATCH 395/514] JS: Openly recommend SummarizedCallable --- .../ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll | 2 ++ .../ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll | 2 ++ javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll | 1 + 3 files changed, 5 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll b/javascript/ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll index 457d5892675..49b6d11bbc9 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/AdditionalFlowSteps.qll @@ -28,6 +28,8 @@ private import semmle.javascript.internal.CachedStages * * This class is a singleton, and thus subclasses do not need to specify a characteristic predicate. * + * As an alternative to this class, consider using `DataFlow::SummarizedCallable`. + * * Note: For performance reasons, all subclasses of this class should be part * of the standard library. Use `isAdditionalFlowStep` for query-specific flow steps. */ diff --git a/javascript/ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll b/javascript/ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll index 37742a26c40..fa52b568173 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/AdditionalTaintSteps.qll @@ -11,6 +11,8 @@ private import semmle.javascript.internal.CachedStages * * This class is a singleton, and thus subclasses do not need to specify a characteristic predicate. * + * As an alternative to this class, consider using `DataFlow::SummarizedCallable`. + * * Note: For performance reasons, all subclasses of this class should be part * of the standard library. Use `isAdditionalFlowStep` for query-specific taint steps. */ diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index 263e5cdc007..ab11e011a7d 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -1935,4 +1935,5 @@ module DataFlow { import internal.FunctionWrapperSteps import internal.sharedlib.DataFlow import internal.BarrierGuards + import FlowSummary } From a568d8c08654ad70fbf76df689361d883c7a8173 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 11:05:52 +0100 Subject: [PATCH 396/514] JS: Port threat-model test to ConfigSig --- .../sources/TestSources.expected | 1 + .../threat-models/sources/TestSources.ql | 21 +++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/javascript/ql/test/library-tests/threat-models/sources/TestSources.expected b/javascript/ql/test/library-tests/threat-models/sources/TestSources.expected index 8ec8033d086..0df66c66113 100644 --- a/javascript/ql/test/library-tests/threat-models/sources/TestSources.expected +++ b/javascript/ql/test/library-tests/threat-models/sources/TestSources.expected @@ -1,2 +1,3 @@ +legacyDataFlowDifference testFailures failures diff --git a/javascript/ql/test/library-tests/threat-models/sources/TestSources.ql b/javascript/ql/test/library-tests/threat-models/sources/TestSources.ql index 3dc112c487e..432a86ce102 100644 --- a/javascript/ql/test/library-tests/threat-models/sources/TestSources.ql +++ b/javascript/ql/test/library-tests/threat-models/sources/TestSources.ql @@ -1,12 +1,10 @@ import javascript import testUtilities.InlineExpectationsTest -class TestSourcesConfiguration extends TaintTracking::Configuration { - TestSourcesConfiguration() { this = "TestSources" } +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof ThreatModelSource } - override predicate isSource(DataFlow::Node source) { source instanceof ThreatModelSource } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(CallExpr call | call.getAnArgument() = sink.asExpr() and call.getCalleeName() = "SINK" @@ -14,12 +12,22 @@ class TestSourcesConfiguration extends TaintTracking::Configuration { } } +module TestFlow = TaintTracking::Global; + +deprecated class LegacyConfig extends TaintTracking::Configuration { + LegacyConfig() { this = "TestSources" } + + override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } + + override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } +} + private module InlineTestSources implements TestSig { string getARelevantTag() { result in ["hasFlow", "threat-source"] } predicate hasActualResult(Location location, string element, string tag, string value) { exists(DataFlow::Node sink | - any(TestSourcesConfiguration c).hasFlow(_, sink) and + TestFlow::flowTo(sink) and value = "" and location = sink.getLocation() and tag = "hasFlow" and @@ -36,3 +44,4 @@ private module InlineTestSources implements TestSig { } import MakeTest +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff From 3548544970a16ec8017c9eaac3ac9aac7b64501f Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 11:07:23 +0100 Subject: [PATCH 397/514] JS: Avoid some uses of deprecated guard classes in tests --- .../LabelledBarrierGuards.ql | 37 ++++++++++--------- .../TaintTracking/DataFlowTracking.ql | 20 +++++----- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/javascript/ql/test/library-tests/LabelledBarrierGuards/LabelledBarrierGuards.ql b/javascript/ql/test/library-tests/LabelledBarrierGuards/LabelledBarrierGuards.ql index 781db8026f3..ad8b63ea13e 100644 --- a/javascript/ql/test/library-tests/LabelledBarrierGuards/LabelledBarrierGuards.ql +++ b/javascript/ql/test/library-tests/LabelledBarrierGuards/LabelledBarrierGuards.ql @@ -20,19 +20,15 @@ module TestConfig implements DataFlow::StateConfigSig { ) } - additional predicate isBarrierGuard(DataFlow::BarrierGuardNode node) { - node instanceof IsTypeAGuard or - node instanceof IsSanitizedGuard - } - predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel lbl) { - node = DataFlow::MakeLegacyBarrierGuardLabeled::getABarrierNode(lbl) + node = DataFlow::MakeLabeledBarrierGuard::getABarrierNode(lbl) or + node = DataFlow::MakeLabeledBarrierGuard::getABarrierNode(lbl) } } module TestFlow = TaintTracking::GlobalWithState; -class LegacyConfig extends TaintTracking::Configuration { +deprecated class LegacyConfig extends TaintTracking::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node node, DataFlow::FlowLabel lbl) { @@ -44,7 +40,8 @@ class LegacyConfig extends TaintTracking::Configuration { } override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode node) { - TestConfig::isBarrierGuard(node) + node instanceof IsTypeAGuardLegacy or + node instanceof IsSanitizedGuardLegacy } } @@ -52,13 +49,9 @@ class LegacyConfig extends TaintTracking::Configuration { * A condition that checks what kind of value the input is. Not enough to * sanitize the value, but later sanitizers only need to handle the relevant case. */ -class IsTypeAGuard extends TaintTracking::LabeledSanitizerGuardNode, DataFlow::CallNode { +class IsTypeAGuard extends DataFlow::CallNode { IsTypeAGuard() { this.getCalleeName() = "isTypeA" } - override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { - this.blocksExpr(outcome, e, lbl) - } - predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { e = this.getArgument(0).asExpr() and ( @@ -69,12 +62,14 @@ class IsTypeAGuard extends TaintTracking::LabeledSanitizerGuardNode, DataFlow::C } } -class IsSanitizedGuard extends TaintTracking::LabeledSanitizerGuardNode, DataFlow::CallNode { - IsSanitizedGuard() { this.getCalleeName() = "sanitizeA" or this.getCalleeName() = "sanitizeB" } - +deprecated class IsTypeAGuardLegacy extends IsTypeAGuard, TaintTracking::LabeledSanitizerGuardNode { override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { this.blocksExpr(outcome, e, lbl) } +} + +class IsSanitizedGuard extends DataFlow::CallNode { + IsSanitizedGuard() { this.getCalleeName() = "sanitizeA" or this.getCalleeName() = "sanitizeB" } predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { e = this.getArgument(0).asExpr() and @@ -87,7 +82,15 @@ class IsSanitizedGuard extends TaintTracking::LabeledSanitizerGuardNode, DataFlo } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated class IsSanitizedGuardLegacy extends IsSanitizedGuard, + TaintTracking::LabeledSanitizerGuardNode +{ + override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { + this.blocksExpr(outcome, e, lbl) + } +} + +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff from DataFlow::Node source, DataFlow::Node sink where TestFlow::flow(source, sink) diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.ql b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.ql index 62abcda81a5..8617c8bcf51 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.ql +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.ql @@ -7,28 +7,26 @@ module TestConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node node) { node = getACall("sink").getAnArgument() } - additional predicate isBarrierGuard(DataFlow::BarrierGuardNode node) { - node instanceof BasicBarrierGuard - } - predicate isBarrier(DataFlow::Node node) { - node = DataFlow::MakeLegacyBarrierGuard::getABarrierNode() + node = DataFlow::MakeBarrierGuard::getABarrierNode() } } module TestFlow = DataFlow::Global; -class BasicBarrierGuard extends DataFlow::BarrierGuardNode, DataFlow::CallNode { +class BasicBarrierGuard extends DataFlow::CallNode { BasicBarrierGuard() { this = getACall("isSafe") } - override predicate blocks(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } - predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = this.getArgument(0).asExpr() } } -class LegacyConfig extends DataFlow::Configuration { +deprecated class BasicBarrierGuardLegacy extends DataFlow::BarrierGuardNode, BasicBarrierGuard { + override predicate blocks(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } +} + +deprecated class LegacyConfig extends DataFlow::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -36,10 +34,10 @@ class LegacyConfig extends DataFlow::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } override predicate isBarrierGuard(DataFlow::BarrierGuardNode node) { - TestConfig::isBarrierGuard(node) + node instanceof BasicBarrierGuardLegacy } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff query predicate flow = TestFlow::flow/2; From 4d7401a07479624d1ec593db664d4539954fe1b0 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 11:09:55 +0100 Subject: [PATCH 398/514] JS: Deprecate tests for deprecated APIs Mainly adds 'deprecated' in front of a bunch of tests for deprecated APIs. --- .../ql/test/library-tests/Arrays/DataFlow.ql | 4 ++-- .../ql/test/library-tests/Arrays/TaintFlow.ql | 4 ++-- .../library-tests/Barriers/SimpleBarrierGuard.ql | 4 ++-- javascript/ql/test/library-tests/Classes/tests.ql | 4 ++-- .../library-tests/CustomLoadStoreSteps/test.ql | 8 ++++---- .../ql/test/library-tests/Generators/DataFlow.ql | 4 ++-- javascript/ql/test/library-tests/Promises/flow.qll | 6 +++--- javascript/ql/test/library-tests/Routing/test.ql | 4 ++-- .../Security/heuristics/HeuristicSource.ql | 4 ++-- .../TaintBarriers/ExampleConfiguration.qll | 2 +- .../ql/test/library-tests/TaintBarriers/tests.ql | 14 +++++++++----- .../TaintTracking/BasicTaintTracking.ql | 4 ++-- .../library-tests/TypeScript/ImportEquals/tests.ql | 4 ++-- .../test/library-tests/frameworks/Angular2/test.ql | 4 ++-- .../frameworks/AsyncPackage/AsyncTaintTracking.ql | 4 ++-- .../library-tests/frameworks/Collections/test.ql | 4 ++-- .../frameworks/ComposedFunctions/compose.ql | 4 ++-- .../library-tests/frameworks/Immutable/tests.ql | 4 ++-- .../ql/test/library-tests/frameworks/Next/tests.ql | 4 ++-- .../PropertyProjection/PropertyInjectionTaint.ql | 4 ++-- .../ql/test/library-tests/frameworks/Redux/test.ql | 4 ++-- .../library-tests/frameworks/Templating/XssDiff.ql | 2 +- .../ql/test/library-tests/frameworks/Vuex/test.ql | 4 ++-- .../ql/test/library-tests/frameworks/data/test.ql | 4 ++-- .../ql/test/testUtilities/LegacyDataFlowDiff.qll | 4 +++- 25 files changed, 59 insertions(+), 53 deletions(-) diff --git a/javascript/ql/test/library-tests/Arrays/DataFlow.ql b/javascript/ql/test/library-tests/Arrays/DataFlow.ql index dab899b56b0..4ececa96773 100644 --- a/javascript/ql/test/library-tests/Arrays/DataFlow.ql +++ b/javascript/ql/test/library-tests/Arrays/DataFlow.ql @@ -10,7 +10,7 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = DataFlow::Global; -class LegacyConfig extends DataFlow::Configuration { +deprecated class LegacyConfig extends DataFlow::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -18,6 +18,6 @@ class LegacyConfig extends DataFlow::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff query predicate flow = TestFlow::flow/2; diff --git a/javascript/ql/test/library-tests/Arrays/TaintFlow.ql b/javascript/ql/test/library-tests/Arrays/TaintFlow.ql index 8e0763c8a39..5a77fd2ff76 100644 --- a/javascript/ql/test/library-tests/Arrays/TaintFlow.ql +++ b/javascript/ql/test/library-tests/Arrays/TaintFlow.ql @@ -10,7 +10,7 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = TaintTracking::Global; -class LegacyConfig extends TaintTracking::Configuration { +deprecated class LegacyConfig extends TaintTracking::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -18,6 +18,6 @@ class LegacyConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff query predicate flow = TestFlow::flow/2; diff --git a/javascript/ql/test/library-tests/Barriers/SimpleBarrierGuard.ql b/javascript/ql/test/library-tests/Barriers/SimpleBarrierGuard.ql index a548e99a1ff..7f1c572b710 100644 --- a/javascript/ql/test/library-tests/Barriers/SimpleBarrierGuard.ql +++ b/javascript/ql/test/library-tests/Barriers/SimpleBarrierGuard.ql @@ -30,7 +30,7 @@ class SimpleBarrierGuardNode extends DataFlow::BarrierGuardNode, DataFlow::Invok } } -class LegacyConfig extends DataFlow::Configuration { +deprecated class LegacyConfig extends DataFlow::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -42,6 +42,6 @@ class LegacyConfig extends DataFlow::Configuration { } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff query predicate flow = TestFlow::flow/2; diff --git a/javascript/ql/test/library-tests/Classes/tests.ql b/javascript/ql/test/library-tests/Classes/tests.ql index d01f8f6f640..1dcab4ca134 100644 --- a/javascript/ql/test/library-tests/Classes/tests.ql +++ b/javascript/ql/test/library-tests/Classes/tests.ql @@ -69,7 +69,7 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = DataFlow::Global; -class LegacyConfig extends DataFlow::Configuration { +deprecated class LegacyConfig extends DataFlow::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -77,7 +77,7 @@ class LegacyConfig extends DataFlow::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff query predicate dataflow = TestFlow::flow/2; diff --git a/javascript/ql/test/library-tests/CustomLoadStoreSteps/test.ql b/javascript/ql/test/library-tests/CustomLoadStoreSteps/test.ql index c6721b52217..ac213ba2624 100644 --- a/javascript/ql/test/library-tests/CustomLoadStoreSteps/test.ql +++ b/javascript/ql/test/library-tests/CustomLoadStoreSteps/test.ql @@ -1,7 +1,7 @@ import javascript // Note: this test has not been ported to ConfigSig, because isAdditionalLoadStep has no equivalent there -class Configuration extends TaintTracking::Configuration { +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "PromiseFlowTestingConfig" } override predicate isSource(DataFlow::Node source) { @@ -34,6 +34,6 @@ class Configuration extends TaintTracking::Configuration { } } -from DataFlow::Node pred, DataFlow::Node succ, Configuration cfg -where cfg.hasFlow(pred, succ) -select pred, succ +deprecated query predicate flow(DataFlow::Node source, DataFlow::Node sink) { + any(Configuration cfg).hasFlow(source, sink) +} diff --git a/javascript/ql/test/library-tests/Generators/DataFlow.ql b/javascript/ql/test/library-tests/Generators/DataFlow.ql index f613ed62f3b..71fce93ae32 100644 --- a/javascript/ql/test/library-tests/Generators/DataFlow.ql +++ b/javascript/ql/test/library-tests/Generators/DataFlow.ql @@ -11,7 +11,7 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = DataFlow::Global; -class LegacyConfig extends DataFlow::Configuration { +deprecated class LegacyConfig extends DataFlow::Configuration { LegacyConfig() { this = "GeneratorFlowConfig" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -19,7 +19,7 @@ class LegacyConfig extends DataFlow::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff class Consistency extends ConsistencyConfiguration { Consistency() { this = "Consistency" } diff --git a/javascript/ql/test/library-tests/Promises/flow.qll b/javascript/ql/test/library-tests/Promises/flow.qll index 90069773b45..b77a8691ec8 100644 --- a/javascript/ql/test/library-tests/Promises/flow.qll +++ b/javascript/ql/test/library-tests/Promises/flow.qll @@ -1,6 +1,6 @@ import javascript private import semmle.javascript.dataflow.internal.StepSummary -import testUtilities.LegacyDataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff module ValueFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { @@ -45,7 +45,7 @@ class LegacyValueConfig extends DataFlow::Configuration { override predicate isSink(DataFlow::Node sink) { ValueFlowConfig::isSink(sink) } } -query predicate valueFlowDifference = +deprecated query predicate valueFlowDifference = DataFlowDiff::legacyDataFlowDifference/3; class LegacyTaintConfig extends TaintTracking::Configuration { @@ -56,5 +56,5 @@ class LegacyTaintConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { TaintConfig::isSink(sink) } } -query predicate taintFlowDifference = +deprecated query predicate taintFlowDifference = DataFlowDiff::legacyDataFlowDifference/3; diff --git a/javascript/ql/test/library-tests/Routing/test.ql b/javascript/ql/test/library-tests/Routing/test.ql index 6a97d040bb9..07b7295dc65 100644 --- a/javascript/ql/test/library-tests/Routing/test.ql +++ b/javascript/ql/test/library-tests/Routing/test.ql @@ -25,7 +25,7 @@ class Consistency extends ConsistencyConfiguration { override DataFlow::Node getAnAlert() { TestFlow::flowTo(result) } } -class LegacyConfig extends TaintTracking::Configuration { +deprecated class LegacyConfig extends TaintTracking::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -33,4 +33,4 @@ class LegacyConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff diff --git a/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.ql b/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.ql index 44258ecb6ff..4568bed8a6d 100644 --- a/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.ql +++ b/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.ql @@ -18,7 +18,7 @@ class Consistency extends ConsistencyConfiguration { override DataFlow::Node getAnAlert() { TestFlow::flowTo(result) } } -class LegacyConfig extends TaintTracking::Configuration { +deprecated class LegacyConfig extends TaintTracking::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -26,4 +26,4 @@ class LegacyConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff diff --git a/javascript/ql/test/library-tests/TaintBarriers/ExampleConfiguration.qll b/javascript/ql/test/library-tests/TaintBarriers/ExampleConfiguration.qll index 56217573da8..5408ada4dcc 100644 --- a/javascript/ql/test/library-tests/TaintBarriers/ExampleConfiguration.qll +++ b/javascript/ql/test/library-tests/TaintBarriers/ExampleConfiguration.qll @@ -42,7 +42,7 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = TaintTracking::Global; -class ExampleConfiguration extends TaintTracking::Configuration { +deprecated class ExampleConfiguration extends TaintTracking::Configuration { ExampleConfiguration() { this = "ExampleConfiguration" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } diff --git a/javascript/ql/test/library-tests/TaintBarriers/tests.ql b/javascript/ql/test/library-tests/TaintBarriers/tests.ql index d6f3b4ae845..7c6ad5231ac 100644 --- a/javascript/ql/test/library-tests/TaintBarriers/tests.ql +++ b/javascript/ql/test/library-tests/TaintBarriers/tests.ql @@ -1,17 +1,21 @@ import javascript import ExampleConfiguration -query predicate isBarrier(ExampleConfiguration cfg, DataFlow::Node n) { cfg.isBarrier(n) } +deprecated query predicate isBarrier(ExampleConfiguration cfg, DataFlow::Node n) { + cfg.isBarrier(n) +} -query predicate isLabeledBarrier( +deprecated query predicate isLabeledBarrier( ExampleConfiguration cfg, DataFlow::Node n, DataFlow::FlowLabel label ) { cfg.isLabeledBarrier(n, label) } -query predicate isSanitizer(ExampleConfiguration cfg, DataFlow::Node n) { cfg.isSanitizer(n) } +deprecated query predicate isSanitizer(ExampleConfiguration cfg, DataFlow::Node n) { + cfg.isSanitizer(n) +} -query predicate sanitizingGuard(DataFlow::Node g, Expr e, boolean b) { +deprecated query predicate sanitizingGuard(DataFlow::Node g, Expr e, boolean b) { g.(TaintTracking::SanitizerGuardNode).sanitizes(b, e) or g.(TaintTracking::AdditionalSanitizerGuardNode).sanitizes(b, e) @@ -21,4 +25,4 @@ query predicate taintedSink(DataFlow::Node source, DataFlow::Node sink) { TestFlow::flow(source, sink) } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql index d76cd7b8fb9..a8aee22efb1 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql @@ -22,7 +22,7 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = TaintTracking::Global; -class LegacyConfig extends TaintTracking::Configuration { +deprecated class LegacyConfig extends TaintTracking::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node node) { TestConfig::isSource(node) } @@ -39,7 +39,7 @@ class LegacyConfig extends TaintTracking::Configuration { } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff class BasicSanitizerGuard extends TaintTracking::SanitizerGuardNode, DataFlow::CallNode { BasicSanitizerGuard() { this = getACall("isSafe") } diff --git a/javascript/ql/test/library-tests/TypeScript/ImportEquals/tests.ql b/javascript/ql/test/library-tests/TypeScript/ImportEquals/tests.ql index caa919ffe8d..a7c1c072690 100644 --- a/javascript/ql/test/library-tests/TypeScript/ImportEquals/tests.ql +++ b/javascript/ql/test/library-tests/TypeScript/ImportEquals/tests.ql @@ -52,7 +52,7 @@ module TestFlow = TaintTracking::Global; query predicate taint = TestFlow::flow/2; -class LegacyConfig extends TaintTracking::Configuration { +deprecated class LegacyConfig extends TaintTracking::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -60,4 +60,4 @@ class LegacyConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff diff --git a/javascript/ql/test/library-tests/frameworks/Angular2/test.ql b/javascript/ql/test/library-tests/frameworks/Angular2/test.ql index ee5dc370eee..ec9dc3d46ba 100644 --- a/javascript/ql/test/library-tests/frameworks/Angular2/test.ql +++ b/javascript/ql/test/library-tests/frameworks/Angular2/test.ql @@ -33,7 +33,7 @@ query predicate testAttrSourceLocation(HTML::Attribute attrib, Angular2::Templat top = attrib.getCodeInAttribute() } -class LegacyConfig extends TaintTracking::Configuration { +deprecated class LegacyConfig extends TaintTracking::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -41,4 +41,4 @@ class LegacyConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff diff --git a/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.ql b/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.ql index f3afe84d75a..b444b7cbff7 100644 --- a/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.ql +++ b/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.ql @@ -10,7 +10,7 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = TaintTracking::Global; -class LegacyConfig extends TaintTracking::Configuration { +deprecated class LegacyConfig extends TaintTracking::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -18,7 +18,7 @@ class LegacyConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff from DataFlow::Node src, DataFlow::Node sink where TestFlow::flow(src, sink) diff --git a/javascript/ql/test/library-tests/frameworks/Collections/test.ql b/javascript/ql/test/library-tests/frameworks/Collections/test.ql index f55cce9e035..a4bdd7dcfbc 100644 --- a/javascript/ql/test/library-tests/frameworks/Collections/test.ql +++ b/javascript/ql/test/library-tests/frameworks/Collections/test.ql @@ -14,7 +14,7 @@ module TestFlow = DataFlow::Global; query predicate dataFlow = TestFlow::flow/2; -class LegacyConfig extends DataFlow::Configuration { +deprecated class LegacyConfig extends DataFlow::Configuration { LegacyConfig() { this = "Config" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -22,7 +22,7 @@ class LegacyConfig extends DataFlow::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff DataFlow::SourceNode trackSource(DataFlow::TypeTracker t, DataFlow::SourceNode start) { t.start() and diff --git a/javascript/ql/test/library-tests/frameworks/ComposedFunctions/compose.ql b/javascript/ql/test/library-tests/frameworks/ComposedFunctions/compose.ql index dba04b72ef1..5e56ebd399e 100644 --- a/javascript/ql/test/library-tests/frameworks/ComposedFunctions/compose.ql +++ b/javascript/ql/test/library-tests/frameworks/ComposedFunctions/compose.ql @@ -15,7 +15,7 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = TaintTracking::Global; -class LegacyConfig extends TaintTracking::Configuration { +deprecated class LegacyConfig extends TaintTracking::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -23,7 +23,7 @@ class LegacyConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff from DataFlow::Node source, DataFlow::Node sink where TestFlow::flow(source, sink) diff --git a/javascript/ql/test/library-tests/frameworks/Immutable/tests.ql b/javascript/ql/test/library-tests/frameworks/Immutable/tests.ql index d530e770093..0fdfb05b206 100644 --- a/javascript/ql/test/library-tests/frameworks/Immutable/tests.ql +++ b/javascript/ql/test/library-tests/frameworks/Immutable/tests.ql @@ -13,7 +13,7 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = DataFlow::Global; -class LegacyConfig extends DataFlow::Configuration { +deprecated class LegacyConfig extends DataFlow::Configuration { LegacyConfig() { this = "Config" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -23,4 +23,4 @@ class LegacyConfig extends DataFlow::Configuration { query predicate dataFlow = TestFlow::flow/2; -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff diff --git a/javascript/ql/test/library-tests/frameworks/Next/tests.ql b/javascript/ql/test/library-tests/frameworks/Next/tests.ql index 98f4185b9ec..c8229ee9103 100644 --- a/javascript/ql/test/library-tests/frameworks/Next/tests.ql +++ b/javascript/ql/test/library-tests/frameworks/Next/tests.ql @@ -14,7 +14,7 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = DataFlow::Global; -class LegacyConfig extends DataFlow::Configuration { +deprecated class LegacyConfig extends DataFlow::Configuration { LegacyConfig() { this = "Config" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -22,6 +22,6 @@ class LegacyConfig extends DataFlow::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff query predicate dataFlow = TestFlow::flow/2; diff --git a/javascript/ql/test/library-tests/frameworks/PropertyProjection/PropertyInjectionTaint.ql b/javascript/ql/test/library-tests/frameworks/PropertyProjection/PropertyInjectionTaint.ql index dba04b72ef1..5e56ebd399e 100644 --- a/javascript/ql/test/library-tests/frameworks/PropertyProjection/PropertyInjectionTaint.ql +++ b/javascript/ql/test/library-tests/frameworks/PropertyProjection/PropertyInjectionTaint.ql @@ -15,7 +15,7 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = TaintTracking::Global; -class LegacyConfig extends TaintTracking::Configuration { +deprecated class LegacyConfig extends TaintTracking::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -23,7 +23,7 @@ class LegacyConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff from DataFlow::Node source, DataFlow::Node sink where TestFlow::flow(source, sink) diff --git a/javascript/ql/test/library-tests/frameworks/Redux/test.ql b/javascript/ql/test/library-tests/frameworks/Redux/test.ql index 0cf6c7913ad..6ca6332ef69 100644 --- a/javascript/ql/test/library-tests/frameworks/Redux/test.ql +++ b/javascript/ql/test/library-tests/frameworks/Redux/test.ql @@ -54,7 +54,7 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = TaintTracking::Global; -class LegacyConfig extends TaintTracking::Configuration { +deprecated class LegacyConfig extends TaintTracking::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -62,7 +62,7 @@ class LegacyConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff query predicate taintFlow(DataFlow::Node source, DataFlow::Node sink) { TestFlow::flow(source, sink) diff --git a/javascript/ql/test/library-tests/frameworks/Templating/XssDiff.ql b/javascript/ql/test/library-tests/frameworks/Templating/XssDiff.ql index def7b283440..81ccaeea475 100644 --- a/javascript/ql/test/library-tests/frameworks/Templating/XssDiff.ql +++ b/javascript/ql/test/library-tests/frameworks/Templating/XssDiff.ql @@ -1,6 +1,6 @@ import javascript import semmle.javascript.security.dataflow.DomBasedXssQuery -import testUtilities.LegacyDataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff deprecated query predicate legacyDataFlowDifference = DataFlowDiff::legacyDataFlowDifference/3; diff --git a/javascript/ql/test/library-tests/frameworks/Vuex/test.ql b/javascript/ql/test/library-tests/frameworks/Vuex/test.ql index ac58a94374e..00a3f258135 100644 --- a/javascript/ql/test/library-tests/frameworks/Vuex/test.ql +++ b/javascript/ql/test/library-tests/frameworks/Vuex/test.ql @@ -17,7 +17,7 @@ class Consistency extends ConsistencyConfiguration { override DataFlow::Node getAnAlert() { TestFlow::flowTo(result) } } -class LegacyConfig extends TaintTracking::Configuration { +deprecated class LegacyConfig extends TaintTracking::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -25,4 +25,4 @@ class LegacyConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff diff --git a/javascript/ql/test/library-tests/frameworks/data/test.ql b/javascript/ql/test/library-tests/frameworks/data/test.ql index f0ef2e129e7..11c7d78e9cc 100644 --- a/javascript/ql/test/library-tests/frameworks/data/test.ql +++ b/javascript/ql/test/library-tests/frameworks/data/test.ql @@ -33,7 +33,7 @@ class Consistency extends ConsistencyConfiguration { override DataFlow::Node getAnAlert() { TestFlow::flowTo(result) } } -class LegacyConfig extends TaintTracking::Configuration { +deprecated class LegacyConfig extends TaintTracking::Configuration { LegacyConfig() { this = "LegacyConfig" } override predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } @@ -41,7 +41,7 @@ class LegacyConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } } -import testUtilities.LegacyDataFlowDiff::DataFlowDiff +deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff query predicate taintFlow(DataFlow::Node source, DataFlow::Node sink) { TestFlow::flow(source, sink) diff --git a/javascript/ql/test/testUtilities/LegacyDataFlowDiff.qll b/javascript/ql/test/testUtilities/LegacyDataFlowDiff.qll index 00fd8217c21..0995d06199c 100644 --- a/javascript/ql/test/testUtilities/LegacyDataFlowDiff.qll +++ b/javascript/ql/test/testUtilities/LegacyDataFlowDiff.qll @@ -1,6 +1,8 @@ private import javascript -private signature class LegacyConfigSig extends DataFlow::Configuration; +private signature class LegacyConfigSig { + predicate hasFlow(DataFlow::Node source, DataFlow::Node sink); +} module DataFlowDiff { query predicate legacyDataFlowDifference( From 1832e937660dd6c74a11580e6e62002d30484826 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 11:13:30 +0100 Subject: [PATCH 399/514] JS: Port FormParsers test to ConfigSig --- .../FormParsers/RemoteFlowSource.expected | 302 ++++++------------ .../FormParsers/RemoteFlowSource.ql | 17 +- 2 files changed, 103 insertions(+), 216 deletions(-) diff --git a/javascript/ql/test/experimental/FormParsers/RemoteFlowSource.expected b/javascript/ql/test/experimental/FormParsers/RemoteFlowSource.expected index bbd62023e24..4cd0cf23378 100644 --- a/javascript/ql/test/experimental/FormParsers/RemoteFlowSource.expected +++ b/javascript/ql/test/experimental/FormParsers/RemoteFlowSource.expected @@ -1,212 +1,98 @@ -nodes -| busybus.js:9:30:9:33 | file | -| busybus.js:9:30:9:33 | file | -| busybus.js:9:36:9:39 | info | -| busybus.js:9:36:9:39 | info | -| busybus.js:10:19:10:50 | { filen ... eType } | -| busybus.js:10:19:10:57 | encoding | -| busybus.js:10:19:10:57 | filename | -| busybus.js:10:19:10:57 | mimeType | -| busybus.js:10:21:10:28 | filename | -| busybus.js:10:31:10:38 | encoding | -| busybus.js:10:41:10:48 | mimeType | -| busybus.js:10:54:10:57 | info | -| busybus.js:12:18:12:25 | filename | -| busybus.js:12:18:12:25 | filename | -| busybus.js:12:28:12:35 | encoding | -| busybus.js:12:28:12:35 | encoding | -| busybus.js:12:38:12:45 | mimeType | -| busybus.js:12:38:12:45 | mimeType | -| busybus.js:13:23:13:23 | z | -| busybus.js:13:31:13:36 | sink() | -| busybus.js:13:31:13:36 | sink() | -| busybus.js:15:30:15:33 | data | -| busybus.js:15:30:15:33 | data | -| busybus.js:16:22:16:25 | data | -| busybus.js:16:22:16:25 | data | -| busybus.js:22:25:22:42 | data | -| busybus.js:22:32:22:42 | this.read() | -| busybus.js:22:32:22:42 | this.read() | -| busybus.js:23:26:23:29 | data | -| busybus.js:23:26:23:29 | data | -| busybus.js:27:25:27:28 | name | -| busybus.js:27:25:27:28 | name | -| busybus.js:27:31:27:33 | val | -| busybus.js:27:31:27:33 | val | -| busybus.js:27:36:27:39 | info | -| busybus.js:27:36:27:39 | info | -| busybus.js:28:18:28:21 | name | -| busybus.js:28:18:28:21 | name | -| busybus.js:28:24:28:26 | val | -| busybus.js:28:24:28:26 | val | -| busybus.js:28:29:28:32 | info | -| busybus.js:28:29:28:32 | info | -| dicer.js:12:23:12:26 | part | -| dicer.js:12:23:12:26 | part | -| dicer.js:13:19:13:24 | sink() | -| dicer.js:13:19:13:24 | sink() | -| dicer.js:14:28:14:33 | header | -| dicer.js:14:28:14:33 | header | -| dicer.js:16:22:16:27 | header | -| dicer.js:16:22:16:30 | header[h] | -| dicer.js:16:22:16:30 | header[h] | -| dicer.js:19:26:19:29 | data | -| dicer.js:19:26:19:29 | data | -| dicer.js:20:18:20:21 | data | -| dicer.js:20:18:20:21 | data | -| formidable.js:7:11:7:25 | [fields, files] | -| formidable.js:7:11:7:49 | fields | -| formidable.js:7:11:7:49 | files | -| formidable.js:7:12:7:17 | fields | -| formidable.js:7:20:7:24 | files | -| formidable.js:7:29:7:49 | await f ... se(req) | -| formidable.js:7:35:7:49 | form.parse(req) | -| formidable.js:7:35:7:49 | form.parse(req) | -| formidable.js:8:10:8:15 | fields | -| formidable.js:8:10:8:15 | fields | -| formidable.js:8:18:8:22 | files | -| formidable.js:8:18:8:22 | files | -| formidable.js:9:27:9:34 | formname | -| formidable.js:9:27:9:34 | formname | -| formidable.js:9:37:9:40 | file | -| formidable.js:9:37:9:40 | file | -| formidable.js:10:14:10:21 | formname | -| formidable.js:10:14:10:21 | formname | -| formidable.js:10:24:10:27 | file | -| formidable.js:10:24:10:27 | file | -| formidable.js:12:22:12:29 | formname | -| formidable.js:12:22:12:29 | formname | -| formidable.js:12:32:12:35 | file | -| formidable.js:12:32:12:35 | file | -| formidable.js:13:14:13:21 | formname | -| formidable.js:13:14:13:21 | formname | -| formidable.js:13:24:13:27 | file | -| formidable.js:13:24:13:27 | file | -| formidable.js:15:23:15:31 | fieldName | -| formidable.js:15:23:15:31 | fieldName | -| formidable.js:15:34:15:43 | fieldValue | -| formidable.js:15:34:15:43 | fieldValue | -| formidable.js:16:14:16:22 | fieldName | -| formidable.js:16:14:16:22 | fieldName | -| formidable.js:16:25:16:34 | fieldValue | -| formidable.js:16:25:16:34 | fieldValue | -| multiparty.js:8:22:8:25 | part | -| multiparty.js:8:22:8:25 | part | -| multiparty.js:9:14:9:17 | part | -| multiparty.js:9:14:9:17 | part | -| multiparty.js:10:19:10:24 | sink() | -| multiparty.js:10:19:10:24 | sink() | -| multiparty.js:14:37:14:42 | fields | -| multiparty.js:14:37:14:42 | fields | -| multiparty.js:14:45:14:49 | files | -| multiparty.js:14:45:14:49 | files | -| multiparty.js:15:14:15:19 | fields | -| multiparty.js:15:14:15:19 | fields | -| multiparty.js:15:22:15:26 | files | -| multiparty.js:15:22:15:26 | files | edges -| busybus.js:9:30:9:33 | file | busybus.js:13:23:13:23 | z | -| busybus.js:9:30:9:33 | file | busybus.js:13:23:13:23 | z | -| busybus.js:9:36:9:39 | info | busybus.js:10:54:10:57 | info | -| busybus.js:9:36:9:39 | info | busybus.js:10:54:10:57 | info | -| busybus.js:10:19:10:50 | { filen ... eType } | busybus.js:10:21:10:28 | filename | -| busybus.js:10:19:10:50 | { filen ... eType } | busybus.js:10:31:10:38 | encoding | -| busybus.js:10:19:10:50 | { filen ... eType } | busybus.js:10:41:10:48 | mimeType | -| busybus.js:10:19:10:57 | encoding | busybus.js:12:28:12:35 | encoding | -| busybus.js:10:19:10:57 | encoding | busybus.js:12:28:12:35 | encoding | -| busybus.js:10:19:10:57 | filename | busybus.js:12:18:12:25 | filename | -| busybus.js:10:19:10:57 | filename | busybus.js:12:18:12:25 | filename | -| busybus.js:10:19:10:57 | mimeType | busybus.js:12:38:12:45 | mimeType | -| busybus.js:10:19:10:57 | mimeType | busybus.js:12:38:12:45 | mimeType | -| busybus.js:10:21:10:28 | filename | busybus.js:10:19:10:57 | filename | -| busybus.js:10:31:10:38 | encoding | busybus.js:10:19:10:57 | encoding | -| busybus.js:10:41:10:48 | mimeType | busybus.js:10:19:10:57 | mimeType | -| busybus.js:10:54:10:57 | info | busybus.js:10:19:10:50 | { filen ... eType } | -| busybus.js:13:23:13:23 | z | busybus.js:13:31:13:36 | sink() | -| busybus.js:13:23:13:23 | z | busybus.js:13:31:13:36 | sink() | -| busybus.js:15:30:15:33 | data | busybus.js:16:22:16:25 | data | -| busybus.js:15:30:15:33 | data | busybus.js:16:22:16:25 | data | -| busybus.js:15:30:15:33 | data | busybus.js:16:22:16:25 | data | -| busybus.js:15:30:15:33 | data | busybus.js:16:22:16:25 | data | -| busybus.js:22:25:22:42 | data | busybus.js:23:26:23:29 | data | -| busybus.js:22:25:22:42 | data | busybus.js:23:26:23:29 | data | -| busybus.js:22:32:22:42 | this.read() | busybus.js:22:25:22:42 | data | -| busybus.js:22:32:22:42 | this.read() | busybus.js:22:25:22:42 | data | -| busybus.js:27:25:27:28 | name | busybus.js:28:18:28:21 | name | -| busybus.js:27:25:27:28 | name | busybus.js:28:18:28:21 | name | -| busybus.js:27:25:27:28 | name | busybus.js:28:18:28:21 | name | -| busybus.js:27:25:27:28 | name | busybus.js:28:18:28:21 | name | -| busybus.js:27:31:27:33 | val | busybus.js:28:24:28:26 | val | -| busybus.js:27:31:27:33 | val | busybus.js:28:24:28:26 | val | -| busybus.js:27:31:27:33 | val | busybus.js:28:24:28:26 | val | -| busybus.js:27:31:27:33 | val | busybus.js:28:24:28:26 | val | -| busybus.js:27:36:27:39 | info | busybus.js:28:29:28:32 | info | -| busybus.js:27:36:27:39 | info | busybus.js:28:29:28:32 | info | -| busybus.js:27:36:27:39 | info | busybus.js:28:29:28:32 | info | -| busybus.js:27:36:27:39 | info | busybus.js:28:29:28:32 | info | -| dicer.js:12:23:12:26 | part | dicer.js:13:19:13:24 | sink() | -| dicer.js:12:23:12:26 | part | dicer.js:13:19:13:24 | sink() | -| dicer.js:12:23:12:26 | part | dicer.js:13:19:13:24 | sink() | -| dicer.js:12:23:12:26 | part | dicer.js:13:19:13:24 | sink() | -| dicer.js:14:28:14:33 | header | dicer.js:16:22:16:27 | header | -| dicer.js:14:28:14:33 | header | dicer.js:16:22:16:27 | header | -| dicer.js:16:22:16:27 | header | dicer.js:16:22:16:30 | header[h] | -| dicer.js:16:22:16:27 | header | dicer.js:16:22:16:30 | header[h] | -| dicer.js:19:26:19:29 | data | dicer.js:20:18:20:21 | data | -| dicer.js:19:26:19:29 | data | dicer.js:20:18:20:21 | data | -| dicer.js:19:26:19:29 | data | dicer.js:20:18:20:21 | data | -| dicer.js:19:26:19:29 | data | dicer.js:20:18:20:21 | data | -| formidable.js:7:11:7:25 | [fields, files] | formidable.js:7:12:7:17 | fields | -| formidable.js:7:11:7:25 | [fields, files] | formidable.js:7:20:7:24 | files | -| formidable.js:7:11:7:49 | fields | formidable.js:8:10:8:15 | fields | -| formidable.js:7:11:7:49 | fields | formidable.js:8:10:8:15 | fields | -| formidable.js:7:11:7:49 | files | formidable.js:8:18:8:22 | files | -| formidable.js:7:11:7:49 | files | formidable.js:8:18:8:22 | files | -| formidable.js:7:12:7:17 | fields | formidable.js:7:11:7:49 | fields | -| formidable.js:7:20:7:24 | files | formidable.js:7:11:7:49 | files | -| formidable.js:7:29:7:49 | await f ... se(req) | formidable.js:7:11:7:25 | [fields, files] | -| formidable.js:7:35:7:49 | form.parse(req) | formidable.js:7:29:7:49 | await f ... se(req) | -| formidable.js:7:35:7:49 | form.parse(req) | formidable.js:7:29:7:49 | await f ... se(req) | -| formidable.js:9:27:9:34 | formname | formidable.js:10:14:10:21 | formname | -| formidable.js:9:27:9:34 | formname | formidable.js:10:14:10:21 | formname | -| formidable.js:9:27:9:34 | formname | formidable.js:10:14:10:21 | formname | -| formidable.js:9:27:9:34 | formname | formidable.js:10:14:10:21 | formname | -| formidable.js:9:37:9:40 | file | formidable.js:10:24:10:27 | file | -| formidable.js:9:37:9:40 | file | formidable.js:10:24:10:27 | file | -| formidable.js:9:37:9:40 | file | formidable.js:10:24:10:27 | file | -| formidable.js:9:37:9:40 | file | formidable.js:10:24:10:27 | file | -| formidable.js:12:22:12:29 | formname | formidable.js:13:14:13:21 | formname | -| formidable.js:12:22:12:29 | formname | formidable.js:13:14:13:21 | formname | -| formidable.js:12:22:12:29 | formname | formidable.js:13:14:13:21 | formname | -| formidable.js:12:22:12:29 | formname | formidable.js:13:14:13:21 | formname | -| formidable.js:12:32:12:35 | file | formidable.js:13:24:13:27 | file | -| formidable.js:12:32:12:35 | file | formidable.js:13:24:13:27 | file | -| formidable.js:12:32:12:35 | file | formidable.js:13:24:13:27 | file | -| formidable.js:12:32:12:35 | file | formidable.js:13:24:13:27 | file | -| formidable.js:15:23:15:31 | fieldName | formidable.js:16:14:16:22 | fieldName | -| formidable.js:15:23:15:31 | fieldName | formidable.js:16:14:16:22 | fieldName | -| formidable.js:15:23:15:31 | fieldName | formidable.js:16:14:16:22 | fieldName | -| formidable.js:15:23:15:31 | fieldName | formidable.js:16:14:16:22 | fieldName | -| formidable.js:15:34:15:43 | fieldValue | formidable.js:16:25:16:34 | fieldValue | -| formidable.js:15:34:15:43 | fieldValue | formidable.js:16:25:16:34 | fieldValue | -| formidable.js:15:34:15:43 | fieldValue | formidable.js:16:25:16:34 | fieldValue | -| formidable.js:15:34:15:43 | fieldValue | formidable.js:16:25:16:34 | fieldValue | -| multiparty.js:8:22:8:25 | part | multiparty.js:9:14:9:17 | part | -| multiparty.js:8:22:8:25 | part | multiparty.js:9:14:9:17 | part | -| multiparty.js:8:22:8:25 | part | multiparty.js:9:14:9:17 | part | -| multiparty.js:8:22:8:25 | part | multiparty.js:9:14:9:17 | part | -| multiparty.js:8:22:8:25 | part | multiparty.js:10:19:10:24 | sink() | -| multiparty.js:8:22:8:25 | part | multiparty.js:10:19:10:24 | sink() | -| multiparty.js:8:22:8:25 | part | multiparty.js:10:19:10:24 | sink() | -| multiparty.js:8:22:8:25 | part | multiparty.js:10:19:10:24 | sink() | -| multiparty.js:14:37:14:42 | fields | multiparty.js:15:14:15:19 | fields | -| multiparty.js:14:37:14:42 | fields | multiparty.js:15:14:15:19 | fields | -| multiparty.js:14:37:14:42 | fields | multiparty.js:15:14:15:19 | fields | -| multiparty.js:14:37:14:42 | fields | multiparty.js:15:14:15:19 | fields | -| multiparty.js:14:45:14:49 | files | multiparty.js:15:22:15:26 | files | -| multiparty.js:14:45:14:49 | files | multiparty.js:15:22:15:26 | files | -| multiparty.js:14:45:14:49 | files | multiparty.js:15:22:15:26 | files | -| multiparty.js:14:45:14:49 | files | multiparty.js:15:22:15:26 | files | +| busybus.js:9:30:9:33 | file | busybus.js:13:23:13:23 | z | provenance | | +| busybus.js:9:36:9:39 | info | busybus.js:10:54:10:57 | info | provenance | | +| busybus.js:10:19:10:50 | { filen ... eType } | busybus.js:10:19:10:57 | encoding | provenance | | +| busybus.js:10:19:10:50 | { filen ... eType } | busybus.js:10:19:10:57 | filename | provenance | | +| busybus.js:10:19:10:50 | { filen ... eType } | busybus.js:10:19:10:57 | mimeType | provenance | | +| busybus.js:10:19:10:57 | encoding | busybus.js:12:28:12:35 | encoding | provenance | | +| busybus.js:10:19:10:57 | filename | busybus.js:12:18:12:25 | filename | provenance | | +| busybus.js:10:19:10:57 | mimeType | busybus.js:12:38:12:45 | mimeType | provenance | | +| busybus.js:10:54:10:57 | info | busybus.js:10:19:10:50 | { filen ... eType } | provenance | | +| busybus.js:13:23:13:23 | z | busybus.js:13:31:13:36 | sink() | provenance | | +| busybus.js:15:30:15:33 | data | busybus.js:16:22:16:25 | data | provenance | | +| busybus.js:22:25:22:42 | data | busybus.js:23:26:23:29 | data | provenance | | +| busybus.js:22:32:22:42 | this.read() | busybus.js:22:25:22:42 | data | provenance | | +| busybus.js:27:25:27:28 | name | busybus.js:28:18:28:21 | name | provenance | | +| busybus.js:27:31:27:33 | val | busybus.js:28:24:28:26 | val | provenance | | +| busybus.js:27:36:27:39 | info | busybus.js:28:29:28:32 | info | provenance | | +| dicer.js:12:23:12:26 | part | dicer.js:13:19:13:24 | sink() | provenance | | +| dicer.js:14:28:14:33 | header | dicer.js:16:22:16:27 | header | provenance | | +| dicer.js:16:22:16:27 | header | dicer.js:16:22:16:30 | header[h] | provenance | | +| dicer.js:19:26:19:29 | data | dicer.js:20:18:20:21 | data | provenance | | +| formidable.js:7:11:7:25 | [fields, files] | formidable.js:7:11:7:49 | fields | provenance | | +| formidable.js:7:11:7:25 | [fields, files] | formidable.js:7:11:7:49 | files | provenance | | +| formidable.js:7:11:7:49 | fields | formidable.js:8:10:8:15 | fields | provenance | | +| formidable.js:7:11:7:49 | files | formidable.js:8:18:8:22 | files | provenance | | +| formidable.js:7:29:7:49 | await f ... se(req) | formidable.js:7:11:7:25 | [fields, files] | provenance | | +| formidable.js:7:35:7:49 | form.parse(req) | formidable.js:7:29:7:49 | await f ... se(req) | provenance | | +| formidable.js:9:27:9:34 | formname | formidable.js:10:14:10:21 | formname | provenance | | +| formidable.js:9:37:9:40 | file | formidable.js:10:24:10:27 | file | provenance | | +| formidable.js:12:22:12:29 | formname | formidable.js:13:14:13:21 | formname | provenance | | +| formidable.js:12:32:12:35 | file | formidable.js:13:24:13:27 | file | provenance | | +| formidable.js:15:23:15:31 | fieldName | formidable.js:16:14:16:22 | fieldName | provenance | | +| formidable.js:15:34:15:43 | fieldValue | formidable.js:16:25:16:34 | fieldValue | provenance | | +| multiparty.js:8:22:8:25 | part | multiparty.js:9:14:9:17 | part | provenance | | +| multiparty.js:8:22:8:25 | part | multiparty.js:10:19:10:24 | sink() | provenance | | +| multiparty.js:14:37:14:42 | fields | multiparty.js:15:14:15:19 | fields | provenance | | +| multiparty.js:14:45:14:49 | files | multiparty.js:15:22:15:26 | files | provenance | | +nodes +| busybus.js:9:30:9:33 | file | semmle.label | file | +| busybus.js:9:36:9:39 | info | semmle.label | info | +| busybus.js:10:19:10:50 | { filen ... eType } | semmle.label | { filen ... eType } | +| busybus.js:10:19:10:57 | encoding | semmle.label | encoding | +| busybus.js:10:19:10:57 | filename | semmle.label | filename | +| busybus.js:10:19:10:57 | mimeType | semmle.label | mimeType | +| busybus.js:10:54:10:57 | info | semmle.label | info | +| busybus.js:12:18:12:25 | filename | semmle.label | filename | +| busybus.js:12:28:12:35 | encoding | semmle.label | encoding | +| busybus.js:12:38:12:45 | mimeType | semmle.label | mimeType | +| busybus.js:13:23:13:23 | z | semmle.label | z | +| busybus.js:13:31:13:36 | sink() | semmle.label | sink() | +| busybus.js:15:30:15:33 | data | semmle.label | data | +| busybus.js:16:22:16:25 | data | semmle.label | data | +| busybus.js:22:25:22:42 | data | semmle.label | data | +| busybus.js:22:32:22:42 | this.read() | semmle.label | this.read() | +| busybus.js:23:26:23:29 | data | semmle.label | data | +| busybus.js:27:25:27:28 | name | semmle.label | name | +| busybus.js:27:31:27:33 | val | semmle.label | val | +| busybus.js:27:36:27:39 | info | semmle.label | info | +| busybus.js:28:18:28:21 | name | semmle.label | name | +| busybus.js:28:24:28:26 | val | semmle.label | val | +| busybus.js:28:29:28:32 | info | semmle.label | info | +| dicer.js:12:23:12:26 | part | semmle.label | part | +| dicer.js:13:19:13:24 | sink() | semmle.label | sink() | +| dicer.js:14:28:14:33 | header | semmle.label | header | +| dicer.js:16:22:16:27 | header | semmle.label | header | +| dicer.js:16:22:16:30 | header[h] | semmle.label | header[h] | +| dicer.js:19:26:19:29 | data | semmle.label | data | +| dicer.js:20:18:20:21 | data | semmle.label | data | +| formidable.js:7:11:7:25 | [fields, files] | semmle.label | [fields, files] | +| formidable.js:7:11:7:49 | fields | semmle.label | fields | +| formidable.js:7:11:7:49 | files | semmle.label | files | +| formidable.js:7:29:7:49 | await f ... se(req) | semmle.label | await f ... se(req) | +| formidable.js:7:35:7:49 | form.parse(req) | semmle.label | form.parse(req) | +| formidable.js:8:10:8:15 | fields | semmle.label | fields | +| formidable.js:8:18:8:22 | files | semmle.label | files | +| formidable.js:9:27:9:34 | formname | semmle.label | formname | +| formidable.js:9:37:9:40 | file | semmle.label | file | +| formidable.js:10:14:10:21 | formname | semmle.label | formname | +| formidable.js:10:24:10:27 | file | semmle.label | file | +| formidable.js:12:22:12:29 | formname | semmle.label | formname | +| formidable.js:12:32:12:35 | file | semmle.label | file | +| formidable.js:13:14:13:21 | formname | semmle.label | formname | +| formidable.js:13:24:13:27 | file | semmle.label | file | +| formidable.js:15:23:15:31 | fieldName | semmle.label | fieldName | +| formidable.js:15:34:15:43 | fieldValue | semmle.label | fieldValue | +| formidable.js:16:14:16:22 | fieldName | semmle.label | fieldName | +| formidable.js:16:25:16:34 | fieldValue | semmle.label | fieldValue | +| multiparty.js:8:22:8:25 | part | semmle.label | part | +| multiparty.js:9:14:9:17 | part | semmle.label | part | +| multiparty.js:10:19:10:24 | sink() | semmle.label | sink() | +| multiparty.js:14:37:14:42 | fields | semmle.label | fields | +| multiparty.js:14:45:14:49 | files | semmle.label | files | +| multiparty.js:15:14:15:19 | fields | semmle.label | fields | +| multiparty.js:15:22:15:26 | files | semmle.label | files | +subpaths #select | busybus.js:12:18:12:25 | filename | busybus.js:9:36:9:39 | info | busybus.js:12:18:12:25 | filename | This entity depends on a $@. | busybus.js:9:36:9:39 | info | user-provided value | | busybus.js:12:28:12:35 | encoding | busybus.js:9:36:9:39 | info | busybus.js:12:28:12:35 | encoding | This entity depends on a $@. | busybus.js:9:36:9:39 | info | user-provided value | diff --git a/javascript/ql/test/experimental/FormParsers/RemoteFlowSource.ql b/javascript/ql/test/experimental/FormParsers/RemoteFlowSource.ql index ab526eeb54a..bdc52a60b96 100644 --- a/javascript/ql/test/experimental/FormParsers/RemoteFlowSource.ql +++ b/javascript/ql/test/experimental/FormParsers/RemoteFlowSource.ql @@ -11,24 +11,25 @@ */ import javascript -import DataFlow::PathGraph import experimental.semmle.javascript.FormParsers /** * A taint-tracking configuration for test */ -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "RemoteFlowSourcesOUserForm" } +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink = API::moduleImport("sink").getAParameter().asSink() or sink = API::moduleImport("sink").getReturn().asSource() } } -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +module TestFlow = TaintTracking::Global; + +import TestFlow::PathGraph + +from TestFlow::PathNode source, TestFlow::PathNode sink +where TestFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This entity depends on a $@.", source.getNode(), "user-provided value" From 8887ca17227b4e0b3fd1d26abba7506bc143fd67 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 11:19:52 +0100 Subject: [PATCH 400/514] JS: Port an experimental CodeInjection variant to ConfigSig --- .../Security/CWE-094-dataURL/CodeInjection.ql | 37 +++++---- .../CWE-094-dataURL/CodeInjection.expected | 79 ++++++++----------- 2 files changed, 55 insertions(+), 61 deletions(-) diff --git a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql index b4b66293ee5..1e6f7a64aec 100644 --- a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql +++ b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql @@ -15,13 +15,11 @@ */ import javascript -import DataFlow -import DataFlow::PathGraph -abstract class Sanitizer extends DataFlow::Node { } +abstract class Barrier extends DataFlow::Node { } /** A non-first leaf in a string-concatenation. Seen as a sanitizer for dynamic import code injection. */ -class NonFirstStringConcatLeaf extends Sanitizer { +class NonFirstStringConcatLeaf extends Barrier { NonFirstStringConcatLeaf() { exists(StringOps::ConcatenationRoot root | this = root.getALeaf() and @@ -51,39 +49,46 @@ class WorkerThreads extends DataFlow::Node { } } -class UrlConstructorLabel extends FlowLabel { +class UrlConstructorLabel extends DataFlow::FlowLabel { UrlConstructorLabel() { this = "UrlConstructorLabel" } } /** * A taint-tracking configuration for reasoning about code injection vulnerabilities. */ -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CodeInjection" } +module CodeInjectionConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { + source instanceof ActiveThreatModelSource and label.isTaint() + } - override predicate isSink(DataFlow::Node sink) { sink instanceof DynamicImport } + predicate isSink(DataFlow::Node sink) { sink instanceof DynamicImport } - override predicate isSink(DataFlow::Node sink, FlowLabel label) { + predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { sink instanceof WorkerThreads and label instanceof UrlConstructorLabel } - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } + predicate isBarrier(DataFlow::Node node) { node instanceof Barrier } - override predicate isAdditionalFlowStep( - DataFlow::Node pred, DataFlow::Node succ, FlowLabel predlbl, FlowLabel succlbl + predicate isAdditionalFlowStep( + DataFlow::Node pred, DataFlow::FlowLabel predlbl, DataFlow::Node succ, + DataFlow::FlowLabel succlbl ) { exists(DataFlow::NewNode newUrl | succ = newUrl | newUrl = DataFlow::globalVarRef("URL").getAnInstantiation() and pred = newUrl.getArgument(0) ) and - predlbl instanceof StandardFlowLabel and + predlbl.isDataOrTaint() and succlbl instanceof UrlConstructorLabel } } -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +module CodeInjectionFlow = TaintTracking::GlobalWithState; + +import CodeInjectionFlow::PathGraph + +from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink +where CodeInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This command line depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected b/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected index 3a5963b4094..ab162e0b311 100644 --- a/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected +++ b/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected @@ -1,49 +1,38 @@ -nodes -| test.js:5:11:5:44 | payload | -| test.js:5:21:5:44 | req.que ... rameter | -| test.js:5:21:5:44 | req.que ... rameter | -| test.js:6:9:6:43 | payloadURL | -| test.js:6:22:6:43 | new URL ... + sth) | -| test.js:6:30:6:36 | payload | -| test.js:6:30:6:42 | payload + sth | -| test.js:7:16:7:25 | payloadURL | -| test.js:7:16:7:25 | payloadURL | -| test.js:9:5:9:39 | payloadURL | -| test.js:9:18:9:39 | new URL ... + sth) | -| test.js:9:26:9:32 | payload | -| test.js:9:26:9:38 | payload + sth | -| test.js:10:16:10:25 | payloadURL | -| test.js:10:16:10:25 | payloadURL | -| test.js:17:11:17:44 | payload | -| test.js:17:21:17:44 | req.que ... rameter | -| test.js:17:21:17:44 | req.que ... rameter | -| test.js:18:18:18:24 | payload | -| test.js:18:18:18:24 | payload | -| test.js:19:18:19:24 | payload | -| test.js:19:18:19:30 | payload + sth | -| test.js:19:18:19:30 | payload + sth | edges -| test.js:5:11:5:44 | payload | test.js:6:30:6:36 | payload | -| test.js:5:11:5:44 | payload | test.js:9:26:9:32 | payload | -| test.js:5:21:5:44 | req.que ... rameter | test.js:5:11:5:44 | payload | -| test.js:5:21:5:44 | req.que ... rameter | test.js:5:11:5:44 | payload | -| test.js:6:9:6:43 | payloadURL | test.js:7:16:7:25 | payloadURL | -| test.js:6:9:6:43 | payloadURL | test.js:7:16:7:25 | payloadURL | -| test.js:6:22:6:43 | new URL ... + sth) | test.js:6:9:6:43 | payloadURL | -| test.js:6:30:6:36 | payload | test.js:6:30:6:42 | payload + sth | -| test.js:6:30:6:42 | payload + sth | test.js:6:22:6:43 | new URL ... + sth) | -| test.js:9:5:9:39 | payloadURL | test.js:10:16:10:25 | payloadURL | -| test.js:9:5:9:39 | payloadURL | test.js:10:16:10:25 | payloadURL | -| test.js:9:18:9:39 | new URL ... + sth) | test.js:9:5:9:39 | payloadURL | -| test.js:9:26:9:32 | payload | test.js:9:26:9:38 | payload + sth | -| test.js:9:26:9:38 | payload + sth | test.js:9:18:9:39 | new URL ... + sth) | -| test.js:17:11:17:44 | payload | test.js:18:18:18:24 | payload | -| test.js:17:11:17:44 | payload | test.js:18:18:18:24 | payload | -| test.js:17:11:17:44 | payload | test.js:19:18:19:24 | payload | -| test.js:17:21:17:44 | req.que ... rameter | test.js:17:11:17:44 | payload | -| test.js:17:21:17:44 | req.que ... rameter | test.js:17:11:17:44 | payload | -| test.js:19:18:19:24 | payload | test.js:19:18:19:30 | payload + sth | -| test.js:19:18:19:24 | payload | test.js:19:18:19:30 | payload + sth | +| test.js:5:11:5:44 | payload | test.js:6:30:6:36 | payload | provenance | | +| test.js:5:11:5:44 | payload | test.js:9:26:9:32 | payload | provenance | | +| test.js:5:21:5:44 | req.que ... rameter | test.js:5:11:5:44 | payload | provenance | | +| test.js:6:9:6:43 | payloadURL | test.js:7:16:7:25 | payloadURL | provenance | | +| test.js:6:22:6:43 | new URL ... + sth) | test.js:6:9:6:43 | payloadURL | provenance | | +| test.js:6:30:6:36 | payload | test.js:6:30:6:42 | payload + sth | provenance | | +| test.js:6:30:6:42 | payload + sth | test.js:6:22:6:43 | new URL ... + sth) | provenance | Config | +| test.js:9:5:9:39 | payloadURL | test.js:10:16:10:25 | payloadURL | provenance | | +| test.js:9:18:9:39 | new URL ... + sth) | test.js:9:5:9:39 | payloadURL | provenance | | +| test.js:9:26:9:32 | payload | test.js:9:26:9:38 | payload + sth | provenance | | +| test.js:9:26:9:38 | payload + sth | test.js:9:18:9:39 | new URL ... + sth) | provenance | Config | +| test.js:17:11:17:44 | payload | test.js:18:18:18:24 | payload | provenance | | +| test.js:17:11:17:44 | payload | test.js:19:18:19:24 | payload | provenance | | +| test.js:17:21:17:44 | req.que ... rameter | test.js:17:11:17:44 | payload | provenance | | +| test.js:19:18:19:24 | payload | test.js:19:18:19:30 | payload + sth | provenance | | +nodes +| test.js:5:11:5:44 | payload | semmle.label | payload | +| test.js:5:21:5:44 | req.que ... rameter | semmle.label | req.que ... rameter | +| test.js:6:9:6:43 | payloadURL | semmle.label | payloadURL | +| test.js:6:22:6:43 | new URL ... + sth) | semmle.label | new URL ... + sth) | +| test.js:6:30:6:36 | payload | semmle.label | payload | +| test.js:6:30:6:42 | payload + sth | semmle.label | payload + sth | +| test.js:7:16:7:25 | payloadURL | semmle.label | payloadURL | +| test.js:9:5:9:39 | payloadURL | semmle.label | payloadURL | +| test.js:9:18:9:39 | new URL ... + sth) | semmle.label | new URL ... + sth) | +| test.js:9:26:9:32 | payload | semmle.label | payload | +| test.js:9:26:9:38 | payload + sth | semmle.label | payload + sth | +| test.js:10:16:10:25 | payloadURL | semmle.label | payloadURL | +| test.js:17:11:17:44 | payload | semmle.label | payload | +| test.js:17:21:17:44 | req.que ... rameter | semmle.label | req.que ... rameter | +| test.js:18:18:18:24 | payload | semmle.label | payload | +| test.js:19:18:19:24 | payload | semmle.label | payload | +| test.js:19:18:19:30 | payload + sth | semmle.label | payload + sth | +subpaths #select | test.js:7:16:7:25 | payloadURL | test.js:5:21:5:44 | req.que ... rameter | test.js:7:16:7:25 | payloadURL | This command line depends on a $@. | test.js:5:21:5:44 | req.que ... rameter | user-provided value | | test.js:10:16:10:25 | payloadURL | test.js:5:21:5:44 | req.que ... rameter | test.js:10:16:10:25 | payloadURL | This command line depends on a $@. | test.js:5:21:5:44 | req.que ... rameter | user-provided value | From 4f839070a090c7231dc05a4f9f882fa6be44c4ae Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 11:23:03 +0100 Subject: [PATCH 401/514] JS: Port experimental EnvValueAndKeyInjection to ConfigSig --- .../CWE-099/EnvValueAndKeyInjection.ql | 23 +++--- .../EnvValueAndKeyInjection.expected | 79 +++++++------------ 2 files changed, 40 insertions(+), 62 deletions(-) diff --git a/javascript/ql/src/experimental/Security/CWE-099/EnvValueAndKeyInjection.ql b/javascript/ql/src/experimental/Security/CWE-099/EnvValueAndKeyInjection.ql index 38c7e591211..0f638167dc6 100644 --- a/javascript/ql/src/experimental/Security/CWE-099/EnvValueAndKeyInjection.ql +++ b/javascript/ql/src/experimental/Security/CWE-099/EnvValueAndKeyInjection.ql @@ -11,20 +11,17 @@ */ import javascript -import DataFlow::PathGraph /** A taint tracking configuration for unsafe environment injection. */ -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "envInjection" } +module EnvValueAndKeyInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource } - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink = keyOfEnv() or sink = valueOfEnv() } - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { exists(DataFlow::InvokeNode ikn | ikn = DataFlow::globalVarRef("Object").getAMemberInvocation("keys") | @@ -38,6 +35,8 @@ class Configuration extends TaintTracking::Configuration { } } +module EnvValueAndKeyInjectionFlow = TaintTracking::Global; + DataFlow::Node keyOfEnv() { result = NodeJSLib::process().getAPropertyRead("env").getAPropertyWrite().getPropertyNameExpr().flow() @@ -56,13 +55,15 @@ private predicate readToProcessEnv(DataFlow::Node envKey, DataFlow::Node envValu ) } +import EnvValueAndKeyInjectionFlow::PathGraph + from - Configuration cfgForValue, Configuration cfgForKey, DataFlow::PathNode source, - DataFlow::PathNode envKey, DataFlow::PathNode envValue + EnvValueAndKeyInjectionFlow::PathNode source, EnvValueAndKeyInjectionFlow::PathNode envKey, + EnvValueAndKeyInjectionFlow::PathNode envValue where - cfgForValue.hasFlowPath(source, envKey) and + EnvValueAndKeyInjectionFlow::flowPath(source, envKey) and envKey.getNode() = keyOfEnv() and - cfgForKey.hasFlowPath(source, envValue) and + EnvValueAndKeyInjectionFlow::flowPath(source, envValue) and envValue.getNode() = valueOfEnv() and readToProcessEnv(envKey.getNode(), envValue.getNode()) select envKey.getNode(), source, envKey, "arbitrary environment variable assignment from this $@.", diff --git a/javascript/ql/test/experimental/Security/CWE-099/EnvValueAndKeyInjection/EnvValueAndKeyInjection.expected b/javascript/ql/test/experimental/Security/CWE-099/EnvValueAndKeyInjection/EnvValueAndKeyInjection.expected index f36626a7384..40313cf964c 100644 --- a/javascript/ql/test/experimental/Security/CWE-099/EnvValueAndKeyInjection/EnvValueAndKeyInjection.expected +++ b/javascript/ql/test/experimental/Security/CWE-099/EnvValueAndKeyInjection/EnvValueAndKeyInjection.expected @@ -1,55 +1,32 @@ -nodes -| test.js:5:9:5:28 | { EnvValue, EnvKey } | -| test.js:5:9:5:39 | EnvKey | -| test.js:5:9:5:39 | EnvValue | -| test.js:5:11:5:18 | EnvValue | -| test.js:5:21:5:26 | EnvKey | -| test.js:5:32:5:39 | req.body | -| test.js:5:32:5:39 | req.body | -| test.js:6:15:6:20 | EnvKey | -| test.js:6:15:6:20 | EnvKey | -| test.js:6:25:6:32 | EnvValue | -| test.js:6:25:6:32 | EnvValue | -| test.js:7:15:7:20 | EnvKey | -| test.js:7:15:7:20 | EnvKey | -| test.js:7:25:7:32 | EnvValue | -| test.js:7:25:7:32 | EnvValue | -| test.js:13:9:13:28 | { EnvValue, EnvKey } | -| test.js:13:9:13:39 | EnvKey | -| test.js:13:9:13:39 | EnvValue | -| test.js:13:11:13:18 | EnvValue | -| test.js:13:21:13:26 | EnvKey | -| test.js:13:32:13:39 | req.body | -| test.js:13:32:13:39 | req.body | -| test.js:15:15:15:20 | EnvKey | -| test.js:15:15:15:20 | EnvKey | -| test.js:16:26:16:33 | EnvValue | -| test.js:16:26:16:33 | EnvValue | edges -| test.js:5:9:5:28 | { EnvValue, EnvKey } | test.js:5:11:5:18 | EnvValue | -| test.js:5:9:5:28 | { EnvValue, EnvKey } | test.js:5:21:5:26 | EnvKey | -| test.js:5:9:5:39 | EnvKey | test.js:6:15:6:20 | EnvKey | -| test.js:5:9:5:39 | EnvKey | test.js:6:15:6:20 | EnvKey | -| test.js:5:9:5:39 | EnvKey | test.js:7:15:7:20 | EnvKey | -| test.js:5:9:5:39 | EnvKey | test.js:7:15:7:20 | EnvKey | -| test.js:5:9:5:39 | EnvValue | test.js:6:25:6:32 | EnvValue | -| test.js:5:9:5:39 | EnvValue | test.js:6:25:6:32 | EnvValue | -| test.js:5:9:5:39 | EnvValue | test.js:7:25:7:32 | EnvValue | -| test.js:5:9:5:39 | EnvValue | test.js:7:25:7:32 | EnvValue | -| test.js:5:11:5:18 | EnvValue | test.js:5:9:5:39 | EnvValue | -| test.js:5:21:5:26 | EnvKey | test.js:5:9:5:39 | EnvKey | -| test.js:5:32:5:39 | req.body | test.js:5:9:5:28 | { EnvValue, EnvKey } | -| test.js:5:32:5:39 | req.body | test.js:5:9:5:28 | { EnvValue, EnvKey } | -| test.js:13:9:13:28 | { EnvValue, EnvKey } | test.js:13:11:13:18 | EnvValue | -| test.js:13:9:13:28 | { EnvValue, EnvKey } | test.js:13:21:13:26 | EnvKey | -| test.js:13:9:13:39 | EnvKey | test.js:15:15:15:20 | EnvKey | -| test.js:13:9:13:39 | EnvKey | test.js:15:15:15:20 | EnvKey | -| test.js:13:9:13:39 | EnvValue | test.js:16:26:16:33 | EnvValue | -| test.js:13:9:13:39 | EnvValue | test.js:16:26:16:33 | EnvValue | -| test.js:13:11:13:18 | EnvValue | test.js:13:9:13:39 | EnvValue | -| test.js:13:21:13:26 | EnvKey | test.js:13:9:13:39 | EnvKey | -| test.js:13:32:13:39 | req.body | test.js:13:9:13:28 | { EnvValue, EnvKey } | -| test.js:13:32:13:39 | req.body | test.js:13:9:13:28 | { EnvValue, EnvKey } | +| test.js:5:9:5:28 | { EnvValue, EnvKey } | test.js:5:9:5:39 | EnvKey | provenance | | +| test.js:5:9:5:28 | { EnvValue, EnvKey } | test.js:5:9:5:39 | EnvValue | provenance | | +| test.js:5:9:5:39 | EnvKey | test.js:6:15:6:20 | EnvKey | provenance | | +| test.js:5:9:5:39 | EnvKey | test.js:7:15:7:20 | EnvKey | provenance | | +| test.js:5:9:5:39 | EnvValue | test.js:6:25:6:32 | EnvValue | provenance | | +| test.js:5:9:5:39 | EnvValue | test.js:7:25:7:32 | EnvValue | provenance | | +| test.js:5:32:5:39 | req.body | test.js:5:9:5:28 | { EnvValue, EnvKey } | provenance | | +| test.js:13:9:13:28 | { EnvValue, EnvKey } | test.js:13:9:13:39 | EnvKey | provenance | | +| test.js:13:9:13:28 | { EnvValue, EnvKey } | test.js:13:9:13:39 | EnvValue | provenance | | +| test.js:13:9:13:39 | EnvKey | test.js:15:15:15:20 | EnvKey | provenance | | +| test.js:13:9:13:39 | EnvValue | test.js:16:26:16:33 | EnvValue | provenance | | +| test.js:13:32:13:39 | req.body | test.js:13:9:13:28 | { EnvValue, EnvKey } | provenance | | +nodes +| test.js:5:9:5:28 | { EnvValue, EnvKey } | semmle.label | { EnvValue, EnvKey } | +| test.js:5:9:5:39 | EnvKey | semmle.label | EnvKey | +| test.js:5:9:5:39 | EnvValue | semmle.label | EnvValue | +| test.js:5:32:5:39 | req.body | semmle.label | req.body | +| test.js:6:15:6:20 | EnvKey | semmle.label | EnvKey | +| test.js:6:25:6:32 | EnvValue | semmle.label | EnvValue | +| test.js:7:15:7:20 | EnvKey | semmle.label | EnvKey | +| test.js:7:25:7:32 | EnvValue | semmle.label | EnvValue | +| test.js:13:9:13:28 | { EnvValue, EnvKey } | semmle.label | { EnvValue, EnvKey } | +| test.js:13:9:13:39 | EnvKey | semmle.label | EnvKey | +| test.js:13:9:13:39 | EnvValue | semmle.label | EnvValue | +| test.js:13:32:13:39 | req.body | semmle.label | req.body | +| test.js:15:15:15:20 | EnvKey | semmle.label | EnvKey | +| test.js:16:26:16:33 | EnvValue | semmle.label | EnvValue | +subpaths #select | test.js:6:15:6:20 | EnvKey | test.js:5:32:5:39 | req.body | test.js:6:15:6:20 | EnvKey | arbitrary environment variable assignment from this $@. | test.js:5:32:5:39 | req.body | user controllable source | | test.js:7:15:7:20 | EnvKey | test.js:5:32:5:39 | req.body | test.js:7:15:7:20 | EnvKey | arbitrary environment variable assignment from this $@. | test.js:5:32:5:39 | req.body | user controllable source | From 7e162f5451e6ee4089929bb774cbf28ad6feb993 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 11:25:01 +0100 Subject: [PATCH 402/514] JS: Port experimental EnvValueInjection to ConfigSig --- .../Security/CWE-099/EnvValueInjection.ql | 17 ++++----- .../EnvValueInjection.expected | 35 +++++++------------ 2 files changed, 22 insertions(+), 30 deletions(-) diff --git a/javascript/ql/src/experimental/Security/CWE-099/EnvValueInjection.ql b/javascript/ql/src/experimental/Security/CWE-099/EnvValueInjection.ql index 3eb9f230564..82490a5200a 100644 --- a/javascript/ql/src/experimental/Security/CWE-099/EnvValueInjection.ql +++ b/javascript/ql/src/experimental/Security/CWE-099/EnvValueInjection.ql @@ -11,20 +11,21 @@ */ import javascript -import DataFlow::PathGraph /** A taint tracking configuration for unsafe environment injection. */ -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "envInjection" } +module EnvValueInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink = API::moduleImport("process").getMember("env").getAMember().asSink() } } -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +module EnvValueInjectionFlow = TaintTracking::Global; + +import EnvValueInjectionFlow::PathGraph + +from EnvValueInjectionFlow::PathNode source, EnvValueInjectionFlow::PathNode sink +where EnvValueInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "this environment variable assignment is $@.", source.getNode(), "user controllable" diff --git a/javascript/ql/test/experimental/Security/CWE-099/EnvValueInjection/EnvValueInjection.expected b/javascript/ql/test/experimental/Security/CWE-099/EnvValueInjection/EnvValueInjection.expected index 7461f72ee7e..87f6e5d4b86 100644 --- a/javascript/ql/test/experimental/Security/CWE-099/EnvValueInjection/EnvValueInjection.expected +++ b/javascript/ql/test/experimental/Security/CWE-099/EnvValueInjection/EnvValueInjection.expected @@ -1,26 +1,17 @@ -nodes -| test.js:4:9:4:20 | { EnvValue } | -| test.js:4:9:4:31 | EnvValue | -| test.js:4:11:4:18 | EnvValue | -| test.js:4:24:4:31 | req.body | -| test.js:4:24:4:31 | req.body | -| test.js:5:35:5:42 | EnvValue | -| test.js:5:35:5:42 | EnvValue | -| test.js:6:23:6:30 | EnvValue | -| test.js:6:23:6:30 | EnvValue | -| test.js:7:22:7:29 | EnvValue | -| test.js:7:22:7:29 | EnvValue | edges -| test.js:4:9:4:20 | { EnvValue } | test.js:4:11:4:18 | EnvValue | -| test.js:4:9:4:31 | EnvValue | test.js:5:35:5:42 | EnvValue | -| test.js:4:9:4:31 | EnvValue | test.js:5:35:5:42 | EnvValue | -| test.js:4:9:4:31 | EnvValue | test.js:6:23:6:30 | EnvValue | -| test.js:4:9:4:31 | EnvValue | test.js:6:23:6:30 | EnvValue | -| test.js:4:9:4:31 | EnvValue | test.js:7:22:7:29 | EnvValue | -| test.js:4:9:4:31 | EnvValue | test.js:7:22:7:29 | EnvValue | -| test.js:4:11:4:18 | EnvValue | test.js:4:9:4:31 | EnvValue | -| test.js:4:24:4:31 | req.body | test.js:4:9:4:20 | { EnvValue } | -| test.js:4:24:4:31 | req.body | test.js:4:9:4:20 | { EnvValue } | +| test.js:4:9:4:20 | { EnvValue } | test.js:4:9:4:31 | EnvValue | provenance | | +| test.js:4:9:4:31 | EnvValue | test.js:5:35:5:42 | EnvValue | provenance | | +| test.js:4:9:4:31 | EnvValue | test.js:6:23:6:30 | EnvValue | provenance | | +| test.js:4:9:4:31 | EnvValue | test.js:7:22:7:29 | EnvValue | provenance | | +| test.js:4:24:4:31 | req.body | test.js:4:9:4:20 | { EnvValue } | provenance | | +nodes +| test.js:4:9:4:20 | { EnvValue } | semmle.label | { EnvValue } | +| test.js:4:9:4:31 | EnvValue | semmle.label | EnvValue | +| test.js:4:24:4:31 | req.body | semmle.label | req.body | +| test.js:5:35:5:42 | EnvValue | semmle.label | EnvValue | +| test.js:6:23:6:30 | EnvValue | semmle.label | EnvValue | +| test.js:7:22:7:29 | EnvValue | semmle.label | EnvValue | +subpaths #select | test.js:5:35:5:42 | EnvValue | test.js:4:24:4:31 | req.body | test.js:5:35:5:42 | EnvValue | this environment variable assignment is $@. | test.js:4:24:4:31 | req.body | user controllable | | test.js:6:23:6:30 | EnvValue | test.js:4:24:4:31 | req.body | test.js:6:23:6:30 | EnvValue | this environment variable assignment is $@. | test.js:4:24:4:31 | req.body | user controllable | From 72e522631d32850b0d7a46a076164d12d1408315 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 11:31:51 +0100 Subject: [PATCH 403/514] JS: Port experimental jwtDecodeWithoutVerification to ConfigSig --- .../CWE-347/decodeJwtWithoutVerification.ql | 29 ++- .../decodeJwtWithoutVerification.expected | 202 +++++------------- 2 files changed, 63 insertions(+), 168 deletions(-) diff --git a/javascript/ql/src/experimental/Security/CWE-347/decodeJwtWithoutVerification.ql b/javascript/ql/src/experimental/Security/CWE-347/decodeJwtWithoutVerification.ql index ca0e602f63a..1ee38491d5f 100644 --- a/javascript/ql/src/experimental/Security/CWE-347/decodeJwtWithoutVerification.ql +++ b/javascript/ql/src/experimental/Security/CWE-347/decodeJwtWithoutVerification.ql @@ -11,30 +11,29 @@ */ import javascript -import DataFlow::PathGraph import JWT -class ConfigurationUnverifiedDecode extends TaintTracking::Configuration { - ConfigurationUnverifiedDecode() { this = "jsonwebtoken without any signature verification" } +module UnverifiedDecodeConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource } - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - - override predicate isSink(DataFlow::Node sink) { sink = unverifiedDecode() } + predicate isSink(DataFlow::Node sink) { sink = unverifiedDecode() } } -class ConfigurationVerifiedDecode extends TaintTracking::Configuration { - ConfigurationVerifiedDecode() { this = "jsonwebtoken with signature verification" } +module UnverifiedDecodeFlow = TaintTracking::Global; - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } +module VerifiedDecodeConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource } - override predicate isSink(DataFlow::Node sink) { sink = verifiedDecode() } + predicate isSink(DataFlow::Node sink) { sink = verifiedDecode() } } -from ConfigurationUnverifiedDecode cfg, DataFlow::PathNode source, DataFlow::PathNode sink +module VerifiedDecodeFlow = TaintTracking::Global; + +import UnverifiedDecodeFlow::PathGraph + +from UnverifiedDecodeFlow::PathNode source, UnverifiedDecodeFlow::PathNode sink where - cfg.hasFlowPath(source, sink) and - not exists(ConfigurationVerifiedDecode cfg2 | - cfg2.hasFlowPath(any(DataFlow::PathNode p | p.getNode() = source.getNode()), _) - ) + UnverifiedDecodeFlow::flowPath(source, sink) and + not VerifiedDecodeFlow::flow(source.getNode(), _) select source.getNode(), source, sink, "Decoding JWT $@.", sink.getNode(), "without signature verification" diff --git a/javascript/ql/test/experimental/Security/CWE-347/remotesource/decodeJwtWithoutVerification.expected b/javascript/ql/test/experimental/Security/CWE-347/remotesource/decodeJwtWithoutVerification.expected index ae3ef8507f6..bb6ca940759 100644 --- a/javascript/ql/test/experimental/Security/CWE-347/remotesource/decodeJwtWithoutVerification.expected +++ b/javascript/ql/test/experimental/Security/CWE-347/remotesource/decodeJwtWithoutVerification.expected @@ -1,157 +1,53 @@ -nodes -| JsonWebToken.js:10:11:10:47 | UserToken | -| JsonWebToken.js:10:23:10:47 | req.hea ... ization | -| JsonWebToken.js:10:23:10:47 | req.hea ... ization | -| JsonWebToken.js:13:28:13:36 | UserToken | -| JsonWebToken.js:13:28:13:36 | UserToken | -| JsonWebToken.js:17:11:17:47 | UserToken | -| JsonWebToken.js:17:23:17:47 | req.hea ... ization | -| JsonWebToken.js:17:23:17:47 | req.hea ... ization | -| JsonWebToken.js:20:28:20:36 | UserToken | -| JsonWebToken.js:20:28:20:36 | UserToken | -| JsonWebToken.js:21:28:21:36 | UserToken | -| JsonWebToken.js:21:28:21:36 | UserToken | -| JsonWebToken.js:25:11:25:47 | UserToken | -| JsonWebToken.js:25:23:25:47 | req.hea ... ization | -| JsonWebToken.js:25:23:25:47 | req.hea ... ization | -| JsonWebToken.js:28:28:28:36 | UserToken | -| JsonWebToken.js:28:28:28:36 | UserToken | -| JsonWebToken.js:32:11:32:47 | UserToken | -| JsonWebToken.js:32:11:32:47 | UserToken | -| JsonWebToken.js:32:23:32:47 | req.hea ... ization | -| JsonWebToken.js:32:23:32:47 | req.hea ... ization | -| JsonWebToken.js:32:23:32:47 | req.hea ... ization | -| JsonWebToken.js:32:23:32:47 | req.hea ... ization | -| JsonWebToken.js:35:28:35:36 | UserToken | -| JsonWebToken.js:35:28:35:36 | UserToken | -| JsonWebToken.js:36:28:36:36 | UserToken | -| JsonWebToken.js:36:28:36:36 | UserToken | -| JsonWebToken.js:40:11:40:47 | UserToken | -| JsonWebToken.js:40:11:40:47 | UserToken | -| JsonWebToken.js:40:23:40:47 | req.hea ... ization | -| JsonWebToken.js:40:23:40:47 | req.hea ... ization | -| JsonWebToken.js:40:23:40:47 | req.hea ... ization | -| JsonWebToken.js:40:23:40:47 | req.hea ... ization | -| JsonWebToken.js:43:28:43:36 | UserToken | -| JsonWebToken.js:43:28:43:36 | UserToken | -| JsonWebToken.js:44:28:44:36 | UserToken | -| JsonWebToken.js:44:28:44:36 | UserToken | -| jose.js:11:11:11:47 | UserToken | -| jose.js:11:23:11:47 | req.hea ... ization | -| jose.js:11:23:11:47 | req.hea ... ization | -| jose.js:13:20:13:28 | UserToken | -| jose.js:13:20:13:28 | UserToken | -| jose.js:18:11:18:47 | UserToken | -| jose.js:18:23:18:47 | req.hea ... ization | -| jose.js:18:23:18:47 | req.hea ... ization | -| jose.js:20:26:20:34 | UserToken | -| jose.js:20:26:20:34 | UserToken | -| jose.js:24:11:24:47 | UserToken | -| jose.js:24:11:24:47 | UserToken | -| jose.js:24:23:24:47 | req.hea ... ization | -| jose.js:24:23:24:47 | req.hea ... ization | -| jose.js:24:23:24:47 | req.hea ... ization | -| jose.js:24:23:24:47 | req.hea ... ization | -| jose.js:26:20:26:28 | UserToken | -| jose.js:26:20:26:28 | UserToken | -| jose.js:27:26:27:34 | UserToken | -| jose.js:27:26:27:34 | UserToken | -| jwtDecode.js:11:11:11:47 | UserToken | -| jwtDecode.js:11:23:11:47 | req.hea ... ization | -| jwtDecode.js:11:23:11:47 | req.hea ... ization | -| jwtDecode.js:15:16:15:24 | UserToken | -| jwtDecode.js:15:16:15:24 | UserToken | -| jwtSimple.js:10:11:10:47 | UserToken | -| jwtSimple.js:10:23:10:47 | req.hea ... ization | -| jwtSimple.js:10:23:10:47 | req.hea ... ization | -| jwtSimple.js:13:23:13:31 | UserToken | -| jwtSimple.js:13:23:13:31 | UserToken | -| jwtSimple.js:17:11:17:47 | UserToken | -| jwtSimple.js:17:23:17:47 | req.hea ... ization | -| jwtSimple.js:17:23:17:47 | req.hea ... ization | -| jwtSimple.js:20:23:20:31 | UserToken | -| jwtSimple.js:20:23:20:31 | UserToken | -| jwtSimple.js:21:23:21:31 | UserToken | -| jwtSimple.js:21:23:21:31 | UserToken | -| jwtSimple.js:25:11:25:47 | UserToken | -| jwtSimple.js:25:11:25:47 | UserToken | -| jwtSimple.js:25:23:25:47 | req.hea ... ization | -| jwtSimple.js:25:23:25:47 | req.hea ... ization | -| jwtSimple.js:25:23:25:47 | req.hea ... ization | -| jwtSimple.js:25:23:25:47 | req.hea ... ization | -| jwtSimple.js:28:23:28:31 | UserToken | -| jwtSimple.js:28:23:28:31 | UserToken | -| jwtSimple.js:29:23:29:31 | UserToken | -| jwtSimple.js:29:23:29:31 | UserToken | edges -| JsonWebToken.js:10:11:10:47 | UserToken | JsonWebToken.js:13:28:13:36 | UserToken | -| JsonWebToken.js:10:11:10:47 | UserToken | JsonWebToken.js:13:28:13:36 | UserToken | -| JsonWebToken.js:10:23:10:47 | req.hea ... ization | JsonWebToken.js:10:11:10:47 | UserToken | -| JsonWebToken.js:10:23:10:47 | req.hea ... ization | JsonWebToken.js:10:11:10:47 | UserToken | -| JsonWebToken.js:17:11:17:47 | UserToken | JsonWebToken.js:20:28:20:36 | UserToken | -| JsonWebToken.js:17:11:17:47 | UserToken | JsonWebToken.js:20:28:20:36 | UserToken | -| JsonWebToken.js:17:11:17:47 | UserToken | JsonWebToken.js:21:28:21:36 | UserToken | -| JsonWebToken.js:17:11:17:47 | UserToken | JsonWebToken.js:21:28:21:36 | UserToken | -| JsonWebToken.js:17:23:17:47 | req.hea ... ization | JsonWebToken.js:17:11:17:47 | UserToken | -| JsonWebToken.js:17:23:17:47 | req.hea ... ization | JsonWebToken.js:17:11:17:47 | UserToken | -| JsonWebToken.js:25:11:25:47 | UserToken | JsonWebToken.js:28:28:28:36 | UserToken | -| JsonWebToken.js:25:11:25:47 | UserToken | JsonWebToken.js:28:28:28:36 | UserToken | -| JsonWebToken.js:25:23:25:47 | req.hea ... ization | JsonWebToken.js:25:11:25:47 | UserToken | -| JsonWebToken.js:25:23:25:47 | req.hea ... ization | JsonWebToken.js:25:11:25:47 | UserToken | -| JsonWebToken.js:32:11:32:47 | UserToken | JsonWebToken.js:35:28:35:36 | UserToken | -| JsonWebToken.js:32:11:32:47 | UserToken | JsonWebToken.js:35:28:35:36 | UserToken | -| JsonWebToken.js:32:11:32:47 | UserToken | JsonWebToken.js:36:28:36:36 | UserToken | -| JsonWebToken.js:32:11:32:47 | UserToken | JsonWebToken.js:36:28:36:36 | UserToken | -| JsonWebToken.js:32:23:32:47 | req.hea ... ization | JsonWebToken.js:32:11:32:47 | UserToken | -| JsonWebToken.js:32:23:32:47 | req.hea ... ization | JsonWebToken.js:32:11:32:47 | UserToken | -| JsonWebToken.js:32:23:32:47 | req.hea ... ization | JsonWebToken.js:32:11:32:47 | UserToken | -| JsonWebToken.js:32:23:32:47 | req.hea ... ization | JsonWebToken.js:32:11:32:47 | UserToken | -| JsonWebToken.js:40:11:40:47 | UserToken | JsonWebToken.js:43:28:43:36 | UserToken | -| JsonWebToken.js:40:11:40:47 | UserToken | JsonWebToken.js:43:28:43:36 | UserToken | -| JsonWebToken.js:40:11:40:47 | UserToken | JsonWebToken.js:44:28:44:36 | UserToken | -| JsonWebToken.js:40:11:40:47 | UserToken | JsonWebToken.js:44:28:44:36 | UserToken | -| JsonWebToken.js:40:23:40:47 | req.hea ... ization | JsonWebToken.js:40:11:40:47 | UserToken | -| JsonWebToken.js:40:23:40:47 | req.hea ... ization | JsonWebToken.js:40:11:40:47 | UserToken | -| JsonWebToken.js:40:23:40:47 | req.hea ... ization | JsonWebToken.js:40:11:40:47 | UserToken | -| JsonWebToken.js:40:23:40:47 | req.hea ... ization | JsonWebToken.js:40:11:40:47 | UserToken | -| jose.js:11:11:11:47 | UserToken | jose.js:13:20:13:28 | UserToken | -| jose.js:11:11:11:47 | UserToken | jose.js:13:20:13:28 | UserToken | -| jose.js:11:23:11:47 | req.hea ... ization | jose.js:11:11:11:47 | UserToken | -| jose.js:11:23:11:47 | req.hea ... ization | jose.js:11:11:11:47 | UserToken | -| jose.js:18:11:18:47 | UserToken | jose.js:20:26:20:34 | UserToken | -| jose.js:18:11:18:47 | UserToken | jose.js:20:26:20:34 | UserToken | -| jose.js:18:23:18:47 | req.hea ... ization | jose.js:18:11:18:47 | UserToken | -| jose.js:18:23:18:47 | req.hea ... ization | jose.js:18:11:18:47 | UserToken | -| jose.js:24:11:24:47 | UserToken | jose.js:26:20:26:28 | UserToken | -| jose.js:24:11:24:47 | UserToken | jose.js:26:20:26:28 | UserToken | -| jose.js:24:11:24:47 | UserToken | jose.js:27:26:27:34 | UserToken | -| jose.js:24:11:24:47 | UserToken | jose.js:27:26:27:34 | UserToken | -| jose.js:24:23:24:47 | req.hea ... ization | jose.js:24:11:24:47 | UserToken | -| jose.js:24:23:24:47 | req.hea ... ization | jose.js:24:11:24:47 | UserToken | -| jose.js:24:23:24:47 | req.hea ... ization | jose.js:24:11:24:47 | UserToken | -| jose.js:24:23:24:47 | req.hea ... ization | jose.js:24:11:24:47 | UserToken | -| jwtDecode.js:11:11:11:47 | UserToken | jwtDecode.js:15:16:15:24 | UserToken | -| jwtDecode.js:11:11:11:47 | UserToken | jwtDecode.js:15:16:15:24 | UserToken | -| jwtDecode.js:11:23:11:47 | req.hea ... ization | jwtDecode.js:11:11:11:47 | UserToken | -| jwtDecode.js:11:23:11:47 | req.hea ... ization | jwtDecode.js:11:11:11:47 | UserToken | -| jwtSimple.js:10:11:10:47 | UserToken | jwtSimple.js:13:23:13:31 | UserToken | -| jwtSimple.js:10:11:10:47 | UserToken | jwtSimple.js:13:23:13:31 | UserToken | -| jwtSimple.js:10:23:10:47 | req.hea ... ization | jwtSimple.js:10:11:10:47 | UserToken | -| jwtSimple.js:10:23:10:47 | req.hea ... ization | jwtSimple.js:10:11:10:47 | UserToken | -| jwtSimple.js:17:11:17:47 | UserToken | jwtSimple.js:20:23:20:31 | UserToken | -| jwtSimple.js:17:11:17:47 | UserToken | jwtSimple.js:20:23:20:31 | UserToken | -| jwtSimple.js:17:11:17:47 | UserToken | jwtSimple.js:21:23:21:31 | UserToken | -| jwtSimple.js:17:11:17:47 | UserToken | jwtSimple.js:21:23:21:31 | UserToken | -| jwtSimple.js:17:23:17:47 | req.hea ... ization | jwtSimple.js:17:11:17:47 | UserToken | -| jwtSimple.js:17:23:17:47 | req.hea ... ization | jwtSimple.js:17:11:17:47 | UserToken | -| jwtSimple.js:25:11:25:47 | UserToken | jwtSimple.js:28:23:28:31 | UserToken | -| jwtSimple.js:25:11:25:47 | UserToken | jwtSimple.js:28:23:28:31 | UserToken | -| jwtSimple.js:25:11:25:47 | UserToken | jwtSimple.js:29:23:29:31 | UserToken | -| jwtSimple.js:25:11:25:47 | UserToken | jwtSimple.js:29:23:29:31 | UserToken | -| jwtSimple.js:25:23:25:47 | req.hea ... ization | jwtSimple.js:25:11:25:47 | UserToken | -| jwtSimple.js:25:23:25:47 | req.hea ... ization | jwtSimple.js:25:11:25:47 | UserToken | -| jwtSimple.js:25:23:25:47 | req.hea ... ization | jwtSimple.js:25:11:25:47 | UserToken | -| jwtSimple.js:25:23:25:47 | req.hea ... ization | jwtSimple.js:25:11:25:47 | UserToken | +| JsonWebToken.js:10:11:10:47 | UserToken | JsonWebToken.js:13:28:13:36 | UserToken | provenance | | +| JsonWebToken.js:10:23:10:47 | req.hea ... ization | JsonWebToken.js:10:11:10:47 | UserToken | provenance | | +| JsonWebToken.js:17:11:17:47 | UserToken | JsonWebToken.js:20:28:20:36 | UserToken | provenance | | +| JsonWebToken.js:17:11:17:47 | UserToken | JsonWebToken.js:21:28:21:36 | UserToken | provenance | | +| JsonWebToken.js:17:23:17:47 | req.hea ... ization | JsonWebToken.js:17:11:17:47 | UserToken | provenance | | +| JsonWebToken.js:32:11:32:47 | UserToken | JsonWebToken.js:35:28:35:36 | UserToken | provenance | | +| JsonWebToken.js:32:23:32:47 | req.hea ... ization | JsonWebToken.js:32:11:32:47 | UserToken | provenance | | +| JsonWebToken.js:40:11:40:47 | UserToken | JsonWebToken.js:43:28:43:36 | UserToken | provenance | | +| JsonWebToken.js:40:23:40:47 | req.hea ... ization | JsonWebToken.js:40:11:40:47 | UserToken | provenance | | +| jose.js:11:11:11:47 | UserToken | jose.js:13:20:13:28 | UserToken | provenance | | +| jose.js:11:23:11:47 | req.hea ... ization | jose.js:11:11:11:47 | UserToken | provenance | | +| jose.js:24:11:24:47 | UserToken | jose.js:26:20:26:28 | UserToken | provenance | | +| jose.js:24:23:24:47 | req.hea ... ization | jose.js:24:11:24:47 | UserToken | provenance | | +| jwtDecode.js:11:11:11:47 | UserToken | jwtDecode.js:15:16:15:24 | UserToken | provenance | | +| jwtDecode.js:11:23:11:47 | req.hea ... ization | jwtDecode.js:11:11:11:47 | UserToken | provenance | | +| jwtSimple.js:10:11:10:47 | UserToken | jwtSimple.js:13:23:13:31 | UserToken | provenance | | +| jwtSimple.js:10:23:10:47 | req.hea ... ization | jwtSimple.js:10:11:10:47 | UserToken | provenance | | +| jwtSimple.js:25:11:25:47 | UserToken | jwtSimple.js:28:23:28:31 | UserToken | provenance | | +| jwtSimple.js:25:23:25:47 | req.hea ... ization | jwtSimple.js:25:11:25:47 | UserToken | provenance | | +nodes +| JsonWebToken.js:10:11:10:47 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:10:23:10:47 | req.hea ... ization | semmle.label | req.hea ... ization | +| JsonWebToken.js:13:28:13:36 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:17:11:17:47 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:17:23:17:47 | req.hea ... ization | semmle.label | req.hea ... ization | +| JsonWebToken.js:20:28:20:36 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:21:28:21:36 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:32:11:32:47 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:32:23:32:47 | req.hea ... ization | semmle.label | req.hea ... ization | +| JsonWebToken.js:35:28:35:36 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:40:11:40:47 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:40:23:40:47 | req.hea ... ization | semmle.label | req.hea ... ization | +| JsonWebToken.js:43:28:43:36 | UserToken | semmle.label | UserToken | +| jose.js:11:11:11:47 | UserToken | semmle.label | UserToken | +| jose.js:11:23:11:47 | req.hea ... ization | semmle.label | req.hea ... ization | +| jose.js:13:20:13:28 | UserToken | semmle.label | UserToken | +| jose.js:24:11:24:47 | UserToken | semmle.label | UserToken | +| jose.js:24:23:24:47 | req.hea ... ization | semmle.label | req.hea ... ization | +| jose.js:26:20:26:28 | UserToken | semmle.label | UserToken | +| jwtDecode.js:11:11:11:47 | UserToken | semmle.label | UserToken | +| jwtDecode.js:11:23:11:47 | req.hea ... ization | semmle.label | req.hea ... ization | +| jwtDecode.js:15:16:15:24 | UserToken | semmle.label | UserToken | +| jwtSimple.js:10:11:10:47 | UserToken | semmle.label | UserToken | +| jwtSimple.js:10:23:10:47 | req.hea ... ization | semmle.label | req.hea ... ization | +| jwtSimple.js:13:23:13:31 | UserToken | semmle.label | UserToken | +| jwtSimple.js:25:11:25:47 | UserToken | semmle.label | UserToken | +| jwtSimple.js:25:23:25:47 | req.hea ... ization | semmle.label | req.hea ... ization | +| jwtSimple.js:28:23:28:31 | UserToken | semmle.label | UserToken | +subpaths #select | JsonWebToken.js:10:23:10:47 | req.hea ... ization | JsonWebToken.js:10:23:10:47 | req.hea ... ization | JsonWebToken.js:13:28:13:36 | UserToken | Decoding JWT $@. | JsonWebToken.js:13:28:13:36 | UserToken | without signature verification | | JsonWebToken.js:17:23:17:47 | req.hea ... ization | JsonWebToken.js:17:23:17:47 | req.hea ... ization | JsonWebToken.js:20:28:20:36 | UserToken | Decoding JWT $@. | JsonWebToken.js:20:28:20:36 | UserToken | without signature verification | From f5a6485ef20545b14be4ac66def375908a5ff579 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 11:35:02 +0100 Subject: [PATCH 404/514] JS: Port experimental decodeJwtWithoutVerificationLocalSource --- ...decodeJwtWithoutVerificationLocalSource.ql | 32 ++- ...JwtWithoutVerificationLocalSource.expected | 207 +++++++----------- 2 files changed, 89 insertions(+), 150 deletions(-) diff --git a/javascript/ql/src/experimental/Security/CWE-347/decodeJwtWithoutVerificationLocalSource.ql b/javascript/ql/src/experimental/Security/CWE-347/decodeJwtWithoutVerificationLocalSource.ql index ed2283b7641..d75041426a1 100644 --- a/javascript/ql/src/experimental/Security/CWE-347/decodeJwtWithoutVerificationLocalSource.ql +++ b/javascript/ql/src/experimental/Security/CWE-347/decodeJwtWithoutVerificationLocalSource.ql @@ -11,29 +11,25 @@ */ import javascript -import DataFlow::PathGraph import JWT -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "jsonwebtoken without any signature verification" } - - override predicate isSource(DataFlow::Node source) { +module DecodeWithoutVerificationConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source = [unverifiedDecode(), verifiedDecode()].getALocalSource() } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink = unverifiedDecode() or sink = verifiedDecode() } } +module DecodeWithoutVerificationFlow = TaintTracking::Global; + /** Holds if `source` flows to the first parameter of jsonwebtoken.verify */ -predicate isSafe(Configuration cfg, DataFlow::Node source) { - exists(DataFlow::Node sink | - cfg.hasFlow(source, sink) and - sink = verifiedDecode() - ) +predicate isSafe(DataFlow::Node source) { + DecodeWithoutVerificationFlow::flow(source, verifiedDecode()) } /** @@ -41,15 +37,17 @@ predicate isSafe(Configuration cfg, DataFlow::Node source) { * - `source` does not flow to the first parameter of `jsonwebtoken.verify`, and * - `source` flows to the first parameter of `jsonwebtoken.decode` */ -predicate isVulnerable(Configuration cfg, DataFlow::Node source, DataFlow::Node sink) { - not isSafe(cfg, source) and // i.e., source does not flow to a verify call - cfg.hasFlow(source, sink) and // but it does flow to something else +predicate isVulnerable(DataFlow::Node source, DataFlow::Node sink) { + not isSafe(source) and // i.e., source does not flow to a verify call + DecodeWithoutVerificationFlow::flow(source, sink) and // but it does flow to something else sink = unverifiedDecode() // and that something else is a call to decode. } -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink +import DecodeWithoutVerificationFlow::PathGraph + +from DecodeWithoutVerificationFlow::PathNode source, DecodeWithoutVerificationFlow::PathNode sink where - cfg.hasFlowPath(source, sink) and - isVulnerable(cfg, source.getNode(), sink.getNode()) + DecodeWithoutVerificationFlow::flowPath(source, sink) and + isVulnerable(source.getNode(), sink.getNode()) select source.getNode(), source, sink, "Decoding JWT $@.", sink.getNode(), "without signature verification" diff --git a/javascript/ql/test/experimental/Security/CWE-347/localsource/decodeJwtWithoutVerificationLocalSource.expected b/javascript/ql/test/experimental/Security/CWE-347/localsource/decodeJwtWithoutVerificationLocalSource.expected index a3fe059065b..0f67cfc8513 100644 --- a/javascript/ql/test/experimental/Security/CWE-347/localsource/decodeJwtWithoutVerificationLocalSource.expected +++ b/javascript/ql/test/experimental/Security/CWE-347/localsource/decodeJwtWithoutVerificationLocalSource.expected @@ -1,137 +1,78 @@ -nodes -| JsonWebToken.js:13:11:13:28 | UserToken | -| JsonWebToken.js:13:23:13:28 | aJwt() | -| JsonWebToken.js:13:23:13:28 | aJwt() | -| JsonWebToken.js:16:28:16:36 | UserToken | -| JsonWebToken.js:16:28:16:36 | UserToken | -| JsonWebToken.js:20:11:20:28 | UserToken | -| JsonWebToken.js:20:23:20:28 | aJwt() | -| JsonWebToken.js:20:23:20:28 | aJwt() | -| JsonWebToken.js:23:28:23:36 | UserToken | -| JsonWebToken.js:23:28:23:36 | UserToken | -| JsonWebToken.js:24:28:24:36 | UserToken | -| JsonWebToken.js:24:28:24:36 | UserToken | -| JsonWebToken.js:28:11:28:28 | UserToken | -| JsonWebToken.js:28:23:28:28 | aJwt() | -| JsonWebToken.js:28:23:28:28 | aJwt() | -| JsonWebToken.js:31:28:31:36 | UserToken | -| JsonWebToken.js:31:28:31:36 | UserToken | -| JsonWebToken.js:35:11:35:28 | UserToken | -| JsonWebToken.js:35:23:35:28 | aJwt() | -| JsonWebToken.js:35:23:35:28 | aJwt() | -| JsonWebToken.js:38:28:38:36 | UserToken | -| JsonWebToken.js:38:28:38:36 | UserToken | -| JsonWebToken.js:39:28:39:36 | UserToken | -| JsonWebToken.js:39:28:39:36 | UserToken | -| JsonWebToken.js:43:11:43:28 | UserToken | -| JsonWebToken.js:43:23:43:28 | aJwt() | -| JsonWebToken.js:43:23:43:28 | aJwt() | -| JsonWebToken.js:46:28:46:36 | UserToken | -| JsonWebToken.js:46:28:46:36 | UserToken | -| JsonWebToken.js:47:28:47:36 | UserToken | -| JsonWebToken.js:47:28:47:36 | UserToken | -| jose.js:12:11:12:28 | UserToken | -| jose.js:12:23:12:28 | aJwt() | -| jose.js:12:23:12:28 | aJwt() | -| jose.js:15:20:15:28 | UserToken | -| jose.js:15:20:15:28 | UserToken | -| jose.js:19:11:19:28 | UserToken | -| jose.js:19:23:19:28 | aJwt() | -| jose.js:19:23:19:28 | aJwt() | -| jose.js:22:20:22:28 | UserToken | -| jose.js:22:20:22:28 | UserToken | -| jose.js:23:26:23:34 | UserToken | -| jose.js:23:26:23:34 | UserToken | -| jose.js:27:11:27:28 | UserToken | -| jose.js:27:23:27:28 | aJwt() | -| jose.js:27:23:27:28 | aJwt() | -| jose.js:30:26:30:34 | UserToken | -| jose.js:30:26:30:34 | UserToken | -| jwtDecode.js:13:11:13:28 | UserToken | -| jwtDecode.js:13:23:13:28 | aJwt() | -| jwtDecode.js:13:23:13:28 | aJwt() | -| jwtDecode.js:17:16:17:24 | UserToken | -| jwtDecode.js:17:16:17:24 | UserToken | -| jwtSimple.js:13:11:13:28 | UserToken | -| jwtSimple.js:13:23:13:28 | aJwt() | -| jwtSimple.js:13:23:13:28 | aJwt() | -| jwtSimple.js:16:23:16:31 | UserToken | -| jwtSimple.js:16:23:16:31 | UserToken | -| jwtSimple.js:20:11:20:28 | UserToken | -| jwtSimple.js:20:23:20:28 | aJwt() | -| jwtSimple.js:20:23:20:28 | aJwt() | -| jwtSimple.js:23:23:23:31 | UserToken | -| jwtSimple.js:23:23:23:31 | UserToken | -| jwtSimple.js:24:23:24:31 | UserToken | -| jwtSimple.js:24:23:24:31 | UserToken | -| jwtSimple.js:28:11:28:28 | UserToken | -| jwtSimple.js:28:23:28:28 | aJwt() | -| jwtSimple.js:28:23:28:28 | aJwt() | -| jwtSimple.js:31:23:31:31 | UserToken | -| jwtSimple.js:31:23:31:31 | UserToken | -| jwtSimple.js:32:23:32:31 | UserToken | -| jwtSimple.js:32:23:32:31 | UserToken | edges -| JsonWebToken.js:13:11:13:28 | UserToken | JsonWebToken.js:16:28:16:36 | UserToken | -| JsonWebToken.js:13:11:13:28 | UserToken | JsonWebToken.js:16:28:16:36 | UserToken | -| JsonWebToken.js:13:23:13:28 | aJwt() | JsonWebToken.js:13:11:13:28 | UserToken | -| JsonWebToken.js:13:23:13:28 | aJwt() | JsonWebToken.js:13:11:13:28 | UserToken | -| JsonWebToken.js:20:11:20:28 | UserToken | JsonWebToken.js:23:28:23:36 | UserToken | -| JsonWebToken.js:20:11:20:28 | UserToken | JsonWebToken.js:23:28:23:36 | UserToken | -| JsonWebToken.js:20:11:20:28 | UserToken | JsonWebToken.js:24:28:24:36 | UserToken | -| JsonWebToken.js:20:11:20:28 | UserToken | JsonWebToken.js:24:28:24:36 | UserToken | -| JsonWebToken.js:20:23:20:28 | aJwt() | JsonWebToken.js:20:11:20:28 | UserToken | -| JsonWebToken.js:20:23:20:28 | aJwt() | JsonWebToken.js:20:11:20:28 | UserToken | -| JsonWebToken.js:28:11:28:28 | UserToken | JsonWebToken.js:31:28:31:36 | UserToken | -| JsonWebToken.js:28:11:28:28 | UserToken | JsonWebToken.js:31:28:31:36 | UserToken | -| JsonWebToken.js:28:23:28:28 | aJwt() | JsonWebToken.js:28:11:28:28 | UserToken | -| JsonWebToken.js:28:23:28:28 | aJwt() | JsonWebToken.js:28:11:28:28 | UserToken | -| JsonWebToken.js:35:11:35:28 | UserToken | JsonWebToken.js:38:28:38:36 | UserToken | -| JsonWebToken.js:35:11:35:28 | UserToken | JsonWebToken.js:38:28:38:36 | UserToken | -| JsonWebToken.js:35:11:35:28 | UserToken | JsonWebToken.js:39:28:39:36 | UserToken | -| JsonWebToken.js:35:11:35:28 | UserToken | JsonWebToken.js:39:28:39:36 | UserToken | -| JsonWebToken.js:35:23:35:28 | aJwt() | JsonWebToken.js:35:11:35:28 | UserToken | -| JsonWebToken.js:35:23:35:28 | aJwt() | JsonWebToken.js:35:11:35:28 | UserToken | -| JsonWebToken.js:43:11:43:28 | UserToken | JsonWebToken.js:46:28:46:36 | UserToken | -| JsonWebToken.js:43:11:43:28 | UserToken | JsonWebToken.js:46:28:46:36 | UserToken | -| JsonWebToken.js:43:11:43:28 | UserToken | JsonWebToken.js:47:28:47:36 | UserToken | -| JsonWebToken.js:43:11:43:28 | UserToken | JsonWebToken.js:47:28:47:36 | UserToken | -| JsonWebToken.js:43:23:43:28 | aJwt() | JsonWebToken.js:43:11:43:28 | UserToken | -| JsonWebToken.js:43:23:43:28 | aJwt() | JsonWebToken.js:43:11:43:28 | UserToken | -| jose.js:12:11:12:28 | UserToken | jose.js:15:20:15:28 | UserToken | -| jose.js:12:11:12:28 | UserToken | jose.js:15:20:15:28 | UserToken | -| jose.js:12:23:12:28 | aJwt() | jose.js:12:11:12:28 | UserToken | -| jose.js:12:23:12:28 | aJwt() | jose.js:12:11:12:28 | UserToken | -| jose.js:19:11:19:28 | UserToken | jose.js:22:20:22:28 | UserToken | -| jose.js:19:11:19:28 | UserToken | jose.js:22:20:22:28 | UserToken | -| jose.js:19:11:19:28 | UserToken | jose.js:23:26:23:34 | UserToken | -| jose.js:19:11:19:28 | UserToken | jose.js:23:26:23:34 | UserToken | -| jose.js:19:23:19:28 | aJwt() | jose.js:19:11:19:28 | UserToken | -| jose.js:19:23:19:28 | aJwt() | jose.js:19:11:19:28 | UserToken | -| jose.js:27:11:27:28 | UserToken | jose.js:30:26:30:34 | UserToken | -| jose.js:27:11:27:28 | UserToken | jose.js:30:26:30:34 | UserToken | -| jose.js:27:23:27:28 | aJwt() | jose.js:27:11:27:28 | UserToken | -| jose.js:27:23:27:28 | aJwt() | jose.js:27:11:27:28 | UserToken | -| jwtDecode.js:13:11:13:28 | UserToken | jwtDecode.js:17:16:17:24 | UserToken | -| jwtDecode.js:13:11:13:28 | UserToken | jwtDecode.js:17:16:17:24 | UserToken | -| jwtDecode.js:13:23:13:28 | aJwt() | jwtDecode.js:13:11:13:28 | UserToken | -| jwtDecode.js:13:23:13:28 | aJwt() | jwtDecode.js:13:11:13:28 | UserToken | -| jwtSimple.js:13:11:13:28 | UserToken | jwtSimple.js:16:23:16:31 | UserToken | -| jwtSimple.js:13:11:13:28 | UserToken | jwtSimple.js:16:23:16:31 | UserToken | -| jwtSimple.js:13:23:13:28 | aJwt() | jwtSimple.js:13:11:13:28 | UserToken | -| jwtSimple.js:13:23:13:28 | aJwt() | jwtSimple.js:13:11:13:28 | UserToken | -| jwtSimple.js:20:11:20:28 | UserToken | jwtSimple.js:23:23:23:31 | UserToken | -| jwtSimple.js:20:11:20:28 | UserToken | jwtSimple.js:23:23:23:31 | UserToken | -| jwtSimple.js:20:11:20:28 | UserToken | jwtSimple.js:24:23:24:31 | UserToken | -| jwtSimple.js:20:11:20:28 | UserToken | jwtSimple.js:24:23:24:31 | UserToken | -| jwtSimple.js:20:23:20:28 | aJwt() | jwtSimple.js:20:11:20:28 | UserToken | -| jwtSimple.js:20:23:20:28 | aJwt() | jwtSimple.js:20:11:20:28 | UserToken | -| jwtSimple.js:28:11:28:28 | UserToken | jwtSimple.js:31:23:31:31 | UserToken | -| jwtSimple.js:28:11:28:28 | UserToken | jwtSimple.js:31:23:31:31 | UserToken | -| jwtSimple.js:28:11:28:28 | UserToken | jwtSimple.js:32:23:32:31 | UserToken | -| jwtSimple.js:28:11:28:28 | UserToken | jwtSimple.js:32:23:32:31 | UserToken | -| jwtSimple.js:28:23:28:28 | aJwt() | jwtSimple.js:28:11:28:28 | UserToken | -| jwtSimple.js:28:23:28:28 | aJwt() | jwtSimple.js:28:11:28:28 | UserToken | +| JsonWebToken.js:13:11:13:28 | UserToken | JsonWebToken.js:16:28:16:36 | UserToken | provenance | | +| JsonWebToken.js:13:23:13:28 | aJwt() | JsonWebToken.js:13:11:13:28 | UserToken | provenance | | +| JsonWebToken.js:20:11:20:28 | UserToken | JsonWebToken.js:23:28:23:36 | UserToken | provenance | | +| JsonWebToken.js:20:11:20:28 | UserToken | JsonWebToken.js:24:28:24:36 | UserToken | provenance | | +| JsonWebToken.js:20:23:20:28 | aJwt() | JsonWebToken.js:20:11:20:28 | UserToken | provenance | | +| JsonWebToken.js:28:11:28:28 | UserToken | JsonWebToken.js:31:28:31:36 | UserToken | provenance | | +| JsonWebToken.js:28:23:28:28 | aJwt() | JsonWebToken.js:28:11:28:28 | UserToken | provenance | | +| JsonWebToken.js:35:11:35:28 | UserToken | JsonWebToken.js:38:28:38:36 | UserToken | provenance | | +| JsonWebToken.js:35:11:35:28 | UserToken | JsonWebToken.js:39:28:39:36 | UserToken | provenance | | +| JsonWebToken.js:35:23:35:28 | aJwt() | JsonWebToken.js:35:11:35:28 | UserToken | provenance | | +| JsonWebToken.js:43:11:43:28 | UserToken | JsonWebToken.js:46:28:46:36 | UserToken | provenance | | +| JsonWebToken.js:43:11:43:28 | UserToken | JsonWebToken.js:47:28:47:36 | UserToken | provenance | | +| JsonWebToken.js:43:23:43:28 | aJwt() | JsonWebToken.js:43:11:43:28 | UserToken | provenance | | +| jose.js:12:11:12:28 | UserToken | jose.js:15:20:15:28 | UserToken | provenance | | +| jose.js:12:23:12:28 | aJwt() | jose.js:12:11:12:28 | UserToken | provenance | | +| jose.js:19:11:19:28 | UserToken | jose.js:22:20:22:28 | UserToken | provenance | | +| jose.js:19:11:19:28 | UserToken | jose.js:23:26:23:34 | UserToken | provenance | | +| jose.js:19:23:19:28 | aJwt() | jose.js:19:11:19:28 | UserToken | provenance | | +| jose.js:27:11:27:28 | UserToken | jose.js:30:26:30:34 | UserToken | provenance | | +| jose.js:27:23:27:28 | aJwt() | jose.js:27:11:27:28 | UserToken | provenance | | +| jwtDecode.js:13:11:13:28 | UserToken | jwtDecode.js:17:16:17:24 | UserToken | provenance | | +| jwtDecode.js:13:23:13:28 | aJwt() | jwtDecode.js:13:11:13:28 | UserToken | provenance | | +| jwtSimple.js:13:11:13:28 | UserToken | jwtSimple.js:16:23:16:31 | UserToken | provenance | | +| jwtSimple.js:13:23:13:28 | aJwt() | jwtSimple.js:13:11:13:28 | UserToken | provenance | | +| jwtSimple.js:20:11:20:28 | UserToken | jwtSimple.js:23:23:23:31 | UserToken | provenance | | +| jwtSimple.js:20:11:20:28 | UserToken | jwtSimple.js:24:23:24:31 | UserToken | provenance | | +| jwtSimple.js:20:23:20:28 | aJwt() | jwtSimple.js:20:11:20:28 | UserToken | provenance | | +| jwtSimple.js:28:11:28:28 | UserToken | jwtSimple.js:31:23:31:31 | UserToken | provenance | | +| jwtSimple.js:28:11:28:28 | UserToken | jwtSimple.js:32:23:32:31 | UserToken | provenance | | +| jwtSimple.js:28:23:28:28 | aJwt() | jwtSimple.js:28:11:28:28 | UserToken | provenance | | +nodes +| JsonWebToken.js:13:11:13:28 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:13:23:13:28 | aJwt() | semmle.label | aJwt() | +| JsonWebToken.js:16:28:16:36 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:20:11:20:28 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:20:23:20:28 | aJwt() | semmle.label | aJwt() | +| JsonWebToken.js:23:28:23:36 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:24:28:24:36 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:28:11:28:28 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:28:23:28:28 | aJwt() | semmle.label | aJwt() | +| JsonWebToken.js:31:28:31:36 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:35:11:35:28 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:35:23:35:28 | aJwt() | semmle.label | aJwt() | +| JsonWebToken.js:38:28:38:36 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:39:28:39:36 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:43:11:43:28 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:43:23:43:28 | aJwt() | semmle.label | aJwt() | +| JsonWebToken.js:46:28:46:36 | UserToken | semmle.label | UserToken | +| JsonWebToken.js:47:28:47:36 | UserToken | semmle.label | UserToken | +| jose.js:12:11:12:28 | UserToken | semmle.label | UserToken | +| jose.js:12:23:12:28 | aJwt() | semmle.label | aJwt() | +| jose.js:15:20:15:28 | UserToken | semmle.label | UserToken | +| jose.js:19:11:19:28 | UserToken | semmle.label | UserToken | +| jose.js:19:23:19:28 | aJwt() | semmle.label | aJwt() | +| jose.js:22:20:22:28 | UserToken | semmle.label | UserToken | +| jose.js:23:26:23:34 | UserToken | semmle.label | UserToken | +| jose.js:27:11:27:28 | UserToken | semmle.label | UserToken | +| jose.js:27:23:27:28 | aJwt() | semmle.label | aJwt() | +| jose.js:30:26:30:34 | UserToken | semmle.label | UserToken | +| jwtDecode.js:13:11:13:28 | UserToken | semmle.label | UserToken | +| jwtDecode.js:13:23:13:28 | aJwt() | semmle.label | aJwt() | +| jwtDecode.js:17:16:17:24 | UserToken | semmle.label | UserToken | +| jwtSimple.js:13:11:13:28 | UserToken | semmle.label | UserToken | +| jwtSimple.js:13:23:13:28 | aJwt() | semmle.label | aJwt() | +| jwtSimple.js:16:23:16:31 | UserToken | semmle.label | UserToken | +| jwtSimple.js:20:11:20:28 | UserToken | semmle.label | UserToken | +| jwtSimple.js:20:23:20:28 | aJwt() | semmle.label | aJwt() | +| jwtSimple.js:23:23:23:31 | UserToken | semmle.label | UserToken | +| jwtSimple.js:24:23:24:31 | UserToken | semmle.label | UserToken | +| jwtSimple.js:28:11:28:28 | UserToken | semmle.label | UserToken | +| jwtSimple.js:28:23:28:28 | aJwt() | semmle.label | aJwt() | +| jwtSimple.js:31:23:31:31 | UserToken | semmle.label | UserToken | +| jwtSimple.js:32:23:32:31 | UserToken | semmle.label | UserToken | +subpaths #select | JsonWebToken.js:13:23:13:28 | aJwt() | JsonWebToken.js:13:23:13:28 | aJwt() | JsonWebToken.js:16:28:16:36 | UserToken | Decoding JWT $@. | JsonWebToken.js:16:28:16:36 | UserToken | without signature verification | | JsonWebToken.js:20:23:20:28 | aJwt() | JsonWebToken.js:20:23:20:28 | aJwt() | JsonWebToken.js:23:28:23:36 | UserToken | Decoding JWT $@. | JsonWebToken.js:23:28:23:36 | UserToken | without signature verification | From 871bc3b84a7a72c552602c852bae0b628b3099af Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 11:46:56 +0100 Subject: [PATCH 405/514] JS: Port experimental CorsPermissiveConfiguration to ConfigSig The tests show a new (source, sink) pair for an already-flagged sink. Not sure why it was not flagged originally since the data flow path seems valid, given the steps provided by our models. --- .../CWE-942/CorsPermissiveConfiguration.ql | 7 +- .../CorsPermissiveConfigurationQuery.qll | 30 ++++++-- .../CorsPermissiveConfiguration.expected | 70 +++++++------------ 3 files changed, 56 insertions(+), 51 deletions(-) diff --git a/javascript/ql/src/experimental/Security/CWE-942/CorsPermissiveConfiguration.ql b/javascript/ql/src/experimental/Security/CWE-942/CorsPermissiveConfiguration.ql index e82d0e85ade..87db66ad98d 100644 --- a/javascript/ql/src/experimental/Security/CWE-942/CorsPermissiveConfiguration.ql +++ b/javascript/ql/src/experimental/Security/CWE-942/CorsPermissiveConfiguration.ql @@ -12,9 +12,10 @@ import javascript import CorsPermissiveConfigurationQuery -import DataFlow::PathGraph +import CorsPermissiveConfigurationFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from + CorsPermissiveConfigurationFlow::PathNode source, CorsPermissiveConfigurationFlow::PathNode sink +where CorsPermissiveConfigurationFlow::flowPath(source, sink) select sink.getNode(), source, sink, "CORS Origin misconfiguration due to a $@.", source.getNode(), "too permissive or user controlled value" diff --git a/javascript/ql/src/experimental/Security/CWE-942/CorsPermissiveConfigurationQuery.qll b/javascript/ql/src/experimental/Security/CWE-942/CorsPermissiveConfigurationQuery.qll index 4d56365aafe..ea17de322ac 100644 --- a/javascript/ql/src/experimental/Security/CWE-942/CorsPermissiveConfigurationQuery.qll +++ b/javascript/ql/src/experimental/Security/CWE-942/CorsPermissiveConfigurationQuery.qll @@ -14,10 +14,10 @@ import CorsPermissiveConfigurationCustomizations::CorsPermissiveConfiguration /** * A data flow configuration for overly permissive CORS configuration. */ -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CorsPermissiveConfiguration" } +module CorsPermissiveConfigurationConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; - override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { source instanceof TrueNullValue and label = truenullLabel() or source instanceof WildcardValue and label = wildcardLabel() @@ -25,15 +25,35 @@ class Configuration extends TaintTracking::Configuration { source instanceof RemoteFlowSource and label = DataFlow::FlowLabel::taint() } - override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { + predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { sink instanceof CorsApolloServer and label = [DataFlow::FlowLabel::taint(), truenullLabel()] or sink instanceof ExpressCors and label = [DataFlow::FlowLabel::taint(), wildcardLabel()] } + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +module CorsPermissiveConfigurationFlow = + TaintTracking::GlobalWithState; + +/** + * DEPRECATED. Use the `CorsPermissiveConfigurationFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { + Configuration() { this = "CorsPermissiveConfiguration" } + + override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { + CorsPermissiveConfigurationConfig::isSource(source, label) + } + + override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { + CorsPermissiveConfigurationConfig::isSink(sink, label) + } + override predicate isSanitizer(DataFlow::Node node) { super.isSanitizer(node) or - node instanceof Sanitizer + CorsPermissiveConfigurationConfig::isBarrier(node) } } diff --git a/javascript/ql/test/experimental/Security/CWE-942/CorsPermissiveConfiguration.expected b/javascript/ql/test/experimental/Security/CWE-942/CorsPermissiveConfiguration.expected index 965fc4c722b..6c28b7105a1 100644 --- a/javascript/ql/test/experimental/Security/CWE-942/CorsPermissiveConfiguration.expected +++ b/javascript/ql/test/experimental/Security/CWE-942/CorsPermissiveConfiguration.expected @@ -1,50 +1,34 @@ -nodes -| apollo-test.js:8:9:8:59 | user_origin | -| apollo-test.js:8:23:8:46 | url.par ... , true) | -| apollo-test.js:8:23:8:52 | url.par ... ).query | -| apollo-test.js:8:23:8:59 | url.par ... .origin | -| apollo-test.js:8:33:8:39 | req.url | -| apollo-test.js:8:33:8:39 | req.url | -| apollo-test.js:11:25:11:28 | true | -| apollo-test.js:11:25:11:28 | true | -| apollo-test.js:11:25:11:28 | true | -| apollo-test.js:21:25:21:28 | null | -| apollo-test.js:21:25:21:28 | null | -| apollo-test.js:21:25:21:28 | null | -| apollo-test.js:26:25:26:35 | user_origin | -| apollo-test.js:26:25:26:35 | user_origin | -| express-test.js:10:9:10:59 | user_origin | -| express-test.js:10:23:10:46 | url.par ... , true) | -| express-test.js:10:23:10:52 | url.par ... ).query | -| express-test.js:10:23:10:59 | url.par ... .origin | -| express-test.js:10:33:10:39 | req.url | -| express-test.js:10:33:10:39 | req.url | -| express-test.js:26:17:26:19 | '*' | -| express-test.js:26:17:26:19 | '*' | -| express-test.js:26:17:26:19 | '*' | -| express-test.js:33:17:33:27 | user_origin | -| express-test.js:33:17:33:27 | user_origin | edges -| apollo-test.js:8:9:8:59 | user_origin | apollo-test.js:26:25:26:35 | user_origin | -| apollo-test.js:8:9:8:59 | user_origin | apollo-test.js:26:25:26:35 | user_origin | -| apollo-test.js:8:23:8:46 | url.par ... , true) | apollo-test.js:8:23:8:52 | url.par ... ).query | -| apollo-test.js:8:23:8:52 | url.par ... ).query | apollo-test.js:8:23:8:59 | url.par ... .origin | -| apollo-test.js:8:23:8:59 | url.par ... .origin | apollo-test.js:8:9:8:59 | user_origin | -| apollo-test.js:8:33:8:39 | req.url | apollo-test.js:8:23:8:46 | url.par ... , true) | -| apollo-test.js:8:33:8:39 | req.url | apollo-test.js:8:23:8:46 | url.par ... , true) | -| apollo-test.js:11:25:11:28 | true | apollo-test.js:11:25:11:28 | true | -| apollo-test.js:21:25:21:28 | null | apollo-test.js:21:25:21:28 | null | -| express-test.js:10:9:10:59 | user_origin | express-test.js:33:17:33:27 | user_origin | -| express-test.js:10:9:10:59 | user_origin | express-test.js:33:17:33:27 | user_origin | -| express-test.js:10:23:10:46 | url.par ... , true) | express-test.js:10:23:10:52 | url.par ... ).query | -| express-test.js:10:23:10:52 | url.par ... ).query | express-test.js:10:23:10:59 | url.par ... .origin | -| express-test.js:10:23:10:59 | url.par ... .origin | express-test.js:10:9:10:59 | user_origin | -| express-test.js:10:33:10:39 | req.url | express-test.js:10:23:10:46 | url.par ... , true) | -| express-test.js:10:33:10:39 | req.url | express-test.js:10:23:10:46 | url.par ... , true) | -| express-test.js:26:17:26:19 | '*' | express-test.js:26:17:26:19 | '*' | +| apollo-test.js:8:9:8:59 | user_origin | apollo-test.js:26:25:26:35 | user_origin | provenance | | +| apollo-test.js:8:9:8:59 | user_origin | apollo-test.js:26:25:26:35 | user_origin | provenance | | +| apollo-test.js:8:23:8:46 | url.par ... , true) | apollo-test.js:8:9:8:59 | user_origin | provenance | | +| apollo-test.js:8:23:8:46 | url.par ... , true) | apollo-test.js:8:9:8:59 | user_origin | provenance | | +| apollo-test.js:8:33:8:39 | req.url | apollo-test.js:8:23:8:46 | url.par ... , true) | provenance | | +| apollo-test.js:8:42:8:45 | true | apollo-test.js:8:23:8:46 | url.par ... , true) | provenance | | +| express-test.js:10:9:10:59 | user_origin | express-test.js:33:17:33:27 | user_origin | provenance | | +| express-test.js:10:23:10:46 | url.par ... , true) | express-test.js:10:9:10:59 | user_origin | provenance | | +| express-test.js:10:33:10:39 | req.url | express-test.js:10:23:10:46 | url.par ... , true) | provenance | | +nodes +| apollo-test.js:8:9:8:59 | user_origin | semmle.label | user_origin | +| apollo-test.js:8:9:8:59 | user_origin | semmle.label | user_origin | +| apollo-test.js:8:23:8:46 | url.par ... , true) | semmle.label | url.par ... , true) | +| apollo-test.js:8:23:8:46 | url.par ... , true) | semmle.label | url.par ... , true) | +| apollo-test.js:8:33:8:39 | req.url | semmle.label | req.url | +| apollo-test.js:8:42:8:45 | true | semmle.label | true | +| apollo-test.js:11:25:11:28 | true | semmle.label | true | +| apollo-test.js:21:25:21:28 | null | semmle.label | null | +| apollo-test.js:26:25:26:35 | user_origin | semmle.label | user_origin | +| apollo-test.js:26:25:26:35 | user_origin | semmle.label | user_origin | +| express-test.js:10:9:10:59 | user_origin | semmle.label | user_origin | +| express-test.js:10:23:10:46 | url.par ... , true) | semmle.label | url.par ... , true) | +| express-test.js:10:33:10:39 | req.url | semmle.label | req.url | +| express-test.js:26:17:26:19 | '*' | semmle.label | '*' | +| express-test.js:33:17:33:27 | user_origin | semmle.label | user_origin | +subpaths #select | apollo-test.js:11:25:11:28 | true | apollo-test.js:11:25:11:28 | true | apollo-test.js:11:25:11:28 | true | CORS Origin misconfiguration due to a $@. | apollo-test.js:11:25:11:28 | true | too permissive or user controlled value | | apollo-test.js:21:25:21:28 | null | apollo-test.js:21:25:21:28 | null | apollo-test.js:21:25:21:28 | null | CORS Origin misconfiguration due to a $@. | apollo-test.js:21:25:21:28 | null | too permissive or user controlled value | | apollo-test.js:26:25:26:35 | user_origin | apollo-test.js:8:33:8:39 | req.url | apollo-test.js:26:25:26:35 | user_origin | CORS Origin misconfiguration due to a $@. | apollo-test.js:8:33:8:39 | req.url | too permissive or user controlled value | +| apollo-test.js:26:25:26:35 | user_origin | apollo-test.js:8:42:8:45 | true | apollo-test.js:26:25:26:35 | user_origin | CORS Origin misconfiguration due to a $@. | apollo-test.js:8:42:8:45 | true | too permissive or user controlled value | | express-test.js:26:17:26:19 | '*' | express-test.js:26:17:26:19 | '*' | express-test.js:26:17:26:19 | '*' | CORS Origin misconfiguration due to a $@. | express-test.js:26:17:26:19 | '*' | too permissive or user controlled value | | express-test.js:33:17:33:27 | user_origin | express-test.js:10:33:10:39 | req.url | express-test.js:33:17:33:27 | user_origin | CORS Origin misconfiguration due to a $@. | express-test.js:10:33:10:39 | req.url | too permissive or user controlled value | From 834d35bc42d239d57e25c9500df3d0936016d2d3 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 11:49:27 +0100 Subject: [PATCH 406/514] JS: Port experimental DecompressionBombs to ConfigSig --- .../DecompressionBombs.ql | 19 +- .../DecompressionBombs.qll | 1 - .../DecompressionBombs.expected | 561 +++++++----------- 3 files changed, 220 insertions(+), 361 deletions(-) diff --git a/javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/DecompressionBombs.ql b/javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/DecompressionBombs.ql index 0e734f4c0c6..29e62b85d4e 100644 --- a/javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/DecompressionBombs.ql +++ b/javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/DecompressionBombs.ql @@ -12,24 +12,25 @@ */ import javascript -import DataFlow::PathGraph import DecompressionBombs -class BombConfiguration extends TaintTracking::Configuration { - BombConfiguration() { this = "DecompressionBombs" } +module DecompressionBombConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSink(DataFlow::Node sink) { sink instanceof DecompressionBomb::Sink } - override predicate isSink(DataFlow::Node sink) { sink instanceof DecompressionBomb::Sink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { exists(DecompressionBomb::AdditionalTaintStep addstep | addstep.isAdditionalTaintStep(pred, succ) ) } } -from BombConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +module DecompressionBombFlow = TaintTracking::Global; + +import DecompressionBombFlow::PathGraph + +from DecompressionBombFlow::PathNode source, DecompressionBombFlow::PathNode sink +where DecompressionBombFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This Decompression depends on a $@.", source.getNode(), "potentially untrusted source" diff --git a/javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/DecompressionBombs.qll b/javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/DecompressionBombs.qll index 8a20fea499b..798e8c6f268 100644 --- a/javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/DecompressionBombs.qll +++ b/javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/DecompressionBombs.qll @@ -1,7 +1,6 @@ import javascript import experimental.semmle.javascript.FormParsers import experimental.semmle.javascript.ReadableStream -import DataFlow::PathGraph module DecompressionBomb { /** diff --git a/javascript/ql/test/query-tests/Security/CWE-522-DecompressionBombs/DecompressionBombs.expected b/javascript/ql/test/query-tests/Security/CWE-522-DecompressionBombs/DecompressionBombs.expected index 659e49339d1..3ba33bc2625 100644 --- a/javascript/ql/test/query-tests/Security/CWE-522-DecompressionBombs/DecompressionBombs.expected +++ b/javascript/ql/test/query-tests/Security/CWE-522-DecompressionBombs/DecompressionBombs.expected @@ -1,355 +1,214 @@ -nodes -| adm-zip.js:13:13:13:21 | req.files | -| adm-zip.js:13:13:13:21 | req.files | -| adm-zip.js:13:13:13:33 | req.fil ... ombFile | -| adm-zip.js:17:18:17:24 | tarFile | -| adm-zip.js:24:22:24:28 | tarFile | -| adm-zip.js:24:22:24:33 | tarFile.data | -| adm-zip.js:28:25:28:42 | zipEntry.getData() | -| adm-zip.js:28:25:28:42 | zipEntry.getData() | -| adm-zip.js:32:17:32:41 | admZip. ... "10GB") | -| adm-zip.js:32:17:32:41 | admZip. ... "10GB") | -| adm-zip.js:34:5:34:55 | admZip. ... , true) | -| adm-zip.js:34:5:34:55 | admZip. ... , true) | -| adm-zip.js:36:5:36:38 | admZip. ... , true) | -| adm-zip.js:36:5:36:38 | admZip. ... , true) | -| decompress.js:11:16:11:33 | req.query.filePath | -| decompress.js:11:16:11:33 | req.query.filePath | -| decompress.js:11:16:11:33 | req.query.filePath | -| jszip.js:12:13:12:21 | req.files | -| jszip.js:12:13:12:21 | req.files | -| jszip.js:12:13:12:33 | req.fil ... ombFile | -| jszip.js:12:13:12:38 | req.fil ... le.data | -| jszip.js:32:18:32:24 | zipFile | -| jszip.js:33:22:33:28 | zipFile | -| jszip.js:33:22:33:33 | zipFile.data | -| jszip.js:33:22:33:33 | zipFile.data | -| node-tar.js:15:13:15:21 | req.files | -| node-tar.js:15:13:15:21 | req.files | -| node-tar.js:15:13:15:33 | req.fil ... ombFile | -| node-tar.js:15:13:15:38 | req.fil ... le.data | -| node-tar.js:19:18:19:24 | tarFile | -| node-tar.js:21:23:21:49 | Readabl ... e.data) | -| node-tar.js:21:37:21:43 | tarFile | -| node-tar.js:21:37:21:48 | tarFile.data | -| node-tar.js:24:9:24:15 | tar.x() | -| node-tar.js:24:9:24:15 | tar.x() | -| node-tar.js:29:5:29:37 | fs.crea ... e.name) | -| node-tar.js:29:25:29:31 | tarFile | -| node-tar.js:29:25:29:36 | tarFile.name | -| node-tar.js:30:9:33:10 | tar.x({ ... }) | -| node-tar.js:30:9:33:10 | tar.x({ ... }) | -| node-tar.js:45:5:45:37 | fs.crea ... e.name) | -| node-tar.js:45:25:45:31 | tarFile | -| node-tar.js:45:25:45:36 | tarFile.name | -| node-tar.js:46:9:46:20 | decompressor | -| node-tar.js:48:9:50:10 | tar.x({ ... }) | -| node-tar.js:48:9:50:10 | tar.x({ ... }) | -| node-tar.js:58:19:58:25 | tarFile | -| node-tar.js:58:19:58:30 | tarFile.name | -| node-tar.js:58:19:58:30 | tarFile.name | -| node-tar.js:59:25:59:31 | tarFile | -| node-tar.js:59:25:59:36 | tarFile.name | -| node-tar.js:59:25:59:36 | tarFile.name | -| pako.js:12:14:12:22 | req.files | -| pako.js:12:14:12:22 | req.files | -| pako.js:12:14:12:34 | req.fil ... ombFile | -| pako.js:12:14:12:39 | req.fil ... le.data | -| pako.js:13:14:13:22 | req.files | -| pako.js:13:14:13:22 | req.files | -| pako.js:13:14:13:34 | req.fil ... ombFile | -| pako.js:13:14:13:39 | req.fil ... le.data | -| pako.js:17:19:17:25 | zipFile | -| pako.js:18:11:18:68 | myArray | -| pako.js:18:21:18:68 | Buffer. ... uffer)) | -| pako.js:18:33:18:67 | new Uin ... buffer) | -| pako.js:18:48:18:54 | zipFile | -| pako.js:18:48:18:59 | zipFile.data | -| pako.js:18:48:18:66 | zipFile.data.buffer | -| pako.js:21:31:21:37 | myArray | -| pako.js:21:31:21:37 | myArray | -| pako.js:28:19:28:25 | zipFile | -| pako.js:29:11:29:62 | myArray | -| pako.js:29:21:29:55 | new Uin ... buffer) | -| pako.js:29:21:29:62 | new Uin ... .buffer | -| pako.js:29:36:29:42 | zipFile | -| pako.js:29:36:29:47 | zipFile.data | -| pako.js:29:36:29:54 | zipFile.data.buffer | -| pako.js:32:31:32:37 | myArray | -| pako.js:32:31:32:37 | myArray | -| unbzip2.js:12:5:12:43 | fs.crea ... lePath) | -| unbzip2.js:12:25:12:42 | req.query.FilePath | -| unbzip2.js:12:25:12:42 | req.query.FilePath | -| unbzip2.js:12:50:12:54 | bz2() | -| unbzip2.js:12:50:12:54 | bz2() | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | -| unzipper.js:13:40:13:48 | req.files | -| unzipper.js:13:40:13:48 | req.files | -| unzipper.js:13:40:13:56 | req.files.ZipFile | -| unzipper.js:13:40:13:61 | req.fil ... le.data | -| unzipper.js:16:23:16:63 | unzippe ... ath' }) | -| unzipper.js:16:23:16:63 | unzippe ... ath' }) | -| unzipper.js:19:23:19:41 | unzipper.ParseOne() | -| unzipper.js:19:23:19:41 | unzipper.ParseOne() | -| unzipper.js:24:15:24:30 | unzipper.Parse() | -| unzipper.js:24:15:24:30 | unzipper.Parse() | -| unzipper.js:34:15:34:30 | unzipper.Parse() | -| unzipper.js:34:15:34:30 | unzipper.Parse() | -| unzipper.js:41:35:41:71 | unzippe ... true }) | -| unzipper.js:41:35:41:71 | unzippe ... true }) | -| unzipper.js:51:36:51:72 | unzippe ... true }) | -| unzipper.js:51:36:51:72 | unzippe ... true }) | -| unzipper.js:60:23:60:38 | unzipper.Parse() | -| unzipper.js:60:23:60:38 | unzipper.Parse() | -| unzipper.js:73:23:73:38 | unzipper.Parse() | -| unzipper.js:73:23:73:38 | unzipper.Parse() | -| yauzl.js:12:18:12:26 | req.files | -| yauzl.js:12:18:12:26 | req.files | -| yauzl.js:12:18:12:34 | req.files.zipFile | -| yauzl.js:12:18:12:39 | req.fil ... le.data | -| yauzl.js:12:18:12:39 | req.fil ... le.data | -| yauzl.js:13:22:13:30 | req.files | -| yauzl.js:13:22:13:30 | req.files | -| yauzl.js:13:22:13:38 | req.files.zipFile | -| yauzl.js:13:22:13:43 | req.fil ... le.data | -| yauzl.js:13:22:13:43 | req.fil ... le.data | -| yauzl.js:14:34:14:42 | req.files | -| yauzl.js:14:34:14:42 | req.files | -| yauzl.js:14:34:14:50 | req.files.zipFile | -| yauzl.js:14:34:14:55 | req.fil ... le.data | -| yauzl.js:14:34:14:55 | req.fil ... le.data | -| yauzl.js:37:16:37:33 | req.query.filePath | -| yauzl.js:37:16:37:33 | req.query.filePath | -| yauzl.js:39:9:39:27 | zipfile.readEntry() | -| yauzl.js:39:9:39:27 | zipfile.readEntry() | -| yauzl.js:41:64:41:73 | readStream | -| yauzl.js:41:64:41:73 | readStream | -| yauzl.js:43:21:43:39 | zipfile.readEntry() | -| yauzl.js:43:21:43:39 | zipfile.readEntry() | -| zlib.js:15:19:15:27 | req.files | -| zlib.js:15:19:15:27 | req.files | -| zlib.js:15:19:15:39 | req.fil ... ombFile | -| zlib.js:15:19:15:44 | req.fil ... le.data | -| zlib.js:17:18:17:26 | req.files | -| zlib.js:17:18:17:26 | req.files | -| zlib.js:17:18:17:38 | req.fil ... ombFile | -| zlib.js:17:18:17:43 | req.fil ... le.data | -| zlib.js:19:24:19:32 | req.files | -| zlib.js:19:24:19:32 | req.files | -| zlib.js:19:24:19:44 | req.fil ... ombFile | -| zlib.js:19:24:19:49 | req.fil ... le.data | -| zlib.js:21:32:21:40 | req.files | -| zlib.js:21:32:21:40 | req.files | -| zlib.js:21:32:21:52 | req.fil ... ombFile | -| zlib.js:21:32:21:57 | req.fil ... le.data | -| zlib.js:27:24:27:30 | zipFile | -| zlib.js:29:9:29:15 | zipFile | -| zlib.js:29:9:29:20 | zipFile.data | -| zlib.js:29:9:29:20 | zipFile.data | -| zlib.js:33:9:33:15 | zipFile | -| zlib.js:33:9:33:20 | zipFile.data | -| zlib.js:33:9:33:20 | zipFile.data | -| zlib.js:38:9:38:15 | zipFile | -| zlib.js:38:9:38:20 | zipFile.data | -| zlib.js:38:9:38:20 | zipFile.data | -| zlib.js:62:23:62:29 | zipFile | -| zlib.js:63:21:63:27 | zipFile | -| zlib.js:63:21:63:32 | zipFile.data | -| zlib.js:63:21:63:32 | zipFile.data | -| zlib.js:64:20:64:26 | zipFile | -| zlib.js:64:20:64:31 | zipFile.data | -| zlib.js:64:20:64:31 | zipFile.data | -| zlib.js:65:31:65:37 | zipFile | -| zlib.js:65:31:65:42 | zipFile.data | -| zlib.js:65:31:65:42 | zipFile.data | -| zlib.js:74:29:74:35 | zipFile | -| zlib.js:75:25:75:51 | Readabl ... e.data) | -| zlib.js:75:39:75:45 | zipFile | -| zlib.js:75:39:75:50 | zipFile.data | -| zlib.js:77:22:77:40 | zlib.createGunzip() | -| zlib.js:77:22:77:40 | zlib.createGunzip() | -| zlib.js:78:22:78:39 | zlib.createUnzip() | -| zlib.js:78:22:78:39 | zlib.createUnzip() | -| zlib.js:79:22:79:50 | zlib.cr ... press() | -| zlib.js:79:22:79:50 | zlib.cr ... press() | -| zlib.js:82:43:82:49 | zipFile | -| zlib.js:83:11:83:51 | inputStream | -| zlib.js:83:25:83:51 | Readabl ... e.data) | -| zlib.js:83:39:83:45 | zipFile | -| zlib.js:83:39:83:50 | zipFile.data | -| zlib.js:86:9:86:19 | inputStream | -| zlib.js:87:9:87:27 | zlib.createGunzip() | -| zlib.js:87:9:87:27 | zlib.createGunzip() | edges -| adm-zip.js:13:13:13:21 | req.files | adm-zip.js:13:13:13:33 | req.fil ... ombFile | -| adm-zip.js:13:13:13:21 | req.files | adm-zip.js:13:13:13:33 | req.fil ... ombFile | -| adm-zip.js:13:13:13:33 | req.fil ... ombFile | adm-zip.js:17:18:17:24 | tarFile | -| adm-zip.js:17:18:17:24 | tarFile | adm-zip.js:24:22:24:28 | tarFile | -| adm-zip.js:24:22:24:28 | tarFile | adm-zip.js:24:22:24:33 | tarFile.data | -| adm-zip.js:24:22:24:33 | tarFile.data | adm-zip.js:28:25:28:42 | zipEntry.getData() | -| adm-zip.js:24:22:24:33 | tarFile.data | adm-zip.js:28:25:28:42 | zipEntry.getData() | -| adm-zip.js:24:22:24:33 | tarFile.data | adm-zip.js:32:17:32:41 | admZip. ... "10GB") | -| adm-zip.js:24:22:24:33 | tarFile.data | adm-zip.js:32:17:32:41 | admZip. ... "10GB") | -| adm-zip.js:24:22:24:33 | tarFile.data | adm-zip.js:34:5:34:55 | admZip. ... , true) | -| adm-zip.js:24:22:24:33 | tarFile.data | adm-zip.js:34:5:34:55 | admZip. ... , true) | -| adm-zip.js:24:22:24:33 | tarFile.data | adm-zip.js:36:5:36:38 | admZip. ... , true) | -| adm-zip.js:24:22:24:33 | tarFile.data | adm-zip.js:36:5:36:38 | admZip. ... , true) | -| decompress.js:11:16:11:33 | req.query.filePath | decompress.js:11:16:11:33 | req.query.filePath | -| jszip.js:12:13:12:21 | req.files | jszip.js:12:13:12:33 | req.fil ... ombFile | -| jszip.js:12:13:12:21 | req.files | jszip.js:12:13:12:33 | req.fil ... ombFile | -| jszip.js:12:13:12:33 | req.fil ... ombFile | jszip.js:12:13:12:38 | req.fil ... le.data | -| jszip.js:12:13:12:38 | req.fil ... le.data | jszip.js:32:18:32:24 | zipFile | -| jszip.js:32:18:32:24 | zipFile | jszip.js:33:22:33:28 | zipFile | -| jszip.js:33:22:33:28 | zipFile | jszip.js:33:22:33:33 | zipFile.data | -| jszip.js:33:22:33:28 | zipFile | jszip.js:33:22:33:33 | zipFile.data | -| node-tar.js:15:13:15:21 | req.files | node-tar.js:15:13:15:33 | req.fil ... ombFile | -| node-tar.js:15:13:15:21 | req.files | node-tar.js:15:13:15:33 | req.fil ... ombFile | -| node-tar.js:15:13:15:33 | req.fil ... ombFile | node-tar.js:15:13:15:38 | req.fil ... le.data | -| node-tar.js:15:13:15:38 | req.fil ... le.data | node-tar.js:19:18:19:24 | tarFile | -| node-tar.js:19:18:19:24 | tarFile | node-tar.js:21:37:21:43 | tarFile | -| node-tar.js:19:18:19:24 | tarFile | node-tar.js:29:25:29:31 | tarFile | -| node-tar.js:19:18:19:24 | tarFile | node-tar.js:45:25:45:31 | tarFile | -| node-tar.js:19:18:19:24 | tarFile | node-tar.js:58:19:58:25 | tarFile | -| node-tar.js:19:18:19:24 | tarFile | node-tar.js:59:25:59:31 | tarFile | -| node-tar.js:21:23:21:49 | Readabl ... e.data) | node-tar.js:24:9:24:15 | tar.x() | -| node-tar.js:21:23:21:49 | Readabl ... e.data) | node-tar.js:24:9:24:15 | tar.x() | -| node-tar.js:21:37:21:43 | tarFile | node-tar.js:21:37:21:48 | tarFile.data | -| node-tar.js:21:37:21:48 | tarFile.data | node-tar.js:21:23:21:49 | Readabl ... e.data) | -| node-tar.js:29:5:29:37 | fs.crea ... e.name) | node-tar.js:30:9:33:10 | tar.x({ ... }) | -| node-tar.js:29:5:29:37 | fs.crea ... e.name) | node-tar.js:30:9:33:10 | tar.x({ ... }) | -| node-tar.js:29:25:29:31 | tarFile | node-tar.js:29:25:29:36 | tarFile.name | -| node-tar.js:29:25:29:36 | tarFile.name | node-tar.js:29:5:29:37 | fs.crea ... e.name) | -| node-tar.js:45:5:45:37 | fs.crea ... e.name) | node-tar.js:46:9:46:20 | decompressor | -| node-tar.js:45:25:45:31 | tarFile | node-tar.js:45:25:45:36 | tarFile.name | -| node-tar.js:45:25:45:36 | tarFile.name | node-tar.js:45:5:45:37 | fs.crea ... e.name) | -| node-tar.js:46:9:46:20 | decompressor | node-tar.js:48:9:50:10 | tar.x({ ... }) | -| node-tar.js:46:9:46:20 | decompressor | node-tar.js:48:9:50:10 | tar.x({ ... }) | -| node-tar.js:58:19:58:25 | tarFile | node-tar.js:58:19:58:30 | tarFile.name | -| node-tar.js:58:19:58:25 | tarFile | node-tar.js:58:19:58:30 | tarFile.name | -| node-tar.js:59:25:59:31 | tarFile | node-tar.js:59:25:59:36 | tarFile.name | -| node-tar.js:59:25:59:31 | tarFile | node-tar.js:59:25:59:36 | tarFile.name | -| pako.js:12:14:12:22 | req.files | pako.js:12:14:12:34 | req.fil ... ombFile | -| pako.js:12:14:12:22 | req.files | pako.js:12:14:12:34 | req.fil ... ombFile | -| pako.js:12:14:12:34 | req.fil ... ombFile | pako.js:12:14:12:39 | req.fil ... le.data | -| pako.js:12:14:12:39 | req.fil ... le.data | pako.js:17:19:17:25 | zipFile | -| pako.js:13:14:13:22 | req.files | pako.js:13:14:13:34 | req.fil ... ombFile | -| pako.js:13:14:13:22 | req.files | pako.js:13:14:13:34 | req.fil ... ombFile | -| pako.js:13:14:13:34 | req.fil ... ombFile | pako.js:13:14:13:39 | req.fil ... le.data | -| pako.js:13:14:13:39 | req.fil ... le.data | pako.js:28:19:28:25 | zipFile | -| pako.js:17:19:17:25 | zipFile | pako.js:18:48:18:54 | zipFile | -| pako.js:18:11:18:68 | myArray | pako.js:21:31:21:37 | myArray | -| pako.js:18:11:18:68 | myArray | pako.js:21:31:21:37 | myArray | -| pako.js:18:21:18:68 | Buffer. ... uffer)) | pako.js:18:11:18:68 | myArray | -| pako.js:18:33:18:67 | new Uin ... buffer) | pako.js:18:21:18:68 | Buffer. ... uffer)) | -| pako.js:18:48:18:54 | zipFile | pako.js:18:48:18:59 | zipFile.data | -| pako.js:18:48:18:59 | zipFile.data | pako.js:18:48:18:66 | zipFile.data.buffer | -| pako.js:18:48:18:66 | zipFile.data.buffer | pako.js:18:33:18:67 | new Uin ... buffer) | -| pako.js:28:19:28:25 | zipFile | pako.js:29:36:29:42 | zipFile | -| pako.js:29:11:29:62 | myArray | pako.js:32:31:32:37 | myArray | -| pako.js:29:11:29:62 | myArray | pako.js:32:31:32:37 | myArray | -| pako.js:29:21:29:55 | new Uin ... buffer) | pako.js:29:21:29:62 | new Uin ... .buffer | -| pako.js:29:21:29:62 | new Uin ... .buffer | pako.js:29:11:29:62 | myArray | -| pako.js:29:36:29:42 | zipFile | pako.js:29:36:29:47 | zipFile.data | -| pako.js:29:36:29:47 | zipFile.data | pako.js:29:36:29:54 | zipFile.data.buffer | -| pako.js:29:36:29:54 | zipFile.data.buffer | pako.js:29:21:29:55 | new Uin ... buffer) | -| unbzip2.js:12:5:12:43 | fs.crea ... lePath) | unbzip2.js:12:50:12:54 | bz2() | -| unbzip2.js:12:5:12:43 | fs.crea ... lePath) | unbzip2.js:12:50:12:54 | bz2() | -| unbzip2.js:12:25:12:42 | req.query.FilePath | unbzip2.js:12:5:12:43 | fs.crea ... lePath) | -| unbzip2.js:12:25:12:42 | req.query.FilePath | unbzip2.js:12:5:12:43 | fs.crea ... lePath) | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:16:23:16:63 | unzippe ... ath' }) | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:16:23:16:63 | unzippe ... ath' }) | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:19:23:19:41 | unzipper.ParseOne() | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:19:23:19:41 | unzipper.ParseOne() | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:24:15:24:30 | unzipper.Parse() | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:24:15:24:30 | unzipper.Parse() | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:34:15:34:30 | unzipper.Parse() | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:34:15:34:30 | unzipper.Parse() | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:41:35:41:71 | unzippe ... true }) | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:41:35:41:71 | unzippe ... true }) | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:51:36:51:72 | unzippe ... true }) | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:51:36:51:72 | unzippe ... true }) | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:60:23:60:38 | unzipper.Parse() | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:60:23:60:38 | unzipper.Parse() | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:73:23:73:38 | unzipper.Parse() | -| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:73:23:73:38 | unzipper.Parse() | -| unzipper.js:13:40:13:48 | req.files | unzipper.js:13:40:13:56 | req.files.ZipFile | -| unzipper.js:13:40:13:48 | req.files | unzipper.js:13:40:13:56 | req.files.ZipFile | -| unzipper.js:13:40:13:56 | req.files.ZipFile | unzipper.js:13:40:13:61 | req.fil ... le.data | -| unzipper.js:13:40:13:61 | req.fil ... le.data | unzipper.js:13:26:13:62 | Readabl ... e.data) | -| yauzl.js:12:18:12:26 | req.files | yauzl.js:12:18:12:34 | req.files.zipFile | -| yauzl.js:12:18:12:26 | req.files | yauzl.js:12:18:12:34 | req.files.zipFile | -| yauzl.js:12:18:12:34 | req.files.zipFile | yauzl.js:12:18:12:39 | req.fil ... le.data | -| yauzl.js:12:18:12:34 | req.files.zipFile | yauzl.js:12:18:12:39 | req.fil ... le.data | -| yauzl.js:13:22:13:30 | req.files | yauzl.js:13:22:13:38 | req.files.zipFile | -| yauzl.js:13:22:13:30 | req.files | yauzl.js:13:22:13:38 | req.files.zipFile | -| yauzl.js:13:22:13:38 | req.files.zipFile | yauzl.js:13:22:13:43 | req.fil ... le.data | -| yauzl.js:13:22:13:38 | req.files.zipFile | yauzl.js:13:22:13:43 | req.fil ... le.data | -| yauzl.js:14:34:14:42 | req.files | yauzl.js:14:34:14:50 | req.files.zipFile | -| yauzl.js:14:34:14:42 | req.files | yauzl.js:14:34:14:50 | req.files.zipFile | -| yauzl.js:14:34:14:50 | req.files.zipFile | yauzl.js:14:34:14:55 | req.fil ... le.data | -| yauzl.js:14:34:14:50 | req.files.zipFile | yauzl.js:14:34:14:55 | req.fil ... le.data | -| yauzl.js:37:16:37:33 | req.query.filePath | yauzl.js:39:9:39:27 | zipfile.readEntry() | -| yauzl.js:37:16:37:33 | req.query.filePath | yauzl.js:39:9:39:27 | zipfile.readEntry() | -| yauzl.js:37:16:37:33 | req.query.filePath | yauzl.js:39:9:39:27 | zipfile.readEntry() | -| yauzl.js:37:16:37:33 | req.query.filePath | yauzl.js:39:9:39:27 | zipfile.readEntry() | -| yauzl.js:37:16:37:33 | req.query.filePath | yauzl.js:41:64:41:73 | readStream | -| yauzl.js:37:16:37:33 | req.query.filePath | yauzl.js:41:64:41:73 | readStream | -| yauzl.js:37:16:37:33 | req.query.filePath | yauzl.js:41:64:41:73 | readStream | -| yauzl.js:37:16:37:33 | req.query.filePath | yauzl.js:41:64:41:73 | readStream | -| yauzl.js:37:16:37:33 | req.query.filePath | yauzl.js:43:21:43:39 | zipfile.readEntry() | -| yauzl.js:37:16:37:33 | req.query.filePath | yauzl.js:43:21:43:39 | zipfile.readEntry() | -| yauzl.js:37:16:37:33 | req.query.filePath | yauzl.js:43:21:43:39 | zipfile.readEntry() | -| yauzl.js:37:16:37:33 | req.query.filePath | yauzl.js:43:21:43:39 | zipfile.readEntry() | -| zlib.js:15:19:15:27 | req.files | zlib.js:15:19:15:39 | req.fil ... ombFile | -| zlib.js:15:19:15:27 | req.files | zlib.js:15:19:15:39 | req.fil ... ombFile | -| zlib.js:15:19:15:39 | req.fil ... ombFile | zlib.js:15:19:15:44 | req.fil ... le.data | -| zlib.js:15:19:15:44 | req.fil ... le.data | zlib.js:27:24:27:30 | zipFile | -| zlib.js:17:18:17:26 | req.files | zlib.js:17:18:17:38 | req.fil ... ombFile | -| zlib.js:17:18:17:26 | req.files | zlib.js:17:18:17:38 | req.fil ... ombFile | -| zlib.js:17:18:17:38 | req.fil ... ombFile | zlib.js:17:18:17:43 | req.fil ... le.data | -| zlib.js:17:18:17:43 | req.fil ... le.data | zlib.js:62:23:62:29 | zipFile | -| zlib.js:19:24:19:32 | req.files | zlib.js:19:24:19:44 | req.fil ... ombFile | -| zlib.js:19:24:19:32 | req.files | zlib.js:19:24:19:44 | req.fil ... ombFile | -| zlib.js:19:24:19:44 | req.fil ... ombFile | zlib.js:19:24:19:49 | req.fil ... le.data | -| zlib.js:19:24:19:49 | req.fil ... le.data | zlib.js:74:29:74:35 | zipFile | -| zlib.js:21:32:21:40 | req.files | zlib.js:21:32:21:52 | req.fil ... ombFile | -| zlib.js:21:32:21:40 | req.files | zlib.js:21:32:21:52 | req.fil ... ombFile | -| zlib.js:21:32:21:52 | req.fil ... ombFile | zlib.js:21:32:21:57 | req.fil ... le.data | -| zlib.js:21:32:21:57 | req.fil ... le.data | zlib.js:82:43:82:49 | zipFile | -| zlib.js:27:24:27:30 | zipFile | zlib.js:29:9:29:15 | zipFile | -| zlib.js:27:24:27:30 | zipFile | zlib.js:33:9:33:15 | zipFile | -| zlib.js:27:24:27:30 | zipFile | zlib.js:38:9:38:15 | zipFile | -| zlib.js:29:9:29:15 | zipFile | zlib.js:29:9:29:20 | zipFile.data | -| zlib.js:29:9:29:15 | zipFile | zlib.js:29:9:29:20 | zipFile.data | -| zlib.js:33:9:33:15 | zipFile | zlib.js:33:9:33:20 | zipFile.data | -| zlib.js:33:9:33:15 | zipFile | zlib.js:33:9:33:20 | zipFile.data | -| zlib.js:38:9:38:15 | zipFile | zlib.js:38:9:38:20 | zipFile.data | -| zlib.js:38:9:38:15 | zipFile | zlib.js:38:9:38:20 | zipFile.data | -| zlib.js:62:23:62:29 | zipFile | zlib.js:63:21:63:27 | zipFile | -| zlib.js:62:23:62:29 | zipFile | zlib.js:64:20:64:26 | zipFile | -| zlib.js:62:23:62:29 | zipFile | zlib.js:65:31:65:37 | zipFile | -| zlib.js:63:21:63:27 | zipFile | zlib.js:63:21:63:32 | zipFile.data | -| zlib.js:63:21:63:27 | zipFile | zlib.js:63:21:63:32 | zipFile.data | -| zlib.js:64:20:64:26 | zipFile | zlib.js:64:20:64:31 | zipFile.data | -| zlib.js:64:20:64:26 | zipFile | zlib.js:64:20:64:31 | zipFile.data | -| zlib.js:65:31:65:37 | zipFile | zlib.js:65:31:65:42 | zipFile.data | -| zlib.js:65:31:65:37 | zipFile | zlib.js:65:31:65:42 | zipFile.data | -| zlib.js:74:29:74:35 | zipFile | zlib.js:75:39:75:45 | zipFile | -| zlib.js:75:25:75:51 | Readabl ... e.data) | zlib.js:77:22:77:40 | zlib.createGunzip() | -| zlib.js:75:25:75:51 | Readabl ... e.data) | zlib.js:77:22:77:40 | zlib.createGunzip() | -| zlib.js:75:25:75:51 | Readabl ... e.data) | zlib.js:78:22:78:39 | zlib.createUnzip() | -| zlib.js:75:25:75:51 | Readabl ... e.data) | zlib.js:78:22:78:39 | zlib.createUnzip() | -| zlib.js:75:25:75:51 | Readabl ... e.data) | zlib.js:79:22:79:50 | zlib.cr ... press() | -| zlib.js:75:25:75:51 | Readabl ... e.data) | zlib.js:79:22:79:50 | zlib.cr ... press() | -| zlib.js:75:39:75:45 | zipFile | zlib.js:75:39:75:50 | zipFile.data | -| zlib.js:75:39:75:50 | zipFile.data | zlib.js:75:25:75:51 | Readabl ... e.data) | -| zlib.js:82:43:82:49 | zipFile | zlib.js:83:39:83:45 | zipFile | -| zlib.js:83:11:83:51 | inputStream | zlib.js:86:9:86:19 | inputStream | -| zlib.js:83:25:83:51 | Readabl ... e.data) | zlib.js:83:11:83:51 | inputStream | -| zlib.js:83:39:83:45 | zipFile | zlib.js:83:39:83:50 | zipFile.data | -| zlib.js:83:39:83:50 | zipFile.data | zlib.js:83:25:83:51 | Readabl ... e.data) | -| zlib.js:86:9:86:19 | inputStream | zlib.js:87:9:87:27 | zlib.createGunzip() | -| zlib.js:86:9:86:19 | inputStream | zlib.js:87:9:87:27 | zlib.createGunzip() | +| adm-zip.js:13:13:13:21 | req.files | adm-zip.js:13:13:13:33 | req.fil ... ombFile | provenance | | +| adm-zip.js:13:13:13:33 | req.fil ... ombFile | adm-zip.js:17:18:17:24 | tarFile | provenance | | +| adm-zip.js:17:18:17:24 | tarFile | adm-zip.js:24:22:24:28 | tarFile | provenance | | +| adm-zip.js:24:22:24:28 | tarFile | adm-zip.js:24:22:24:33 | tarFile.data | provenance | | +| adm-zip.js:24:22:24:33 | tarFile.data | adm-zip.js:28:25:28:42 | zipEntry.getData() | provenance | Config | +| adm-zip.js:24:22:24:33 | tarFile.data | adm-zip.js:32:17:32:41 | admZip. ... "10GB") | provenance | Config | +| adm-zip.js:24:22:24:33 | tarFile.data | adm-zip.js:34:5:34:55 | admZip. ... , true) | provenance | Config | +| adm-zip.js:24:22:24:33 | tarFile.data | adm-zip.js:36:5:36:38 | admZip. ... , true) | provenance | Config | +| jszip.js:12:13:12:21 | req.files | jszip.js:12:13:12:38 | req.fil ... le.data | provenance | | +| jszip.js:12:13:12:38 | req.fil ... le.data | jszip.js:32:18:32:24 | zipFile | provenance | | +| jszip.js:32:18:32:24 | zipFile | jszip.js:33:22:33:28 | zipFile | provenance | | +| jszip.js:33:22:33:28 | zipFile | jszip.js:33:22:33:33 | zipFile.data | provenance | | +| node-tar.js:15:13:15:21 | req.files | node-tar.js:15:13:15:38 | req.fil ... le.data | provenance | | +| node-tar.js:15:13:15:38 | req.fil ... le.data | node-tar.js:19:18:19:24 | tarFile | provenance | | +| node-tar.js:19:18:19:24 | tarFile | node-tar.js:21:37:21:43 | tarFile | provenance | | +| node-tar.js:19:18:19:24 | tarFile | node-tar.js:29:25:29:31 | tarFile | provenance | | +| node-tar.js:19:18:19:24 | tarFile | node-tar.js:45:25:45:31 | tarFile | provenance | | +| node-tar.js:19:18:19:24 | tarFile | node-tar.js:58:19:58:25 | tarFile | provenance | | +| node-tar.js:19:18:19:24 | tarFile | node-tar.js:59:25:59:31 | tarFile | provenance | | +| node-tar.js:21:23:21:49 | Readabl ... e.data) | node-tar.js:24:9:24:15 | tar.x() | provenance | Config | +| node-tar.js:21:37:21:43 | tarFile | node-tar.js:21:37:21:48 | tarFile.data | provenance | | +| node-tar.js:21:37:21:48 | tarFile.data | node-tar.js:21:23:21:49 | Readabl ... e.data) | provenance | Config | +| node-tar.js:29:5:29:37 | fs.crea ... e.name) | node-tar.js:30:9:33:10 | tar.x({ ... }) | provenance | Config | +| node-tar.js:29:25:29:31 | tarFile | node-tar.js:29:25:29:36 | tarFile.name | provenance | | +| node-tar.js:29:25:29:36 | tarFile.name | node-tar.js:29:5:29:37 | fs.crea ... e.name) | provenance | Config | +| node-tar.js:45:5:45:37 | fs.crea ... e.name) | node-tar.js:46:9:46:20 | decompressor | provenance | Config | +| node-tar.js:45:25:45:31 | tarFile | node-tar.js:45:25:45:36 | tarFile.name | provenance | | +| node-tar.js:45:25:45:36 | tarFile.name | node-tar.js:45:5:45:37 | fs.crea ... e.name) | provenance | Config | +| node-tar.js:46:9:46:20 | decompressor | node-tar.js:48:9:50:10 | tar.x({ ... }) | provenance | Config | +| node-tar.js:58:19:58:25 | tarFile | node-tar.js:58:19:58:30 | tarFile.name | provenance | | +| node-tar.js:59:25:59:31 | tarFile | node-tar.js:59:25:59:36 | tarFile.name | provenance | | +| pako.js:12:14:12:22 | req.files | pako.js:12:14:12:39 | req.fil ... le.data | provenance | | +| pako.js:12:14:12:39 | req.fil ... le.data | pako.js:17:19:17:25 | zipFile | provenance | | +| pako.js:13:14:13:22 | req.files | pako.js:13:14:13:39 | req.fil ... le.data | provenance | | +| pako.js:13:14:13:39 | req.fil ... le.data | pako.js:28:19:28:25 | zipFile | provenance | | +| pako.js:17:19:17:25 | zipFile | pako.js:18:48:18:54 | zipFile | provenance | | +| pako.js:18:11:18:68 | myArray | pako.js:21:31:21:37 | myArray | provenance | | +| pako.js:18:21:18:68 | Buffer. ... uffer)) | pako.js:18:11:18:68 | myArray | provenance | | +| pako.js:18:33:18:67 | new Uin ... buffer) | pako.js:18:21:18:68 | Buffer. ... uffer)) | provenance | | +| pako.js:18:48:18:54 | zipFile | pako.js:18:48:18:66 | zipFile.data.buffer | provenance | | +| pako.js:18:48:18:66 | zipFile.data.buffer | pako.js:18:33:18:67 | new Uin ... buffer) | provenance | Config | +| pako.js:28:19:28:25 | zipFile | pako.js:29:36:29:42 | zipFile | provenance | | +| pako.js:29:11:29:62 | myArray | pako.js:32:31:32:37 | myArray | provenance | | +| pako.js:29:21:29:55 | new Uin ... buffer) | pako.js:29:11:29:62 | myArray | provenance | | +| pako.js:29:36:29:42 | zipFile | pako.js:29:36:29:54 | zipFile.data.buffer | provenance | | +| pako.js:29:36:29:54 | zipFile.data.buffer | pako.js:29:21:29:55 | new Uin ... buffer) | provenance | Config | +| unbzip2.js:12:5:12:43 | fs.crea ... lePath) | unbzip2.js:12:50:12:54 | bz2() | provenance | Config | +| unbzip2.js:12:25:12:42 | req.query.FilePath | unbzip2.js:12:5:12:43 | fs.crea ... lePath) | provenance | Config | +| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:16:23:16:63 | unzippe ... ath' }) | provenance | Config | +| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:19:23:19:41 | unzipper.ParseOne() | provenance | Config | +| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:24:15:24:30 | unzipper.Parse() | provenance | Config | +| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:34:15:34:30 | unzipper.Parse() | provenance | Config | +| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:41:35:41:71 | unzippe ... true }) | provenance | Config | +| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:51:36:51:72 | unzippe ... true }) | provenance | Config | +| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:60:23:60:38 | unzipper.Parse() | provenance | Config | +| unzipper.js:13:26:13:62 | Readabl ... e.data) | unzipper.js:73:23:73:38 | unzipper.Parse() | provenance | Config | +| unzipper.js:13:40:13:48 | req.files | unzipper.js:13:40:13:61 | req.fil ... le.data | provenance | | +| unzipper.js:13:40:13:61 | req.fil ... le.data | unzipper.js:13:26:13:62 | Readabl ... e.data) | provenance | Config | +| yauzl.js:12:18:12:26 | req.files | yauzl.js:12:18:12:39 | req.fil ... le.data | provenance | | +| yauzl.js:13:22:13:30 | req.files | yauzl.js:13:22:13:43 | req.fil ... le.data | provenance | | +| yauzl.js:14:34:14:42 | req.files | yauzl.js:14:34:14:55 | req.fil ... le.data | provenance | | +| yauzl.js:37:16:37:33 | req.query.filePath | yauzl.js:39:9:39:27 | zipfile.readEntry() | provenance | Config | +| yauzl.js:37:16:37:33 | req.query.filePath | yauzl.js:41:64:41:73 | readStream | provenance | Config | +| yauzl.js:37:16:37:33 | req.query.filePath | yauzl.js:43:21:43:39 | zipfile.readEntry() | provenance | Config | +| zlib.js:15:19:15:27 | req.files | zlib.js:15:19:15:44 | req.fil ... le.data | provenance | | +| zlib.js:15:19:15:44 | req.fil ... le.data | zlib.js:27:24:27:30 | zipFile | provenance | | +| zlib.js:17:18:17:26 | req.files | zlib.js:17:18:17:43 | req.fil ... le.data | provenance | | +| zlib.js:17:18:17:43 | req.fil ... le.data | zlib.js:62:23:62:29 | zipFile | provenance | | +| zlib.js:19:24:19:32 | req.files | zlib.js:19:24:19:49 | req.fil ... le.data | provenance | | +| zlib.js:19:24:19:49 | req.fil ... le.data | zlib.js:74:29:74:35 | zipFile | provenance | | +| zlib.js:21:32:21:40 | req.files | zlib.js:21:32:21:57 | req.fil ... le.data | provenance | | +| zlib.js:21:32:21:57 | req.fil ... le.data | zlib.js:82:43:82:49 | zipFile | provenance | | +| zlib.js:27:24:27:30 | zipFile | zlib.js:29:9:29:15 | zipFile | provenance | | +| zlib.js:27:24:27:30 | zipFile | zlib.js:33:9:33:15 | zipFile | provenance | | +| zlib.js:27:24:27:30 | zipFile | zlib.js:38:9:38:15 | zipFile | provenance | | +| zlib.js:29:9:29:15 | zipFile | zlib.js:29:9:29:20 | zipFile.data | provenance | | +| zlib.js:33:9:33:15 | zipFile | zlib.js:33:9:33:20 | zipFile.data | provenance | | +| zlib.js:38:9:38:15 | zipFile | zlib.js:38:9:38:20 | zipFile.data | provenance | | +| zlib.js:62:23:62:29 | zipFile | zlib.js:63:21:63:27 | zipFile | provenance | | +| zlib.js:62:23:62:29 | zipFile | zlib.js:64:20:64:26 | zipFile | provenance | | +| zlib.js:62:23:62:29 | zipFile | zlib.js:65:31:65:37 | zipFile | provenance | | +| zlib.js:63:21:63:27 | zipFile | zlib.js:63:21:63:32 | zipFile.data | provenance | | +| zlib.js:64:20:64:26 | zipFile | zlib.js:64:20:64:31 | zipFile.data | provenance | | +| zlib.js:65:31:65:37 | zipFile | zlib.js:65:31:65:42 | zipFile.data | provenance | | +| zlib.js:74:29:74:35 | zipFile | zlib.js:75:39:75:45 | zipFile | provenance | | +| zlib.js:75:25:75:51 | Readabl ... e.data) | zlib.js:77:22:77:40 | zlib.createGunzip() | provenance | Config | +| zlib.js:75:25:75:51 | Readabl ... e.data) | zlib.js:78:22:78:39 | zlib.createUnzip() | provenance | Config | +| zlib.js:75:25:75:51 | Readabl ... e.data) | zlib.js:79:22:79:50 | zlib.cr ... press() | provenance | Config | +| zlib.js:75:39:75:45 | zipFile | zlib.js:75:39:75:50 | zipFile.data | provenance | | +| zlib.js:75:39:75:50 | zipFile.data | zlib.js:75:25:75:51 | Readabl ... e.data) | provenance | Config | +| zlib.js:82:43:82:49 | zipFile | zlib.js:83:39:83:45 | zipFile | provenance | | +| zlib.js:83:11:83:51 | inputStream | zlib.js:86:9:86:19 | inputStream | provenance | | +| zlib.js:83:25:83:51 | Readabl ... e.data) | zlib.js:83:11:83:51 | inputStream | provenance | | +| zlib.js:83:39:83:45 | zipFile | zlib.js:83:39:83:50 | zipFile.data | provenance | | +| zlib.js:83:39:83:50 | zipFile.data | zlib.js:83:25:83:51 | Readabl ... e.data) | provenance | Config | +| zlib.js:86:9:86:19 | inputStream | zlib.js:87:9:87:27 | zlib.createGunzip() | provenance | Config | +nodes +| adm-zip.js:13:13:13:21 | req.files | semmle.label | req.files | +| adm-zip.js:13:13:13:33 | req.fil ... ombFile | semmle.label | req.fil ... ombFile | +| adm-zip.js:17:18:17:24 | tarFile | semmle.label | tarFile | +| adm-zip.js:24:22:24:28 | tarFile | semmle.label | tarFile | +| adm-zip.js:24:22:24:33 | tarFile.data | semmle.label | tarFile.data | +| adm-zip.js:28:25:28:42 | zipEntry.getData() | semmle.label | zipEntry.getData() | +| adm-zip.js:32:17:32:41 | admZip. ... "10GB") | semmle.label | admZip. ... "10GB") | +| adm-zip.js:34:5:34:55 | admZip. ... , true) | semmle.label | admZip. ... , true) | +| adm-zip.js:36:5:36:38 | admZip. ... , true) | semmle.label | admZip. ... , true) | +| decompress.js:11:16:11:33 | req.query.filePath | semmle.label | req.query.filePath | +| jszip.js:12:13:12:21 | req.files | semmle.label | req.files | +| jszip.js:12:13:12:38 | req.fil ... le.data | semmle.label | req.fil ... le.data | +| jszip.js:32:18:32:24 | zipFile | semmle.label | zipFile | +| jszip.js:33:22:33:28 | zipFile | semmle.label | zipFile | +| jszip.js:33:22:33:33 | zipFile.data | semmle.label | zipFile.data | +| node-tar.js:15:13:15:21 | req.files | semmle.label | req.files | +| node-tar.js:15:13:15:38 | req.fil ... le.data | semmle.label | req.fil ... le.data | +| node-tar.js:19:18:19:24 | tarFile | semmle.label | tarFile | +| node-tar.js:21:23:21:49 | Readabl ... e.data) | semmle.label | Readabl ... e.data) | +| node-tar.js:21:37:21:43 | tarFile | semmle.label | tarFile | +| node-tar.js:21:37:21:48 | tarFile.data | semmle.label | tarFile.data | +| node-tar.js:24:9:24:15 | tar.x() | semmle.label | tar.x() | +| node-tar.js:29:5:29:37 | fs.crea ... e.name) | semmle.label | fs.crea ... e.name) | +| node-tar.js:29:25:29:31 | tarFile | semmle.label | tarFile | +| node-tar.js:29:25:29:36 | tarFile.name | semmle.label | tarFile.name | +| node-tar.js:30:9:33:10 | tar.x({ ... }) | semmle.label | tar.x({ ... }) | +| node-tar.js:45:5:45:37 | fs.crea ... e.name) | semmle.label | fs.crea ... e.name) | +| node-tar.js:45:25:45:31 | tarFile | semmle.label | tarFile | +| node-tar.js:45:25:45:36 | tarFile.name | semmle.label | tarFile.name | +| node-tar.js:46:9:46:20 | decompressor | semmle.label | decompressor | +| node-tar.js:48:9:50:10 | tar.x({ ... }) | semmle.label | tar.x({ ... }) | +| node-tar.js:58:19:58:25 | tarFile | semmle.label | tarFile | +| node-tar.js:58:19:58:30 | tarFile.name | semmle.label | tarFile.name | +| node-tar.js:59:25:59:31 | tarFile | semmle.label | tarFile | +| node-tar.js:59:25:59:36 | tarFile.name | semmle.label | tarFile.name | +| pako.js:12:14:12:22 | req.files | semmle.label | req.files | +| pako.js:12:14:12:39 | req.fil ... le.data | semmle.label | req.fil ... le.data | +| pako.js:13:14:13:22 | req.files | semmle.label | req.files | +| pako.js:13:14:13:39 | req.fil ... le.data | semmle.label | req.fil ... le.data | +| pako.js:17:19:17:25 | zipFile | semmle.label | zipFile | +| pako.js:18:11:18:68 | myArray | semmle.label | myArray | +| pako.js:18:21:18:68 | Buffer. ... uffer)) | semmle.label | Buffer. ... uffer)) | +| pako.js:18:33:18:67 | new Uin ... buffer) | semmle.label | new Uin ... buffer) | +| pako.js:18:48:18:54 | zipFile | semmle.label | zipFile | +| pako.js:18:48:18:66 | zipFile.data.buffer | semmle.label | zipFile.data.buffer | +| pako.js:21:31:21:37 | myArray | semmle.label | myArray | +| pako.js:28:19:28:25 | zipFile | semmle.label | zipFile | +| pako.js:29:11:29:62 | myArray | semmle.label | myArray | +| pako.js:29:21:29:55 | new Uin ... buffer) | semmle.label | new Uin ... buffer) | +| pako.js:29:36:29:42 | zipFile | semmle.label | zipFile | +| pako.js:29:36:29:54 | zipFile.data.buffer | semmle.label | zipFile.data.buffer | +| pako.js:32:31:32:37 | myArray | semmle.label | myArray | +| unbzip2.js:12:5:12:43 | fs.crea ... lePath) | semmle.label | fs.crea ... lePath) | +| unbzip2.js:12:25:12:42 | req.query.FilePath | semmle.label | req.query.FilePath | +| unbzip2.js:12:50:12:54 | bz2() | semmle.label | bz2() | +| unzipper.js:13:26:13:62 | Readabl ... e.data) | semmle.label | Readabl ... e.data) | +| unzipper.js:13:40:13:48 | req.files | semmle.label | req.files | +| unzipper.js:13:40:13:61 | req.fil ... le.data | semmle.label | req.fil ... le.data | +| unzipper.js:16:23:16:63 | unzippe ... ath' }) | semmle.label | unzippe ... ath' }) | +| unzipper.js:19:23:19:41 | unzipper.ParseOne() | semmle.label | unzipper.ParseOne() | +| unzipper.js:24:15:24:30 | unzipper.Parse() | semmle.label | unzipper.Parse() | +| unzipper.js:34:15:34:30 | unzipper.Parse() | semmle.label | unzipper.Parse() | +| unzipper.js:41:35:41:71 | unzippe ... true }) | semmle.label | unzippe ... true }) | +| unzipper.js:51:36:51:72 | unzippe ... true }) | semmle.label | unzippe ... true }) | +| unzipper.js:60:23:60:38 | unzipper.Parse() | semmle.label | unzipper.Parse() | +| unzipper.js:73:23:73:38 | unzipper.Parse() | semmle.label | unzipper.Parse() | +| yauzl.js:12:18:12:26 | req.files | semmle.label | req.files | +| yauzl.js:12:18:12:39 | req.fil ... le.data | semmle.label | req.fil ... le.data | +| yauzl.js:13:22:13:30 | req.files | semmle.label | req.files | +| yauzl.js:13:22:13:43 | req.fil ... le.data | semmle.label | req.fil ... le.data | +| yauzl.js:14:34:14:42 | req.files | semmle.label | req.files | +| yauzl.js:14:34:14:55 | req.fil ... le.data | semmle.label | req.fil ... le.data | +| yauzl.js:37:16:37:33 | req.query.filePath | semmle.label | req.query.filePath | +| yauzl.js:39:9:39:27 | zipfile.readEntry() | semmle.label | zipfile.readEntry() | +| yauzl.js:41:64:41:73 | readStream | semmle.label | readStream | +| yauzl.js:43:21:43:39 | zipfile.readEntry() | semmle.label | zipfile.readEntry() | +| zlib.js:15:19:15:27 | req.files | semmle.label | req.files | +| zlib.js:15:19:15:44 | req.fil ... le.data | semmle.label | req.fil ... le.data | +| zlib.js:17:18:17:26 | req.files | semmle.label | req.files | +| zlib.js:17:18:17:43 | req.fil ... le.data | semmle.label | req.fil ... le.data | +| zlib.js:19:24:19:32 | req.files | semmle.label | req.files | +| zlib.js:19:24:19:49 | req.fil ... le.data | semmle.label | req.fil ... le.data | +| zlib.js:21:32:21:40 | req.files | semmle.label | req.files | +| zlib.js:21:32:21:57 | req.fil ... le.data | semmle.label | req.fil ... le.data | +| zlib.js:27:24:27:30 | zipFile | semmle.label | zipFile | +| zlib.js:29:9:29:15 | zipFile | semmle.label | zipFile | +| zlib.js:29:9:29:20 | zipFile.data | semmle.label | zipFile.data | +| zlib.js:33:9:33:15 | zipFile | semmle.label | zipFile | +| zlib.js:33:9:33:20 | zipFile.data | semmle.label | zipFile.data | +| zlib.js:38:9:38:15 | zipFile | semmle.label | zipFile | +| zlib.js:38:9:38:20 | zipFile.data | semmle.label | zipFile.data | +| zlib.js:62:23:62:29 | zipFile | semmle.label | zipFile | +| zlib.js:63:21:63:27 | zipFile | semmle.label | zipFile | +| zlib.js:63:21:63:32 | zipFile.data | semmle.label | zipFile.data | +| zlib.js:64:20:64:26 | zipFile | semmle.label | zipFile | +| zlib.js:64:20:64:31 | zipFile.data | semmle.label | zipFile.data | +| zlib.js:65:31:65:37 | zipFile | semmle.label | zipFile | +| zlib.js:65:31:65:42 | zipFile.data | semmle.label | zipFile.data | +| zlib.js:74:29:74:35 | zipFile | semmle.label | zipFile | +| zlib.js:75:25:75:51 | Readabl ... e.data) | semmle.label | Readabl ... e.data) | +| zlib.js:75:39:75:45 | zipFile | semmle.label | zipFile | +| zlib.js:75:39:75:50 | zipFile.data | semmle.label | zipFile.data | +| zlib.js:77:22:77:40 | zlib.createGunzip() | semmle.label | zlib.createGunzip() | +| zlib.js:78:22:78:39 | zlib.createUnzip() | semmle.label | zlib.createUnzip() | +| zlib.js:79:22:79:50 | zlib.cr ... press() | semmle.label | zlib.cr ... press() | +| zlib.js:82:43:82:49 | zipFile | semmle.label | zipFile | +| zlib.js:83:11:83:51 | inputStream | semmle.label | inputStream | +| zlib.js:83:25:83:51 | Readabl ... e.data) | semmle.label | Readabl ... e.data) | +| zlib.js:83:39:83:45 | zipFile | semmle.label | zipFile | +| zlib.js:83:39:83:50 | zipFile.data | semmle.label | zipFile.data | +| zlib.js:86:9:86:19 | inputStream | semmle.label | inputStream | +| zlib.js:87:9:87:27 | zlib.createGunzip() | semmle.label | zlib.createGunzip() | +subpaths #select | adm-zip.js:28:25:28:42 | zipEntry.getData() | adm-zip.js:13:13:13:21 | req.files | adm-zip.js:28:25:28:42 | zipEntry.getData() | This Decompression depends on a $@. | adm-zip.js:13:13:13:21 | req.files | potentially untrusted source | | adm-zip.js:32:17:32:41 | admZip. ... "10GB") | adm-zip.js:13:13:13:21 | req.files | adm-zip.js:32:17:32:41 | admZip. ... "10GB") | This Decompression depends on a $@. | adm-zip.js:13:13:13:21 | req.files | potentially untrusted source | From 04a3a6707f944bb4704a1847c1f1a1062d10bd7e Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 11:53:02 +0100 Subject: [PATCH 407/514] JS: Update a reference to AdditionalSanitizerGuardNode Unlike most other references to this class, we're not subclassing it here, we're just trying to reuse some standard barrier guards but with a different flow state. --- .../ql/src/Security/CWE-915/PrototypePollutingFunction.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/Security/CWE-915/PrototypePollutingFunction.ql b/javascript/ql/src/Security/CWE-915/PrototypePollutingFunction.ql index 161763d341e..5df916c9d2b 100644 --- a/javascript/ql/src/Security/CWE-915/PrototypePollutingFunction.ql +++ b/javascript/ql/src/Security/CWE-915/PrototypePollutingFunction.ql @@ -465,7 +465,7 @@ class AllowListInclusionGuard extends BarrierGuard { } override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel lbl) { - this.(TaintTracking::AdditionalSanitizerGuardNode).sanitizes(outcome, e) and + this.(TaintTracking::AdditionalBarrierGuard).blocksExpr(outcome, e) and lbl instanceof UnsafePropLabel } } From 0ce1fe767d94a7ce09199fc952abe1f8d9f7c170 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 13:43:07 +0100 Subject: [PATCH 408/514] JS: Deprecate ConsistencyChecking to avoid deprecation warnings --- .../ql/test/library-tests/FlowSummary/test.ql | 4 +-- .../test/library-tests/Generators/DataFlow.ql | 2 +- .../ql/test/library-tests/Routing/test.ql | 2 +- .../Security/heuristics/HeuristicSource.ql | 2 +- .../TaintTracking/BasicTaintTracking.ql | 2 +- .../frameworks/Nest/Consistency.ql | 2 +- .../library-tests/frameworks/Vuex/test.ql | 2 +- .../library-tests/frameworks/data/test.ql | 2 +- .../CWE-022/TaintedPath/Consistency.ql | 2 +- .../Security/CWE-073/Consistency.ql | 2 +- .../Security/CWE-078/Consistency.ql | 2 +- .../DomBasedXss/ConsistencyDomBasedXss.ql | 2 +- .../ExceptionXss/ConsistencyExceptionXss.ql | 2 +- .../ReflectedXss/ConsistencyReflectedXss.ql | 2 +- .../CWE-079/StoredXss/ConsistencyStoredXss.ql | 2 +- .../ConsistencyUnsafeHtmlConstruction.ql | 2 +- .../ConsistencyUnsafeJQueryPlugin.ql | 2 +- .../XssThroughDom/ConsistencyXssThroughDom.ql | 2 +- .../Security/CWE-089/untyped/Consistency.ql | 2 +- .../Security/CWE-502/Consistency.ql | 2 +- .../CWE-770/ResourceExhaustion/Consistency.ql | 2 +- .../Consistency.ql | 2 +- .../Security/CWE-918/Consistency.ql | 2 +- .../testUtilities/ConsistencyChecking.qll | 30 ++++++++++++------- 24 files changed, 44 insertions(+), 34 deletions(-) diff --git a/javascript/ql/test/library-tests/FlowSummary/test.ql b/javascript/ql/test/library-tests/FlowSummary/test.ql index 7d0d0db7ee2..346943323b1 100644 --- a/javascript/ql/test/library-tests/FlowSummary/test.ql +++ b/javascript/ql/test/library-tests/FlowSummary/test.ql @@ -1,5 +1,5 @@ import javascript -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking import testUtilities.InlineSummaries DataFlow::CallNode getACall(string name) { @@ -29,7 +29,7 @@ class BasicBarrierGuard extends DataFlow::CallNode { } } -class ConsistencyConfig extends ConsistencyConfiguration { +deprecated class ConsistencyConfig extends ConsistencyConfiguration { ConsistencyConfig() { this = "ConsistencyConfig" } override DataFlow::Node getAnAlert() { Configuration::flow(_, result) } diff --git a/javascript/ql/test/library-tests/Generators/DataFlow.ql b/javascript/ql/test/library-tests/Generators/DataFlow.ql index 71fce93ae32..24c7b56f587 100644 --- a/javascript/ql/test/library-tests/Generators/DataFlow.ql +++ b/javascript/ql/test/library-tests/Generators/DataFlow.ql @@ -1,5 +1,5 @@ import javascript -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking module TestConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.asExpr().getStringValue() = "source" } diff --git a/javascript/ql/test/library-tests/Routing/test.ql b/javascript/ql/test/library-tests/Routing/test.ql index 07b7295dc65..ac0e09c1dfd 100644 --- a/javascript/ql/test/library-tests/Routing/test.ql +++ b/javascript/ql/test/library-tests/Routing/test.ql @@ -1,5 +1,5 @@ import javascript -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking API::Node testInstance() { result = API::moduleImport("@example/test").getInstance() } diff --git a/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.ql b/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.ql index 4568bed8a6d..dce4f7a6de1 100644 --- a/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.ql +++ b/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.ql @@ -1,6 +1,6 @@ import javascript private import semmle.javascript.heuristics.AdditionalSources -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking module TestConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { node instanceof HeuristicSource } diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql index a8aee22efb1..d48f8ad8a59 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql @@ -1,6 +1,6 @@ import javascript import semmle.javascript.dataflow.InferredTypes -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking DataFlow::CallNode getACall(string name) { result.getCalleeName() = name diff --git a/javascript/ql/test/library-tests/frameworks/Nest/Consistency.ql b/javascript/ql/test/library-tests/frameworks/Nest/Consistency.ql index e96cbc4b70f..221b425b101 100644 --- a/javascript/ql/test/library-tests/frameworks/Nest/Consistency.ql +++ b/javascript/ql/test/library-tests/frameworks/Nest/Consistency.ql @@ -1,3 +1,3 @@ -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking import semmle.javascript.security.dataflow.ReflectedXssQuery as ReflectedXss import semmle.javascript.security.dataflow.ServerSideUrlRedirectQuery as ServerSideUrlRedirect diff --git a/javascript/ql/test/library-tests/frameworks/Vuex/test.ql b/javascript/ql/test/library-tests/frameworks/Vuex/test.ql index 00a3f258135..3d46b90be05 100644 --- a/javascript/ql/test/library-tests/frameworks/Vuex/test.ql +++ b/javascript/ql/test/library-tests/frameworks/Vuex/test.ql @@ -1,5 +1,5 @@ import javascript -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking module TestConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { node.(DataFlow::CallNode).getCalleeName() = "source" } diff --git a/javascript/ql/test/library-tests/frameworks/data/test.ql b/javascript/ql/test/library-tests/frameworks/data/test.ql index 11c7d78e9cc..ce1574f5e9b 100644 --- a/javascript/ql/test/library-tests/frameworks/data/test.ql +++ b/javascript/ql/test/library-tests/frameworks/data/test.ql @@ -1,5 +1,5 @@ import javascript -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking import semmle.javascript.frameworks.data.internal.ApiGraphModels as ApiGraphModels class TypeModelFromCodeQL extends ModelInput::TypeModel { diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.ql index fae97fdf6d0..adbeec47ad9 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.ql @@ -1,6 +1,6 @@ import javascript import semmle.javascript.security.dataflow.TaintedPathQuery -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking class TaintedPathConsistency extends ConsistencyConfiguration { TaintedPathConsistency() { this = "TaintedPathConsistency" } diff --git a/javascript/ql/test/query-tests/Security/CWE-073/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-073/Consistency.ql index 17260e5daa0..6453aabefad 100644 --- a/javascript/ql/test/query-tests/Security/CWE-073/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-073/Consistency.ql @@ -1,3 +1,3 @@ import javascript import semmle.javascript.security.dataflow.TemplateObjectInjectionQuery -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking diff --git a/javascript/ql/test/query-tests/Security/CWE-078/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-078/Consistency.ql index c48af1a7971..543581e4d5f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-078/Consistency.ql @@ -1,5 +1,5 @@ import javascript -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking import semmle.javascript.security.dataflow.CommandInjectionQuery as CommandInjection import semmle.javascript.security.dataflow.IndirectCommandInjectionQuery as IndirectCommandInjection import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironmentQuery as ShellCommandInjectionFromEnvironment diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.ql b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.ql index cb88a7a2a26..dcda8c7c0f3 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.ql @@ -1,5 +1,5 @@ import javascript -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking import semmle.javascript.security.dataflow.DomBasedXssQuery class ConsistencyConfig extends ConsistencyConfiguration { diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ConsistencyExceptionXss.ql b/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ConsistencyExceptionXss.ql index 5b40a626e4a..0cc7b613fb9 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ConsistencyExceptionXss.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ConsistencyExceptionXss.ql @@ -1,3 +1,3 @@ import javascript -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking import semmle.javascript.security.dataflow.ExceptionXssQuery as ExceptionXss diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ConsistencyReflectedXss.ql b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ConsistencyReflectedXss.ql index 3200271daa6..179ece10405 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ConsistencyReflectedXss.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ConsistencyReflectedXss.ql @@ -1,3 +1,3 @@ import javascript -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking import semmle.javascript.security.dataflow.ReflectedXssQuery as ReflectedXss diff --git a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/ConsistencyStoredXss.ql b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/ConsistencyStoredXss.ql index c75dbb17b71..93ee2dc1725 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/ConsistencyStoredXss.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/ConsistencyStoredXss.ql @@ -1,3 +1,3 @@ import javascript -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking import semmle.javascript.security.dataflow.StoredXssQuery as StoredXss diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/ConsistencyUnsafeHtmlConstruction.ql b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/ConsistencyUnsafeHtmlConstruction.ql index f09744a4d6c..65330ff64f5 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/ConsistencyUnsafeHtmlConstruction.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/ConsistencyUnsafeHtmlConstruction.ql @@ -1,3 +1,3 @@ import javascript -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking import semmle.javascript.security.dataflow.UnsafeHtmlConstructionQuery as UnsafeHtmlConstruction diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/ConsistencyUnsafeJQueryPlugin.ql b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/ConsistencyUnsafeJQueryPlugin.ql index b77df2a8d67..385890e8765 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/ConsistencyUnsafeJQueryPlugin.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/ConsistencyUnsafeJQueryPlugin.ql @@ -1,3 +1,3 @@ import javascript -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking import semmle.javascript.security.dataflow.UnsafeJQueryPluginQuery as UnsafeJqueryPlugin diff --git a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql index 08eb6eda7fb..f152b3c656c 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql @@ -1,5 +1,5 @@ import javascript -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking import semmle.javascript.security.dataflow.XssThroughDomQuery class ConsistencyConfig extends ConsistencyConfiguration { diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-089/untyped/Consistency.ql index bd24059f31c..4e5ebce7190 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/Consistency.ql @@ -1,4 +1,4 @@ import javascript -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking import semmle.javascript.security.dataflow.SqlInjectionQuery as SqlInjection import semmle.javascript.security.dataflow.NosqlInjectionQuery as NosqlInjection diff --git a/javascript/ql/test/query-tests/Security/CWE-502/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-502/Consistency.ql index 410d56326ef..a5b670eddd6 100644 --- a/javascript/ql/test/query-tests/Security/CWE-502/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-502/Consistency.ql @@ -1,3 +1,3 @@ import javascript import semmle.javascript.security.dataflow.UnsafeDeserializationQuery -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking diff --git a/javascript/ql/test/query-tests/Security/CWE-770/ResourceExhaustion/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-770/ResourceExhaustion/Consistency.ql index 5742c3e1fea..9a05f88251e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-770/ResourceExhaustion/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-770/ResourceExhaustion/Consistency.ql @@ -1,3 +1,3 @@ import javascript import semmle.javascript.security.dataflow.ResourceExhaustionQuery -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.ql index 636d6e3bbda..b9420810416 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.ql @@ -1,5 +1,5 @@ import javascript -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking import semmle.javascript.security.dataflow.PrototypePollutingAssignmentQuery class Config extends ConsistencyConfiguration { diff --git a/javascript/ql/test/query-tests/Security/CWE-918/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-918/Consistency.ql index 1e81213b108..808e45dd8cb 100644 --- a/javascript/ql/test/query-tests/Security/CWE-918/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-918/Consistency.ql @@ -1,7 +1,7 @@ import javascript import semmle.javascript.security.dataflow.RequestForgeryQuery as RequestForgery import semmle.javascript.security.dataflow.ClientSideRequestForgeryQuery as ClientSideRequestForgery -import testUtilities.ConsistencyChecking +deprecated import testUtilities.ConsistencyChecking query predicate resultInWrongFile(DataFlow::Node node) { exists(string filePattern | diff --git a/javascript/ql/test/testUtilities/ConsistencyChecking.qll b/javascript/ql/test/testUtilities/ConsistencyChecking.qll index 94979bcaab0..407caf908b0 100644 --- a/javascript/ql/test/testUtilities/ConsistencyChecking.qll +++ b/javascript/ql/test/testUtilities/ConsistencyChecking.qll @@ -1,3 +1,9 @@ +/** + * DEPRECATED, but can be imported with a `deprecated import`. + * + * Will be replaced with standardized inline test expectations in the future. + */ + import javascript /** @@ -7,7 +13,7 @@ import javascript * * If no configuration is specified, then the default is that the all sinks from a `DataFlow::Configuration` are alerts, and all files are consistency-checked. */ -abstract class ConsistencyConfiguration extends string { +abstract deprecated class ConsistencyConfiguration extends string { bindingset[this] ConsistencyConfiguration() { any() } @@ -30,7 +36,7 @@ abstract class ConsistencyConfiguration extends string { * * Is used internally to match a configuration or lack thereof. */ -final private class Conf extends string { +deprecated final private class Conf extends string { Conf() { this instanceof ConsistencyConfiguration or @@ -65,12 +71,14 @@ private class AssertionComment extends LineComment { predicate expectConsistencyError() { this.getText().matches("%[INCONSISTENCY]%") } } -private DataFlow::Node getASink() { exists(DataFlow::Configuration cfg | cfg.hasFlow(_, result)) } +deprecated private DataFlow::Node getASink() { + exists(DataFlow::Configuration cfg | cfg.hasFlow(_, result)) +} /** * Gets all the alerts for consistency consistency checking from a configuration `conf`. */ -private DataFlow::Node alerts(Conf conf) { +deprecated private DataFlow::Node alerts(Conf conf) { result = conf.(ConsistencyConfiguration).getAnAlert() or not exists(ConsistencyConfiguration r) and @@ -83,7 +91,7 @@ private DataFlow::Node alerts(Conf conf) { * The `line` can be either the first or the last line of the alert. * And if no expression exists at `line`, then an alert on the next line is used. */ -private DataFlow::Node getAlert(File file, int line, Conf conf) { +deprecated private DataFlow::Node getAlert(File file, int line, Conf conf) { result = alerts(conf) and result.getFile() = file and (result.hasLocationInfo(_, _, _, line, _) or result.hasLocationInfo(_, line, _, _, _)) @@ -108,7 +116,7 @@ private AssertionComment getComment(File file, int line) { /** * Holds if there is a false positive in `file` at `line` for configuration `conf`. */ -private predicate falsePositive(File file, int line, AssertionComment comment, Conf conf) { +deprecated private predicate falsePositive(File file, int line, AssertionComment comment, Conf conf) { exists(getAlert(file, line, conf)) and comment = getComment(file, line) and not comment.shouldHaveAlert() @@ -117,7 +125,7 @@ private predicate falsePositive(File file, int line, AssertionComment comment, C /** * Holds if there is a false negative in `file` at `line` for configuration `conf`. */ -private predicate falseNegative(File file, int line, AssertionComment comment, Conf conf) { +deprecated private predicate falseNegative(File file, int line, AssertionComment comment, Conf conf) { not exists(getAlert(file, line, conf)) and comment = getComment(file, line) and comment.shouldHaveAlert() @@ -126,7 +134,7 @@ private predicate falseNegative(File file, int line, AssertionComment comment, C /** * Gets a file that should be included for consistency checking for configuration `conf`. */ -private File getATestFile(string conf) { +deprecated private File getATestFile(string conf) { not exists(any(ConsistencyConfiguration res).getAFile()) and result = any(LineComment comment).getFile() and (conf = "" or conf instanceof ConsistencyConfiguration) @@ -139,7 +147,7 @@ private File getATestFile(string conf) { * Or the empty string */ bindingset[file, line] -private string getSinkDescription(File file, int line, Conf conf) { +deprecated private string getSinkDescription(File file, int line, Conf conf) { not exists(DataFlow::Configuration c | c.hasFlow(_, getAlert(file, line, conf))) and result = "" or @@ -153,7 +161,9 @@ private string getSinkDescription(File file, int line, Conf conf) { * The consistency issue an unexpected false positive/negative. * Or that false positive/negative was expected, and none were found. */ -query predicate consistencyIssue(string location, string msg, string commentText, Conf conf) { +deprecated query predicate consistencyIssue( + string location, string msg, string commentText, Conf conf +) { exists(File file, int line | file = getATestFile(conf) and location = file.getRelativePath() + ":" + line | From e6680dec8ff66e53079e89ae9189c05cb7e29ce5 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 13:55:06 +0100 Subject: [PATCH 409/514] JS: Avoid use of LabeledSanitizerGuardNode in TaintedObject Drive-by bugfix: Rename sanitizes -> blocksExpr. This fixes a bug that caused the sanitizer guard not to work in df2. The test output reflects the fact that the barrier guard works now. --- .../javascript/security/TaintedObject.qll | 21 +++++++++++++++---- .../CWE-089/untyped/SqlInjection.expected | 5 ----- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/TaintedObject.qll b/javascript/ql/lib/semmle/javascript/security/TaintedObject.qll index 22f253e1423..4b230d0de66 100644 --- a/javascript/ql/lib/semmle/javascript/security/TaintedObject.qll +++ b/javascript/ql/lib/semmle/javascript/security/TaintedObject.qll @@ -81,18 +81,31 @@ module TaintedObject { /** * A sanitizer guard that blocks deep object taint. */ - abstract class SanitizerGuard extends TaintTracking::LabeledSanitizerGuardNode { + abstract class SanitizerGuard extends DataFlow::Node { /** Holds if this node blocks flow through `e`, provided it evaluates to `outcome`. */ predicate blocksExpr(boolean outcome, Expr e) { none() } /** Holds if this node blocks flow of `label` through `e`, provided it evaluates to `outcome`. */ predicate blocksExpr(boolean outcome, Expr e, FlowLabel label) { none() } - override predicate sanitizes(boolean outcome, Expr e, FlowLabel label) { + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e, FlowLabel label) { this.blocksExpr(outcome, e, label) } - override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + } + + deprecated private class SanitizerGuardLegacy extends TaintTracking::LabeledSanitizerGuardNode instanceof SanitizerGuard + { + deprecated override predicate sanitizes(boolean outcome, Expr e, FlowLabel label) { + SanitizerGuard.super.sanitizes(outcome, e, label) + } + + deprecated override predicate sanitizes(boolean outcome, Expr e) { + SanitizerGuard.super.sanitizes(outcome, e) + } } /** @@ -148,7 +161,7 @@ module TaintedObject { .getACall() } - override predicate sanitizes(boolean outcome, Expr e, FlowLabel lbl) { + override predicate blocksExpr(boolean outcome, Expr e, FlowLabel lbl) { e = super.getAnArgument().asExpr() and outcome = true and lbl = label() } } diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected index 8a50f15963b..3664d7db828 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected @@ -198,7 +198,6 @@ nodes | mongoose.js:130:16:130:26 | { _id: id } | semmle.label | { _id: id } | | mongoose.js:130:23:130:24 | id | semmle.label | id | | mongoose.js:133:38:133:42 | query | semmle.label | query | -| mongoose.js:134:30:134:34 | query | semmle.label | query | | mongoose.js:136:30:136:34 | query | semmle.label | query | | mongooseJsonParse.js:19:11:19:20 | query | semmle.label | query | | mongooseJsonParse.js:19:19:19:20 | {} | semmle.label | {} | @@ -453,7 +452,6 @@ edges | mongoose.js:20:8:20:17 | query | mongoose.js:111:14:111:18 | query | provenance | | | mongoose.js:20:8:20:17 | query | mongoose.js:113:31:113:35 | query | provenance | | | mongoose.js:20:8:20:17 | query | mongoose.js:133:38:133:42 | query | provenance | | -| mongoose.js:20:8:20:17 | query | mongoose.js:134:30:134:34 | query | provenance | | | mongoose.js:20:8:20:17 | query | mongoose.js:136:30:136:34 | query | provenance | | | mongoose.js:20:16:20:17 | {} | mongoose.js:20:8:20:17 | query | provenance | | | mongoose.js:21:2:21:6 | query | mongoose.js:24:22:24:26 | query | provenance | | @@ -498,7 +496,6 @@ edges | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:111:14:111:18 | query | provenance | Config | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:113:31:113:35 | query | provenance | Config | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:133:38:133:42 | query | provenance | Config | -| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:134:30:134:34 | query | provenance | Config | | mongoose.js:21:16:21:29 | req.body.title | mongoose.js:136:30:136:34 | query | provenance | Config | | mongoose.js:24:22:24:26 | query | mongoose.js:24:21:24:27 | [query] | provenance | Config | | mongoose.js:24:22:24:26 | query | mongoose.js:27:17:27:21 | query | provenance | | @@ -555,7 +552,6 @@ edges | mongoose.js:115:25:115:45 | cond | mongoose.js:129:21:129:24 | cond | provenance | | | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:115:25:115:45 | cond | provenance | | | mongoose.js:130:23:130:24 | id | mongoose.js:130:16:130:26 | { _id: id } | provenance | Config | -| mongoose.js:133:38:133:42 | query | mongoose.js:134:30:134:34 | query | provenance | | | mongoose.js:133:38:133:42 | query | mongoose.js:136:30:136:34 | query | provenance | | | mongooseJsonParse.js:19:11:19:20 | query | mongooseJsonParse.js:23:19:23:23 | query | provenance | | | mongooseJsonParse.js:19:19:19:20 | {} | mongooseJsonParse.js:19:11:19:20 | query | provenance | | @@ -718,7 +714,6 @@ subpaths | mongoose.js:128:22:128:25 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:128:22:128:25 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | | mongoose.js:129:21:129:24 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:129:21:129:24 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | | mongoose.js:130:16:130:26 | { _id: id } | mongoose.js:115:11:115:22 | req.query.id | mongoose.js:130:16:130:26 | { _id: id } | This query object depends on a $@. | mongoose.js:115:11:115:22 | req.query.id | user-provided value | -| mongoose.js:134:30:134:34 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:134:30:134:34 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | | mongoose.js:136:30:136:34 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:136:30:136:34 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | | mongooseJsonParse.js:23:19:23:23 | query | mongooseJsonParse.js:20:30:20:43 | req.query.data | mongooseJsonParse.js:23:19:23:23 | query | This query object depends on a $@. | mongooseJsonParse.js:20:30:20:43 | req.query.data | user-provided value | | mongooseModelClient.js:11:16:11:24 | { id: v } | mongooseModelClient.js:10:22:10:29 | req.body | mongooseModelClient.js:11:16:11:24 | { id: v } | This query object depends on a $@. | mongooseModelClient.js:10:22:10:29 | req.body | user-provided value | From 75ab4856b8bd3beb9ebfbdd354dfdec8ddc0282f Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 13:55:25 +0100 Subject: [PATCH 410/514] Remove unsupported features from PoI --- javascript/ql/src/experimental/poi/PoI.qll | 48 ------------------- .../CommandInjectionPoIConfiguration.expected | 4 -- .../PoI/CommandInjectionPoIConfiguration.ql | 13 ----- .../PoI/TaintedPathPoIConfiguration.expected | 6 --- .../PoI/TaintedPathPoIConfiguration.ql | 11 ----- .../PoI/XssPoIConfiguration.expected | 4 -- .../experimental/PoI/XssPoIConfiguration.ql | 14 ------ 7 files changed, 100 deletions(-) delete mode 100644 javascript/ql/test/experimental/PoI/CommandInjectionPoIConfiguration.expected delete mode 100644 javascript/ql/test/experimental/PoI/CommandInjectionPoIConfiguration.ql delete mode 100644 javascript/ql/test/experimental/PoI/TaintedPathPoIConfiguration.expected delete mode 100644 javascript/ql/test/experimental/PoI/TaintedPathPoIConfiguration.ql delete mode 100644 javascript/ql/test/experimental/PoI/XssPoIConfiguration.expected delete mode 100644 javascript/ql/test/experimental/PoI/XssPoIConfiguration.ql diff --git a/javascript/ql/src/experimental/poi/PoI.qll b/javascript/ql/src/experimental/poi/PoI.qll index 9539459c60b..10d5ab06072 100644 --- a/javascript/ql/src/experimental/poi/PoI.qll +++ b/javascript/ql/src/experimental/poi/PoI.qll @@ -133,44 +133,6 @@ private module StandardPoIs { override predicate is(Node l0) { l0 instanceof RemoteFlowSource } } - /** - * A "source" for any active configuration. - */ - class SourcePoI extends PoI { - SourcePoI() { this = "SourcePoI" } - - override predicate is(Node l0) { - exists(Configuration cfg | cfg.isSource(l0) or cfg.isSource(l0, _)) - } - } - - /** - * A "sink" for any active configuration. - */ - class SinkPoI extends PoI { - SinkPoI() { this = "SinkPoI" } - - override predicate is(Node l0) { - exists(Configuration cfg | cfg.isSink(l0) or cfg.isSink(l0, _)) - } - } - - /** - * A "barrier" for any active configuration. - */ - class BarrierPoI extends PoI { - BarrierPoI() { this = "BarrierPoI" } - - override predicate is(Node l0) { - exists(Configuration cfg | - cfg.isBarrier(l0) or - cfg.isBarrierEdge(l0, _) or - cfg.isBarrierEdge(l0, _, _) or - cfg.isLabeledBarrier(l0, _) - ) - } - } - /** * Provides groups of often used points of interest. */ @@ -185,16 +147,6 @@ private module StandardPoIs { this instanceof UnpromotedRouteHandlerWithFlowPoI } } - - /** - * A configuration-related point of interest. - */ - class DataFlowConfigurationPoI extends PoI { - DataFlowConfigurationPoI() { - this instanceof SourcePoI or - this instanceof SinkPoI - } - } } import StandardPoIGroups diff --git a/javascript/ql/test/experimental/PoI/CommandInjectionPoIConfiguration.expected b/javascript/ql/test/experimental/PoI/CommandInjectionPoIConfiguration.expected deleted file mode 100644 index 76ec9dc360b..00000000000 --- a/javascript/ql/test/experimental/PoI/CommandInjectionPoIConfiguration.expected +++ /dev/null @@ -1,4 +0,0 @@ -| tst.js:16:15:16:25 | req.query.x | SourcePoI | tst.js:16:15:16:25 | req.query.x | irrelevant | tst.js:16:15:16:25 | req.query.x | irrelevant | -| tst.js:17:11:17:21 | req.query.x | SinkPoI | tst.js:17:11:17:21 | req.query.x | irrelevant | tst.js:17:11:17:21 | req.query.x | irrelevant | -| tst.js:17:11:17:21 | req.query.x | SourcePoI | tst.js:17:11:17:21 | req.query.x | irrelevant | tst.js:17:11:17:21 | req.query.x | irrelevant | -| tst.js:18:12:18:22 | req.query.x | SourcePoI | tst.js:18:12:18:22 | req.query.x | irrelevant | tst.js:18:12:18:22 | req.query.x | irrelevant | diff --git a/javascript/ql/test/experimental/PoI/CommandInjectionPoIConfiguration.ql b/javascript/ql/test/experimental/PoI/CommandInjectionPoIConfiguration.ql deleted file mode 100644 index 5ea8c17fc28..00000000000 --- a/javascript/ql/test/experimental/PoI/CommandInjectionPoIConfiguration.ql +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @kind problem - */ - -import javascript -import experimental.poi.PoI -import semmle.javascript.security.dataflow.CommandInjectionQuery as CommandInjection -import semmle.javascript.security.dataflow.IndirectCommandInjectionQuery as IndirectCommandInjection -import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironmentQuery as ShellCommandInjectionFromEnvironment - -class MyDataFlowConfigurationPoIs extends DataFlowConfigurationPoI, ActivePoI { } - -query predicate problems = alertQuery/6; diff --git a/javascript/ql/test/experimental/PoI/TaintedPathPoIConfiguration.expected b/javascript/ql/test/experimental/PoI/TaintedPathPoIConfiguration.expected deleted file mode 100644 index 7de2d09cd54..00000000000 --- a/javascript/ql/test/experimental/PoI/TaintedPathPoIConfiguration.expected +++ /dev/null @@ -1,6 +0,0 @@ -| tst.js:1:23:1:31 | "express" | SinkPoI | tst.js:1:23:1:31 | "express" | irrelevant | tst.js:1:23:1:31 | "express" | irrelevant | -| tst.js:2:16:2:19 | "fs" | SinkPoI | tst.js:2:16:2:19 | "fs" | irrelevant | tst.js:2:16:2:19 | "fs" | irrelevant | -| tst.js:3:16:3:30 | "child_process" | SinkPoI | tst.js:3:16:3:30 | "child_process" | irrelevant | tst.js:3:16:3:30 | "child_process" | irrelevant | -| tst.js:16:15:16:25 | req.query.x | SourcePoI | tst.js:16:15:16:25 | req.query.x | irrelevant | tst.js:16:15:16:25 | req.query.x | irrelevant | -| tst.js:17:11:17:21 | req.query.x | SourcePoI | tst.js:17:11:17:21 | req.query.x | irrelevant | tst.js:17:11:17:21 | req.query.x | irrelevant | -| tst.js:18:12:18:22 | req.query.x | SourcePoI | tst.js:18:12:18:22 | req.query.x | irrelevant | tst.js:18:12:18:22 | req.query.x | irrelevant | diff --git a/javascript/ql/test/experimental/PoI/TaintedPathPoIConfiguration.ql b/javascript/ql/test/experimental/PoI/TaintedPathPoIConfiguration.ql deleted file mode 100644 index 784abb7e85b..00000000000 --- a/javascript/ql/test/experimental/PoI/TaintedPathPoIConfiguration.ql +++ /dev/null @@ -1,11 +0,0 @@ -/** - * @kind problem - */ - -import javascript -import experimental.poi.PoI -import semmle.javascript.security.dataflow.TaintedPathQuery as TaintedPath - -class MyDataflowRelatedPoIs extends DataFlowConfigurationPoI, ActivePoI { } - -query predicate problems = alertQuery/6; diff --git a/javascript/ql/test/experimental/PoI/XssPoIConfiguration.expected b/javascript/ql/test/experimental/PoI/XssPoIConfiguration.expected deleted file mode 100644 index dca2edaef2b..00000000000 --- a/javascript/ql/test/experimental/PoI/XssPoIConfiguration.expected +++ /dev/null @@ -1,4 +0,0 @@ -| tst.js:16:15:16:25 | req.query.x | SourcePoI | tst.js:16:15:16:25 | req.query.x | irrelevant | tst.js:16:15:16:25 | req.query.x | irrelevant | -| tst.js:17:11:17:21 | req.query.x | SourcePoI | tst.js:17:11:17:21 | req.query.x | irrelevant | tst.js:17:11:17:21 | req.query.x | irrelevant | -| tst.js:18:12:18:22 | req.query.x | SinkPoI | tst.js:18:12:18:22 | req.query.x | irrelevant | tst.js:18:12:18:22 | req.query.x | irrelevant | -| tst.js:18:12:18:22 | req.query.x | SourcePoI | tst.js:18:12:18:22 | req.query.x | irrelevant | tst.js:18:12:18:22 | req.query.x | irrelevant | diff --git a/javascript/ql/test/experimental/PoI/XssPoIConfiguration.ql b/javascript/ql/test/experimental/PoI/XssPoIConfiguration.ql deleted file mode 100644 index 05b43a06cd1..00000000000 --- a/javascript/ql/test/experimental/PoI/XssPoIConfiguration.ql +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @kind problem - */ - -import javascript -import experimental.poi.PoI -import semmle.javascript.security.dataflow.ReflectedXssQuery as ReflectedXss -import semmle.javascript.security.dataflow.StoredXssQuery as StoredXss -import semmle.javascript.security.dataflow.DomBasedXssQuery as DomBasedXss -import semmle.javascript.security.dataflow.ExceptionXssQuery as ExceptionXss - -class MyDataFlowConfigurationPoIs extends DataFlowConfigurationPoI, ActivePoI { } - -query predicate problems = alertQuery/6; From 08d25c122d8572c47150456defdd821b877aeaeb Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 Nov 2024 14:44:24 +0100 Subject: [PATCH 411/514] JS: Deprecate more uses of ConsistencyConfiguration --- javascript/ql/test/library-tests/Routing/test.ql | 2 +- .../test/library-tests/Security/heuristics/HeuristicSource.ql | 2 +- .../ql/test/library-tests/TaintTracking/BasicTaintTracking.ql | 2 +- javascript/ql/test/library-tests/frameworks/Vuex/test.ql | 2 +- javascript/ql/test/library-tests/frameworks/data/test.ql | 2 +- .../query-tests/Security/CWE-022/TaintedPath/Consistency.ql | 2 +- .../ql/test/query-tests/Security/CWE-078/Consistency.ql | 4 ++-- .../Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.ql | 2 +- .../CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql | 2 +- .../CWE-915/PrototypePollutingAssignment/Consistency.ql | 2 +- .../ql/test/query-tests/Security/CWE-918/Consistency.ql | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/javascript/ql/test/library-tests/Routing/test.ql b/javascript/ql/test/library-tests/Routing/test.ql index ac0e09c1dfd..78f01aa3699 100644 --- a/javascript/ql/test/library-tests/Routing/test.ql +++ b/javascript/ql/test/library-tests/Routing/test.ql @@ -19,7 +19,7 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = TaintTracking::Global; -class Consistency extends ConsistencyConfiguration { +deprecated class Consistency extends ConsistencyConfiguration { Consistency() { this = "Consistency" } override DataFlow::Node getAnAlert() { TestFlow::flowTo(result) } diff --git a/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.ql b/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.ql index dce4f7a6de1..e3fad7eef3e 100644 --- a/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.ql +++ b/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.ql @@ -12,7 +12,7 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = TaintTracking::Global; -class Consistency extends ConsistencyConfiguration { +deprecated class Consistency extends ConsistencyConfiguration { Consistency() { this = "Consistency" } override DataFlow::Node getAnAlert() { TestFlow::flowTo(result) } diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql index d48f8ad8a59..087b7497c24 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql @@ -53,7 +53,7 @@ class BasicSanitizerGuard extends TaintTracking::SanitizerGuardNode, DataFlow::C query predicate flow = TestFlow::flow/2; -class Consistency extends ConsistencyConfiguration { +deprecated class Consistency extends ConsistencyConfiguration { Consistency() { this = "Consistency" } override DataFlow::Node getAnAlert() { TestFlow::flowTo(result) } diff --git a/javascript/ql/test/library-tests/frameworks/Vuex/test.ql b/javascript/ql/test/library-tests/frameworks/Vuex/test.ql index 3d46b90be05..c4ea02ab81d 100644 --- a/javascript/ql/test/library-tests/frameworks/Vuex/test.ql +++ b/javascript/ql/test/library-tests/frameworks/Vuex/test.ql @@ -11,7 +11,7 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = TaintTracking::Global; -class Consistency extends ConsistencyConfiguration { +deprecated class Consistency extends ConsistencyConfiguration { Consistency() { this = "Consistency" } override DataFlow::Node getAnAlert() { TestFlow::flowTo(result) } diff --git a/javascript/ql/test/library-tests/frameworks/data/test.ql b/javascript/ql/test/library-tests/frameworks/data/test.ql index ce1574f5e9b..b0ca4ae8934 100644 --- a/javascript/ql/test/library-tests/frameworks/data/test.ql +++ b/javascript/ql/test/library-tests/frameworks/data/test.ql @@ -27,7 +27,7 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = TaintTracking::Global; -class Consistency extends ConsistencyConfiguration { +deprecated class Consistency extends ConsistencyConfiguration { Consistency() { this = "Consistency" } override DataFlow::Node getAnAlert() { TestFlow::flowTo(result) } diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.ql index adbeec47ad9..997f31f2b1d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/Consistency.ql @@ -2,7 +2,7 @@ import javascript import semmle.javascript.security.dataflow.TaintedPathQuery deprecated import testUtilities.ConsistencyChecking -class TaintedPathConsistency extends ConsistencyConfiguration { +deprecated class TaintedPathConsistency extends ConsistencyConfiguration { TaintedPathConsistency() { this = "TaintedPathConsistency" } override DataFlow::Node getAnAlert() { TaintedPathFlow::flowTo(result) } diff --git a/javascript/ql/test/query-tests/Security/CWE-078/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-078/Consistency.ql index 543581e4d5f..beaef10cadf 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-078/Consistency.ql @@ -6,7 +6,7 @@ import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironmentQ import semmle.javascript.security.dataflow.UnsafeShellCommandConstructionQuery as UnsafeShellCommandConstruction import semmle.javascript.security.dataflow.SecondOrderCommandInjectionQuery as SecondOrderCommandInjectionQuery -class CommandInjectionConsistency extends ConsistencyConfiguration { +deprecated class CommandInjectionConsistency extends ConsistencyConfiguration { CommandInjectionConsistency() { this = "ComandInjection" } override File getAFile() { not result.getBaseName() = "uselesscat.js" } @@ -14,7 +14,7 @@ class CommandInjectionConsistency extends ConsistencyConfiguration { import semmle.javascript.security.UselessUseOfCat -class UselessCatConsistency extends ConsistencyConfiguration { +deprecated class UselessCatConsistency extends ConsistencyConfiguration { UselessCatConsistency() { this = "Cat" } override DataFlow::Node getAnAlert() { result instanceof UselessCat } diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.ql b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.ql index dcda8c7c0f3..28a557d25c8 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.ql @@ -2,7 +2,7 @@ import javascript deprecated import testUtilities.ConsistencyChecking import semmle.javascript.security.dataflow.DomBasedXssQuery -class ConsistencyConfig extends ConsistencyConfiguration { +deprecated class ConsistencyConfig extends ConsistencyConfiguration { ConsistencyConfig() { this = "ConsistencyConfig" } override DataFlow::Node getAnAlert() { DomBasedXssFlow::flow(_, result) } diff --git a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql index f152b3c656c..7907ff623a8 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql @@ -2,7 +2,7 @@ import javascript deprecated import testUtilities.ConsistencyChecking import semmle.javascript.security.dataflow.XssThroughDomQuery -class ConsistencyConfig extends ConsistencyConfiguration { +deprecated class ConsistencyConfig extends ConsistencyConfiguration { ConsistencyConfig() { this = "ConsistencyConfig" } override DataFlow::Node getAnAlert() { diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.ql index b9420810416..d52f57bd580 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/Consistency.ql @@ -2,7 +2,7 @@ import javascript deprecated import testUtilities.ConsistencyChecking import semmle.javascript.security.dataflow.PrototypePollutingAssignmentQuery -class Config extends ConsistencyConfiguration { +deprecated class Config extends ConsistencyConfiguration { Config() { this = "Config" } override File getAFile() { any() } diff --git a/javascript/ql/test/query-tests/Security/CWE-918/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-918/Consistency.ql index 808e45dd8cb..b201b6f0552 100644 --- a/javascript/ql/test/query-tests/Security/CWE-918/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-918/Consistency.ql @@ -15,7 +15,7 @@ query predicate resultInWrongFile(DataFlow::Node node) { ) } -class Consistency extends ConsistencyConfiguration { +deprecated class Consistency extends ConsistencyConfiguration { Consistency() { this = "Consistency" } override DataFlow::Node getAnAlert() { From a574ff1669d80fafa1560aa44c632d3db826e68e Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 29 Nov 2024 08:42:14 +0100 Subject: [PATCH 412/514] JS: Remove use of MakeLegacyBarrierGuard in experimental SSRF --- .../experimental/Security/CWE-918/SSRF.qll | 41 ++++++++----------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/javascript/ql/src/experimental/Security/CWE-918/SSRF.qll b/javascript/ql/src/experimental/Security/CWE-918/SSRF.qll index da20923ce1a..70098fe9dc8 100644 --- a/javascript/ql/src/experimental/Security/CWE-918/SSRF.qll +++ b/javascript/ql/src/experimental/Security/CWE-918/SSRF.qll @@ -8,7 +8,8 @@ module SsrfConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof RequestForgery::Sink } predicate isBarrier(DataFlow::Node node) { - node instanceof RequestForgery::Sanitizer or node = Guards::getABarrierNode() + node instanceof RequestForgery::Sanitizer or + node = DataFlow::MakeBarrierGuard::getABarrierNode() } private predicate hasSanitizingSubstring(DataFlow::Node nd) { @@ -27,14 +28,6 @@ module SsrfConfig implements DataFlow::ConfigSig { } predicate isBarrierOut(DataFlow::Node node) { strictSanitizingPrefixEdge(node, _) } - - private predicate isBarrierGuard(DataFlow::BarrierGuardNode nd) { - nd instanceof IntegerCheck or - nd instanceof ValidatorCheck or - nd instanceof TernaryOperatorSanitizerGuard - } - - private module Guards = DataFlow::MakeLegacyBarrierGuard; } module SsrfFlow = TaintTracking::Global; @@ -87,6 +80,12 @@ class TernaryOperatorSanitizer extends RequestForgery::Sanitizer { } } +/** A barrier guard for this SSRF query. */ +abstract class BarrierGuard extends DataFlow::Node { + /** Holds if flow through `e` should be blocked, provided this evaluates to `outcome`. */ + abstract predicate blocksExpr(boolean outcome, Expr e); +} + /** * This sanitizer guard is another way of modeling the example from above * In this case: @@ -101,8 +100,8 @@ class TernaryOperatorSanitizer extends RequestForgery::Sanitizer { * Thats why we model this sanitizer guard which says that * the result of the ternary operator execution is a sanitizer guard. */ -class TernaryOperatorSanitizerGuard extends TaintTracking::SanitizerGuardNode { - TaintTracking::SanitizerGuardNode originalGuard; +class TernaryOperatorSanitizerGuard extends BarrierGuard { + TaintTracking::AdditionalBarrierGuard originalGuard; TernaryOperatorSanitizerGuard() { this.getAPredecessor+().asExpr().(BooleanLiteral).mayHaveBooleanValue(false) and @@ -110,15 +109,13 @@ class TernaryOperatorSanitizerGuard extends TaintTracking::SanitizerGuardNode { not this.asExpr() instanceof LogicalBinaryExpr } - override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } - - predicate blocksExpr(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { not this.asExpr() instanceof LogNotExpr and - originalGuard.sanitizes(outcome, e) + originalGuard.blocksExpr(outcome, e) or exists(boolean originalOutcome | this.asExpr() instanceof LogNotExpr and - originalGuard.sanitizes(originalOutcome, e) and + originalGuard.blocksExpr(originalOutcome, e) and ( originalOutcome = true and outcome = false or @@ -131,12 +128,10 @@ class TernaryOperatorSanitizerGuard extends TaintTracking::SanitizerGuardNode { /** * A call to Number.isInteger seen as a sanitizer guard because a number can't be used to exploit a SSRF. */ -class IntegerCheck extends TaintTracking::SanitizerGuardNode, DataFlow::CallNode { +class IntegerCheck extends DataFlow::CallNode, BarrierGuard { IntegerCheck() { this = DataFlow::globalVarRef("Number").getAMemberCall("isInteger") } - override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } - - predicate blocksExpr(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = this.getArgument(0).asExpr() } @@ -147,7 +142,7 @@ class IntegerCheck extends TaintTracking::SanitizerGuardNode, DataFlow::CallNode * validator is a library which has a variety of input-validation functions. We are interesed in * checking that source is a number (any type of number) or an alphanumeric value. */ -class ValidatorCheck extends TaintTracking::SanitizerGuardNode, DataFlow::CallNode { +class ValidatorCheck extends DataFlow::CallNode, BarrierGuard { ValidatorCheck() { exists(DataFlow::SourceNode mod, string method | mod = DataFlow::moduleImport("validator") and @@ -159,9 +154,7 @@ class ValidatorCheck extends TaintTracking::SanitizerGuardNode, DataFlow::CallNo ) } - override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } - - predicate blocksExpr(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = this.getArgument(0).asExpr() } From 21494fbdffb6a1ec5eb1fc00dc53ad3ef3c89f16 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 29 Nov 2024 09:19:01 +0100 Subject: [PATCH 413/514] JS: Refactor BarrierGuardLegacy pattern to not depend on SanitizerGuardNode Previously our barrier guard classes were direct descendents of SanitizerGuardNode which made it hard to deprecate that class. Now our barrier guards are not descending from any shared class. Instead they are contributed to SanitizerGuardNode via a private helper class we can remove in the future. --- .../dataflow/DomBasedXssCustomizations.qll | 19 +++++++--- .../LoopBoundInjectionCustomizations.qll | 23 ++++++++---- ...otypePollutingAssignmentCustomizations.qll | 17 +++++++-- .../PrototypePollutingAssignmentQuery.qll | 18 +++++----- .../ResourceExhaustionCustomizations.qll | 10 ++++-- .../dataflow/ResourceExhaustionQuery.qll | 2 +- ...ondOrderCommandInjectionCustomizations.qll | 21 ++++++++--- .../dataflow/TaintedPathCustomizations.qll | 35 ++++++++++++------- ...hroughParameterTamperingCustomizations.qll | 10 ++++-- ...onfusionThroughParameterTamperingQuery.qll | 4 +-- .../UnsafeHtmlConstructionCustomizations.qll | 19 +++++++--- .../UnsafeJQueryPluginCustomizations.qll | 16 ++++++--- ...ShellCommandConstructionCustomizations.qll | 16 ++++++--- ...lidatedDynamicMethodCallCustomizations.qll | 21 ++++++++--- .../dataflow/XssThroughDomCustomizations.qll | 10 ++++-- .../security/dataflow/XssThroughDomQuery.qll | 2 +- .../regexp/PolynomialReDoSCustomizations.qll | 12 +++++-- 17 files changed, 184 insertions(+), 71 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssCustomizations.qll index e63fcac238b..8dd89667959 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssCustomizations.qll @@ -31,14 +31,25 @@ module DomBasedXss { * 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() } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { + this.blocksExpr(outcome, e, label) + } } /** 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) } + deprecated final private class BarrierGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof BarrierGuard + { + override predicate sanitizes(boolean outcome, Expr e) { + BarrierGuard.super.sanitizes(outcome, e) + } override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { - this.blocksExpr(outcome, e, label) + BarrierGuard.super.sanitizes(outcome, e, label) } } @@ -378,7 +389,7 @@ module DomBasedXss { /** * A sanitizer that blocks the `PrefixString` label when the start of the string is being tested as being of a particular prefix. */ - abstract class PrefixStringSanitizer extends BarrierGuardLegacy instanceof StringOps::StartsWith { + abstract class PrefixStringSanitizer extends BarrierGuard instanceof StringOps::StartsWith { override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { e = super.getBaseString().asExpr() and label = prefixLabel() and diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionCustomizations.qll index c140eed0785..f018428252c 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionCustomizations.qll @@ -179,14 +179,25 @@ module LoopBoundInjection { * 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() } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { + this.blocksExpr(outcome, e, label) + } } /** 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) } + deprecated final private class BarrierGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof BarrierGuard + { + override predicate sanitizes(boolean outcome, Expr e) { + BarrierGuard.super.sanitizes(outcome, e) + } override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { - this.blocksExpr(outcome, e, label) + BarrierGuard.super.sanitizes(outcome, e, label) } } @@ -198,7 +209,7 @@ module LoopBoundInjection { /** * A sanitizer that blocks taint flow if the array is checked to be an array using an `isArray` function. */ - class IsArraySanitizerGuard extends BarrierGuardLegacy, DataFlow::ValueNode { + class IsArraySanitizerGuard extends BarrierGuard, DataFlow::ValueNode { override CallExpr astNode; IsArraySanitizerGuard() { astNode.getCalleeName() = "isArray" } @@ -213,7 +224,7 @@ module LoopBoundInjection { /** * A sanitizer that blocks taint flow if the array is checked to be an array using an `X instanceof Array` check. */ - class InstanceofArraySanitizerGuard extends BarrierGuardLegacy, DataFlow::ValueNode { + class InstanceofArraySanitizerGuard extends BarrierGuard, DataFlow::ValueNode { override BinaryExpr astNode; InstanceofArraySanitizerGuard() { @@ -233,7 +244,7 @@ module LoopBoundInjection { * * Also implicitly makes sure that only the first DoS-prone loop is selected by the query (as the .length test has outcome=false when exiting the loop). */ - class LengthCheckSanitizerGuard extends BarrierGuardLegacy, DataFlow::ValueNode { + class LengthCheckSanitizerGuard extends BarrierGuard, DataFlow::ValueNode { override RelationalComparison astNode; DataFlow::PropRead propRead; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentCustomizations.qll index 4b0b954066a..5ac278924e2 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentCustomizations.qll @@ -51,14 +51,25 @@ module PrototypePollutingAssignment { * 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() } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { + this.blocksExpr(outcome, e, label) + } } /** 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) } + deprecated final private class BarrierGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof BarrierGuard + { + override predicate sanitizes(boolean outcome, Expr e) { + BarrierGuard.super.sanitizes(outcome, e) + } override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { - this.blocksExpr(outcome, e, label) + BarrierGuard.super.sanitizes(outcome, e, label) } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll index ca61ebf284d..517da8f7c02 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll @@ -256,7 +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 BarrierGuardLegacy, DataFlow::ValueNode { +private class PropertyPresenceCheck extends BarrierGuard, DataFlow::ValueNode { override PropAccess astNode; PropertyPresenceCheck() { @@ -272,7 +272,7 @@ private class PropertyPresenceCheck extends BarrierGuardLegacy, DataFlow::ValueN } /** A check of form `"prop" in e` where `prop` is not present on `Object.prototype`. */ -private class InExprCheck extends BarrierGuardLegacy, DataFlow::ValueNode { +private class InExprCheck extends BarrierGuard, DataFlow::ValueNode { override InExpr astNode; InExprCheck() { @@ -287,7 +287,7 @@ private class InExprCheck extends BarrierGuardLegacy, DataFlow::ValueNode { } /** A check of form `e instanceof X`, which is always false for `Object.prototype`. */ -private class InstanceofCheck extends BarrierGuardLegacy, DataFlow::ValueNode { +private class InstanceofCheck extends BarrierGuard, DataFlow::ValueNode { override InstanceofExpr astNode; override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { @@ -298,7 +298,7 @@ private class InstanceofCheck extends BarrierGuardLegacy, DataFlow::ValueNode { } /** A check of form `typeof e === "string"`. */ -private class TypeofCheck extends BarrierGuardLegacy, DataFlow::ValueNode { +private class TypeofCheck extends BarrierGuard, DataFlow::ValueNode { override EqualityTest astNode; Expr operand; boolean polarity; @@ -319,7 +319,7 @@ private class TypeofCheck extends BarrierGuardLegacy, DataFlow::ValueNode { } /** A guard that checks whether `x` is a number. */ -class NumberGuard extends BarrierGuardLegacy instanceof DataFlow::CallNode { +class NumberGuard extends BarrierGuard instanceof DataFlow::CallNode { Expr x; boolean polarity; @@ -329,7 +329,7 @@ class NumberGuard extends BarrierGuardLegacy instanceof DataFlow::CallNode { } /** A call to `Array.isArray`, which is false for `Object.prototype`. */ -private class IsArrayCheck extends BarrierGuardLegacy, DataFlow::CallNode { +private class IsArrayCheck extends BarrierGuard, DataFlow::CallNode { IsArrayCheck() { this = DataFlow::globalVarRef("Array").getAMemberCall("isArray") } override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { @@ -342,7 +342,7 @@ private class IsArrayCheck extends BarrierGuardLegacy, DataFlow::CallNode { /** * Sanitizer guard of form `x !== "__proto__"`. */ -private class EqualityCheck extends BarrierGuardLegacy, DataFlow::ValueNode { +private class EqualityCheck extends BarrierGuard, DataFlow::ValueNode { override EqualityTest astNode; EqualityCheck() { astNode.getAnOperand().getStringValue() = "__proto__" } @@ -356,7 +356,7 @@ private class EqualityCheck extends BarrierGuardLegacy, DataFlow::ValueNode { /** * Sanitizer guard of the form `x.includes("__proto__")`. */ -private class IncludesCheck extends BarrierGuardLegacy, InclusionTest { +private class IncludesCheck extends BarrierGuard, InclusionTest { IncludesCheck() { this.getContainedNode().mayHaveStringValue("__proto__") } override predicate blocksExpr(boolean outcome, Expr e) { @@ -368,7 +368,7 @@ private class IncludesCheck extends BarrierGuardLegacy, InclusionTest { /** * A sanitizer guard that checks tests whether `x` is included in a list like `["__proto__"].includes(x)`. */ -private class DenyListInclusionGuard extends BarrierGuardLegacy, InclusionTest { +private class DenyListInclusionGuard extends BarrierGuard, InclusionTest { DenyListInclusionGuard() { this.getContainerNode() .getALocalSource() diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionCustomizations.qll index 7a93287ab90..c62aedd4b5c 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionCustomizations.qll @@ -39,11 +39,17 @@ module ResourceExhaustion { * 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() } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } } /** 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) } + deprecated final private class BarrierGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof BarrierGuard + { + override predicate sanitizes(boolean outcome, Expr e) { + BarrierGuard.super.sanitizes(outcome, e) + } } /** diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionQuery.qll index 01cab949741..65481b929d0 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionQuery.qll @@ -73,7 +73,7 @@ predicate isNumericFlowStep(DataFlow::Node src, DataFlow::Node dst) { /** * A sanitizer that blocks taint flow if the size of a number is limited. */ -class UpperBoundsCheckSanitizerGuard extends BarrierGuardLegacy, DataFlow::ValueNode { +class UpperBoundsCheckSanitizerGuard extends BarrierGuard, DataFlow::ValueNode { override RelationalComparison astNode; override predicate blocksExpr(boolean outcome, Expr e) { diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionCustomizations.qll index 95a363bfa17..520cf57b3af 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionCustomizations.qll @@ -96,14 +96,25 @@ module SecondOrderCommandInjection { * 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() } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { + this.blocksExpr(outcome, e, label) + } } /** 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) } + deprecated final private class BarrierGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof BarrierGuard + { + override predicate sanitizes(boolean outcome, Expr e) { + BarrierGuard.super.sanitizes(outcome, e) + } override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { - this.blocksExpr(outcome, e, label) + BarrierGuard.super.sanitizes(outcome, e, label) } } @@ -214,7 +225,7 @@ module SecondOrderCommandInjection { /** * A sanitizer that blocks flow when a string is tested to start with a certain prefix. */ - class PrefixStringSanitizer extends BarrierGuardLegacy instanceof StringOps::StartsWith { + class PrefixStringSanitizer extends BarrierGuard instanceof StringOps::StartsWith { override predicate blocksExpr(boolean outcome, Expr e) { e = super.getBaseString().asExpr() and outcome = super.getPolarity() @@ -224,7 +235,7 @@ module SecondOrderCommandInjection { /** * A sanitizer that blocks flow when a string does not start with "--" */ - class DoubleDashSanitizer extends BarrierGuardLegacy instanceof StringOps::StartsWith { + class DoubleDashSanitizer extends BarrierGuard instanceof StringOps::StartsWith { DoubleDashSanitizer() { super.getSubstring().mayHaveStringValue("--") } override predicate blocksExpr(boolean outcome, Expr e) { diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll index 3262ac9fee7..062c73c286b 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll @@ -41,14 +41,25 @@ module TaintedPath { * 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() } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { + this.blocksExpr(outcome, e, label) + } } /** A subclass of `BarrierGuard` that is used for backward compatibility with the old data flow library. */ - abstract class BarrierGuardLegacy extends BarrierGuard, DataFlow::BarrierGuardNode { - override predicate blocks(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + deprecated final private class BarrierGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof BarrierGuard + { + override predicate sanitizes(boolean outcome, Expr e) { + BarrierGuard.super.sanitizes(outcome, e) + } - override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel label) { - this.blocksExpr(outcome, e, label) + override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { + BarrierGuard.super.sanitizes(outcome, e, label) } } @@ -366,7 +377,7 @@ module TaintedPath { * * This is relevant for paths that are known to be normalized. */ - class StartsWithDotDotSanitizer extends BarrierGuardLegacy instanceof StringOps::StartsWith { + class StartsWithDotDotSanitizer extends BarrierGuard instanceof StringOps::StartsWith { StartsWithDotDotSanitizer() { isDotDotSlashPrefix(super.getSubstring()) } override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { @@ -386,7 +397,7 @@ module TaintedPath { /** * A check of the form `whitelist.includes(x)` or equivalent, which sanitizes `x` in its "then" branch. */ - class MembershipTestBarrierGuard extends BarrierGuardLegacy { + class MembershipTestBarrierGuard extends BarrierGuard { MembershipCandidate candidate; MembershipTestBarrierGuard() { this = candidate.getTest() } @@ -401,7 +412,7 @@ module TaintedPath { * A check of form `x.startsWith(dir)` that sanitizes normalized absolute paths, since it is then * known to be in a subdirectory of `dir`. */ - class StartsWithDirSanitizer extends BarrierGuardLegacy { + class StartsWithDirSanitizer extends BarrierGuard { StringOps::StartsWith startsWith; StartsWithDirSanitizer() { @@ -425,7 +436,7 @@ module TaintedPath { * A call to `path.isAbsolute` as a sanitizer for relative paths in true branch, * and a sanitizer for absolute paths in the false branch. */ - class IsAbsoluteSanitizer extends BarrierGuardLegacy { + class IsAbsoluteSanitizer extends BarrierGuard { DataFlow::Node operand; boolean polarity; boolean negatable; @@ -461,7 +472,7 @@ module TaintedPath { /** * An expression of form `x.includes("..")` or similar. */ - class ContainsDotDotSanitizer extends BarrierGuardLegacy instanceof StringOps::Includes { + class ContainsDotDotSanitizer extends BarrierGuard instanceof StringOps::Includes { ContainsDotDotSanitizer() { isDotDotSlashPrefix(super.getSubstring()) } override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { @@ -474,7 +485,7 @@ module TaintedPath { /** * An expression of form `x.matches(/\.\./)` or similar. */ - class ContainsDotDotRegExpSanitizer extends BarrierGuardLegacy instanceof StringOps::RegExpTest { + class ContainsDotDotRegExpSanitizer extends BarrierGuard instanceof StringOps::RegExpTest { ContainsDotDotRegExpSanitizer() { super.getRegExp().getAMatchedString() = [".", "..", "../"] } override predicate blocksExpr(boolean outcome, Expr e, DataFlow::FlowLabel label) { @@ -505,7 +516,7 @@ module TaintedPath { * } * ``` */ - class RelativePathStartsWithSanitizer extends BarrierGuardLegacy { + class RelativePathStartsWithSanitizer extends BarrierGuard { StringOps::StartsWith startsWith; DataFlow::CallNode pathCall; string member; @@ -563,7 +574,7 @@ module TaintedPath { * An expression of form `isInside(x, y)` or similar, where `isInside` is * a library check for the relation between `x` and `y`. */ - class IsInsideCheckSanitizer extends BarrierGuardLegacy { + class IsInsideCheckSanitizer extends BarrierGuard { DataFlow::Node checked; boolean onlyNormalizedAbsolutePaths; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingCustomizations.qll index 6857ab308a4..de09aedce12 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingCustomizations.qll @@ -31,11 +31,17 @@ module TypeConfusionThroughParameterTampering { * 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() } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } } /** 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) } + deprecated final private class BarrierGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof BarrierGuard + { + override predicate sanitizes(boolean outcome, Expr e) { + BarrierGuard.super.sanitizes(outcome, e) + } } /** diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingQuery.qll index a490d11a429..7ca9e9509f5 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingQuery.qll @@ -34,7 +34,7 @@ module TypeConfusionConfig implements DataFlow::ConfigSig { */ module TypeConfusionFlow = DataFlow::Global; -private class TypeOfTestBarrier extends BarrierGuardLegacy, DataFlow::ValueNode { +private class TypeOfTestBarrier extends BarrierGuard, DataFlow::ValueNode { override EqualityTest astNode; TypeOfTestBarrier() { TaintTracking::isTypeofGuard(astNode, _, _) } @@ -49,7 +49,7 @@ private class TypeOfTestBarrier extends BarrierGuardLegacy, DataFlow::ValueNode } } -private class IsArrayBarrier extends BarrierGuardLegacy, DataFlow::CallNode { +private class IsArrayBarrier extends BarrierGuard, DataFlow::CallNode { IsArrayBarrier() { this = DataFlow::globalVarRef("Array").getAMemberCall("isArray") } override predicate blocksExpr(boolean outcome, Expr e) { diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll index 47535107bd8..f4ce860c860 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll @@ -74,14 +74,25 @@ module UnsafeHtmlConstruction { * 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() } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { + this.blocksExpr(outcome, e, label) + } } /** 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) } + deprecated final private class BarrierGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof BarrierGuard + { + override predicate sanitizes(boolean outcome, Expr e) { + BarrierGuard.super.sanitizes(outcome, e) + } override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { - this.blocksExpr(outcome, e, label) + BarrierGuard.super.sanitizes(outcome, e, label) } } @@ -200,7 +211,7 @@ module UnsafeHtmlConstruction { } /** A test for the value of `typeof x`, restricting the potential types of `x`. */ - class TypeTestGuard extends BarrierGuardLegacy, DataFlow::ValueNode { + class TypeTestGuard extends BarrierGuard, DataFlow::ValueNode { override EqualityTest astNode; Expr operand; boolean polarity; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll index 9209a7b1f8a..d9c1daec4e4 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll @@ -39,11 +39,17 @@ module UnsafeJQueryPlugin { * 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() } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } } /** 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) } + deprecated final private class BarrierGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof BarrierGuard + { + override predicate sanitizes(boolean outcome, Expr e) { + BarrierGuard.super.sanitizes(outcome, e) + } } /** @@ -125,7 +131,7 @@ module UnsafeJQueryPlugin { /** * An expression of form `isElement(x)`, which sanitizes `x`. */ - class IsElementSanitizer extends BarrierGuardLegacy, DataFlow::CallNode { + class IsElementSanitizer extends BarrierGuard, DataFlow::CallNode { IsElementSanitizer() { // common ad hoc sanitizing calls exists(string name | this.getCalleeName() = name | @@ -141,7 +147,7 @@ module UnsafeJQueryPlugin { /** * An expression like `typeof x. !== "undefined"` or `x.`, which sanitizes `x`, as it is unlikely to be a string afterwards. */ - class PropertyPresenceSanitizer extends BarrierGuardLegacy, DataFlow::ValueNode { + class PropertyPresenceSanitizer extends BarrierGuard, DataFlow::ValueNode { DataFlow::Node input; boolean polarity; @@ -177,7 +183,7 @@ module UnsafeJQueryPlugin { } /** A guard that checks whether `x` is a number. */ - class NumberGuard extends BarrierGuardLegacy instanceof DataFlow::CallNode { + class NumberGuard extends BarrierGuard instanceof DataFlow::CallNode { Expr x; boolean polarity; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll index 9a6710217e5..052d06020e6 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll @@ -54,11 +54,17 @@ module UnsafeShellCommandConstruction { * 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() } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } } /** 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) } + deprecated final private class BarrierGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof BarrierGuard + { + override predicate sanitizes(boolean outcome, Expr e) { + BarrierGuard.super.sanitizes(outcome, e) + } } /** @@ -285,7 +291,7 @@ module UnsafeShellCommandConstruction { * A sanitizer that sanitizers paths that exist in the file-system. * For example: `x` is sanitized in `fs.existsSync(x)` or `fs.existsSync(x + "/suffix/path")`. */ - class PathExistsSanitizerGuard extends BarrierGuardLegacy, DataFlow::CallNode { + class PathExistsSanitizerGuard extends BarrierGuard, DataFlow::CallNode { PathExistsSanitizerGuard() { this = DataFlow::moduleMember("path", "exist").getACall() or this = DataFlow::moduleMember("fs", "existsSync").getACall() @@ -304,7 +310,7 @@ module UnsafeShellCommandConstruction { * A guard of the form `typeof x === ""`, where `` is "number", or "boolean", * which sanitizes `x` in its "then" branch. */ - class TypeOfSanitizer extends BarrierGuardLegacy, DataFlow::ValueNode { + class TypeOfSanitizer extends BarrierGuard, DataFlow::ValueNode { Expr x; override EqualityTest astNode; @@ -317,7 +323,7 @@ module UnsafeShellCommandConstruction { } /** A guard that checks whether `x` is a number. */ - class NumberGuard extends BarrierGuardLegacy instanceof DataFlow::CallNode { + class NumberGuard extends BarrierGuard instanceof DataFlow::CallNode { Expr x; boolean polarity; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallCustomizations.qll index b0fef3685b7..00542294d88 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallCustomizations.qll @@ -67,14 +67,25 @@ module UnvalidatedDynamicMethodCall { * 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() } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { + this.blocksExpr(outcome, e, label) + } } /** 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) } + deprecated final private class BarrierGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof BarrierGuard + { + override predicate sanitizes(boolean outcome, Expr e) { + BarrierGuard.super.sanitizes(outcome, e) + } override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) { - this.blocksExpr(outcome, e, label) + BarrierGuard.super.sanitizes(outcome, e, label) } } @@ -138,7 +149,7 @@ module UnvalidatedDynamicMethodCall { * A check of the form `typeof x === 'function'`, which sanitizes away the `MaybeNonFunction` * taint kind. */ - class FunctionCheck extends BarrierGuardLegacy, DataFlow::ValueNode { + class FunctionCheck extends BarrierGuard, DataFlow::ValueNode { override EqualityTest astNode; Expr operand; @@ -152,7 +163,7 @@ module UnvalidatedDynamicMethodCall { } /** A guard that checks whether `x` is a number. */ - class NumberGuard extends BarrierGuardLegacy instanceof DataFlow::CallNode { + class NumberGuard extends BarrierGuard instanceof DataFlow::CallNode { Expr x; boolean polarity; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll index 57ec885b1a8..95f02768456 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll @@ -24,11 +24,17 @@ module XssThroughDom { * 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() } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } } /** 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) } + deprecated final private class BarrierGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof BarrierGuard + { + override predicate sanitizes(boolean outcome, Expr e) { + BarrierGuard.super.sanitizes(outcome, e) + } } /** diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll index 22486167db3..086cbe1abf0 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll @@ -87,7 +87,7 @@ deprecated class Configuration extends TaintTracking::Configuration { } /** A test for the value of `typeof x`, restricting the potential types of `x`. */ -class TypeTestGuard extends BarrierGuardLegacy, DataFlow::ValueNode { +class TypeTestGuard extends BarrierGuard, DataFlow::ValueNode { override EqualityTest astNode; Expr operand; boolean polarity; diff --git a/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSCustomizations.qll index 196bead33f1..dce63894f8b 100644 --- a/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSCustomizations.qll @@ -54,11 +54,17 @@ module PolynomialReDoS { * 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() } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } } /** 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) } + deprecated final private class BarrierGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof BarrierGuard + { + override predicate sanitizes(boolean outcome, Expr e) { + BarrierGuard.super.sanitizes(outcome, e) + } } /** @@ -133,7 +139,7 @@ module PolynomialReDoS { /** * An check on the length of a string, seen as a sanitizer guard. */ - class LengthGuard extends BarrierGuardLegacy, DataFlow::ValueNode { + class LengthGuard extends BarrierGuard, DataFlow::ValueNode { DataFlow::Node input; boolean polarity; From 2ef652da2c9e5e6b82dda1e2998990f6fe62da98 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 29 Nov 2024 09:24:46 +0100 Subject: [PATCH 414/514] JS: Add more deprecation annotations in tests --- javascript/ql/test/library-tests/Generators/DataFlow.ql | 2 +- javascript/ql/test/library-tests/Promises/flow.qll | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/javascript/ql/test/library-tests/Generators/DataFlow.ql b/javascript/ql/test/library-tests/Generators/DataFlow.ql index 24c7b56f587..24cae106ec7 100644 --- a/javascript/ql/test/library-tests/Generators/DataFlow.ql +++ b/javascript/ql/test/library-tests/Generators/DataFlow.ql @@ -21,7 +21,7 @@ deprecated class LegacyConfig extends DataFlow::Configuration { deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff -class Consistency extends ConsistencyConfiguration { +deprecated class Consistency extends ConsistencyConfiguration { Consistency() { this = "Consistency" } override DataFlow::Node getAnAlert() { TestFlow::flowTo(result) } diff --git a/javascript/ql/test/library-tests/Promises/flow.qll b/javascript/ql/test/library-tests/Promises/flow.qll index b77a8691ec8..6582e85474e 100644 --- a/javascript/ql/test/library-tests/Promises/flow.qll +++ b/javascript/ql/test/library-tests/Promises/flow.qll @@ -37,7 +37,7 @@ query predicate typetrack(DataFlow::SourceNode succ, DataFlow::SourceNode pred, succ = PromiseTypeTracking::promiseStep(pred, summary) } -class LegacyValueConfig extends DataFlow::Configuration { +deprecated class LegacyValueConfig extends DataFlow::Configuration { LegacyValueConfig() { this = "LegacyValueConfig" } override predicate isSource(DataFlow::Node source) { ValueFlowConfig::isSource(source) } @@ -48,7 +48,7 @@ class LegacyValueConfig extends DataFlow::Configuration { deprecated query predicate valueFlowDifference = DataFlowDiff::legacyDataFlowDifference/3; -class LegacyTaintConfig extends TaintTracking::Configuration { +deprecated class LegacyTaintConfig extends TaintTracking::Configuration { LegacyTaintConfig() { this = "LegacyTaintConfig" } override predicate isSource(DataFlow::Node source) { TaintConfig::isSource(source) } From 2ae7386775dd8666be9a728b389b10a5410814ca Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 29 Nov 2024 09:29:00 +0100 Subject: [PATCH 415/514] JS: Also apply new BarrierGuardLegacy pattern in Xss.qll --- .../javascript/security/dataflow/Xss.qll | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/Xss.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/Xss.qll index 93a9fa7fc40..ea3016d11ee 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/Xss.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/Xss.qll @@ -79,6 +79,9 @@ module Shared { * 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() } + + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } } /** @@ -86,8 +89,19 @@ module Shared { */ module BarrierGuard = DataFlow::MakeBarrierGuard; - private class QuoteGuard2 extends BarrierGuard, StringOps::Includes { - QuoteGuard2() { + /** A subclass of `BarrierGuard` that is used for backward compatibility with the old data flow library. */ + deprecated final private class BarrierGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof BarrierGuard + { + override predicate sanitizes(boolean outcome, Expr e) { + BarrierGuard.super.sanitizes(outcome, e) + } + } + + /** + * A guard that checks if a string can contain quotes, which is a guard for strings that are inside an HTML attribute. + */ + class QuoteGuard extends BarrierGuard, StringOps::Includes { + QuoteGuard() { this.getSubstring().mayHaveStringValue("\"") and this.getBaseString() .getALocalSource() @@ -100,14 +114,11 @@ module Shared { } /** - * A guard that checks if a string can contain quotes, which is a guard for strings that are inside an HTML attribute. + * A sanitizer guard that checks for the existence of HTML chars in a string. + * E.g. `/["'&<>]/.exec(str)`. */ - abstract class QuoteGuard extends TaintTracking::SanitizerGuardNode instanceof QuoteGuard2 { - override predicate sanitizes(boolean outcome, Expr e) { super.blocksExpr(outcome, e) } - } - - private class ContainsHtmlGuard2 extends BarrierGuard, StringOps::RegExpTest { - ContainsHtmlGuard2() { + class ContainsHtmlGuard extends BarrierGuard, StringOps::RegExpTest { + ContainsHtmlGuard() { exists(RegExpCharacterClass regExp | regExp = this.getRegExp() and forall(string s | s = ["\"", "&", "<", ">"] | regExp.getAMatchedString() = s) @@ -119,15 +130,6 @@ module Shared { } } - /** - * A sanitizer guard that checks for the existence of HTML chars in a string. - * E.g. `/["'&<>]/.exec(str)`. - */ - abstract class ContainsHtmlGuard extends TaintTracking::SanitizerGuardNode instanceof ContainsHtmlGuard2 - { - override predicate sanitizes(boolean outcome, Expr e) { super.blocksExpr(outcome, e) } - } - /** * Holds if `str` is used in a switch-case that has cases matching HTML escaping. */ From f620191da498fcf729538d1b2767fea1e75cf6ef Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 29 Nov 2024 09:34:01 +0100 Subject: [PATCH 416/514] JS: Deprecate SanitizerGuardNode --- javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 48aaca1a36f..38cf6225293 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -270,8 +270,7 @@ module TaintTracking { * implementations of `sanitizes` will _both_ apply to any configuration that includes either of * them. */ - abstract class SanitizerGuardNode extends DataFlow::BarrierGuardNode { - // TODO: deprecate this class; currently requires too much refactoring + abstract deprecated class SanitizerGuardNode extends DataFlow::BarrierGuardNode { override predicate blocks(boolean outcome, Expr e) { none() } /** From 62c17d3f4efccc6bd2e87e33b4355af374155ee2 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 29 Nov 2024 09:59:42 +0100 Subject: [PATCH 417/514] JS: Update SanitizerGuardNode use in BasicTaintTracking test --- .../library-tests/TaintTracking/BasicTaintTracking.ql | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql index 087b7497c24..5e36bb137d3 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql @@ -34,23 +34,26 @@ deprecated class LegacyConfig extends TaintTracking::Configuration { } override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode node) { - node instanceof BasicSanitizerGuard or + node instanceof BasicSanitizerGuardLegacy or node instanceof TaintTracking::AdHocWhitelistCheckSanitizer } } deprecated import testUtilities.LegacyDataFlowDiff::DataFlowDiff -class BasicSanitizerGuard extends TaintTracking::SanitizerGuardNode, DataFlow::CallNode { +class BasicSanitizerGuard extends DataFlow::CallNode { BasicSanitizerGuard() { this = getACall("isSafe") } - override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } - predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = this.getArgument(0).asExpr() } } +deprecated class BasicSanitizerGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof BasicSanitizerGuard +{ + override predicate sanitizes(boolean outcome, Expr e) { super.blocksExpr(outcome, e) } +} + query predicate flow = TestFlow::flow/2; deprecated class Consistency extends ConsistencyConfiguration { From 0d79c7141c3fbf06749496afaf49354d4fa4ed7c Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 29 Nov 2024 10:08:46 +0100 Subject: [PATCH 418/514] JS: Update two more uses of SanitizerGuardNode --- .../security/dataflow/ServerSideUrlRedirectQuery.qll | 12 ++++++++++-- .../security/dataflow/UrlConcatenation.qll | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirectQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirectQuery.qll index 94614094cb1..e92aa0c9607 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirectQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirectQuery.qll @@ -70,10 +70,11 @@ deprecated class Configuration extends TaintTracking::Configuration { * A call to a function called `isLocalUrl` or similar, which is * considered to sanitize a variable for purposes of URL redirection. */ -class LocalUrlSanitizingGuard extends TaintTracking::SanitizerGuardNode, DataFlow::CallNode { +class LocalUrlSanitizingGuard extends DataFlow::CallNode { LocalUrlSanitizingGuard() { this.getCalleeName().regexpMatch("(?i)(is_?)?local_?url") } - override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } /** Holds if this node blocks flow through `e`, provided it evaluates to `outcome`. */ predicate blocksExpr(boolean outcome, Expr e) { @@ -81,3 +82,10 @@ class LocalUrlSanitizingGuard extends TaintTracking::SanitizerGuardNode, DataFlo outcome = true } } + +deprecated private class LocalUrlSanitizingGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof LocalUrlSanitizingGuard +{ + override predicate sanitizes(boolean outcome, Expr e) { + LocalUrlSanitizingGuard.super.sanitizes(outcome, e) + } +} diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UrlConcatenation.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UrlConcatenation.qll index 4fc434bf178..81b7be46cb2 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UrlConcatenation.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UrlConcatenation.qll @@ -100,10 +100,11 @@ predicate hostnameSanitizingPrefixEdge(DataFlow::Node source, DataFlow::Node sin /** * A check that sanitizes the hostname of a URL. */ -class HostnameSanitizerGuard extends TaintTracking::SanitizerGuardNode, StringOps::StartsWith { +class HostnameSanitizerGuard extends StringOps::StartsWith { HostnameSanitizerGuard() { hasHostnameSanitizingSubstring(this.getSubstring()) } - override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + /** DEPRECATED. Use `blocksExpr` instead. */ + deprecated predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } /** Holds if this node blocks flow through `e`, provided it evaluates to `outcome`. */ predicate blocksExpr(boolean outcome, Expr e) { @@ -112,6 +113,13 @@ class HostnameSanitizerGuard extends TaintTracking::SanitizerGuardNode, StringOp } } +deprecated private class HostnameSanitizerGuardLegacy extends TaintTracking::SanitizerGuardNode instanceof HostnameSanitizerGuard +{ + override predicate sanitizes(boolean outcome, Expr e) { + HostnameSanitizerGuard.super.sanitizes(outcome, e) + } +} + /** * A check that sanitizes the hostname of a URL. */ From b3461989b1d19b0a986d5f54b9413b78308da36f Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 29 Nov 2024 11:06:05 +0100 Subject: [PATCH 419/514] JS: Remove use of SanitizerGuardNode in experimental SSRF query Makes a quick effort attempt to restore the original behaviour, though it is not exactly the same due to lack of recursion. --- javascript/ql/src/experimental/Security/CWE-918/SSRF.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/src/experimental/Security/CWE-918/SSRF.qll b/javascript/ql/src/experimental/Security/CWE-918/SSRF.qll index 70098fe9dc8..690c673401d 100644 --- a/javascript/ql/src/experimental/Security/CWE-918/SSRF.qll +++ b/javascript/ql/src/experimental/Security/CWE-918/SSRF.qll @@ -55,14 +55,14 @@ deprecated class Configuration extends TaintTracking::Configuration { class TernaryOperatorSanitizer extends RequestForgery::Sanitizer { TernaryOperatorSanitizer() { exists( - TaintTracking::SanitizerGuardNode guard, IfStmt ifStmt, DataFlow::Node taintedInput, + TaintTracking::AdditionalBarrierGuard guard, IfStmt ifStmt, DataFlow::Node taintedInput, boolean outcome, Stmt r, DataFlow::Node falseNode | ifStmt.getCondition().flow().getAPredecessor+() = guard and ifStmt.getCondition().flow().getAPredecessor+() = falseNode and falseNode.asExpr().(BooleanLiteral).mayHaveBooleanValue(false) and not ifStmt.getCondition() instanceof LogicalBinaryExpr and - guard.sanitizes(outcome, taintedInput.asExpr()) and + guard.blocksExpr(outcome, taintedInput.asExpr()) and ( outcome = true and r = ifStmt.getThen() and not ifStmt.getCondition() instanceof LogNotExpr or From 3f0d0e3a055663bd00a733c30020327edbd5c56d Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 2 Dec 2024 13:09:53 +0100 Subject: [PATCH 420/514] JS: Deprecate DataFlow::BarrierGuardNode --- .../semmle/javascript/dataflow/Configuration.qll | 3 +-- .../javascript/dataflow/internal/BarrierGuards.qll | 14 +++++++++++--- .../library-tests/Barriers/SimpleBarrierGuard.ql | 11 +++++++---- .../TaintTracking/DataFlowTracking.ql | 5 +++-- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index a9bc65cc0bc..74c445582d8 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -367,8 +367,7 @@ abstract private class BarrierGuardNodeInternal extends DataFlow::Node { } * classes as precise as possible: if two subclasses of `BarrierGuardNode` overlap, their * implementations of `blocks` will _both_ apply to any configuration that includes either of them. */ -abstract class BarrierGuardNode extends BarrierGuardNodeInternal { - // TODO: deprecate this class; currently requires too much refactoring +abstract deprecated class BarrierGuardNode extends BarrierGuardNodeInternal { /** * Holds if this node blocks expression `e` provided it evaluates to `outcome`. * diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll index b7a20acfcad..50e5d48278c 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll @@ -63,13 +63,21 @@ module MakeLabeledBarrierGuard { } } -deprecated private signature predicate isBarrierGuardSig(DataFlow::BarrierGuardNode node); +/** + * Contains deprecated signatures. + * + * This module is a workaround for the fact that deprecated signatures can't refer to deprecated classes + * without getting a deprecation warning + */ +deprecated private module DeprecatedSigs { + signature predicate isBarrierGuardSig(DataFlow::BarrierGuardNode node); +} /** * Converts a labeled barrier guard class to a set of nodes to include in an implementation of `isBarrier(node)` and `isBarrier(node, label)` * in a `DataFlow::StateConfigSig` implementation. */ -deprecated module MakeLegacyBarrierGuardLabeled { +deprecated module MakeLegacyBarrierGuardLabeled { final private class FinalNode = DataFlow::Node; private class Adapter extends FinalNode instanceof DataFlow::BarrierGuardNode { @@ -100,7 +108,7 @@ deprecated module MakeLegacyBarrierGuardLabeled { +deprecated module MakeLegacyBarrierGuard { final private class FinalNode = DataFlow::Node; private class Adapter extends FinalNode instanceof DataFlow::BarrierGuardNode { diff --git a/javascript/ql/test/library-tests/Barriers/SimpleBarrierGuard.ql b/javascript/ql/test/library-tests/Barriers/SimpleBarrierGuard.ql index 7f1c572b710..41e5bdd7355 100644 --- a/javascript/ql/test/library-tests/Barriers/SimpleBarrierGuard.ql +++ b/javascript/ql/test/library-tests/Barriers/SimpleBarrierGuard.ql @@ -19,17 +19,20 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = DataFlow::Global; -class SimpleBarrierGuardNode extends DataFlow::BarrierGuardNode, DataFlow::InvokeNode { +class SimpleBarrierGuardNode extends DataFlow::InvokeNode { SimpleBarrierGuardNode() { this.getCalleeName() = "BARRIER" } - override predicate blocks(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } - predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = this.getArgument(0).asExpr() } } +deprecated class SimpleBarrierGuardNodeLegacy extends DataFlow::BarrierGuardNode instanceof SimpleBarrierGuardNode +{ + override predicate blocks(boolean outcome, Expr e) { super.blocksExpr(outcome, e) } +} + deprecated class LegacyConfig extends DataFlow::Configuration { LegacyConfig() { this = "LegacyConfig" } @@ -38,7 +41,7 @@ deprecated class LegacyConfig extends DataFlow::Configuration { override predicate isSink(DataFlow::Node sink) { TestConfig::isSink(sink) } override predicate isBarrierGuard(DataFlow::BarrierGuardNode guard) { - guard instanceof SimpleBarrierGuardNode + guard instanceof SimpleBarrierGuardNodeLegacy } } diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.ql b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.ql index 8617c8bcf51..b37d902b12e 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.ql +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.ql @@ -22,8 +22,9 @@ class BasicBarrierGuard extends DataFlow::CallNode { } } -deprecated class BasicBarrierGuardLegacy extends DataFlow::BarrierGuardNode, BasicBarrierGuard { - override predicate blocks(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } +deprecated class BasicBarrierGuardLegacy extends DataFlow::BarrierGuardNode instanceof BasicBarrierGuard +{ + override predicate blocks(boolean outcome, Expr e) { super.blocksExpr(outcome, e) } } deprecated class LegacyConfig extends DataFlow::Configuration { From f8ff504f5ca771a483a68c4c0af2faac884d63c2 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Dec 2024 11:27:23 +0100 Subject: [PATCH 421/514] JS: Add ClientSideUrlRedirect test consistency Update Consistency.ql again --- .../CWE-601/ClientSideUrlRedirect/Consistency.ql | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/Consistency.ql diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/Consistency.ql new file mode 100644 index 00000000000..860e607576d --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/Consistency.ql @@ -0,0 +1,9 @@ +import javascript +import semmle.javascript.security.dataflow.ClientSideUrlRedirectQuery +import testUtilities.ConsistencyChecking + +deprecated class ClientSideUrlRedirectConsistency extends ConsistencyConfiguration { + ClientSideUrlRedirectConsistency() { this = "ClientSideUrlRedirectConsistency" } + + override DataFlow::Node getAnAlert() { ClientSideUrlRedirectFlow::flowTo(result) } +} From 712c69ebc8e04c7aa8122cc3e1a88c8626d6ad19 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Dec 2024 13:08:28 +0100 Subject: [PATCH 422/514] JS: Fixup the test expectations --- .../ClientSideUrlRedirect.expected | 62 +++++++++++-------- .../Consistency.expected | 0 .../CWE-601/ClientSideUrlRedirect/tst12.js | 3 +- .../CWE-601/ClientSideUrlRedirect/tst13.js | 44 ++++++------- .../CWE-601/ClientSideUrlRedirect/typed.ts | 28 ++++----- 5 files changed, 72 insertions(+), 65 deletions(-) create mode 100644 javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/Consistency.expected diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected index e1194cd8154..9c756a5a7e6 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected @@ -41,16 +41,16 @@ nodes | tst10.js:11:27:11:50 | documen ... .search | semmle.label | documen ... .search | | tst10.js:14:17:14:56 | 'https: ... .search | semmle.label | 'https: ... .search | | tst10.js:14:33:14:56 | documen ... .search | semmle.label | documen ... .search | -| tst12.js:3:9:3:50 | urlParts | semmle.label | urlParts | -| tst12.js:3:9:3:50 | urlParts [ArrayElement] | semmle.label | urlParts [ArrayElement] | -| tst12.js:3:20:3:39 | window.location.hash | semmle.label | window.location.hash | -| tst12.js:3:20:3:50 | window. ... it('?') | semmle.label | window. ... it('?') | -| tst12.js:3:20:3:50 | window. ... it('?') [ArrayElement] | semmle.label | window. ... it('?') [ArrayElement] | -| tst12.js:4:9:4:45 | loc | semmle.label | loc | -| tst12.js:4:15:4:22 | urlParts | semmle.label | urlParts | -| tst12.js:4:15:4:22 | urlParts [ArrayElement] | semmle.label | urlParts [ArrayElement] | -| tst12.js:4:15:4:25 | urlParts[0] | semmle.label | urlParts[0] | -| tst12.js:5:23:5:25 | loc | semmle.label | loc | +| tst12.js:2:9:2:50 | urlParts | semmle.label | urlParts | +| tst12.js:2:9:2:50 | urlParts [ArrayElement] | semmle.label | urlParts [ArrayElement] | +| tst12.js:2:20:2:39 | window.location.hash | semmle.label | window.location.hash | +| tst12.js:2:20:2:50 | window. ... it('?') | semmle.label | window. ... it('?') | +| tst12.js:2:20:2:50 | window. ... it('?') [ArrayElement] | semmle.label | window. ... it('?') [ArrayElement] | +| tst12.js:3:9:3:45 | loc | semmle.label | loc | +| tst12.js:3:15:3:22 | urlParts | semmle.label | urlParts | +| tst12.js:3:15:3:22 | urlParts [ArrayElement] | semmle.label | urlParts [ArrayElement] | +| tst12.js:3:15:3:25 | urlParts[0] | semmle.label | urlParts[0] | +| tst12.js:4:23:4:25 | loc | semmle.label | loc | | tst13.js:2:9:2:52 | payload | semmle.label | payload | | tst13.js:2:19:2:42 | documen ... .search | semmle.label | documen ... .search | | tst13.js:2:19:2:52 | documen ... bstr(1) | semmle.label | documen ... bstr(1) | @@ -109,16 +109,20 @@ nodes | tst.js:26:22:26:79 | new Reg ... n.href) | semmle.label | new Reg ... n.href) | | tst.js:26:22:26:82 | new Reg ... ref)[1] | semmle.label | new Reg ... ref)[1] | | tst.js:26:62:26:78 | win.location.href | semmle.label | win.location.href | -| typed.ts:4:13:4:36 | params | semmle.label | params | +| typed.ts:4:13:4:49 | params | semmle.label | params | | typed.ts:4:22:4:36 | location.search | semmle.label | location.search | +| typed.ts:4:22:4:49 | locatio ... ring(1) | semmle.label | locatio ... ring(1) | | typed.ts:5:25:5:30 | params | semmle.label | params | | typed.ts:7:24:7:34 | redirectUri | semmle.label | redirectUri | | typed.ts:8:33:8:43 | redirectUri | semmle.label | redirectUri | | typed.ts:25:25:25:34 | loc.search | semmle.label | loc.search | +| typed.ts:25:25:25:47 | loc.sea ... ring(1) | semmle.label | loc.sea ... ring(1) | | typed.ts:28:24:28:34 | redirectUri | semmle.label | redirectUri | | typed.ts:29:33:29:43 | redirectUri | semmle.label | redirectUri | | typed.ts:47:25:47:34 | loc.search | semmle.label | loc.search | +| typed.ts:47:25:47:47 | loc.sea ... ring(1) | semmle.label | loc.sea ... ring(1) | | typed.ts:48:26:48:36 | loc2.search | semmle.label | loc2.search | +| typed.ts:48:26:48:49 | loc2.se ... ring(1) | semmle.label | loc2.se ... ring(1) | | typed.ts:51:24:51:34 | redirectUri | semmle.label | redirectUri | | typed.ts:52:33:52:43 | redirectUri | semmle.label | redirectUri | | typed.ts:55:25:55:35 | redirectUri | semmle.label | redirectUri | @@ -149,16 +153,16 @@ edges | tst10.js:8:24:8:47 | documen ... .search | tst10.js:8:17:8:47 | '//' + ... .search | provenance | | | tst10.js:11:27:11:50 | documen ... .search | tst10.js:11:17:11:50 | '//foo' ... .search | provenance | | | tst10.js:14:33:14:56 | documen ... .search | tst10.js:14:17:14:56 | 'https: ... .search | provenance | | -| tst12.js:3:9:3:50 | urlParts | tst12.js:4:15:4:22 | urlParts | provenance | | -| tst12.js:3:9:3:50 | urlParts [ArrayElement] | tst12.js:4:15:4:22 | urlParts [ArrayElement] | provenance | | -| tst12.js:3:20:3:39 | window.location.hash | tst12.js:3:20:3:50 | window. ... it('?') | provenance | | -| tst12.js:3:20:3:39 | window.location.hash | tst12.js:3:20:3:50 | window. ... it('?') [ArrayElement] | provenance | | -| tst12.js:3:20:3:50 | window. ... it('?') | tst12.js:3:9:3:50 | urlParts | provenance | | -| tst12.js:3:20:3:50 | window. ... it('?') [ArrayElement] | tst12.js:3:9:3:50 | urlParts [ArrayElement] | provenance | | -| tst12.js:4:9:4:45 | loc | tst12.js:5:23:5:25 | loc | provenance | | -| tst12.js:4:15:4:22 | urlParts | tst12.js:4:9:4:45 | loc | provenance | | -| tst12.js:4:15:4:22 | urlParts [ArrayElement] | tst12.js:4:15:4:25 | urlParts[0] | provenance | | -| tst12.js:4:15:4:25 | urlParts[0] | tst12.js:4:9:4:45 | loc | provenance | | +| tst12.js:2:9:2:50 | urlParts | tst12.js:3:15:3:22 | urlParts | provenance | | +| tst12.js:2:9:2:50 | urlParts [ArrayElement] | tst12.js:3:15:3:22 | urlParts [ArrayElement] | provenance | | +| tst12.js:2:20:2:39 | window.location.hash | tst12.js:2:20:2:50 | window. ... it('?') | provenance | | +| tst12.js:2:20:2:39 | window.location.hash | tst12.js:2:20:2:50 | window. ... it('?') [ArrayElement] | provenance | | +| tst12.js:2:20:2:50 | window. ... it('?') | tst12.js:2:9:2:50 | urlParts | provenance | | +| tst12.js:2:20:2:50 | window. ... it('?') [ArrayElement] | tst12.js:2:9:2:50 | urlParts [ArrayElement] | provenance | | +| tst12.js:3:9:3:45 | loc | tst12.js:4:23:4:25 | loc | provenance | | +| tst12.js:3:15:3:22 | urlParts | tst12.js:3:9:3:45 | loc | provenance | | +| tst12.js:3:15:3:22 | urlParts [ArrayElement] | tst12.js:3:15:3:25 | urlParts[0] | provenance | | +| tst12.js:3:15:3:25 | urlParts[0] | tst12.js:3:9:3:45 | loc | provenance | | | tst13.js:2:9:2:52 | payload | tst13.js:4:15:4:21 | payload | provenance | | | tst13.js:2:9:2:52 | payload | tst13.js:8:21:8:27 | payload | provenance | | | tst13.js:2:9:2:52 | payload | tst13.js:12:14:12:20 | payload | provenance | | @@ -203,14 +207,18 @@ edges | tst.js:22:34:22:55 | documen ... on.href | tst.js:22:20:22:56 | indirec ... n.href) | provenance | Config | | tst.js:26:22:26:79 | new Reg ... n.href) | tst.js:26:22:26:82 | new Reg ... ref)[1] | provenance | | | tst.js:26:62:26:78 | win.location.href | tst.js:26:22:26:79 | new Reg ... n.href) | provenance | Config | -| typed.ts:4:13:4:36 | params | typed.ts:5:25:5:30 | params | provenance | | -| typed.ts:4:22:4:36 | location.search | typed.ts:4:13:4:36 | params | provenance | | +| typed.ts:4:13:4:49 | params | typed.ts:5:25:5:30 | params | provenance | | +| typed.ts:4:22:4:36 | location.search | typed.ts:4:22:4:49 | locatio ... ring(1) | provenance | | +| typed.ts:4:22:4:49 | locatio ... ring(1) | typed.ts:4:13:4:49 | params | provenance | | | typed.ts:5:25:5:30 | params | typed.ts:7:24:7:34 | redirectUri | provenance | | | typed.ts:7:24:7:34 | redirectUri | typed.ts:8:33:8:43 | redirectUri | provenance | | -| typed.ts:25:25:25:34 | loc.search | typed.ts:28:24:28:34 | redirectUri | provenance | | +| typed.ts:25:25:25:34 | loc.search | typed.ts:25:25:25:47 | loc.sea ... ring(1) | provenance | | +| typed.ts:25:25:25:47 | loc.sea ... ring(1) | typed.ts:28:24:28:34 | redirectUri | provenance | | | typed.ts:28:24:28:34 | redirectUri | typed.ts:29:33:29:43 | redirectUri | provenance | | -| typed.ts:47:25:47:34 | loc.search | typed.ts:51:24:51:34 | redirectUri | provenance | | -| typed.ts:48:26:48:36 | loc2.search | typed.ts:55:25:55:35 | redirectUri | provenance | | +| typed.ts:47:25:47:34 | loc.search | typed.ts:47:25:47:47 | loc.sea ... ring(1) | provenance | | +| typed.ts:47:25:47:47 | loc.sea ... ring(1) | typed.ts:51:24:51:34 | redirectUri | provenance | | +| typed.ts:48:26:48:36 | loc2.search | typed.ts:48:26:48:49 | loc2.se ... ring(1) | provenance | | +| typed.ts:48:26:48:49 | loc2.se ... ring(1) | typed.ts:55:25:55:35 | redirectUri | provenance | | | typed.ts:51:24:51:34 | redirectUri | typed.ts:52:33:52:43 | redirectUri | provenance | | | typed.ts:55:25:55:35 | redirectUri | typed.ts:56:33:56:43 | redirectUri | provenance | | subpaths @@ -240,7 +248,7 @@ subpaths | tst10.js:8:17:8:47 | '//' + ... .search | tst10.js:8:24:8:47 | documen ... .search | tst10.js:8:17:8:47 | '//' + ... .search | Untrusted URL redirection depends on a $@. | tst10.js:8:24:8:47 | documen ... .search | user-provided value | | tst10.js:11:17:11:50 | '//foo' ... .search | tst10.js:11:27:11:50 | documen ... .search | tst10.js:11:17:11:50 | '//foo' ... .search | Untrusted URL redirection depends on a $@. | tst10.js:11:27:11:50 | documen ... .search | user-provided value | | tst10.js:14:17:14:56 | 'https: ... .search | tst10.js:14:33:14:56 | documen ... .search | tst10.js:14:17:14:56 | 'https: ... .search | Untrusted URL redirection depends on a $@. | tst10.js:14:33:14:56 | documen ... .search | user-provided value | -| tst12.js:5:23:5:25 | loc | tst12.js:3:20:3:39 | window.location.hash | tst12.js:5:23:5:25 | loc | Untrusted URL redirection depends on a $@. | tst12.js:3:20:3:39 | window.location.hash | user-provided value | +| tst12.js:4:23:4:25 | loc | tst12.js:2:20:2:39 | window.location.hash | tst12.js:4:23:4:25 | loc | Untrusted URL redirection depends on a $@. | tst12.js:2:20:2:39 | window.location.hash | user-provided value | | tst13.js:4:15:4:21 | payload | tst13.js:2:19:2:42 | documen ... .search | tst13.js:4:15:4:21 | payload | Untrusted URL redirection depends on a $@. | tst13.js:2:19:2:42 | documen ... .search | user-provided value | | tst13.js:8:21:8:27 | payload | tst13.js:2:19:2:42 | documen ... .search | tst13.js:8:21:8:27 | payload | Untrusted URL redirection depends on a $@. | tst13.js:2:19:2:42 | documen ... .search | user-provided value | | tst13.js:12:14:12:20 | payload | tst13.js:2:19:2:42 | documen ... .search | tst13.js:12:14:12:20 | payload | Untrusted URL redirection depends on a $@. | tst13.js:2:19:2:42 | documen ... .search | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/Consistency.expected b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/Consistency.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst12.js b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst12.js index 74b82808b34..a72efac94d3 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst12.js +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst12.js @@ -1,6 +1,5 @@ -// NOT OK function foo() { var urlParts = window.location.hash.split('?'); var loc = urlParts[0] + "?" + boxes.value; - window.location = loc + window.location = loc; // OK [INCONSISTENCY] - always starts with '#' } diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst13.js b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst13.js index 991e7db369f..8c55257cb56 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst13.js +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst13.js @@ -1,48 +1,48 @@ function foo() { var payload = document.location.search.substr(1); var el = document.createElement("a"); - el.href = payload; - document.body.appendChild(el); // NOT OK + el.href = payload; // NOT OK + document.body.appendChild(el); var el = document.createElement("button"); - el.formaction = payload; - document.body.appendChild(el); // NOT OK + el.formaction = payload; // NOT OK + document.body.appendChild(el); var el = document.createElement("embed"); - el.src = payload; - document.body.appendChild(el); // NOT OK + el.src = payload; // NOT OK + document.body.appendChild(el); var el = document.createElement("form"); - el.action = payload; - document.body.appendChild(el); // NOT OK + el.action = payload; // NOT OK + document.body.appendChild(el); var el = document.createElement("frame"); - el.src = payload; - document.body.appendChild(el); // NOT OK + el.src = payload; // NOT OK + document.body.appendChild(el); var el = document.createElement("iframe"); - el.src = payload; - document.body.appendChild(el); // NOT OK + el.src = payload; // NOT OK + document.body.appendChild(el); var el = document.createElement("input"); - el.formaction = payload; - document.body.appendChild(el); // NOT OK + el.formaction = payload; // NOT OK + document.body.appendChild(el); var el = document.createElement("isindex"); - el.action = payload; - document.body.appendChild(el); // NOT OK + el.action = payload; // NOT OK + document.body.appendChild(el); var el = document.createElement("isindex"); - el.formaction = payload; - document.body.appendChild(el); // NOT OK + el.formaction = payload; // NOT OK + document.body.appendChild(el); var el = document.createElement("object"); - el.data = payload; - document.body.appendChild(el); // NOT OK + el.data = payload; // NOT OK + document.body.appendChild(el); var el = document.createElement("script"); - el.src = payload; - document.body.appendChild(el); // NOT OK + el.src = payload; // NOT OK + document.body.appendChild(el); } (function () { diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/typed.ts b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/typed.ts index bd4af289dca..143b11c1e8b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/typed.ts +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/typed.ts @@ -1,11 +1,11 @@ export class MyComponent { componentDidMount() { const { location }: { location: Location } = (this as any).props; - var params = location.search; + var params = location.search.substring(1); this.doRedirect(params); } private doRedirect(redirectUri: string) { - window.location.replace(redirectUri); + window.location.replace(redirectUri); // NOT OK } } @@ -17,16 +17,16 @@ export class MyTrackingComponent { loc: location }; var secondLoc = container.loc; // type-tracking step 1 - not the source - - this.myIndirectRedirect(secondLoc); + + this.myIndirectRedirect(secondLoc); } private myIndirectRedirect(loc) { // type-tracking step 2 - also not the source - this.doRedirect(loc.search); + this.doRedirect(loc.search.substring(1)); } private doRedirect(redirectUri: string) { - window.location.replace(redirectUri); + window.location.replace(redirectUri); // NOT OK } } @@ -38,21 +38,21 @@ export class WeirdTracking { loc: location }; var secondLoc = container.loc; // type-tracking step 1 - not the source - - this.myIndirectRedirect(secondLoc); + + this.myIndirectRedirect(secondLoc); } private myIndirectRedirect(loc) { // type-tracking step 2 - also not the source - const loc2 : Location = (loc as any).componentDidMount; - this.doRedirect(loc.search); - this.doRedirect2(loc2.search); + const loc2: Location = (loc as any).componentDidMount; + this.doRedirect(loc.search.substring(1)); + this.doRedirect2(loc2.search.substring(1)); } private doRedirect(redirectUri: string) { - window.location.replace(redirectUri); // NOT OK - and correctly flagged + window.location.replace(redirectUri); // NOT OK } private doRedirect2(redirectUri: string) { - window.location.replace(redirectUri); // NOT OK - and correctly flagged + window.location.replace(redirectUri); // NOT OK } -} \ No newline at end of file +} From e2b2d1c9ab528bbbefbcebf0969f7cdec2190297 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Dec 2024 13:53:56 +0100 Subject: [PATCH 423/514] JS: Allow arbitrary comments in ConsistencyChecking Because line comments cannot be used inside JSX elements --- javascript/ql/test/testUtilities/ConsistencyChecking.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/test/testUtilities/ConsistencyChecking.qll b/javascript/ql/test/testUtilities/ConsistencyChecking.qll index 407caf908b0..f614a93500d 100644 --- a/javascript/ql/test/testUtilities/ConsistencyChecking.qll +++ b/javascript/ql/test/testUtilities/ConsistencyChecking.qll @@ -46,10 +46,10 @@ deprecated final private class Conf extends string { } /** - * A line-comment that asserts whether a result exists at that line or not. + * A comment that asserts whether a result exists at that line or not. * Can optionally include `[INCONSISTENCY]` to indicate that a consistency issue is expected at the location */ -private class AssertionComment extends LineComment { +private class AssertionComment extends Comment { boolean shouldHaveAlert; AssertionComment() { From ef833de60ea63e4dafb69e1d0429dff49304182e Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 4 Dec 2024 13:56:56 +0100 Subject: [PATCH 424/514] JS: Replace DocumentUrl with TaintedUrlSuffix --- .../ClientSideUrlRedirectCustomizations.qll | 15 ++++++++------- .../dataflow/ClientSideUrlRedirectQuery.qll | 10 ++++------ .../CWE-601/ClientSideUrlRedirect/react.js | 19 +++++++++++-------- .../CWE-601/ClientSideUrlRedirect/tst10.js | 10 +++++----- .../CWE-601/ClientSideUrlRedirect/tst12.js | 2 +- .../CWE-601/ClientSideUrlRedirect/tst15.js | 16 +++++++++++++--- .../CWE-601/ClientSideUrlRedirect/tst7.js | 4 ++-- 7 files changed, 44 insertions(+), 32 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll index 7d31e97a675..f3a4218659f 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll @@ -5,6 +5,7 @@ */ import javascript +private import semmle.javascript.security.TaintedUrlSuffix module ClientSideUrlRedirect { /** @@ -31,12 +32,12 @@ module ClientSideUrlRedirect { abstract class Sanitizer extends DataFlow::Node { } /** + * DEPRECATED. Replaced by functionality from the `TaintedUrlSuffix` library. + * * A flow label for values that represent the URL of the current document, and * hence are only partially user-controlled. */ - abstract class DocumentUrl extends DataFlow::FlowLabel { - DocumentUrl() { this = "document.url" } // TODO: replace with TaintedUrlSuffix - } + deprecated class DocumentUrl = TaintedUrlSuffix::TaintedUrlSuffixLabel; /** * DEPRECATED: Use `ActiveThreatModelSource` from Concepts instead! @@ -50,8 +51,8 @@ module ClientSideUrlRedirect { ActiveThreatModelSourceAsSource() { not this.(ClientSideRemoteFlowSource).getKind().isPath() } override DataFlow::FlowLabel getAFlowLabel() { - if this.(ClientSideRemoteFlowSource).getKind().isUrl() - then result instanceof DocumentUrl + if this = TaintedUrlSuffix::source() + then result = TaintedUrlSuffix::label() else result.isTaint() } } @@ -60,7 +61,7 @@ module ClientSideUrlRedirect { * Holds if `node` extracts a part of a URL that does not contain the suffix. */ pragma[inline] - predicate isPrefixExtraction(DataFlow::MethodCallNode node) { + deprecated predicate isPrefixExtraction(DataFlow::MethodCallNode node) { // Block flow through prefix-extraction `substring(0, ...)` and `split("#")[0]` node.getMethodName() = [StringOps::substringMethodName(), "split"] and not untrustedUrlSubstring(_, node) @@ -70,7 +71,7 @@ module ClientSideUrlRedirect { * Holds if `substring` refers to a substring of `base` which is considered untrusted * when `base` is the current URL. */ - predicate untrustedUrlSubstring(DataFlow::Node base, DataFlow::Node substring) { + deprecated predicate untrustedUrlSubstring(DataFlow::Node base, DataFlow::Node substring) { exists(DataFlow::MethodCallNode mcn, string methodName | mcn = substring and mcn.calls(base, methodName) | diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectQuery.qll index 33962696484..f703fd6a81d 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectQuery.qll @@ -10,9 +10,10 @@ import javascript import UrlConcatenation import ClientSideUrlRedirectCustomizations::ClientSideUrlRedirect +import semmle.javascript.security.TaintedUrlSuffix // Materialize flow labels -private class ConcreteDocumentUrl extends DocumentUrl { +deprecated private class ConcreteDocumentUrl extends DocumentUrl { ConcreteDocumentUrl() { this = this } } @@ -35,8 +36,7 @@ module ClientSideUrlRedirectConfig implements DataFlow::StateConfigSig { } predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel state) { - isPrefixExtraction(node) and - state instanceof DocumentUrl + TaintedUrlSuffix::isBarrier(node, state) } predicate isBarrierOut(DataFlow::Node node) { hostnameSanitizingPrefixEdge(node, _) } @@ -47,9 +47,7 @@ module ClientSideUrlRedirectConfig implements DataFlow::StateConfigSig { DataFlow::Node node1, DataFlow::FlowLabel state1, DataFlow::Node node2, DataFlow::FlowLabel state2 ) { - untrustedUrlSubstring(node1, node2) and - state1 instanceof DocumentUrl and - state2.isTaint() + TaintedUrlSuffix::step(node1, node2, state1, state2) or exists(HtmlSanitizerCall call | node1 = call.getInput() and diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/react.js b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/react.js index aebb65defc8..6206ec73305 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/react.js +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/react.js @@ -1,13 +1,13 @@ import React from "react"; import {Helmet} from "react-helmet"; - + class Application extends React.Component { render () { return (
    My unsafe app -