diff --git a/change-notes/1.19/analysis-javascript.md b/change-notes/1.19/analysis-javascript.md
index d60034662f2b..06c64b76cbac 100644
--- a/change-notes/1.19/analysis-javascript.md
+++ b/change-notes/1.19/analysis-javascript.md
@@ -13,6 +13,8 @@
* Type inference for function calls has been improved. This may give additional results for queries that rely on type inference.
+* Where applicable, path explanations have been added to the security queries.
+
## New queries
| **Query** | **Tags** | **Purpose** |
diff --git a/javascript/ql/src/Security/CWE-022/TaintedPath.ql b/javascript/ql/src/Security/CWE-022/TaintedPath.ql
index 17d0938de3b4..8a3e70752168 100644
--- a/javascript/ql/src/Security/CWE-022/TaintedPath.ql
+++ b/javascript/ql/src/Security/CWE-022/TaintedPath.ql
@@ -2,7 +2,7 @@
* @name Uncontrolled data used in path expression
* @description Accessing paths influenced by users can allow an attacker to access
* unexpected resources.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @precision high
* @id js/path-injection
@@ -15,9 +15,10 @@
*/
import javascript
-import semmle.javascript.security.dataflow.RemoteFlowSources
import semmle.javascript.security.dataflow.TaintedPath::TaintedPath
+import DataFlow::PathGraph
-from Configuration cfg, DataFlow::Node source, DataFlow::Node sink
-where cfg.hasFlow(source, sink)
-select sink, "This path depends on $@.", source, "a user-provided value"
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "This path depends on $@.",
+ source.getNode(), "a user-provided value"
diff --git a/javascript/ql/src/Security/CWE-078/CommandInjection.ql b/javascript/ql/src/Security/CWE-078/CommandInjection.ql
index 36158c3d0b9b..317c407003cd 100644
--- a/javascript/ql/src/Security/CWE-078/CommandInjection.ql
+++ b/javascript/ql/src/Security/CWE-078/CommandInjection.ql
@@ -2,7 +2,7 @@
* @name Uncontrolled command line
* @description Using externally controlled strings in a command line may allow a malicious
* user to change the meaning of the command.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @precision high
* @id js/command-line-injection
@@ -14,11 +14,13 @@
import javascript
import semmle.javascript.security.dataflow.CommandInjection::CommandInjection
+import DataFlow::PathGraph
-from Configuration cfg, DataFlow::Node source, DataFlow::Node sink, DataFlow::Node highlight
-where cfg.hasFlow(source, sink) and
- if cfg.isSinkWithHighlight(sink, _) then
- cfg.isSinkWithHighlight(sink, highlight)
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node highlight
+where cfg.hasPathFlow(source, sink) and
+ if cfg.isSinkWithHighlight(sink.getNode(), _) then
+ cfg.isSinkWithHighlight(sink.getNode(), highlight)
else
- highlight = sink
-select highlight, "This command depends on $@.", source, "a user-provided value"
+ highlight = sink.getNode()
+select highlight, source, sink, "This command depends on $@.",
+ source.getNode(), "a user-provided value"
diff --git a/javascript/ql/src/Security/CWE-079/ReflectedXss.ql b/javascript/ql/src/Security/CWE-079/ReflectedXss.ql
index 3a4109512adc..5b308800209f 100644
--- a/javascript/ql/src/Security/CWE-079/ReflectedXss.ql
+++ b/javascript/ql/src/Security/CWE-079/ReflectedXss.ql
@@ -2,7 +2,7 @@
* @name Reflected cross-site scripting
* @description Writing user input directly to an HTTP response allows for
* a cross-site scripting vulnerability.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @precision high
* @id js/reflected-xss
@@ -13,8 +13,9 @@
import javascript
import semmle.javascript.security.dataflow.ReflectedXss::ReflectedXss
+import DataFlow::PathGraph
-from Configuration xss, DataFlow::Node source, DataFlow::Node sink
-where xss.hasFlow(source, sink)
-select sink, "Cross-site scripting vulnerability due to $@.",
- source, "user-provided value"
\ No newline at end of file
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "Cross-site scripting vulnerability due to $@.",
+ source.getNode(), "user-provided value"
diff --git a/javascript/ql/src/Security/CWE-079/StoredXss.ql b/javascript/ql/src/Security/CWE-079/StoredXss.ql
index 429bccdf6601..f1e386c291b9 100644
--- a/javascript/ql/src/Security/CWE-079/StoredXss.ql
+++ b/javascript/ql/src/Security/CWE-079/StoredXss.ql
@@ -2,7 +2,7 @@
* @name Stored cross-site scripting
* @description Using uncontrolled stored values in HTML allows for
* a stored cross-site scripting vulnerability.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @precision high
* @id js/stored-xss
@@ -13,8 +13,9 @@
import javascript
import semmle.javascript.security.dataflow.StoredXss::StoredXss
+import DataFlow::PathGraph
-from Configuration xss, DataFlow::Node source, DataFlow::Node sink
-where xss.hasFlow(source, sink)
-select sink, "Stored cross-site scripting vulnerability due to $@.",
- source, "stored value"
\ No newline at end of file
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "Stored cross-site scripting vulnerability due to $@.",
+ source.getNode(), "stored value"
diff --git a/javascript/ql/src/Security/CWE-079/Xss.ql b/javascript/ql/src/Security/CWE-079/Xss.ql
index 1971ac663553..b6ba13918cb6 100644
--- a/javascript/ql/src/Security/CWE-079/Xss.ql
+++ b/javascript/ql/src/Security/CWE-079/Xss.ql
@@ -2,7 +2,7 @@
* @name Client side cross-site scripting
* @description Writing user input directly to the DOM allows for
* a cross-site scripting vulnerability.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @precision high
* @id js/xss
@@ -13,8 +13,9 @@
import javascript
import semmle.javascript.security.dataflow.DomBasedXss::DomBasedXss
+import DataFlow::PathGraph
-from Configuration xss, DataFlow::Node source, Sink sink
-where xss.hasFlow(source, sink)
-select sink, sink.getVulnerabilityKind() + " vulnerability due to $@.",
- source, "user-provided value"
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, sink.getNode().(Sink).getVulnerabilityKind() + " vulnerability due to $@.",
+ source.getNode(), "user-provided value"
diff --git a/javascript/ql/src/Security/CWE-089/SqlInjection.ql b/javascript/ql/src/Security/CWE-089/SqlInjection.ql
index 38b0c304631d..6ae6d0927233 100644
--- a/javascript/ql/src/Security/CWE-089/SqlInjection.ql
+++ b/javascript/ql/src/Security/CWE-089/SqlInjection.ql
@@ -2,7 +2,7 @@
* @name Database query built from user-controlled sources
* @description Building a database query from user-controlled sources is vulnerable to insertion of
* malicious code by the user.
-* @kind problem
+* @kind path-problem
* @problem.severity error
* @precision high
* @id js/sql-injection
@@ -13,16 +13,11 @@
import javascript
import semmle.javascript.security.dataflow.SqlInjection
import semmle.javascript.security.dataflow.NosqlInjection
+import DataFlow::PathGraph
-predicate sqlInjection(DataFlow::Node source, DataFlow::Node sink) {
- any(SqlInjection::Configuration cfg).hasFlow(source, sink)
-}
-
-predicate nosqlInjection(DataFlow::Node source, DataFlow::Node sink) {
- any(NosqlInjection::Configuration cfg).hasFlow(source, sink)
-}
-
-from DataFlow::Node source, DataFlow::Node sink
-where sqlInjection(source, sink) or
- nosqlInjection(source, sink)
-select sink, "This query depends on $@.", source, "a user-provided value"
+from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where (cfg instanceof SqlInjection::Configuration or
+ cfg instanceof NosqlInjection::Configuration) and
+ cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "This query depends on $@.",
+ source.getNode(), "a user-provided value"
diff --git a/javascript/ql/src/Security/CWE-094/CodeInjection.ql b/javascript/ql/src/Security/CWE-094/CodeInjection.ql
index 478b8b9efcc2..506e206bc0aa 100644
--- a/javascript/ql/src/Security/CWE-094/CodeInjection.ql
+++ b/javascript/ql/src/Security/CWE-094/CodeInjection.ql
@@ -2,7 +2,7 @@
* @name Code injection
* @description Interpreting unsanitized user input as code allows a malicious user arbitrary
* code execution.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @precision high
* @id js/code-injection
@@ -14,7 +14,9 @@
import javascript
import semmle.javascript.security.dataflow.CodeInjection::CodeInjection
+import DataFlow::PathGraph
-from Configuration codeInjection, DataFlow::Node source, DataFlow::Node sink
-where codeInjection.hasFlow(source, sink)
-select sink, "$@ flows to here and is interpreted as code.", source, "User-provided value"
\ No newline at end of file
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "$@ flows to here and is interpreted as code.",
+ source.getNode(), "User-provided value"
diff --git a/javascript/ql/src/Security/CWE-134/TaintedFormatString.ql b/javascript/ql/src/Security/CWE-134/TaintedFormatString.ql
index 6845cd5aff87..78ab720d2359 100644
--- a/javascript/ql/src/Security/CWE-134/TaintedFormatString.ql
+++ b/javascript/ql/src/Security/CWE-134/TaintedFormatString.ql
@@ -1,7 +1,7 @@
/**
* @name Use of externally-controlled format string
* @description Using external input in format strings can lead to garbled output.
- * @kind problem
+ * @kind path-problem
* @problem.severity warning
* @precision high
* @id js/tainted-format-string
@@ -11,7 +11,9 @@
import javascript
import semmle.javascript.security.dataflow.TaintedFormatString::TaintedFormatString
+import DataFlow::PathGraph
-from Configuration c, DataFlow::Node source, DataFlow::Node sink
-where c.hasFlow(source, sink)
-select sink, "$@ flows here and is used in a format string.", source, "User-provided value"
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "$@ flows here and is used in a format string.",
+ source.getNode(), "User-provided value"
diff --git a/javascript/ql/src/Security/CWE-200/FileAccessToHttp.ql b/javascript/ql/src/Security/CWE-200/FileAccessToHttp.ql
index 10b40d686a86..22b254a8bd6a 100644
--- a/javascript/ql/src/Security/CWE-200/FileAccessToHttp.ql
+++ b/javascript/ql/src/Security/CWE-200/FileAccessToHttp.ql
@@ -1,7 +1,7 @@
/**
* @name File data in outbound network request
* @description Directly sending file data in an outbound network request can indicate unauthorized information disclosure.
- * @kind problem
+ * @kind path-problem
* @problem.severity warning
* @id js/file-access-to-http
* @tags security
@@ -9,8 +9,10 @@
*/
import javascript
-import semmle.javascript.security.dataflow.FileAccessToHttp
+import semmle.javascript.security.dataflow.FileAccessToHttp::FileAccessToHttp
+import DataFlow::PathGraph
-from FileAccessToHttp::Configuration config, DataFlow::Node src, DataFlow::Node sink
-where config.hasFlow (src, sink)
-select sink, "$@ flows directly to outbound network request", src, "File data"
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "$@ flows directly to outbound network request",
+ source.getNode(), "File data"
diff --git a/javascript/ql/src/Security/CWE-209/StackTraceExposure.ql b/javascript/ql/src/Security/CWE-209/StackTraceExposure.ql
index e86c090ef0cd..d67d9f643ab5 100644
--- a/javascript/ql/src/Security/CWE-209/StackTraceExposure.ql
+++ b/javascript/ql/src/Security/CWE-209/StackTraceExposure.ql
@@ -3,7 +3,7 @@
* @description Propagating stack trace information to an external user can
* unintentionally reveal implementation details that are useful
* to an attacker for developing a subsequent exploit.
- * @kind problem
+ * @kind path-problem
* @problem.severity warning
* @precision very-high
* @id js/stack-trace-exposure
@@ -13,8 +13,9 @@
import javascript
import semmle.javascript.security.dataflow.StackTraceExposure::StackTraceExposure
+import DataFlow::PathGraph
-from Configuration cfg, DataFlow::Node source, DataFlow::Node sink
-where cfg.hasFlow(source, sink)
-select sink, "Stack trace information from $@ may be exposed to an external user here.",
- source, "here"
\ No newline at end of file
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "Stack trace information from $@ may be exposed to an external user here.",
+ source.getNode(), "here"
diff --git a/javascript/ql/src/Security/CWE-312/CleartextLogging.ql b/javascript/ql/src/Security/CWE-312/CleartextLogging.ql
index 1ff15ff07b61..34a4f5414cfb 100644
--- a/javascript/ql/src/Security/CWE-312/CleartextLogging.ql
+++ b/javascript/ql/src/Security/CWE-312/CleartextLogging.ql
@@ -2,7 +2,7 @@
* @name Clear-text logging of sensitive information
* @description Logging sensitive information without encryption or hashing can
* expose it to an attacker.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @precision high
* @id js/clear-text-logging
@@ -14,6 +14,7 @@
import javascript
import semmle.javascript.security.dataflow.CleartextLogging::CleartextLogging
+import DataFlow::PathGraph
/**
* Holds if `tl` is used in a browser environment.
@@ -31,8 +32,9 @@ predicate inBrowserEnvironment(TopLevel tl) {
)
}
-from Configuration cfg, Source source, DataFlow::Node sink
-where cfg.hasFlow(source, sink) and
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink) and
// ignore logging to the browser console (even though it is not a good practice)
- not inBrowserEnvironment(sink.asExpr().getTopLevel())
-select sink, "Sensitive data returned by $@ is logged here.", source, source.describe()
+ not inBrowserEnvironment(sink.getNode().asExpr().getTopLevel())
+select sink.getNode(), source, sink, "Sensitive data returned by $@ is logged here.",
+ source.getNode(), source.getNode().(Source).describe()
diff --git a/javascript/ql/src/Security/CWE-312/CleartextStorage.ql b/javascript/ql/src/Security/CWE-312/CleartextStorage.ql
index b11abf5abfae..b87b266ed36d 100644
--- a/javascript/ql/src/Security/CWE-312/CleartextStorage.ql
+++ b/javascript/ql/src/Security/CWE-312/CleartextStorage.ql
@@ -2,7 +2,7 @@
* @name Clear text storage of sensitive information
* @description Sensitive information stored without encryption or hashing can expose it to an
* attacker.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @precision high
* @id js/clear-text-storage-of-sensitive-data
@@ -14,7 +14,9 @@
import javascript
import semmle.javascript.security.dataflow.CleartextStorage::CleartextStorage
+import DataFlow::PathGraph
-from Configuration cleartextStorage, Source source, DataFlow::Node sink
-where cleartextStorage.hasFlow(source, sink)
-select sink, "Sensitive data returned by $@ is stored here.", source, source.describe()
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "Sensitive data returned by $@ is stored here.",
+ source.getNode(), source.getNode().(Source).describe()
diff --git a/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql b/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql
index a597b6fc60f0..533c81090183 100644
--- a/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql
+++ b/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql
@@ -1,19 +1,21 @@
/**
* @name Use of a broken or weak cryptographic algorithm
* @description Using broken or weak cryptographic algorithms can compromise security.
- * @kind problem
+ * @kind path-problem
* @problem.severity warning
* @precision high
* @id js/weak-cryptographic-algorithm
* @tags security
* external/cwe/cwe-327
*/
+
import javascript
-import semmle.javascript.security.dataflow.RemoteFlowSources
import semmle.javascript.security.dataflow.BrokenCryptoAlgorithm::BrokenCryptoAlgorithm
import semmle.javascript.security.SensitiveActions
+import DataFlow::PathGraph
-from Configuration brokenCrypto, Source source, DataFlow::Node sink
-where brokenCrypto.hasFlow(source, sink) and
- not source.asExpr() instanceof CleartextPasswordExpr // flagged by js/insufficient-password-hash
-select sink, "Sensitive data from $@ is used in a broken or weak cryptographic algorithm.", source , source.describe()
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink) and
+ not source.getNode().asExpr() instanceof CleartextPasswordExpr // flagged by js/insufficient-password-hash
+select sink.getNode(), source, sink, "Sensitive data from $@ is used in a broken or weak cryptographic algorithm.",
+ source.getNode(), source.getNode().(Source).describe()
diff --git a/javascript/ql/src/Security/CWE-338/InsecureRandomness.ql b/javascript/ql/src/Security/CWE-338/InsecureRandomness.ql
index d2007a37636d..3b9df3020088 100644
--- a/javascript/ql/src/Security/CWE-338/InsecureRandomness.ql
+++ b/javascript/ql/src/Security/CWE-338/InsecureRandomness.ql
@@ -3,7 +3,7 @@
* @description Using a cryptographically weak pseudo-random number generator to generate a
* security-sensitive value may allow an attacker to predict what value will
* be generated.
- * @kind problem
+ * @kind path-problem
* @problem.severity warning
* @precision high
* @id js/insecure-randomness
@@ -12,7 +12,9 @@
*/
import javascript
import semmle.javascript.security.dataflow.InsecureRandomness::InsecureRandomness
+import DataFlow::PathGraph
-from Configuration cfg, DataFlow::Node source, DataFlow::Node sink
-where cfg.hasFlow(source, sink)
-select sink, "Cryptographically insecure $@ in a security context.", source, "random value"
\ No newline at end of file
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "Cryptographically insecure $@ in a security context.",
+ source.getNode(), "random value"
diff --git a/javascript/ql/src/Security/CWE-346/CorsMisconfigurationForCredentials.ql b/javascript/ql/src/Security/CWE-346/CorsMisconfigurationForCredentials.ql
index b43f6f700d28..44c478ea1c57 100644
--- a/javascript/ql/src/Security/CWE-346/CorsMisconfigurationForCredentials.ql
+++ b/javascript/ql/src/Security/CWE-346/CorsMisconfigurationForCredentials.ql
@@ -1,7 +1,7 @@
/**
* @name CORS misconfiguration for credentials transfer
* @description Misconfiguration of CORS HTTP headers allows for leaks of secret credentials.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @precision high
* @id js/cors-misconfiguration-for-credentials
@@ -13,9 +13,10 @@
import javascript
import semmle.javascript.security.dataflow.CorsMisconfigurationForCredentials::CorsMisconfigurationForCredentials
+import DataFlow::PathGraph
-from Configuration cfg, DataFlow::Node source, Sink sink
-where cfg.hasFlow(source, sink)
-select sink, "$@ leak vulnerability due to $@.",
- sink.getCredentialsHeader(), "Credential",
- source, "a misconfigured CORS header value"
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "$@ leak vulnerability due to $@.",
+ sink.getNode().(Sink).getCredentialsHeader(), "Credential",
+ source.getNode(), "a misconfigured CORS header value"
diff --git a/javascript/ql/src/Security/CWE-400/RemotePropertyInjection.ql b/javascript/ql/src/Security/CWE-400/RemotePropertyInjection.ql
index ae70f83ed87b..b9af490ffb67 100644
--- a/javascript/ql/src/Security/CWE-400/RemotePropertyInjection.ql
+++ b/javascript/ql/src/Security/CWE-400/RemotePropertyInjection.ql
@@ -3,7 +3,7 @@
* @description Allowing writes to arbitrary properties or calls to arbitrary
* methods of an object may lead to denial-of-service attacks.
*
- * @kind problem
+ * @kind path-problem
* @problem.severity warning
* @precision medium
* @id js/remote-property-injection
@@ -14,9 +14,9 @@
import javascript
import semmle.javascript.security.dataflow.RemotePropertyInjection::RemotePropertyInjection
+import DataFlow::PathGraph
-from Configuration c, DataFlow::Node source, Sink sink
-where c.hasFlow(source, sink)
-select sink, "A $@ is used as" + sink.getMessage(),
- source, "user-provided value"
-
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "A $@ is used as" + sink.getNode().(Sink).getMessage(),
+ source.getNode(), "user-provided value"
diff --git a/javascript/ql/src/Security/CWE-502/UnsafeDeserialization.ql b/javascript/ql/src/Security/CWE-502/UnsafeDeserialization.ql
index 20a1e7fb2c20..107868857bd7 100644
--- a/javascript/ql/src/Security/CWE-502/UnsafeDeserialization.ql
+++ b/javascript/ql/src/Security/CWE-502/UnsafeDeserialization.ql
@@ -2,7 +2,7 @@
* @name Deserialization of user-controlled data
* @description Deserializing user-controlled data may allow attackers to
* execute arbitrary code.
- * @kind problem
+ * @kind path-problem
* @problem.severity warning
* @precision high
* @id js/unsafe-deserialization
@@ -12,7 +12,9 @@
import javascript
import semmle.javascript.security.dataflow.UnsafeDeserialization::UnsafeDeserialization
+import DataFlow::PathGraph
-from Configuration cfg, DataFlow::Node source, DataFlow::Node sink
-where cfg.hasFlow(source, sink)
-select sink, "Unsafe deserialization of $@.", source, "user input"
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "Unsafe deserialization of $@.",
+ source.getNode(), "user input"
diff --git a/javascript/ql/src/Security/CWE-601/ClientSideUrlRedirect.ql b/javascript/ql/src/Security/CWE-601/ClientSideUrlRedirect.ql
index 98ee34f1ef88..8080784e8943 100644
--- a/javascript/ql/src/Security/CWE-601/ClientSideUrlRedirect.ql
+++ b/javascript/ql/src/Security/CWE-601/ClientSideUrlRedirect.ql
@@ -2,7 +2,7 @@
* @name Client-side URL redirect
* @description Client-side URL redirection based on unvalidated user input
* may cause redirection to malicious web sites.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @precision high
* @id js/client-side-unvalidated-url-redirection
@@ -14,7 +14,9 @@
import javascript
import semmle.javascript.security.dataflow.ClientSideUrlRedirect::ClientSideUrlRedirect
+import DataFlow::PathGraph
-from Configuration urlRedirect, DataFlow::Node source, DataFlow::Node sink
-where urlRedirect.hasFlow(source, sink)
-select sink, "Untrusted URL redirection due to $@.", source, "user-provided value"
\ No newline at end of file
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "Untrusted URL redirection due to $@.",
+ source.getNode(), "user-provided value"
diff --git a/javascript/ql/src/Security/CWE-601/ServerSideUrlRedirect.ql b/javascript/ql/src/Security/CWE-601/ServerSideUrlRedirect.ql
index 3c689345fd78..62d2671c8ea7 100644
--- a/javascript/ql/src/Security/CWE-601/ServerSideUrlRedirect.ql
+++ b/javascript/ql/src/Security/CWE-601/ServerSideUrlRedirect.ql
@@ -2,7 +2,7 @@
* @name Server-side URL redirect
* @description Server-side URL redirection based on unvalidated user input
* may cause redirection to malicious web sites.
- * @kind problem
+ * @kind path-problem
* @problem.severity warning
* @id js/server-side-unvalidated-url-redirection
* @tags security
@@ -12,7 +12,9 @@
import javascript
import semmle.javascript.security.dataflow.ServerSideUrlRedirect::ServerSideUrlRedirect
+import DataFlow::PathGraph
-from Configuration urlRedirect, DataFlow::Node source, DataFlow::Node sink
-where urlRedirect.hasFlow(source, sink)
-select sink, "Untrusted URL redirection due to $@.", source, "user-provided value"
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "Untrusted URL redirection due to $@.",
+ source.getNode(), "user-provided value"
diff --git a/javascript/ql/src/Security/CWE-611/Xxe.ql b/javascript/ql/src/Security/CWE-611/Xxe.ql
index 037e6af3dda1..914f1e4a7268 100644
--- a/javascript/ql/src/Security/CWE-611/Xxe.ql
+++ b/javascript/ql/src/Security/CWE-611/Xxe.ql
@@ -2,7 +2,7 @@
* @name XML external entity expansion
* @description Parsing user input as an XML document with external
* entity expansion is vulnerable to XXE attacks.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @precision high
* @id js/xxe
@@ -13,8 +13,9 @@
import javascript
import semmle.javascript.security.dataflow.Xxe::Xxe
+import DataFlow::PathGraph
-from Configuration c, DataFlow::Node source, DataFlow::Node sink
-where c.hasFlow(source, sink)
-select sink, "A $@ is parsed as XML without guarding against external entity expansion.",
- source, "user-provided value"
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "A $@ is parsed as XML without guarding against external entity expansion.",
+ source.getNode(), "user-provided value"
diff --git a/javascript/ql/src/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.ql b/javascript/ql/src/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.ql
index 9d653efb2f7f..c12f0e736f53 100644
--- a/javascript/ql/src/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.ql
+++ b/javascript/ql/src/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.ql
@@ -1,29 +1,20 @@
/**
* @name Host header poisoning in email generation
- * @description Using the HTTP Host header to construct a link in an email can facilitate phishing attacks and leak password reset tokens.
- * @kind problem
+ * @description Using the HTTP Host header to construct a link in an email can facilitate phishing
+ * attacks and leak password reset tokens.
+ * @kind path-problem
* @problem.severity error
* @precision high
* @id js/host-header-forgery-in-email-generation
* @tags security
* external/cwe/cwe-640
*/
-import javascript
-
-class TaintedHostHeader extends TaintTracking::Configuration {
- TaintedHostHeader() { this = "TaintedHostHeader" }
- override predicate isSource(DataFlow::Node node) {
- exists (HTTP::RequestHeaderAccess input | node = input |
- input.getKind() = "header" and
- input.getAHeaderName() = "host")
- }
-
- override predicate isSink(DataFlow::Node node) {
- exists (EmailSender email | node = email.getABody())
- }
-}
+import javascript
+import semmle.javascript.security.dataflow.HostHeaderPoisoningInEmailGeneration::HostHeaderPoisoningInEmailGeneration
+import DataFlow::PathGraph
-from TaintedHostHeader taint, DataFlow::Node src, DataFlow::Node sink
-where taint.hasFlow(src, sink)
-select sink, "Links in this email can be hijacked by poisoning the HTTP host header $@.", src, "here"
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "Links in this email can be hijacked by poisoning the HTTP host header $@.",
+ source.getNode(), "here"
diff --git a/javascript/ql/src/Security/CWE-643/XpathInjection.ql b/javascript/ql/src/Security/CWE-643/XpathInjection.ql
index 32f373db0012..f212e4a7a1a6 100644
--- a/javascript/ql/src/Security/CWE-643/XpathInjection.ql
+++ b/javascript/ql/src/Security/CWE-643/XpathInjection.ql
@@ -2,7 +2,7 @@
* @name XPath injection
* @description Building an XPath expression from user-controlled sources is vulnerable to insertion of
* malicious code by the user.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @precision high
* @id js/xpath-injection
@@ -12,7 +12,9 @@
import javascript
import semmle.javascript.security.dataflow.XpathInjection::XpathInjection
+import DataFlow::PathGraph
-from Configuration c, DataFlow::Node source, DataFlow::Node sink
-where c.hasFlow(source, sink)
-select sink, "$@ flows here and is used in an XPath expression.", source, "User-provided value"
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "$@ flows here and is used in an XPath expression.",
+ source.getNode(), "User-provided value"
diff --git a/javascript/ql/src/Security/CWE-730/RegExpInjection.ql b/javascript/ql/src/Security/CWE-730/RegExpInjection.ql
index 532900895bca..3053a64f53fb 100644
--- a/javascript/ql/src/Security/CWE-730/RegExpInjection.ql
+++ b/javascript/ql/src/Security/CWE-730/RegExpInjection.ql
@@ -3,7 +3,7 @@
* @description User input should not be used in regular expressions without first being escaped,
* otherwise a malicious user may be able to inject an expression that could require
* exponential time on certain inputs.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @precision high
* @id js/regex-injection
@@ -14,7 +14,9 @@
import javascript
import semmle.javascript.security.dataflow.RegExpInjection::RegExpInjection
+import DataFlow::PathGraph
-from Configuration c, DataFlow::Node source, DataFlow::Node sink
-where c.hasFlow(source, sink)
-select sink, "This regular expression is constructed from a $@.", source, "user-provided value"
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "This regular expression is constructed from a $@.",
+ source.getNode(), "user-provided value"
diff --git a/javascript/ql/src/Security/CWE-776/XmlBomb.ql b/javascript/ql/src/Security/CWE-776/XmlBomb.ql
index 3433ab5eb251..733fe7fe4144 100644
--- a/javascript/ql/src/Security/CWE-776/XmlBomb.ql
+++ b/javascript/ql/src/Security/CWE-776/XmlBomb.ql
@@ -2,7 +2,7 @@
* @name XML internal entity expansion
* @description Parsing user input as an XML document with arbitrary internal
* entity expansion is vulnerable to denial-of-service attacks.
- * @kind problem
+ * @kind path-problem
* @problem.severity warning
* @precision high
* @id js/xml-bomb
@@ -13,8 +13,9 @@
import javascript
import semmle.javascript.security.dataflow.XmlBomb::XmlBomb
+import DataFlow::PathGraph
-from Configuration c, DataFlow::Node source, DataFlow::Node sink
-where c.hasFlow(source, sink)
-select sink, "A $@ is parsed as XML without guarding against uncontrolled entity expansion.",
- source, "user-provided value"
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "A $@ is parsed as XML without guarding against uncontrolled entity expansion.",
+ source.getNode(), "user-provided value"
diff --git a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql
index 54b3a023da2c..b172e28edb93 100644
--- a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql
+++ b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql
@@ -2,7 +2,7 @@
* @name Hard-coded credentials
* @description Hard-coding credentials in source code may enable an attacker
* to gain unauthorized access.
- * @kind problem
+ * @kind path-problem
* @problem.severity warning
* @precision high
* @id js/hardcoded-credentials
@@ -14,12 +14,14 @@
import javascript
private import semmle.javascript.security.dataflow.HardcodedCredentials::HardcodedCredentials
+import DataFlow::PathGraph
-from Configuration cfg, DataFlow::Node source, Sink sink, string value
-where cfg.hasFlow(source, sink) and
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, string value
+where cfg.hasPathFlow(source, sink) and
// use source value in message if it's available
- if source.asExpr() instanceof ConstantString then
- value = "The hard-coded value \"" + source.asExpr().(ConstantString).getStringValue() + "\""
+ if source.getNode().asExpr() instanceof ConstantString then
+ value = "The hard-coded value \"" + source.getNode().asExpr().(ConstantString).getStringValue() + "\""
else
value = "This hard-coded value"
-select source, value + " is used as $@.", sink, sink.getKind()
+select source.getNode(), source, sink, value + " is used as $@.",
+ sink.getNode(), sink.getNode().(Sink).getKind()
diff --git a/javascript/ql/src/Security/CWE-807/ConditionalBypass.ql b/javascript/ql/src/Security/CWE-807/ConditionalBypass.ql
index e939bb61f8a1..f31549d259c1 100644
--- a/javascript/ql/src/Security/CWE-807/ConditionalBypass.ql
+++ b/javascript/ql/src/Security/CWE-807/ConditionalBypass.ql
@@ -1,7 +1,7 @@
/**
* @name User-controlled bypass of security check
* @description Conditions that the user controls are not suited for making security-related decisions.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @precision medium
* @id js/user-controlled-bypass
@@ -9,8 +9,10 @@
* external/cwe/cwe-807
* external/cwe/cwe-290
*/
+
import javascript
import semmle.javascript.security.dataflow.ConditionalBypass::ConditionalBypass
+import DataFlow::PathGraph
/**
* Holds if the value of `nd` flows into `guard`.
@@ -65,18 +67,19 @@ class SensitiveActionGuardComparisonOperand extends Sink {
* If flow from `source` taints `sink`, then an attacker can
* control if `action` should be executed or not.
*/
-predicate isTaintedGuardForSensitiveAction(Sink sink, DataFlow::Node source, SensitiveAction action) {
- action = sink.getAction() and
+predicate isTaintedGuardForSensitiveAction(DataFlow::PathNode sink, DataFlow::PathNode source, SensitiveAction action) {
+ action = sink.getNode().(Sink).getAction() and
// exclude the intermediary sink
- not sink instanceof SensitiveActionGuardComparisonOperand and
+ not sink.getNode() instanceof SensitiveActionGuardComparisonOperand and
exists (Configuration cfg |
// ordinary taint tracking to a guard
- cfg.hasFlow(source, sink) or
+ cfg.hasPathFlow(source, sink) or
// taint tracking to both operands of a guard comparison
- exists (SensitiveActionGuardComparison cmp, DataFlow::Node lSource, DataFlow::Node rSource |
- sink = cmp.getGuard() and
- cfg.hasFlow(lSource, DataFlow::valueNode(cmp.getLeftOperand())) and
- cfg.hasFlow(rSource, DataFlow::valueNode(cmp.getRightOperand())) |
+ exists (SensitiveActionGuardComparison cmp, DataFlow::PathNode lSource, DataFlow::PathNode rSource,
+ DataFlow::PathNode lSink, DataFlow::PathNode rSink |
+ sink.getNode() = cmp.getGuard() and
+ cfg.hasPathFlow(lSource, lSink) and lSink.getNode() = DataFlow::valueNode(cmp.getLeftOperand()) and
+ cfg.hasPathFlow(rSource, rSink) and rSink.getNode() = DataFlow::valueNode(cmp.getRightOperand()) |
source = lSource or
source = rSource
)
@@ -88,10 +91,10 @@ predicate isTaintedGuardForSensitiveAction(Sink sink, DataFlow::Node source, Sen
*
* Example: `if (e) return; action(x)`.
*/
-predicate isEarlyAbortGuard(Sink e, SensitiveAction action) {
+predicate isEarlyAbortGuard(DataFlow::PathNode e, SensitiveAction action) {
exists (IfStmt guard |
// `e` is in the condition of an if-statement ...
- e.asExpr().getParentExpr*() = guard.getCondition() and
+ e.getNode().(Sink).asExpr().getParentExpr*() = guard.getCondition() and
// ... where the then-branch always throws or returns
exists (Stmt abort |
abort instanceof ThrowStmt or
@@ -106,9 +109,9 @@ predicate isEarlyAbortGuard(Sink e, SensitiveAction action) {
)
}
-from DataFlow::Node source, DataFlow::Node sink, SensitiveAction action
+from DataFlow::PathNode source, DataFlow::PathNode sink, SensitiveAction action
where isTaintedGuardForSensitiveAction(sink, source, action) and
not isEarlyAbortGuard(sink, action)
-select sink, "This condition guards a sensitive $@, but $@ controls it.",
+select sink.getNode(), source, sink, "This condition guards a sensitive $@, but $@ controls it.",
action, "action",
- source, "a user-provided value"
+ source.getNode(), "a user-provided value"
diff --git a/javascript/ql/src/Security/CWE-843/TypeConfusionThroughParameterTampering.ql b/javascript/ql/src/Security/CWE-843/TypeConfusionThroughParameterTampering.ql
index fccb209a6985..d0499905a93a 100644
--- a/javascript/ql/src/Security/CWE-843/TypeConfusionThroughParameterTampering.ql
+++ b/javascript/ql/src/Security/CWE-843/TypeConfusionThroughParameterTampering.ql
@@ -1,7 +1,7 @@
/**
* @name Type confusion through parameter tampering
* @description Sanitizing an HTTP request parameter may be ineffective if the user controls its type.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @precision high
* @id js/type-confusion-through-parameter-tampering
@@ -11,7 +11,9 @@
import javascript
import semmle.javascript.security.dataflow.TypeConfusionThroughParameterTampering::TypeConfusionThroughParameterTampering
+import DataFlow::PathGraph
-from Configuration cfg, DataFlow::Node source, DataFlow::Node sink
-where cfg.hasFlow(source, sink)
-select sink, "Potential type confusion for $@.", source, "HTTP request parameter"
\ No newline at end of file
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "Potential type confusion for $@.",
+ source.getNode(), "HTTP request parameter"
diff --git a/javascript/ql/src/Security/CWE-912/HttpToFileAccess.ql b/javascript/ql/src/Security/CWE-912/HttpToFileAccess.ql
index fa2aaf95e805..3f913ea45302 100644
--- a/javascript/ql/src/Security/CWE-912/HttpToFileAccess.ql
+++ b/javascript/ql/src/Security/CWE-912/HttpToFileAccess.ql
@@ -1,7 +1,7 @@
/**
* @name User-controlled data written to file
* @description Writing user-controlled data directly to the file system allows arbitrary file upload and might indicate a backdoor.
- * @kind problem
+ * @kind path-problem
* @problem.severity warning
* @id js/http-to-file-access
* @tags security
@@ -9,8 +9,9 @@
*/
import javascript
-import semmle.javascript.security.dataflow.HttpToFileAccess
+import semmle.javascript.security.dataflow.HttpToFileAccess::HttpToFileAccess
+import DataFlow::PathGraph
-from HttpToFileAccess::Configuration configuration, DataFlow::Node src, DataFlow::Node sink
-where configuration.hasFlow(src, sink)
-select sink, "$@ flows to file system", src, "Untrusted data"
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "$@ flows to file system", source.getNode(), "Untrusted data"
diff --git a/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.ql b/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.ql
index 153cc3499079..37d0bb8c8c2c 100644
--- a/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.ql
+++ b/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.ql
@@ -1,17 +1,19 @@
/**
* @name Use of password hash with insufficient computational effort
* @description Creating a hash of a password with low computational effort makes the hash vulnerable to password cracking attacks.
- * @kind problem
+ * @kind path-problem
* @problem.severity warning
* @precision high
* @id js/insufficient-password-hash
* @tags security
* external/cwe/cwe-916
*/
+
import javascript
-import semmle.javascript.security.dataflow.RemoteFlowSources
import semmle.javascript.security.dataflow.InsufficientPasswordHash::InsufficientPasswordHash
+import DataFlow::PathGraph
-from Configuration cfg, Source source, DataFlow::Node sink
-where cfg.hasFlow(source, sink)
-select sink, "Password from $@ is hashed insecurely.", source , source.describe()
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
+where cfg.hasPathFlow(source, sink)
+select sink.getNode(), source, sink, "Password from $@ is hashed insecurely.",
+ source.getNode(), source.getNode().(Source).describe()
diff --git a/javascript/ql/src/Security/CWE-918/RequestForgery.ql b/javascript/ql/src/Security/CWE-918/RequestForgery.ql
index 3c968bf9fa6c..24039a70a1a6 100644
--- a/javascript/ql/src/Security/CWE-918/RequestForgery.ql
+++ b/javascript/ql/src/Security/CWE-918/RequestForgery.ql
@@ -1,7 +1,7 @@
/**
* @name Uncontrolled data used in network request
* @description Sending network requests with user-controlled data allows for request forgery attacks.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @precision medium
* @id js/request-forgery
@@ -11,8 +11,10 @@
import javascript
import semmle.javascript.security.dataflow.RequestForgery::RequestForgery
+import DataFlow::PathGraph
-from Configuration cfg, DataFlow::Node source, Sink sink, DataFlow::Node request
-where cfg.hasFlow(source, sink) and
- request = sink.getARequest()
-select request, "The $@ of this request depends on $@.", sink, sink.getKind(), source, "a user-provided value"
+from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node request
+where cfg.hasPathFlow(source, sink) and
+ request = sink.getNode().(Sink).getARequest()
+select request, source, sink, "The $@ of this request depends on $@.",
+ sink.getNode(), sink.getNode().(Sink).getKind(), source, "a user-provided value"
diff --git a/javascript/ql/src/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/src/semmle/javascript/dataflow/Configuration.qll
index 44baae1a39b8..9f23ef9c5e22 100644
--- a/javascript/ql/src/semmle/javascript/dataflow/Configuration.qll
+++ b/javascript/ql/src/semmle/javascript/dataflow/Configuration.qll
@@ -744,6 +744,7 @@ private predicate onPath(DataFlow::Node nd, DataFlow::Configuration cfg,
*/
private newtype TPathNode =
MkPathNode(DataFlow::Node nd, DataFlow::Configuration cfg, PathSummary summary) {
+ isSource(_, cfg, _) and isSink(_, cfg, _) and
onPath(nd, cfg, summary)
}
@@ -827,9 +828,14 @@ class SinkPathNode extends PathNode {
}
/**
- * Provides the query predicate needed to include a graph in a path-problem query.
+ * Provides the query predicates needed to include a graph in a path-problem query.
*/
module PathGraph {
+ /** Holds if `nd` is a node in the graph of data flow path explanations. */
+ query predicate nodes(PathNode nd) {
+ any()
+ }
+
/** Holds if `pred` → `succ` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode pred, PathNode succ) {
pred.getASuccessor() = succ
diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGeneration.qll b/javascript/ql/src/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGeneration.qll
new file mode 100644
index 000000000000..00dda20e4e4f
--- /dev/null
+++ b/javascript/ql/src/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGeneration.qll
@@ -0,0 +1,26 @@
+/**
+ * Provides a taint tracking configuration for reasoning about host header
+ * poisoning in email generation.
+ */
+
+import javascript
+
+module HostHeaderPoisoningInEmailGeneration {
+ /**
+ * A taint tracking configuration for host header poisoning in email generation.
+ */
+ class Configuration extends TaintTracking::Configuration {
+ Configuration() { this = "TaintedHostHeader" }
+
+ override predicate isSource(DataFlow::Node node) {
+ exists (HTTP::RequestHeaderAccess input | node = input |
+ input.getKind() = "header" and
+ input.getAHeaderName() = "host"
+ )
+ }
+
+ override predicate isSink(DataFlow::Node node) {
+ exists (EmailSender email | node = email.getABody())
+ }
+ }
+}
diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath.expected
index 418873e5c6f0..7a73a250542c 100644
--- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath.expected
@@ -1,29 +1,191 @@
-| TaintedPath-es6.js:10:26:10:45 | join("public", path) | This path depends on $@. | TaintedPath-es6.js:7:20:7:26 | req.url | a user-provided value |
-| TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value |
-| TaintedPath.js:15:29:15:48 | "/home/user/" + path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value |
-| TaintedPath.js:19:33:19:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value |
-| TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value |
-| TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value |
-| TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value |
-| TaintedPath.js:47:29:47:53 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
-| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
-| TaintedPath.js:51:29:51:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
-| TaintedPath.js:53:29:53:49 | pathMod ... n(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
-| TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
-| TaintedPath.js:57:29:57:54 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
-| TaintedPath.js:59:29:59:56 | pathMod ... , path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
-| TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
-| TaintedPath.js:63:29:63:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
-| TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
-| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
-| TaintedPath.js:78:26:78:40 | document.cookie | This path depends on $@. | TaintedPath.js:78:26:78:40 | document.cookie | a user-provided value |
-| TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value |
-| TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value |
-| TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value |
-| TaintedPath.js:94:48:94:60 | req.params[0] | This path depends on $@. | TaintedPath.js:94:48:94:60 | req.params[0] | a user-provided value |
-| tainted-array-steps.js:11:29:11:54 | ['publi ... in('/') | This path depends on $@. | tainted-array-steps.js:9:24:9:30 | req.url | a user-provided value |
-| tainted-array-steps.js:15:29:15:43 | parts.join('/') | This path depends on $@. | tainted-array-steps.js:9:24:9:30 | req.url | a user-provided value |
-| tainted-require.js:7:19:7:37 | req.param("module") | This path depends on $@. | tainted-require.js:7:19:7:37 | req.param("module") | a user-provided value |
-| tainted-sendFile.js:7:16:7:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:7:16:7:33 | req.param("gimme") | a user-provided value |
-| tainted-sendFile.js:9:16:9:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:9:16:9:33 | req.param("gimme") | a user-provided value |
-| views.js:1:43:1:55 | req.params[0] | This path depends on $@. | views.js:1:43:1:55 | req.params[0] | a user-provided value |
+nodes
+| 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:39 | parse(r ... ).query |
+| TaintedPath-es6.js:7:14:7:44 | parse(r ... ry.path |
+| TaintedPath-es6.js:7:20:7:26 | req.url |
+| TaintedPath-es6.js:10:26:10:45 | join("public", path) |
+| TaintedPath-es6.js:10:41:10:44 | path |
+| TaintedPath.js:9:7:9:48 | path |
+| TaintedPath.js:9:14:9:37 | url.par ... , true) |
+| TaintedPath.js:9:14:9:43 | url.par ... ).query |
+| TaintedPath.js:9:14:9:48 | url.par ... ry.path |
+| TaintedPath.js:9:24:9:30 | req.url |
+| TaintedPath.js:12:29:12:32 | path |
+| TaintedPath.js:15:29:15:48 | "/home/user/" + path |
+| TaintedPath.js:15:45:15:48 | path |
+| TaintedPath.js:19:33:19:36 | path |
+| TaintedPath.js:23:33:23:36 | path |
+| TaintedPath.js:27:33:27:36 | path |
+| TaintedPath.js:30:7:30:24 | path |
+| TaintedPath.js:34:3:34:3 | path |
+| TaintedPath.js:34:7:34:24 | path |
+| TaintedPath.js:34:29:34:46 | path |
+| TaintedPath.js:38:3:38:3 | path |
+| TaintedPath.js:38:7:38:24 | path |
+| TaintedPath.js:38:29:38:46 | path |
+| TaintedPath.js:39:5:39:5 | path |
+| TaintedPath.js:39:31:39:34 | path |
+| TaintedPath.js:45:3:45:44 | path |
+| TaintedPath.js:45:10:45:33 | url.par ... , true) |
+| TaintedPath.js:45:10:45:39 | url.par ... ).query |
+| TaintedPath.js:45:10:45:44 | url.par ... ry.path |
+| TaintedPath.js:45:20:45:26 | req.url |
+| TaintedPath.js:47:29:47:53 | pathMod ... e(path) |
+| TaintedPath.js:47:49:47:52 | path |
+| TaintedPath.js:49:29:49:52 | pathMod ... e(path) |
+| TaintedPath.js:49:48:49:51 | path |
+| TaintedPath.js:51:29:51:52 | pathMod ... e(path) |
+| TaintedPath.js:51:48:51:51 | path |
+| TaintedPath.js:53:29:53:49 | pathMod ... n(path) |
+| TaintedPath.js:53:45:53:48 | path |
+| TaintedPath.js:55:29:55:58 | pathMod ... ath, z) |
+| TaintedPath.js:55:51:55:54 | path |
+| TaintedPath.js:57:29:57:54 | pathMod ... e(path) |
+| TaintedPath.js:57:50:57:53 | path |
+| TaintedPath.js:59:29:59:56 | pathMod ... , path) |
+| TaintedPath.js:59:52:59:55 | path |
+| TaintedPath.js:61:29:61:56 | pathMod ... ath, x) |
+| TaintedPath.js:61:49:61:52 | path |
+| TaintedPath.js:63:29:63:52 | pathMod ... e(path) |
+| TaintedPath.js:63:48:63:51 | path |
+| TaintedPath.js:65:29:65:61 | pathMod ... ath, z) |
+| TaintedPath.js:65:54:65:57 | path |
+| TaintedPath.js:67:29:67:61 | pathMod ... h(path) |
+| TaintedPath.js:67:57:67:60 | path |
+| TaintedPath.js:78:26:78:40 | document.cookie |
+| TaintedPath.js:84:31:84:70 | require ... eq.url) |
+| TaintedPath.js:84:31:84:76 | require ... ).query |
+| TaintedPath.js:84:63:84:69 | req.url |
+| TaintedPath.js:85:31:85:68 | require ... eq.url) |
+| TaintedPath.js:85:31:85:74 | require ... ).query |
+| TaintedPath.js:85:61:85:67 | req.url |
+| TaintedPath.js:86:31:86:67 | require ... eq.url) |
+| TaintedPath.js:86:31:86:73 | require ... ).query |
+| TaintedPath.js:86:60:86:66 | req.url |
+| TaintedPath.js:94:48:94:60 | req.params[0] |
+| tainted-array-steps.js:9:7:9:48 | path |
+| tainted-array-steps.js:9:14:9:37 | url.par ... , true) |
+| tainted-array-steps.js:9:14:9:43 | url.par ... ).query |
+| tainted-array-steps.js:9:14:9:48 | url.par ... ry.path |
+| tainted-array-steps.js:9:24:9:30 | req.url |
+| tainted-array-steps.js:11:29:11:44 | ['public', path] |
+| tainted-array-steps.js:11:29:11:54 | ['publi ... in('/') |
+| tainted-array-steps.js:11:40:11:43 | path |
+| tainted-array-steps.js:13:15:13:30 | ['public', path] |
+| tainted-array-steps.js:13:26:13:29 | path |
+| tainted-array-steps.js:14:3:14:41 | parts |
+| tainted-array-steps.js:14:11:14:41 | parts.m ... Case()) |
+| tainted-array-steps.js:14:21:14:21 | x |
+| tainted-array-steps.js:14:26:14:26 | x |
+| tainted-array-steps.js:14:26:14:40 | x.toLowerCase() |
+| tainted-array-steps.js:15:29:15:33 | parts |
+| tainted-array-steps.js:15:29:15:43 | parts.join('/') |
+| tainted-require.js:7:19:7:37 | req.param("module") |
+| tainted-sendFile.js:7:16:7:33 | req.param("gimme") |
+| tainted-sendFile.js:9:16:9:33 | req.param("gimme") |
+| views.js:1:43:1:55 | req.params[0] |
+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:19:33:19:36 | path |
+| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path |
+| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path |
+| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | 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:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path |
+| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path |
+| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path |
+| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path |
+| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path |
+| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path |
+| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path |
+| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path |
+| TaintedPath.js:45:3:45:44 | path | TaintedPath.js:47:49:47:52 | path |
+| TaintedPath.js:45:3:45:44 | path | TaintedPath.js:49:48:49:51 | path |
+| TaintedPath.js:45:3:45:44 | path | TaintedPath.js:51:48:51:51 | path |
+| TaintedPath.js:45:3:45:44 | path | TaintedPath.js:53:45:53:48 | path |
+| TaintedPath.js:45:3:45:44 | path | TaintedPath.js:55:51:55:54 | path |
+| TaintedPath.js:45:3:45:44 | path | TaintedPath.js:57:50:57:53 | path |
+| TaintedPath.js:45:3:45:44 | path | TaintedPath.js:59:52:59:55 | path |
+| TaintedPath.js:45:3:45:44 | path | TaintedPath.js:61:49:61:52 | path |
+| TaintedPath.js:45:3:45:44 | path | TaintedPath.js:63:48:63:51 | path |
+| TaintedPath.js:45:3:45:44 | path | TaintedPath.js:65:54:65:57 | path |
+| TaintedPath.js:45:3:45:44 | path | TaintedPath.js:67:57:67:60 | path |
+| TaintedPath.js:45:10:45:33 | url.par ... , true) | TaintedPath.js:45:10:45:39 | url.par ... ).query |
+| TaintedPath.js:45:10:45:39 | url.par ... ).query | TaintedPath.js:45:10:45:44 | url.par ... ry.path |
+| TaintedPath.js:45:10:45:44 | url.par ... ry.path | TaintedPath.js:45:3:45:44 | path |
+| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) |
+| TaintedPath.js:47:49:47:52 | path | TaintedPath.js:47:29:47:53 | pathMod ... e(path) |
+| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) |
+| TaintedPath.js:51:48:51:51 | path | TaintedPath.js:51:29:51:52 | pathMod ... e(path) |
+| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) |
+| TaintedPath.js:55:51:55:54 | path | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) |
+| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) |
+| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) |
+| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) |
+| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) |
+| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) |
+| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) |
+| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query |
+| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) |
+| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query |
+| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) |
+| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query |
+| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) |
+| tainted-array-steps.js:9:7:9:48 | path | tainted-array-steps.js:11:40:11:43 | path |
+| tainted-array-steps.js:9:7:9:48 | path | tainted-array-steps.js:13:26:13:29 | path |
+| tainted-array-steps.js:9:14:9:37 | url.par ... , true) | tainted-array-steps.js:9:14:9:43 | url.par ... ).query |
+| tainted-array-steps.js:9:14:9:43 | url.par ... ).query | tainted-array-steps.js:9:14:9:48 | url.par ... ry.path |
+| tainted-array-steps.js:9:14:9:48 | url.par ... ry.path | tainted-array-steps.js:9:7:9:48 | path |
+| tainted-array-steps.js:9:24:9:30 | req.url | tainted-array-steps.js:9:14:9:37 | url.par ... , true) |
+| tainted-array-steps.js:11:29:11:44 | ['public', path] | tainted-array-steps.js:11:29:11:54 | ['publi ... in('/') |
+| tainted-array-steps.js:11:40:11:43 | path | tainted-array-steps.js:11:29:11:44 | ['public', path] |
+| tainted-array-steps.js:13:15:13:30 | ['public', path] | tainted-array-steps.js:14:21:14:21 | x |
+| tainted-array-steps.js:13:26:13:29 | path | tainted-array-steps.js:13:15:13:30 | ['public', path] |
+| tainted-array-steps.js:14:3:14:41 | parts | tainted-array-steps.js:15:29:15:33 | parts |
+| tainted-array-steps.js:14:11:14:41 | parts.m ... Case()) | tainted-array-steps.js:14:3:14:41 | parts |
+| tainted-array-steps.js:14:21:14:21 | x | tainted-array-steps.js:14:26:14:26 | x |
+| tainted-array-steps.js:14:26:14:26 | x | tainted-array-steps.js:14:26:14:40 | x.toLowerCase() |
+| tainted-array-steps.js:14:26:14:40 | x.toLowerCase() | tainted-array-steps.js:14:11:14:41 | parts.m ... Case()) |
+| tainted-array-steps.js:15:29:15:33 | parts | tainted-array-steps.js:15:29:15:43 | parts.join('/') |
+#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 $@. | TaintedPath-es6.js:7:20:7:26 | req.url | a 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 $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value |
+| TaintedPath.js:15:29:15:48 | "/home/user/" + path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:15:29:15:48 | "/home/user/" + path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value |
+| TaintedPath.js:19:33:19:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:19:33:19:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value |
+| TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value |
+| TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value |
+| TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value |
+| TaintedPath.js:47:29:47:53 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:47:29:47:53 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
+| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
+| TaintedPath.js:51:29:51:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:51:29:51:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
+| TaintedPath.js:53:29:53:49 | pathMod ... n(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
+| TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
+| TaintedPath.js:57:29:57:54 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
+| TaintedPath.js:59:29:59:56 | pathMod ... , path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:59:29:59:56 | pathMod ... , path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
+| TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
+| TaintedPath.js:63:29:63:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
+| TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
+| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value |
+| TaintedPath.js:78:26:78:40 | document.cookie | TaintedPath.js:78:26:78:40 | document.cookie | TaintedPath.js:78:26:78:40 | document.cookie | This path depends on $@. | TaintedPath.js:78:26:78:40 | document.cookie | a user-provided value |
+| TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value |
+| TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value |
+| TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value |
+| TaintedPath.js:94:48:94:60 | req.params[0] | TaintedPath.js:94:48:94:60 | req.params[0] | TaintedPath.js:94:48:94:60 | req.params[0] | This path depends on $@. | TaintedPath.js:94:48:94:60 | req.params[0] | a user-provided value |
+| tainted-array-steps.js:11:29:11:54 | ['publi ... in('/') | tainted-array-steps.js:9:24:9:30 | req.url | tainted-array-steps.js:11:29:11:54 | ['publi ... in('/') | This path depends on $@. | tainted-array-steps.js:9:24:9:30 | req.url | a user-provided value |
+| tainted-array-steps.js:15:29:15:43 | parts.join('/') | tainted-array-steps.js:9:24:9:30 | req.url | tainted-array-steps.js:15:29:15:43 | parts.join('/') | This path depends on $@. | tainted-array-steps.js:9:24:9:30 | req.url | a 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 $@. | tainted-require.js:7:19:7:37 | req.param("module") | a user-provided value |
+| tainted-sendFile.js:7:16:7:33 | req.param("gimme") | tainted-sendFile.js:7:16:7:33 | req.param("gimme") | tainted-sendFile.js:7:16:7:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:7:16:7:33 | req.param("gimme") | a user-provided value |
+| tainted-sendFile.js:9:16:9:33 | req.param("gimme") | tainted-sendFile.js:9:16:9:33 | req.param("gimme") | tainted-sendFile.js:9:16:9:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:9:16:9:33 | req.param("gimme") | a user-provided value |
+| 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] | This path depends on $@. | views.js:1:43:1:55 | req.params[0] | a user-provided value |
diff --git a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection.expected
index 39a2e7d2ff26..135a30057b3a 100644
--- a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection.expected
@@ -1,11 +1,76 @@
-| child_process-test.js:17:13:17:15 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
-| child_process-test.js:18:17:18:19 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
-| child_process-test.js:19:17:19:19 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
-| child_process-test.js:20:21:20:23 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
-| child_process-test.js:21:14:21:16 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
-| child_process-test.js:22:18:22:20 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
-| child_process-test.js:23:13:23:15 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
-| child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
-| child_process-test.js:39:5:39:31 | cp.spaw ... cmd ]) | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
-| child_process-test.js:44:5:44:34 | cp.exec ... , args) | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
-| child_process-test.js:50:3:50:21 | cp.spawn(cmd, args) | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
+nodes
+| 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:25:6:31 | req.url |
+| child_process-test.js:17:13:17:15 | cmd |
+| child_process-test.js:18:17:18:19 | cmd |
+| child_process-test.js:19:17:19:19 | cmd |
+| child_process-test.js:20:21:20:23 | cmd |
+| child_process-test.js:21:14:21:16 | cmd |
+| child_process-test.js:22:18:22:20 | cmd |
+| child_process-test.js:23:13:23:15 | cmd |
+| child_process-test.js:25:13:25:23 | "foo" + 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:36:7:36:20 | sh |
+| child_process-test.js:36:12:36:20 | 'cmd.exe' |
+| child_process-test.js:38:7:38:20 | sh |
+| child_process-test.js:38:12:38:20 | '/bin/sh' |
+| child_process-test.js:39:5:39:5 | sh |
+| child_process-test.js:39:14:39:15 | sh |
+| child_process-test.js:39:18:39:30 | [ flag, cmd ] |
+| child_process-test.js:39:26:39:28 | cmd |
+| child_process-test.js:41:9:41:17 | args |
+| child_process-test.js:41:16:41:17 | [] |
+| child_process-test.js:43:15:43:17 | cmd |
+| child_process-test.js:44:17:44:27 | "/bin/bash" |
+| child_process-test.js:44:30:44:33 | args |
+| child_process-test.js:46:9:46:12 | "sh" |
+| child_process-test.js:46:15:46:18 | args |
+| child_process-test.js:49:14:49:16 | cmd |
+| child_process-test.js:49:19:49:22 | args |
+| child_process-test.js:50:12:50:14 | cmd |
+| child_process-test.js:50:17:50:20 | args |
+edges
+| 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: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: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:13:25:23 | "foo" + 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:23 | "foo" + cmd |
+| child_process-test.js:36:7:36:20 | sh | child_process-test.js:39:5:39:5 | sh |
+| child_process-test.js:36:12:36:20 | 'cmd.exe' | child_process-test.js:36:7:36:20 | sh |
+| child_process-test.js:38:7:38:20 | sh | child_process-test.js:39:5:39:5 | sh |
+| child_process-test.js:38:12:38:20 | '/bin/sh' | child_process-test.js:38:7:38:20 | sh |
+| child_process-test.js:39:5:39:5 | sh | child_process-test.js:39:14:39:15 | sh |
+| child_process-test.js:41:9:41:17 | args | child_process-test.js:44:30:44:33 | args |
+| child_process-test.js:41:9:41:17 | args | child_process-test.js:46:15:46:18 | args |
+| child_process-test.js:41:16:41:17 | [] | child_process-test.js:41:9:41:17 | args |
+| child_process-test.js:46:9:46:12 | "sh" | child_process-test.js:49:14:49:16 | cmd |
+| child_process-test.js:46:15:46:18 | args | child_process-test.js:49:19:49:22 | args |
+| child_process-test.js:49:14:49:16 | cmd | child_process-test.js:50:12:50:14 | cmd |
+| child_process-test.js:49:19:49:22 | args | child_process-test.js:50:17:50:20 | args |
+#select
+| child_process-test.js:17:13:17:15 | cmd | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:17:13:17:15 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
+| child_process-test.js:18:17:18:19 | cmd | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:18:17:18:19 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
+| child_process-test.js:19:17:19:19 | cmd | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:19:17:19:19 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
+| child_process-test.js:20:21:20:23 | cmd | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:20:21:20:23 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
+| child_process-test.js:21:14:21:16 | cmd | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:21:14:21:16 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
+| child_process-test.js:22:18:22:20 | cmd | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:22:18:22:20 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
+| child_process-test.js:23:13:23:15 | cmd | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:23:13:23:15 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
+| child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
+| child_process-test.js:39:5:39:31 | cp.spaw ... cmd ]) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:39:26:39:28 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
+| child_process-test.js:44:5:44:34 | cp.exec ... , args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:43:15:43:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
+| child_process-test.js:50:3:50:21 | cp.spawn(cmd, args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:43:15:43:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected
index be0c937c38f3..c530d853079f 100644
--- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected
@@ -1,11 +1,91 @@
-| ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:8:33:8:45 | req.params.id | user-provided value |
-| etherpad.js:11:12:11:19 | response | Cross-site scripting vulnerability due to $@. | etherpad.js:9:16:9:30 | req.query.jsonp | user-provided value |
-| formatting.js:6:14:6:47 | util.fo ... , evil) | Cross-site scripting vulnerability due to $@. | formatting.js:4:16:4:29 | req.query.evil | user-provided value |
-| formatting.js:7:14:7:53 | require ... , evil) | Cross-site scripting vulnerability due to $@. | formatting.js:4:16:4:29 | req.query.evil | user-provided value |
-| partial.js:10:14:10:18 | x + y | Cross-site scripting vulnerability due to $@. | partial.js:13:42:13:48 | req.url | user-provided value |
-| partial.js:19:14:19:18 | x + y | Cross-site scripting vulnerability due to $@. | partial.js:22:51:22:57 | req.url | user-provided value |
-| partial.js:28:14:28:18 | x + y | Cross-site scripting vulnerability due to $@. | partial.js:31:47:31:53 | req.url | user-provided value |
-| partial.js:37:14:37:18 | x + y | Cross-site scripting vulnerability due to $@. | partial.js:40:43:40:49 | req.url | user-provided value |
-| promises.js:6:25:6:25 | x | Cross-site scripting vulnerability due to $@. | promises.js:5:44:5:57 | req.query.data | user-provided value |
-| tst2.js:7:12:7:12 | p | Cross-site scripting vulnerability due to $@. | tst2.js:6:9:6:9 | p | user-provided value |
-| tst2.js:8:12:8:12 | r | Cross-site scripting vulnerability due to $@. | tst2.js:6:12:6:15 | q: r | user-provided value |
+nodes
+| ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id |
+| ReflectedXss.js:8:33:8:45 | req.params.id |
+| etherpad.js:9:5:9:53 | response |
+| etherpad.js:9:16:9:30 | req.query.jsonp |
+| etherpad.js:9:16:9:36 | req.que ... p + "(" |
+| etherpad.js:9:16:9:47 | req.que ... esponse |
+| etherpad.js:9:16:9:53 | req.que ... e + ")" |
+| etherpad.js:11:3:11:3 | 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: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:49:7:52 | evil |
+| partial.js:9:25:9:25 | x |
+| 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:18:25:18:25 | x |
+| 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:27:25:27:25 | x |
+| 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:36:25:36:25 | x |
+| partial.js:37:14:37:14 | x |
+| partial.js:37:14:37:18 | x + y |
+| 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:6:11:6:11 | x |
+| 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:12:6:15 | q: r |
+| tst2.js:7:12:7:12 | p |
+| tst2.js:8:12:8:12 | r |
+edges
+| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id |
+| etherpad.js:9:5:9:53 | response | etherpad.js:11:3:11:3 | response |
+| etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:9:16:9:36 | req.que ... p + "(" |
+| etherpad.js:9:16:9:36 | req.que ... p + "(" | etherpad.js:9:16:9:47 | req.que ... esponse |
+| etherpad.js:9:16:9:47 | req.que ... esponse | 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:11:3:11:3 | response | etherpad.js:11:12:11:19 | 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: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) |
+| 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: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: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: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: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: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 | 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:12:6:15 | q: r | tst2.js:6:7:6:30 | r |
+#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 $@. | ReflectedXss.js:8:33:8:45 | req.params.id | user-provided value |
+| etherpad.js:11:12:11:19 | response | etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:11:12:11:19 | response | Cross-site scripting vulnerability due to $@. | etherpad.js:9:16:9:30 | req.query.jsonp | user-provided value |
+| formatting.js:6:14:6:47 | util.fo ... , evil) | formatting.js:4:16:4:29 | req.query.evil | formatting.js:6:14:6:47 | util.fo ... , evil) | Cross-site scripting vulnerability due to $@. | formatting.js:4:16:4:29 | req.query.evil | user-provided value |
+| formatting.js:7:14:7:53 | require ... , evil) | formatting.js:4:16:4:29 | req.query.evil | formatting.js:7:14:7:53 | require ... , evil) | Cross-site scripting vulnerability due to $@. | formatting.js:4:16:4:29 | req.query.evil | user-provided value |
+| partial.js:10:14:10:18 | x + y | partial.js:13:42:13:48 | req.url | partial.js:10:14:10:18 | x + y | Cross-site scripting vulnerability due to $@. | partial.js:13:42:13:48 | req.url | user-provided value |
+| partial.js:19:14:19:18 | x + y | partial.js:22:51:22:57 | req.url | partial.js:19:14:19:18 | x + y | Cross-site scripting vulnerability due to $@. | partial.js:22:51:22:57 | req.url | user-provided value |
+| partial.js:28:14:28:18 | x + y | partial.js:31:47:31:53 | req.url | partial.js:28:14:28:18 | x + y | Cross-site scripting vulnerability due to $@. | partial.js:31:47:31:53 | req.url | user-provided value |
+| partial.js:37:14:37:18 | x + y | partial.js:40:43:40:49 | req.url | partial.js:37:14:37:18 | x + y | Cross-site scripting vulnerability due to $@. | partial.js:40:43:40:49 | req.url | user-provided value |
+| promises.js:6:25:6:25 | x | promises.js:5:44:5:57 | req.query.data | promises.js:6:25:6:25 | x | Cross-site scripting vulnerability due to $@. | promises.js:5:44:5:57 | req.query.data | user-provided value |
+| promises.js:6:25:6:25 | x | promises.js:5:44:5:57 | req.query.data | promises.js:6:25:6:25 | x | Cross-site scripting vulnerability due to $@. | promises.js:5:44:5:57 | req.query.data | user-provided value |
+| tst2.js:7:12:7:12 | p | tst2.js:6:9:6:9 | p | tst2.js:7:12:7:12 | p | Cross-site scripting vulnerability due to $@. | tst2.js:6:9:6:9 | p | user-provided value |
+| tst2.js:8:12:8:12 | r | tst2.js:6:12:6:15 | q: r | tst2.js:8:12:8:12 | r | Cross-site scripting vulnerability due to $@. | tst2.js:6:12:6:15 | q: r | user-provided value |
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXssPath.expected b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXssPath.expected
deleted file mode 100644
index 28682d23433a..000000000000
--- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXssPath.expected
+++ /dev/null
@@ -1,47 +0,0 @@
-edges
-| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id |
-| etherpad.js:9:5:9:53 | response | etherpad.js:11:3:11:3 | response |
-| etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:9:16:9:36 | req.que ... p + "(" |
-| etherpad.js:9:16:9:36 | req.que ... p + "(" | etherpad.js:9:16:9:47 | req.que ... esponse |
-| etherpad.js:9:16:9:47 | req.que ... esponse | 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:11:3:11:3 | response | etherpad.js:11:12:11:19 | 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: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) |
-| 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: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: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: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: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: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 | 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:12:6:15 | q: r | tst2.js:6:7:6:30 | r |
-#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 $@. | ReflectedXss.js:8:33:8:45 | req.params.id | user-provided value |
-| etherpad.js:11:12:11:19 | response | etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:11:12:11:19 | response | Cross-site scripting vulnerability due to $@. | etherpad.js:9:16:9:30 | req.query.jsonp | user-provided value |
-| formatting.js:6:14:6:47 | util.fo ... , evil) | formatting.js:4:16:4:29 | req.query.evil | formatting.js:6:14:6:47 | util.fo ... , evil) | Cross-site scripting vulnerability due to $@. | formatting.js:4:16:4:29 | req.query.evil | user-provided value |
-| formatting.js:7:14:7:53 | require ... , evil) | formatting.js:4:16:4:29 | req.query.evil | formatting.js:7:14:7:53 | require ... , evil) | Cross-site scripting vulnerability due to $@. | formatting.js:4:16:4:29 | req.query.evil | user-provided value |
-| partial.js:10:14:10:18 | x + y | partial.js:13:42:13:48 | req.url | partial.js:10:14:10:18 | x + y | Cross-site scripting vulnerability due to $@. | partial.js:13:42:13:48 | req.url | user-provided value |
-| partial.js:19:14:19:18 | x + y | partial.js:22:51:22:57 | req.url | partial.js:19:14:19:18 | x + y | Cross-site scripting vulnerability due to $@. | partial.js:22:51:22:57 | req.url | user-provided value |
-| partial.js:28:14:28:18 | x + y | partial.js:31:47:31:53 | req.url | partial.js:28:14:28:18 | x + y | Cross-site scripting vulnerability due to $@. | partial.js:31:47:31:53 | req.url | user-provided value |
-| partial.js:37:14:37:18 | x + y | partial.js:40:43:40:49 | req.url | partial.js:37:14:37:18 | x + y | Cross-site scripting vulnerability due to $@. | partial.js:40:43:40:49 | req.url | user-provided value |
-| promises.js:6:25:6:25 | x | promises.js:5:44:5:57 | req.query.data | promises.js:6:25:6:25 | x | Cross-site scripting vulnerability due to $@. | promises.js:5:44:5:57 | req.query.data | user-provided value |
-| promises.js:6:25:6:25 | x | promises.js:5:44:5:57 | req.query.data | promises.js:6:25:6:25 | x | Cross-site scripting vulnerability due to $@. | promises.js:5:44:5:57 | req.query.data | user-provided value |
-| tst2.js:7:12:7:12 | p | tst2.js:6:9:6:9 | p | tst2.js:7:12:7:12 | p | Cross-site scripting vulnerability due to $@. | tst2.js:6:9:6:9 | p | user-provided value |
-| tst2.js:8:12:8:12 | r | tst2.js:6:12:6:15 | q: r | tst2.js:8:12:8:12 | r | Cross-site scripting vulnerability due to $@. | tst2.js:6:12:6:15 | q: r | user-provided value |
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXssPath.ql b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXssPath.ql
deleted file mode 100644
index 2c5cbad56d7f..000000000000
--- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXssPath.ql
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * @name Reflected cross-site scripting
- * @description Writing user input directly to an HTTP response allows for
- * a cross-site scripting vulnerability.
- * @kind path-problem
- * @problem.severity error
- * @precision high
- * @id js/reflected-xss-path
- * @tags security
- * external/cwe/cwe-079
- * external/cwe/cwe-116
- */
-
-import javascript
-import semmle.javascript.security.dataflow.ReflectedXss
-import DataFlow::PathGraph
-
-from DataFlow::PathNode source, DataFlow::PathNode sink, ReflectedXss::Configuration cfg
-where cfg.hasPathFlow(source, sink)
-select sink, source, sink, "Cross-site scripting vulnerability due to $@.",
- source, "user-provided value"
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected
index 9d9a94ff27ea..4b941d5e730b 100644
--- a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected
@@ -1,4 +1,395 @@
-| 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 | Stored cross-site scripting vulnerability due to $@. | xss-through-filenames.js:25:43:25:48 | files1 | stored value |
-| xss-through-filenames.js:33:19:33:24 | files2 | Stored cross-site scripting vulnerability due to $@. | xss-through-filenames.js:25:43:25:48 | files1 | stored value |
-| xss-through-filenames.js:37:19:37:24 | files3 | Stored cross-site scripting vulnerability due to $@. | xss-through-filenames.js:25:43:25:48 | files1 | stored value |
+nodes
+| ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id |
+| ReflectedXss.js:8:33:8:45 | req.params.id |
+| addEventListener.js:1:43:1:47 | event |
+| addEventListener.js:2:20:2:24 | event |
+| addEventListener.js:2:20:2:29 | event.data |
+| etherpad.js:9:5:9:53 | response |
+| etherpad.js:9:16:9:30 | req.query.jsonp |
+| etherpad.js:9:16:9:36 | req.que ... p + "(" |
+| etherpad.js:9:16:9:47 | req.que ... esponse |
+| etherpad.js:9:16:9:53 | req.que ... e + ")" |
+| etherpad.js:11:3:11:3 | 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: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:49:7:52 | evil |
+| jquery.js:2:7:2:40 | tainted |
+| jquery.js:2:17:2:33 | document.location |
+| jquery.js:2:17:2:40 | documen ... .search |
+| jquery.js:4:5:4:11 | tainted |
+| jquery.js:7:5:7:26 | "
" |
+| jquery.js:7:20:7:26 | tainted |
+| jquery.js:8:18:8:34 | "XSS: " + tainted |
+| jquery.js:8:28:8:34 | tainted |
+| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
+| nodemailer.js:13:50:13:66 | req.query.message |
+| partial.js:9:25:9:25 | x |
+| 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:18:25:18:25 | x |
+| 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:27:25:27:25 | x |
+| 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:36:25:36:25 | x |
+| partial.js:37:14:37:14 | x |
+| partial.js:37:14:37:18 | x + y |
+| 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:6:11:6:11 | x |
+| promises.js:6:11:6:11 | x |
+| promises.js:6:25:6:25 | x |
+| promises.js:6:25:6:25 | x |
+| react-native.js:7:7:7:33 | tainted |
+| react-native.js:7:17:7:33 | req.param("code") |
+| react-native.js:8:18:8:24 | tainted |
+| react-native.js:9:27:9:33 | tainted |
+| string-manipulations.js:3:16:3:32 | document.location |
+| string-manipulations.js:4:16:4:32 | document.location |
+| string-manipulations.js:4:16:4:37 | documen ... on.href |
+| string-manipulations.js:5:16:5:32 | document.location |
+| 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:32 | document.location |
+| 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:32 | document.location |
+| 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:32 | document.location |
+| string-manipulations.js:8:16:8:37 | documen ... on.href |
+| string-manipulations.js:8:16:8:48 | documen ... mLeft() |
+| string-manipulations.js:9:16:9:58 | String. ... n.href) |
+| string-manipulations.js:9:36:9:52 | document.location |
+| string-manipulations.js:9:36:9:57 | documen ... on.href |
+| string-manipulations.js:10:16:10:45 | String( ... n.href) |
+| string-manipulations.js:10:23:10:39 | document.location |
+| string-manipulations.js:10:23:10:44 | documen ... on.href |
+| translate.js:6:7:6:39 | target |
+| translate.js:6:16:6:32 | document.location |
+| translate.js:6:16:6:39 | documen ... .search |
+| translate.js:7:42:7:47 | target |
+| translate.js:7:42:7:60 | target.substring(1) |
+| translate.js:9:27:9:50 | searchP ... 'term') |
+| tst2.js:6:7:6:30 | p |
+| tst2.js:6:7:6:30 | r |
+| tst2.js:6:9:6:9 | p |
+| tst2.js:6:12:6:15 | q: r |
+| tst2.js:7:12:7:12 | p |
+| tst2.js:8:12:8:12 | r |
+| tst.js:2:7:2:39 | target |
+| tst.js:2:16:2:32 | document.location |
+| tst.js:2:16:2:39 | documen ... .search |
+| tst.js:5:18:5:23 | target |
+| tst.js:8:18:8:114 | "
" |
+| tst.js:8:37:8:53 | document.location |
+| tst.js:8:37:8:58 | documen ... on.href |
+| tst.js:8:37:8:114 | documen ... t=")+8) |
+| tst.js:12:5:12:33 | '' |
+| tst.js:12:28:12:33 | target |
+| tst.js:19:25:19:41 | document.location |
+| tst.js:20:18:20:35 | params.get('name') |
+| tst.js:23:42:23:47 | target |
+| tst.js:23:42:23:60 | target.substring(1) |
+| tst.js:24:18:24:41 | searchP ... 'name') |
+| tst.js:27:14:27:19 | target |
+| tst.js:29:18:29:23 | target |
+| tst.js:31:5:31:21 | document.location |
+| tst.js:31:5:31:28 | documen ... .search |
+| tst.js:34:10:34:26 | document.location |
+| tst.js:34:10:34:33 | documen ... .search |
+| tst.js:37:16:37:20 | bar() |
+| tst.js:43:16:43:44 | baz(doc ... search) |
+| tst.js:43:20:43:36 | document.location |
+| tst.js:43:20:43:43 | documen ... .search |
+| tst.js:49:16:49:45 | wrap(do ... search) |
+| tst.js:49:21:49:37 | document.location |
+| tst.js:49:21:49:44 | documen ... .search |
+| tst.js:57:16:57:45 | chop(do ... search) |
+| tst.js:57:21:57:37 | document.location |
+| tst.js:57:21:57:44 | documen ... .search |
+| tst.js:59:16:59:45 | chop(do ... search) |
+| tst.js:59:21:59:37 | document.location |
+| tst.js:59:21:59:44 | documen ... .search |
+| tst.js:61:16:61:32 | wrap(chop(bar())) |
+| tst.js:61:21:61:31 | chop(bar()) |
+| tst.js:61:26:61:30 | bar() |
+| tst.js:63:34:63:34 | s |
+| tst.js:65:18:65:18 | s |
+| tst.js:67:25:67:41 | document.location |
+| tst.js:67:25:67:48 | documen ... .search |
+| tst.js:68:25:68:41 | document.location |
+| tst.js:68:25:68:48 | documen ... .search |
+| tst.js:71:16:71:20 | bar() |
+| tst.js:73:1:73:27 | [,docum ... search] |
+| tst.js:73:3:73:19 | document.location |
+| tst.js:73:3:73:26 | documen ... .search |
+| tst.js:73:46:73:46 | x |
+| tst.js:74:7:74:7 | x |
+| tst.js:76:20:76:20 | x |
+| tst.js:80:49:80:65 | document.location |
+| tst.js:80:49:80:72 | documen ... .search |
+| tst.js:84:26:84:42 | document.location |
+| tst.js:84:26:84:49 | documen ... .search |
+| tst.js:85:25:85:41 | document.location |
+| tst.js:85:25:85:48 | documen ... .search |
+| tst.js:87:33:87:49 | document.location |
+| tst.js:87:33:87:56 | documen ... .search |
+| tst.js:88:32:88:48 | document.location |
+| tst.js:88:32:88:55 | documen ... .search |
+| tst.js:93:39:93:55 | document.location |
+| tst.js:93:39:93:62 | documen ... .search |
+| tst.js:99:30:99:46 | document.location |
+| tst.js:99:30:99:53 | documen ... .search |
+| tst.js:105:25:105:41 | document.location |
+| tst.js:105:25:105:48 | documen ... .search |
+| tst.js:110:7:110:44 | v |
+| tst.js:110:11:110:27 | document.location |
+| tst.js:110:11:110:34 | documen ... .search |
+| tst.js:110:11:110:44 | documen ... bstr(1) |
+| tst.js:113:18:113:18 | v |
+| tst.js:145:29:145:43 | window.location |
+| tst.js:145:29:145:50 | window. ... .search |
+| tst.js:148:29:148:29 | v |
+| tst.js:148:49:148:49 | v |
+| tst.js:152:29:152:46 | xssSourceService() |
+| tst.js:155:40:155:54 | window.location |
+| tst.js:155:40:155:61 | window. ... .search |
+| tst.js:174:9:174:41 | target |
+| tst.js:174:18:174:34 | document.location |
+| tst.js:174:18:174:41 | documen ... .search |
+| tst.js:177:28:177:33 | target |
+| tst.js:181:9:181:42 | tainted |
+| tst.js:181:19:181:35 | document.location |
+| tst.js:181:19:181:42 | documen ... .search |
+| tst.js:183:31:183:37 | tainted |
+| tst.js:185:42:185:48 | tainted |
+| tst.js:186:33:186:39 | tainted |
+| tst.js:188:54:188:60 | tainted |
+| tst.js:189:45:189:51 | tainted |
+| tst.js:194:9:194:42 | tainted |
+| tst.js:194:19:194:35 | document.location |
+| tst.js:194:19:194:42 | documen ... .search |
+| tst.js:196:67:196:73 | tainted |
+| tst.js:197:67:197:73 | tainted |
+| tst.js:200:20:200:19 | tainted |
+| tst.js:201:35:201:41 | tainted |
+| tst.js:203:27:203:26 | tainted |
+| tst.js:203:46:203:52 | tainted |
+| tst.js:204:38:204:44 | tainted |
+| tst.js:205:35:205:41 | tainted |
+| tst.js:209:28:209:46 | this.state.tainted1 |
+| tst.js:210:28:210:46 | this.state.tainted2 |
+| tst.js:211:28:211:46 | this.state.tainted3 |
+| tst.js:215:32:215:49 | prevState.tainted4 |
+| tst.js:222:28:222:46 | this.props.tainted1 |
+| tst.js:223:28:223:46 | this.props.tainted2 |
+| tst.js:224:28:224:46 | this.props.tainted3 |
+| tst.js:228:32:228:49 | prevProps.tainted4 |
+| tst.js:233:35:233:41 | tainted |
+| tst.js:235:20:235:26 | tainted |
+| tst.js:237:23:237:29 | tainted |
+| tst.js:238:23:238:29 | tainted |
+| tst.js:244:39:244:55 | props.propTainted |
+| tst.js:248:60:248:82 | this.st ... Tainted |
+| tst.js:252:23:252:29 | tainted |
+| 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:29:13:29:23 | files2 |
+| xss-through-filenames.js:29:22:29:23 | [] |
+| 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: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 |
+edges
+| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id |
+| 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 |
+| etherpad.js:9:5:9:53 | response | etherpad.js:11:3:11:3 | response |
+| etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:9:16:9:36 | req.que ... p + "(" |
+| etherpad.js:9:16:9:36 | req.que ... p + "(" | etherpad.js:9:16:9:47 | req.que ... esponse |
+| etherpad.js:9:16:9:47 | req.que ... esponse | 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:11:3:11:3 | response | etherpad.js:11:12:11:19 | 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: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) |
+| jquery.js:2:7:2:40 | tainted | jquery.js:4:5:4:11 | tainted |
+| 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:17:2:33 | document.location | jquery.js:2:17:2:40 | documen ... .search |
+| jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted |
+| jquery.js:7:5:7:26 | "
" |
+| jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:26 | "
" |
+| tst.js:8:37:8:53 | document.location | 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:8:18:8:114 | "
' |
+| tst.js:12:28:12:33 | target | tst.js:12:5:12:33 | '" | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:33 | document.location | user-provided value |
-| jquery.js:8:18:8:34 | "XSS: " + tainted | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:33 | document.location | user-provided value |
-| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | HTML injection vulnerability due to $@. | nodemailer.js:13:50:13:66 | req.query.message | user-provided value |
-| react-native.js:8:18:8:24 | tainted | Cross-site scripting vulnerability due to $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value |
-| react-native.js:9:27:9:33 | tainted | Cross-site scripting vulnerability due to $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value |
-| string-manipulations.js:3:16:3:32 | document.location | Cross-site scripting vulnerability due to $@. | string-manipulations.js:3:16:3:32 | document.location | user-provided value |
-| string-manipulations.js:4:16:4:37 | documen ... on.href | Cross-site scripting vulnerability due to $@. | string-manipulations.js:4:16:4:32 | document.location | user-provided value |
-| string-manipulations.js:5:16:5:47 | documen ... lueOf() | Cross-site scripting vulnerability due to $@. | string-manipulations.js:5:16:5:32 | document.location | user-provided value |
-| string-manipulations.js:6:16:6:43 | documen ... f.sup() | Cross-site scripting vulnerability due to $@. | string-manipulations.js:6:16:6:32 | document.location | user-provided value |
-| string-manipulations.js:7:16:7:51 | documen ... rCase() | Cross-site scripting vulnerability due to $@. | string-manipulations.js:7:16:7:32 | document.location | user-provided value |
-| string-manipulations.js:8:16:8:48 | documen ... mLeft() | Cross-site scripting vulnerability due to $@. | string-manipulations.js:8:16:8:32 | document.location | user-provided value |
-| string-manipulations.js:9:16:9:58 | String. ... n.href) | Cross-site scripting vulnerability due to $@. | string-manipulations.js:9:36:9:52 | document.location | user-provided value |
-| string-manipulations.js:10:16:10:45 | String( ... n.href) | Cross-site scripting vulnerability due to $@. | string-manipulations.js:10:23:10:39 | document.location | user-provided value |
-| translate.js:9:27:9:50 | searchP ... 'term') | Cross-site scripting vulnerability due to $@. | translate.js:6:16:6:32 | document.location | user-provided value |
-| tst.js:5:18:5:23 | target | Cross-site scripting vulnerability due to $@. | tst.js:2:16:2:32 | document.location | user-provided value |
-| tst.js:8:18:8:126 | "
" | Cross-site scripting vulnerability due to $@. | tst.js:8:37:8:53 | document.location | user-provided value |
-| tst.js:12:5:12:42 | '' | Cross-site scripting vulnerability due to $@. | tst.js:2:16:2:32 | document.location | user-provided value |
-| tst.js:20:18:20:35 | params.get('name') | Cross-site scripting vulnerability due to $@. | tst.js:19:25:19:41 | document.location | user-provided value |
-| tst.js:24:18:24:41 | searchP ... 'name') | Cross-site scripting vulnerability due to $@. | tst.js:2:16:2:32 | document.location | user-provided value |
-| tst.js:29:18:29:23 | target | Cross-site scripting vulnerability due to $@. | tst.js:31:5:31:21 | document.location | user-provided value |
-| tst.js:37:16:37:20 | bar() | Cross-site scripting vulnerability due to $@. | tst.js:34:10:34:26 | document.location | user-provided value |
-| tst.js:43:16:43:44 | baz(doc ... search) | Cross-site scripting vulnerability due to $@. | tst.js:43:20:43:36 | document.location | user-provided value |
-| tst.js:49:16:49:45 | wrap(do ... search) | Cross-site scripting vulnerability due to $@. | tst.js:49:21:49:37 | document.location | user-provided value |
-| tst.js:57:16:57:45 | chop(do ... search) | Cross-site scripting vulnerability due to $@. | tst.js:57:21:57:37 | document.location | user-provided value |
-| tst.js:59:16:59:45 | chop(do ... search) | Cross-site scripting vulnerability due to $@. | tst.js:59:21:59:37 | document.location | user-provided value |
-| tst.js:61:16:61:32 | wrap(chop(bar())) | Cross-site scripting vulnerability due to $@. | tst.js:34:10:34:26 | document.location | user-provided value |
-| tst.js:65:18:65:18 | s | Cross-site scripting vulnerability due to $@. | tst.js:67:25:67:41 | document.location | user-provided value |
-| tst.js:65:18:65:18 | s | Cross-site scripting vulnerability due to $@. | tst.js:68:25:68:41 | document.location | user-provided value |
-| tst.js:71:16:71:20 | bar() | Cross-site scripting vulnerability due to $@. | tst.js:34:10:34:26 | document.location | user-provided value |
-| tst.js:76:20:76:20 | x | Cross-site scripting vulnerability due to $@. | tst.js:73:3:73:19 | document.location | user-provided value |
-| tst.js:80:49:80:72 | documen ... .search | Cross-site scripting vulnerability due to $@. | tst.js:80:49:80:65 | document.location | user-provided value |
-| tst.js:84:26:84:49 | documen ... .search | Cross-site scripting vulnerability due to $@. | tst.js:84:26:84:42 | document.location | user-provided value |
-| tst.js:85:25:85:48 | documen ... .search | Cross-site scripting vulnerability due to $@. | tst.js:85:25:85:41 | document.location | user-provided value |
-| tst.js:87:33:87:56 | documen ... .search | Cross-site scripting vulnerability due to $@. | tst.js:87:33:87:49 | document.location | user-provided value |
-| tst.js:88:32:88:55 | documen ... .search | Cross-site scripting vulnerability due to $@. | tst.js:88:32:88:48 | document.location | user-provided value |
-| tst.js:93:39:93:62 | documen ... .search | Cross-site scripting vulnerability due to $@. | tst.js:93:39:93:55 | document.location | user-provided value |
-| tst.js:99:30:99:53 | documen ... .search | Cross-site scripting vulnerability due to $@. | tst.js:99:30:99:46 | document.location | user-provided value |
-| tst.js:105:25:105:48 | documen ... .search | Cross-site scripting vulnerability due to $@. | tst.js:105:25:105:41 | document.location | user-provided value |
-| tst.js:113:18:113:18 | v | Cross-site scripting vulnerability due to $@. | tst.js:110:11:110:27 | document.location | user-provided value |
-| tst.js:148:49:148:49 | v | Cross-site scripting vulnerability due to $@. | tst.js:145:29:145:43 | window.location | user-provided value |
-| tst.js:152:29:152:46 | xssSourceService() | Cross-site scripting vulnerability due to $@. | tst.js:155:40:155:54 | window.location | user-provided value |
-| tst.js:177:28:177:33 | target | Cross-site scripting vulnerability due to $@. | tst.js:174:18:174:34 | document.location | user-provided value |
-| tst.js:183:31:183:37 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:181:19:181:35 | document.location | user-provided value |
-| tst.js:185:42:185:48 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:181:19:181:35 | document.location | user-provided value |
-| tst.js:186:33:186:39 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:181:19:181:35 | document.location | user-provided value |
-| tst.js:188:54:188:60 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:181:19:181:35 | document.location | user-provided value |
-| tst.js:189:45:189:51 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:181:19:181:35 | document.location | user-provided value |
-| tst.js:196:67:196:73 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
-| tst.js:197:67:197:73 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
-| tst.js:209:28:209:46 | this.state.tainted1 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
-| tst.js:210:28:210:46 | this.state.tainted2 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
-| tst.js:211:28:211:46 | this.state.tainted3 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
-| tst.js:215:32:215:49 | prevState.tainted4 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
-| tst.js:222:28:222:46 | this.props.tainted1 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
-| tst.js:223:28:223:46 | this.props.tainted2 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
-| tst.js:224:28:224:46 | this.props.tainted3 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
-| tst.js:228:32:228:49 | prevProps.tainted4 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
-| tst.js:248:60:248:82 | this.st ... Tainted | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
+nodes
+| addEventListener.js:1:43:1:47 | event |
+| addEventListener.js:2:20:2:24 | event |
+| addEventListener.js:2:20:2:29 | event.data |
+| jquery.js:2:7:2:40 | tainted |
+| jquery.js:2:17:2:33 | document.location |
+| jquery.js:2:17:2:40 | documen ... .search |
+| jquery.js:4:5:4:11 | tainted |
+| jquery.js:7:5:7:26 | "
" |
+| jquery.js:7:20:7:26 | tainted |
+| jquery.js:8:18:8:34 | "XSS: " + tainted |
+| jquery.js:8:28:8:34 | tainted |
+| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
+| nodemailer.js:13:50:13:66 | req.query.message |
+| react-native.js:7:7:7:33 | tainted |
+| react-native.js:7:17:7:33 | req.param("code") |
+| react-native.js:8:18:8:24 | tainted |
+| react-native.js:9:27:9:33 | tainted |
+| string-manipulations.js:3:16:3:32 | document.location |
+| string-manipulations.js:4:16:4:32 | document.location |
+| string-manipulations.js:4:16:4:37 | documen ... on.href |
+| string-manipulations.js:5:16:5:32 | document.location |
+| 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:32 | document.location |
+| 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:32 | document.location |
+| 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:32 | document.location |
+| string-manipulations.js:8:16:8:37 | documen ... on.href |
+| string-manipulations.js:8:16:8:48 | documen ... mLeft() |
+| string-manipulations.js:9:16:9:58 | String. ... n.href) |
+| string-manipulations.js:9:36:9:52 | document.location |
+| string-manipulations.js:9:36:9:57 | documen ... on.href |
+| string-manipulations.js:10:16:10:45 | String( ... n.href) |
+| string-manipulations.js:10:23:10:39 | document.location |
+| string-manipulations.js:10:23:10:44 | documen ... on.href |
+| translate.js:6:7:6:39 | target |
+| translate.js:6:16:6:32 | document.location |
+| translate.js:6:16:6:39 | documen ... .search |
+| translate.js:7:42:7:47 | target |
+| translate.js:7:42:7:60 | target.substring(1) |
+| translate.js:9:27:9:50 | searchP ... 'term') |
+| tst.js:2:7:2:39 | target |
+| tst.js:2:16:2:32 | document.location |
+| tst.js:2:16:2:39 | documen ... .search |
+| tst.js:5:18:5:23 | target |
+| tst.js:8:18:8:114 | "
" |
+| tst.js:8:37:8:53 | document.location |
+| tst.js:8:37:8:58 | documen ... on.href |
+| tst.js:8:37:8:114 | documen ... t=")+8) |
+| tst.js:12:5:12:33 | '' |
+| tst.js:12:28:12:33 | target |
+| tst.js:19:25:19:41 | document.location |
+| tst.js:20:18:20:35 | params.get('name') |
+| tst.js:23:42:23:47 | target |
+| tst.js:23:42:23:60 | target.substring(1) |
+| tst.js:24:18:24:41 | searchP ... 'name') |
+| tst.js:27:14:27:19 | target |
+| tst.js:29:18:29:23 | target |
+| tst.js:31:5:31:21 | document.location |
+| tst.js:31:5:31:28 | documen ... .search |
+| tst.js:34:10:34:26 | document.location |
+| tst.js:34:10:34:33 | documen ... .search |
+| tst.js:37:16:37:20 | bar() |
+| tst.js:43:16:43:44 | baz(doc ... search) |
+| tst.js:43:20:43:36 | document.location |
+| tst.js:43:20:43:43 | documen ... .search |
+| tst.js:49:16:49:45 | wrap(do ... search) |
+| tst.js:49:21:49:37 | document.location |
+| tst.js:49:21:49:44 | documen ... .search |
+| tst.js:57:16:57:45 | chop(do ... search) |
+| tst.js:57:21:57:37 | document.location |
+| tst.js:57:21:57:44 | documen ... .search |
+| tst.js:59:16:59:45 | chop(do ... search) |
+| tst.js:59:21:59:37 | document.location |
+| tst.js:59:21:59:44 | documen ... .search |
+| tst.js:61:16:61:32 | wrap(chop(bar())) |
+| tst.js:61:21:61:31 | chop(bar()) |
+| tst.js:61:26:61:30 | bar() |
+| tst.js:63:34:63:34 | s |
+| tst.js:65:18:65:18 | s |
+| tst.js:67:25:67:41 | document.location |
+| tst.js:67:25:67:48 | documen ... .search |
+| tst.js:68:25:68:41 | document.location |
+| tst.js:68:25:68:48 | documen ... .search |
+| tst.js:71:16:71:20 | bar() |
+| tst.js:73:1:73:27 | [,docum ... search] |
+| tst.js:73:3:73:19 | document.location |
+| tst.js:73:3:73:26 | documen ... .search |
+| tst.js:73:46:73:46 | x |
+| tst.js:74:7:74:7 | x |
+| tst.js:76:20:76:20 | x |
+| tst.js:80:49:80:65 | document.location |
+| tst.js:80:49:80:72 | documen ... .search |
+| tst.js:84:26:84:42 | document.location |
+| tst.js:84:26:84:49 | documen ... .search |
+| tst.js:85:25:85:41 | document.location |
+| tst.js:85:25:85:48 | documen ... .search |
+| tst.js:87:33:87:49 | document.location |
+| tst.js:87:33:87:56 | documen ... .search |
+| tst.js:88:32:88:48 | document.location |
+| tst.js:88:32:88:55 | documen ... .search |
+| tst.js:93:39:93:55 | document.location |
+| tst.js:93:39:93:62 | documen ... .search |
+| tst.js:99:30:99:46 | document.location |
+| tst.js:99:30:99:53 | documen ... .search |
+| tst.js:105:25:105:41 | document.location |
+| tst.js:105:25:105:48 | documen ... .search |
+| tst.js:110:7:110:44 | v |
+| tst.js:110:11:110:27 | document.location |
+| tst.js:110:11:110:34 | documen ... .search |
+| tst.js:110:11:110:44 | documen ... bstr(1) |
+| tst.js:113:18:113:18 | v |
+| tst.js:145:29:145:43 | window.location |
+| tst.js:145:29:145:50 | window. ... .search |
+| tst.js:148:29:148:29 | v |
+| tst.js:148:49:148:49 | v |
+| tst.js:152:29:152:46 | xssSourceService() |
+| tst.js:155:40:155:54 | window.location |
+| tst.js:155:40:155:61 | window. ... .search |
+| tst.js:174:9:174:41 | target |
+| tst.js:174:18:174:34 | document.location |
+| tst.js:174:18:174:41 | documen ... .search |
+| tst.js:177:28:177:33 | target |
+| tst.js:181:9:181:42 | tainted |
+| tst.js:181:19:181:35 | document.location |
+| tst.js:181:19:181:42 | documen ... .search |
+| tst.js:183:31:183:37 | tainted |
+| tst.js:185:42:185:48 | tainted |
+| tst.js:186:33:186:39 | tainted |
+| tst.js:188:54:188:60 | tainted |
+| tst.js:189:45:189:51 | tainted |
+| tst.js:194:9:194:42 | tainted |
+| tst.js:194:19:194:35 | document.location |
+| tst.js:194:19:194:42 | documen ... .search |
+| tst.js:196:67:196:73 | tainted |
+| tst.js:197:67:197:73 | tainted |
+| tst.js:200:20:200:19 | tainted |
+| tst.js:201:35:201:41 | tainted |
+| tst.js:203:27:203:26 | tainted |
+| tst.js:203:46:203:52 | tainted |
+| tst.js:204:38:204:44 | tainted |
+| tst.js:205:35:205:41 | tainted |
+| tst.js:209:28:209:46 | this.state.tainted1 |
+| tst.js:210:28:210:46 | this.state.tainted2 |
+| tst.js:211:28:211:46 | this.state.tainted3 |
+| tst.js:215:32:215:49 | prevState.tainted4 |
+| tst.js:222:28:222:46 | this.props.tainted1 |
+| tst.js:223:28:223:46 | this.props.tainted2 |
+| tst.js:224:28:224:46 | this.props.tainted3 |
+| tst.js:228:32:228:49 | prevProps.tainted4 |
+| tst.js:233:35:233:41 | tainted |
+| tst.js:235:20:235:26 | tainted |
+| tst.js:237:23:237:29 | tainted |
+| tst.js:238:23:238:29 | tainted |
+| tst.js:244:39:244:55 | props.propTainted |
+| tst.js:248:60:248:82 | this.st ... Tainted |
+| tst.js:252:23:252:29 | tainted |
+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 |
+| jquery.js:2:7:2:40 | tainted | jquery.js:4:5:4:11 | tainted |
+| 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:17:2:33 | document.location | jquery.js:2:17:2:40 | documen ... .search |
+| jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted |
+| jquery.js:7:5:7:26 | "
" |
+| jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:26 | "
" |
+| tst.js:8:37:8:53 | document.location | 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:8:18:8:114 | "
' |
+| tst.js:12:28:12:33 | target | tst.js:12:5:12:33 | '" | jquery.js:2:17:2:33 | document.location | jquery.js:7:5:7:34 | "
" | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:33 | document.location | user-provided value |
+| jquery.js:8:18:8:34 | "XSS: " + tainted | jquery.js:2:17:2:33 | document.location | jquery.js:8:18:8:34 | "XSS: " + tainted | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:33 | document.location | user-provided value |
+| 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}.` | HTML injection vulnerability due to $@. | nodemailer.js:13:50:13:66 | req.query.message | user-provided value |
+| react-native.js:8:18:8:24 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:8:18:8:24 | tainted | Cross-site scripting vulnerability due to $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value |
+| react-native.js:9:27:9:33 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:9:27:9:33 | tainted | Cross-site scripting vulnerability due to $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value |
+| 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 | Cross-site scripting vulnerability due to $@. | string-manipulations.js:3:16:3:32 | document.location | user-provided value |
+| string-manipulations.js:4:16:4:37 | documen ... on.href | string-manipulations.js:4:16:4:32 | document.location | string-manipulations.js:4:16:4:37 | documen ... on.href | Cross-site scripting vulnerability due to $@. | string-manipulations.js:4:16:4:32 | document.location | user-provided value |
+| string-manipulations.js:5:16:5:47 | documen ... lueOf() | string-manipulations.js:5:16:5:32 | document.location | string-manipulations.js:5:16:5:47 | documen ... lueOf() | Cross-site scripting vulnerability due to $@. | string-manipulations.js:5:16:5:32 | document.location | user-provided value |
+| string-manipulations.js:6:16:6:43 | documen ... f.sup() | string-manipulations.js:6:16:6:32 | document.location | string-manipulations.js:6:16:6:43 | documen ... f.sup() | Cross-site scripting vulnerability due to $@. | string-manipulations.js:6:16:6:32 | document.location | user-provided value |
+| string-manipulations.js:7:16:7:51 | documen ... rCase() | string-manipulations.js:7:16:7:32 | document.location | string-manipulations.js:7:16:7:51 | documen ... rCase() | Cross-site scripting vulnerability due to $@. | string-manipulations.js:7:16:7:32 | document.location | user-provided value |
+| string-manipulations.js:8:16:8:48 | documen ... mLeft() | string-manipulations.js:8:16:8:32 | document.location | string-manipulations.js:8:16:8:48 | documen ... mLeft() | Cross-site scripting vulnerability due to $@. | string-manipulations.js:8:16:8:32 | document.location | user-provided value |
+| string-manipulations.js:9:16:9:58 | String. ... n.href) | string-manipulations.js:9:36:9:52 | document.location | string-manipulations.js:9:16:9:58 | String. ... n.href) | Cross-site scripting vulnerability due to $@. | string-manipulations.js:9:36:9:52 | document.location | user-provided value |
+| string-manipulations.js:10:16:10:45 | String( ... n.href) | string-manipulations.js:10:23:10:39 | document.location | string-manipulations.js:10:16:10:45 | String( ... n.href) | Cross-site scripting vulnerability due to $@. | string-manipulations.js:10:23:10:39 | document.location | user-provided value |
+| translate.js:9:27:9:50 | searchP ... 'term') | translate.js:6:16:6:32 | document.location | translate.js:9:27:9:50 | searchP ... 'term') | Cross-site scripting vulnerability due to $@. | translate.js:6:16:6:32 | document.location | user-provided value |
+| tst.js:5:18:5:23 | target | tst.js:2:16:2:32 | document.location | tst.js:5:18:5:23 | target | Cross-site scripting vulnerability due to $@. | tst.js:2:16:2:32 | document.location | user-provided value |
+| tst.js:8:18:8:126 | "
" | tst.js:8:37:8:53 | document.location | tst.js:8:18:8:126 | "" | Cross-site scripting vulnerability due to $@. | tst.js:8:37:8:53 | document.location | user-provided value |
+| tst.js:12:5:12:42 | '' | tst.js:2:16:2:32 | document.location | tst.js:12:5:12:42 | '
' | Cross-site scripting vulnerability due to $@. | tst.js:2:16:2:32 | document.location | user-provided value |
+| tst.js:20:18:20:35 | params.get('name') | tst.js:19:25:19:41 | document.location | tst.js:20:18:20:35 | params.get('name') | Cross-site scripting vulnerability due to $@. | tst.js:19:25:19:41 | document.location | user-provided value |
+| tst.js:24:18:24:41 | searchP ... 'name') | tst.js:2:16:2:32 | document.location | tst.js:24:18:24:41 | searchP ... 'name') | Cross-site scripting vulnerability due to $@. | tst.js:2:16:2:32 | document.location | user-provided value |
+| tst.js:29:18:29:23 | target | tst.js:31:5:31:21 | document.location | tst.js:29:18:29:23 | target | Cross-site scripting vulnerability due to $@. | tst.js:31:5:31:21 | document.location | user-provided value |
+| tst.js:37:16:37:20 | bar() | tst.js:34:10:34:26 | document.location | tst.js:37:16:37:20 | bar() | Cross-site scripting vulnerability due to $@. | tst.js:34:10:34:26 | document.location | user-provided value |
+| tst.js:43:16:43:44 | baz(doc ... search) | tst.js:43:20:43:36 | document.location | tst.js:43:16:43:44 | baz(doc ... search) | Cross-site scripting vulnerability due to $@. | tst.js:43:20:43:36 | document.location | user-provided value |
+| tst.js:49:16:49:45 | wrap(do ... search) | tst.js:49:21:49:37 | document.location | tst.js:49:16:49:45 | wrap(do ... search) | Cross-site scripting vulnerability due to $@. | tst.js:49:21:49:37 | document.location | user-provided value |
+| tst.js:57:16:57:45 | chop(do ... search) | tst.js:57:21:57:37 | document.location | tst.js:57:16:57:45 | chop(do ... search) | Cross-site scripting vulnerability due to $@. | tst.js:57:21:57:37 | document.location | user-provided value |
+| tst.js:59:16:59:45 | chop(do ... search) | tst.js:59:21:59:37 | document.location | tst.js:59:16:59:45 | chop(do ... search) | Cross-site scripting vulnerability due to $@. | tst.js:59:21:59:37 | document.location | user-provided value |
+| tst.js:61:16:61:32 | wrap(chop(bar())) | tst.js:34:10:34:26 | document.location | tst.js:61:16:61:32 | wrap(chop(bar())) | Cross-site scripting vulnerability due to $@. | tst.js:34:10:34:26 | document.location | user-provided value |
+| tst.js:65:18:65:18 | s | tst.js:67:25:67:41 | document.location | tst.js:65:18:65:18 | s | Cross-site scripting vulnerability due to $@. | tst.js:67:25:67:41 | document.location | user-provided value |
+| tst.js:65:18:65:18 | s | tst.js:68:25:68:41 | document.location | tst.js:65:18:65:18 | s | Cross-site scripting vulnerability due to $@. | tst.js:68:25:68:41 | document.location | user-provided value |
+| tst.js:71:16:71:20 | bar() | tst.js:34:10:34:26 | document.location | tst.js:71:16:71:20 | bar() | Cross-site scripting vulnerability due to $@. | tst.js:34:10:34:26 | document.location | user-provided value |
+| tst.js:76:20:76:20 | x | tst.js:73:3:73:19 | document.location | tst.js:76:20:76:20 | x | Cross-site scripting vulnerability due to $@. | tst.js:73:3:73:19 | document.location | user-provided value |
+| tst.js:80:49:80:72 | documen ... .search | tst.js:80:49:80:65 | document.location | tst.js:80:49:80:72 | documen ... .search | Cross-site scripting vulnerability due to $@. | tst.js:80:49:80:65 | document.location | user-provided value |
+| tst.js:84:26:84:49 | documen ... .search | tst.js:84:26:84:42 | document.location | tst.js:84:26:84:49 | documen ... .search | Cross-site scripting vulnerability due to $@. | tst.js:84:26:84:42 | document.location | user-provided value |
+| tst.js:85:25:85:48 | documen ... .search | tst.js:85:25:85:41 | document.location | tst.js:85:25:85:48 | documen ... .search | Cross-site scripting vulnerability due to $@. | tst.js:85:25:85:41 | document.location | user-provided value |
+| tst.js:87:33:87:56 | documen ... .search | tst.js:87:33:87:49 | document.location | tst.js:87:33:87:56 | documen ... .search | Cross-site scripting vulnerability due to $@. | tst.js:87:33:87:49 | document.location | user-provided value |
+| tst.js:88:32:88:55 | documen ... .search | tst.js:88:32:88:48 | document.location | tst.js:88:32:88:55 | documen ... .search | Cross-site scripting vulnerability due to $@. | tst.js:88:32:88:48 | document.location | user-provided value |
+| tst.js:93:39:93:62 | documen ... .search | tst.js:93:39:93:55 | document.location | tst.js:93:39:93:62 | documen ... .search | Cross-site scripting vulnerability due to $@. | tst.js:93:39:93:55 | document.location | user-provided value |
+| tst.js:99:30:99:53 | documen ... .search | tst.js:99:30:99:46 | document.location | tst.js:99:30:99:53 | documen ... .search | Cross-site scripting vulnerability due to $@. | tst.js:99:30:99:46 | document.location | user-provided value |
+| tst.js:105:25:105:48 | documen ... .search | tst.js:105:25:105:41 | document.location | tst.js:105:25:105:48 | documen ... .search | Cross-site scripting vulnerability due to $@. | tst.js:105:25:105:41 | document.location | user-provided value |
+| tst.js:113:18:113:18 | v | tst.js:110:11:110:27 | document.location | tst.js:113:18:113:18 | v | Cross-site scripting vulnerability due to $@. | tst.js:110:11:110:27 | document.location | user-provided value |
+| tst.js:148:49:148:49 | v | tst.js:145:29:145:43 | window.location | tst.js:148:49:148:49 | v | Cross-site scripting vulnerability due to $@. | tst.js:145:29:145:43 | window.location | user-provided value |
+| tst.js:152:29:152:46 | xssSourceService() | tst.js:155:40:155:54 | window.location | tst.js:152:29:152:46 | xssSourceService() | Cross-site scripting vulnerability due to $@. | tst.js:155:40:155:54 | window.location | user-provided value |
+| tst.js:177:28:177:33 | target | tst.js:174:18:174:34 | document.location | tst.js:177:28:177:33 | target | Cross-site scripting vulnerability due to $@. | tst.js:174:18:174:34 | document.location | user-provided value |
+| tst.js:183:31:183:37 | tainted | tst.js:181:19:181:35 | document.location | tst.js:183:31:183:37 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:181:19:181:35 | document.location | user-provided value |
+| tst.js:185:42:185:48 | tainted | tst.js:181:19:181:35 | document.location | tst.js:185:42:185:48 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:181:19:181:35 | document.location | user-provided value |
+| tst.js:186:33:186:39 | tainted | tst.js:181:19:181:35 | document.location | tst.js:186:33:186:39 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:181:19:181:35 | document.location | user-provided value |
+| tst.js:188:54:188:60 | tainted | tst.js:181:19:181:35 | document.location | tst.js:188:54:188:60 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:181:19:181:35 | document.location | user-provided value |
+| tst.js:189:45:189:51 | tainted | tst.js:181:19:181:35 | document.location | tst.js:189:45:189:51 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:181:19:181:35 | document.location | user-provided value |
+| tst.js:196:67:196:73 | tainted | tst.js:194:19:194:35 | document.location | tst.js:196:67:196:73 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
+| tst.js:197:67:197:73 | tainted | tst.js:194:19:194:35 | document.location | tst.js:197:67:197:73 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
+| tst.js:209:28:209:46 | this.state.tainted1 | tst.js:194:19:194:35 | document.location | tst.js:209:28:209:46 | this.state.tainted1 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
+| tst.js:210:28:210:46 | this.state.tainted2 | tst.js:194:19:194:35 | document.location | tst.js:210:28:210:46 | this.state.tainted2 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
+| tst.js:211:28:211:46 | this.state.tainted3 | tst.js:194:19:194:35 | document.location | tst.js:211:28:211:46 | this.state.tainted3 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
+| tst.js:215:32:215:49 | prevState.tainted4 | tst.js:194:19:194:35 | document.location | tst.js:215:32:215:49 | prevState.tainted4 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
+| tst.js:222:28:222:46 | this.props.tainted1 | tst.js:194:19:194:35 | document.location | tst.js:222:28:222:46 | this.props.tainted1 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
+| tst.js:223:28:223:46 | this.props.tainted2 | tst.js:194:19:194:35 | document.location | tst.js:223:28:223:46 | this.props.tainted2 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
+| tst.js:224:28:224:46 | this.props.tainted3 | tst.js:194:19:194:35 | document.location | tst.js:224:28:224:46 | this.props.tainted3 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
+| tst.js:228:32:228:49 | prevProps.tainted4 | tst.js:194:19:194:35 | document.location | tst.js:228:32:228:49 | prevProps.tainted4 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
+| tst.js:248:60:248:82 | this.st ... Tainted | tst.js:194:19:194:35 | document.location | tst.js:248:60:248:82 | this.st ... Tainted | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
diff --git a/javascript/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/SqlInjection.expected
index e6c84156dd0c..319e938aecdb 100644
--- a/javascript/ql/test/query-tests/Security/CWE-089/SqlInjection.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-089/SqlInjection.expected
@@ -1,22 +1,160 @@
-| mongodb.js:18:16:18:20 | query | This query depends on $@. | mongodb.js:13:19:13:26 | req.body | a user-provided value |
-| mongodb.js:32:18:32:45 | { title ... itle) } | This query depends on $@. | mongodb.js:26:19:26:26 | req.body | a user-provided value |
-| mongodb.js:54:16:54:20 | query | This query depends on $@. | mongodb.js:49:19:49:33 | req.query.title | a user-provided value |
-| mongodb_bodySafe.js:29:16:29:20 | query | This query depends on $@. | mongodb_bodySafe.js:24:19:24:33 | req.query.title | a user-provided value |
-| mongoose.js:27:20:27:24 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:30:25:30:29 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:33:24:33:28 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:36:31:36:35 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:39:19:39:23 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:42:22:42:26 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:45:31:45:35 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:48:31:48:35 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:51:31:51:35 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:54:25:54:29 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:57:21:57:25 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:60:25:60:29 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:63:24:63:28 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongooseJsonParse.js:23:19:23:23 | query | This query depends on $@. | mongooseJsonParse.js:20:30:20:43 | req.query.data | a user-provided value |
-| tst2.js:9:27:9:84 | "select ... d + "'" | This query depends on $@. | tst2.js:9:66:9:78 | req.params.id | a user-provided value |
-| tst3.js:10:14:10:19 | query1 | This query depends on $@. | tst3.js:9:16:9:34 | req.params.category | a user-provided value |
-| tst4.js:8:10:8:66 | 'SELECT ... d + '"' | This query depends on $@. | tst4.js:8:46:8:60 | $routeParams.id | a user-provided value |
-| tst.js:10:10:10:64 | 'SELECT ... d + '"' | This query depends on $@. | tst.js:10:46:10:58 | req.params.id | a user-provided value |
+nodes
+| 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:32 | req.body.title |
+| mongodb.js:14:59:14:58 | 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:32 | req.body.title |
+| mongodb.js:27:11:27:35 | title |
+| 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:50:59:50:58 | query |
+| mongodb.js:54:16:54:20 | 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:25:59:25:58 | query |
+| mongodb_bodySafe.js:29:16:29:20 | query |
+| mongoose.js:20:11:20:20 | query |
+| mongoose.js:20:19:20:20 | {} |
+| mongoose.js:21:19:21:26 | req.body |
+| mongoose.js:21:19:21:32 | req.body.title |
+| mongoose.js:27:20:27:24 | query |
+| mongoose.js:30:25:30:29 | query |
+| mongoose.js:33:24:33:28 | query |
+| mongoose.js:36:31:36:35 | query |
+| mongoose.js:39:19:39:23 | query |
+| mongoose.js:42:22:42:26 | query |
+| mongoose.js:45:31:45:35 | query |
+| mongoose.js:48:31:48:35 | query |
+| mongoose.js:51:31:51:35 | query |
+| mongoose.js:54:25:54:29 | query |
+| mongoose.js:57:21:57:25 | query |
+| mongoose.js:60:25:60:29 | query |
+| mongoose.js:63:24:63:28 | 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:23:19:23:23 | query |
+| tst2.js:9:27:9:78 | "select ... rams.id |
+| tst2.js:9:27:9:84 | "select ... d + "'" |
+| tst2.js:9:66:9:78 | req.params.id |
+| tst3.js:8:7:9:55 | query1 |
+| tst3.js:8:16:9:34 | "SELECT ... ategory |
+| tst3.js:8:16:9:55 | "SELECT ... PRICE" |
+| tst3.js:9:16:9:34 | req.params.category |
+| tst3.js:10:14:10:19 | query1 |
+| tst4.js:8:10:8:60 | 'SELECT ... rams.id |
+| tst4.js:8:10:8:66 | 'SELECT ... d + '"' |
+| tst4.js:8:46:8:60 | $routeParams.id |
+| tst.js:10:10:10:58 | 'SELECT ... rams.id |
+| tst.js:10:10:10:64 | 'SELECT ... d + '"' |
+| tst.js:10:46:10:58 | req.params.id |
+edges
+| mongodb.js:12:11:12:20 | query | mongodb.js:14:59:14:58 | 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: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:14:59:14:58 | query |
+| mongodb.js:13:19:13:32 | req.body.title | mongodb.js:18:16:18:20 | query |
+| mongodb.js:14:59:14:58 | query | mongodb.js:18:16:18:20 | query |
+| mongodb.js:26:11:26:32 | title | mongodb.js:27:11:27:35 | 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:27:11:27:35 | title | mongodb.js:32:38:32:42 | 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:50:59:50:58 | 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:19:49:33 | req.query.title | mongodb.js:48:19:48:20 | {} |
+| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:50:59:50:58 | query |
+| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:54:16:54:20 | query |
+| mongodb.js:50:59:50:58 | query | mongodb.js:54:16:54:20 | query |
+| mongodb_bodySafe.js:23:11:23:20 | query | mongodb_bodySafe.js:25:59:25:58 | 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: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:25:59:25:58 | query |
+| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query |
+| mongodb_bodySafe.js:25:59:25:58 | query | mongodb_bodySafe.js:29:16:29:20 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:27:20:27:24 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:30:25:30:29 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:33:24:33:28 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:36:31:36:35 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:39:19:39:23 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:42:22:42:26 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:45:31:45:35 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:48:31:48:35 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:51:31:51:35 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:54:25:54:29 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:57:21:57:25 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:60:25:60:29 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:63:24:63:28 | query |
+| mongoose.js:20:19:20:20 | {} | mongoose.js:20:11:20:20 | query |
+| mongoose.js:21:19:21:26 | req.body | mongoose.js:21:19:21:32 | req.body.title |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:20:11:20:20 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:20:19:20:20 | {} |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:27:20:27:24 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:30:25:30:29 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:33:24:33:28 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:36:31:36:35 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:39:19:39:23 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:42:22:42:26 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:45:31:45:35 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:48:31:48:35 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:51:31:51:35 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:54:25:54:29 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:57:21:57:25 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:60:25:60:29 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:63:24:63:28 | 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) |
+| tst2.js:9:27:9:78 | "select ... rams.id | tst2.js:9:27:9:84 | "select ... d + "'" |
+| tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:78 | "select ... rams.id |
+| tst3.js:8:7:9:55 | query1 | tst3.js:10:14:10:19 | query1 |
+| tst3.js:8:16:9:34 | "SELECT ... ategory | tst3.js:8:16:9:55 | "SELECT ... PRICE" |
+| tst3.js:8:16:9:55 | "SELECT ... PRICE" | tst3.js:8:7:9:55 | query1 |
+| tst3.js:9:16:9:34 | req.params.category | tst3.js:8:16:9:34 | "SELECT ... ategory |
+| tst4.js:8:10:8:60 | 'SELECT ... rams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' |
+| tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:60 | 'SELECT ... rams.id |
+| tst.js:10:10:10:58 | 'SELECT ... rams.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' |
+| tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:58 | 'SELECT ... rams.id |
+#select
+| mongodb.js:18:16:18:20 | query | mongodb.js:13:19:13:26 | req.body | mongodb.js:18:16:18:20 | query | This query depends on $@. | mongodb.js:13:19:13:26 | req.body | a user-provided value |
+| mongodb.js:32:18:32:45 | { title ... itle) } | mongodb.js:26:19:26:26 | req.body | mongodb.js:32:18:32:45 | { title ... itle) } | This query depends on $@. | mongodb.js:26:19:26:26 | req.body | a user-provided value |
+| mongodb.js:54:16:54:20 | query | mongodb.js:49:19:49:33 | req.query.title | mongodb.js:54:16:54:20 | query | This query depends on $@. | mongodb.js:49:19:49:33 | req.query.title | a user-provided value |
+| 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 | This query depends on $@. | mongodb_bodySafe.js:24:19:24:33 | req.query.title | a user-provided value |
+| mongoose.js:27:20:27:24 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:27:20:27:24 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:30:25:30:29 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:30:25:30:29 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:33:24:33:28 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:33:24:33:28 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:36:31:36:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:36:31:36:35 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:39:19:39:23 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:39:19:39:23 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:42:22:42:26 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:42:22:42:26 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:45:31:45:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:45:31:45:35 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:48:31:48:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:48:31:48:35 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:51:31:51:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:51:31:51:35 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:54:25:54:29 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:54:25:54:29 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:57:21:57:25 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:57:21:57:25 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:60:25:60:29 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:60:25:60:29 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:63:24:63:28 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:63:24:63:28 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a 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 depends on $@. | mongooseJsonParse.js:20:30:20:43 | req.query.data | a user-provided value |
+| 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 + "'" | This query depends on $@. | tst2.js:9:66:9:78 | req.params.id | a user-provided value |
+| tst3.js:10:14:10:19 | query1 | tst3.js:9:16:9:34 | req.params.category | tst3.js:10:14:10:19 | query1 | This query depends on $@. | tst3.js:9:16:9:34 | req.params.category | a user-provided value |
+| tst4.js:8:10:8:66 | 'SELECT ... d + '"' | tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | This query depends on $@. | tst4.js:8:46:8:60 | $routeParams.id | a user-provided value |
+| 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 + '"' | This query depends on $@. | tst.js:10:46:10:58 | req.params.id | a user-provided value |
diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection.expected
index 988c4d5e2e39..3abab2036520 100644
--- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection.expected
@@ -1,25 +1,84 @@
-| angularjs.js:10:22:10:36 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:10:22:10:36 | document.cookie | User-provided value |
-| angularjs.js:13:23:13:37 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:13:23:13:37 | document.cookie | User-provided value |
-| angularjs.js:16:28:16:42 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:16:28:16:42 | document.cookie | User-provided value |
-| angularjs.js:19:22:19:36 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:19:22:19:36 | document.cookie | User-provided value |
-| angularjs.js:22:27:22:41 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:22:27:22:41 | document.cookie | User-provided value |
-| angularjs.js:25:23:25:37 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:25:23:25:37 | document.cookie | User-provided value |
-| angularjs.js:28:33:28:47 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:28:33:28:47 | document.cookie | User-provided value |
-| angularjs.js:31:28:31:42 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:31:28:31:42 | document.cookie | User-provided value |
-| angularjs.js:34:18:34:32 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:34:18:34:32 | document.cookie | User-provided value |
-| angularjs.js:40:18:40:32 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:40:18:40:32 | document.cookie | User-provided value |
-| angularjs.js:44:17:44:31 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:44:17:44:31 | document.cookie | User-provided value |
-| angularjs.js:47:16:47:30 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:47:16:47:30 | document.cookie | User-provided value |
-| angularjs.js:50:22:50:36 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:50:22:50:36 | document.cookie | User-provided value |
-| angularjs.js:53:32:53:46 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:53:32:53:46 | document.cookie | User-provided value |
-| 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 |
-| express.js:7:24:7:69 | "return ... + "];" | $@ flows to here and is interpreted as code. | express.js:7:44:7:62 | req.param("wobble") | User-provided value |
-| express.js:9:34:9:79 | "return ... + "];" | $@ flows to here and is interpreted as code. | express.js:9:54:9:72 | req.param("wobble") | User-provided value |
-| express.js:12:8:12:53 | "return ... + "];" | $@ flows to here and is interpreted as code. | express.js:12:28:12:46 | req.param("wobble") | User-provided value |
-| react-native.js:8:32:8:38 | tainted | $@ flows to here and is interpreted as code. | react-native.js:7:17:7:33 | req.param("code") | User-provided value |
-| react-native.js:10:23:10:29 | tainted | $@ flows to here and is interpreted as code. | react-native.js:7:17:7:33 | req.param("code") | User-provided value |
-| tst.js:2:6:2:83 | documen ... t=")+8) | $@ flows to here and is interpreted as code. | tst.js:2:6:2:22 | document.location | User-provided value |
-| tst.js:5:12:5:33 | documen ... on.hash | $@ flows to here and is interpreted as code. | tst.js:5:12:5:28 | document.location | User-provided value |
-| tst.js:14:10:14:65 | documen ... , "$1") | $@ flows to here and is interpreted as code. | tst.js:14:10:14:24 | document.cookie | User-provided value |
-| tst.js:17:21:17:42 | documen ... on.hash | $@ flows to here and is interpreted as code. | tst.js:17:21:17:37 | document.location | User-provided value |
-| tst.js:20:30:20:51 | documen ... on.hash | $@ flows to here and is interpreted as code. | tst.js:20:30:20:46 | document.location | User-provided value |
+nodes
+| angularjs.js:10:22:10:36 | document.cookie |
+| angularjs.js:13:23:13:37 | document.cookie |
+| angularjs.js:16:28:16:42 | document.cookie |
+| angularjs.js:19:22:19:36 | document.cookie |
+| angularjs.js:22:27:22:41 | document.cookie |
+| angularjs.js:25:23:25:37 | document.cookie |
+| angularjs.js:28:33:28:47 | document.cookie |
+| angularjs.js:31:28:31:42 | document.cookie |
+| angularjs.js:34:18:34:32 | document.cookie |
+| angularjs.js:40:18:40:32 | document.cookie |
+| angularjs.js:44:17:44:31 | document.cookie |
+| angularjs.js:47:16:47:30 | document.cookie |
+| angularjs.js:50:22:50:36 | document.cookie |
+| angularjs.js:53:32:53:46 | document.cookie |
+| eslint-escope-build.js:20:22:20:22 | c |
+| eslint-escope-build.js:21:16:21:16 | c |
+| express.js:7:24:7:62 | "return ... obble") |
+| express.js:7:24:7:69 | "return ... + "];" |
+| express.js:7:44:7:62 | req.param("wobble") |
+| express.js:9:34:9:72 | "return ... obble") |
+| express.js:9:34:9:79 | "return ... + "];" |
+| express.js:9:54:9:72 | req.param("wobble") |
+| express.js:12:8:12:46 | "return ... obble") |
+| express.js:12:8:12:53 | "return ... + "];" |
+| express.js:12:28:12:46 | req.param("wobble") |
+| react-native.js:7:7:7:33 | tainted |
+| react-native.js:7:17:7:33 | req.param("code") |
+| react-native.js:8:32:8:38 | tainted |
+| react-native.js:10:23:10:29 | tainted |
+| tst.js:2:6:2:22 | document.location |
+| tst.js:2:6:2:27 | documen ... on.href |
+| tst.js:2:6:2:83 | documen ... t=")+8) |
+| tst.js:5:12:5:28 | document.location |
+| tst.js:5:12:5:33 | documen ... on.hash |
+| tst.js:14:10:14:24 | document.cookie |
+| tst.js:14:10:14:65 | documen ... , "$1") |
+| tst.js:17:21:17:37 | document.location |
+| tst.js:17:21:17:42 | documen ... on.hash |
+| tst.js:20:30:20:46 | document.location |
+| tst.js:20:30:20:51 | documen ... on.hash |
+edges
+| eslint-escope-build.js:20:22:20:22 | c | eslint-escope-build.js:21:16:21:16 | c |
+| express.js:7:24:7:62 | "return ... obble") | express.js:7:24:7:69 | "return ... + "];" |
+| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:62 | "return ... obble") |
+| express.js:9:34:9:72 | "return ... obble") | express.js:9:34:9:79 | "return ... + "];" |
+| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:72 | "return ... obble") |
+| express.js:12:8:12:46 | "return ... obble") | express.js:12:8:12:53 | "return ... + "];" |
+| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:46 | "return ... obble") |
+| 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 |
+| tst.js:2:6:2:22 | document.location | 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:5:12:5:28 | document.location | tst.js:5:12:5:33 | documen ... on.hash |
+| tst.js:14:10:14:24 | document.cookie | tst.js:14:10:14:65 | documen ... , "$1") |
+| tst.js:17:21:17:37 | document.location | tst.js:17:21:17:42 | documen ... on.hash |
+| tst.js:20:30:20:46 | document.location | tst.js:20:30:20:51 | documen ... on.hash |
+#select
+| angularjs.js:10:22:10:36 | document.cookie | angularjs.js:10:22:10:36 | document.cookie | angularjs.js:10:22:10:36 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:10:22:10:36 | document.cookie | User-provided value |
+| angularjs.js:13:23:13:37 | document.cookie | angularjs.js:13:23:13:37 | document.cookie | angularjs.js:13:23:13:37 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:13:23:13:37 | document.cookie | User-provided value |
+| angularjs.js:16:28:16:42 | document.cookie | angularjs.js:16:28:16:42 | document.cookie | angularjs.js:16:28:16:42 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:16:28:16:42 | document.cookie | User-provided value |
+| angularjs.js:19:22:19:36 | document.cookie | angularjs.js:19:22:19:36 | document.cookie | angularjs.js:19:22:19:36 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:19:22:19:36 | document.cookie | User-provided value |
+| angularjs.js:22:27:22:41 | document.cookie | angularjs.js:22:27:22:41 | document.cookie | angularjs.js:22:27:22:41 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:22:27:22:41 | document.cookie | User-provided value |
+| angularjs.js:25:23:25:37 | document.cookie | angularjs.js:25:23:25:37 | document.cookie | angularjs.js:25:23:25:37 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:25:23:25:37 | document.cookie | User-provided value |
+| angularjs.js:28:33:28:47 | document.cookie | angularjs.js:28:33:28:47 | document.cookie | angularjs.js:28:33:28:47 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:28:33:28:47 | document.cookie | User-provided value |
+| angularjs.js:31:28:31:42 | document.cookie | angularjs.js:31:28:31:42 | document.cookie | angularjs.js:31:28:31:42 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:31:28:31:42 | document.cookie | User-provided value |
+| angularjs.js:34:18:34:32 | document.cookie | angularjs.js:34:18:34:32 | document.cookie | angularjs.js:34:18:34:32 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:34:18:34:32 | document.cookie | User-provided value |
+| angularjs.js:40:18:40:32 | document.cookie | angularjs.js:40:18:40:32 | document.cookie | angularjs.js:40:18:40:32 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:40:18:40:32 | document.cookie | User-provided value |
+| angularjs.js:44:17:44:31 | document.cookie | angularjs.js:44:17:44:31 | document.cookie | angularjs.js:44:17:44:31 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:44:17:44:31 | document.cookie | User-provided value |
+| angularjs.js:47:16:47:30 | document.cookie | angularjs.js:47:16:47:30 | document.cookie | angularjs.js:47:16:47:30 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:47:16:47:30 | document.cookie | User-provided value |
+| angularjs.js:50:22:50:36 | document.cookie | angularjs.js:50:22:50:36 | document.cookie | angularjs.js:50:22:50:36 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:50:22:50:36 | document.cookie | User-provided value |
+| angularjs.js:53:32:53:46 | document.cookie | angularjs.js:53:32:53:46 | document.cookie | angularjs.js:53:32:53:46 | document.cookie | $@ flows to here and is interpreted as code. | angularjs.js:53:32:53:46 | document.cookie | User-provided value |
+| 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 |
+| express.js:7:24:7:69 | "return ... + "];" | express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | $@ flows to here and is interpreted as code. | express.js:7:44:7:62 | req.param("wobble") | User-provided value |
+| express.js:9:34:9:79 | "return ... + "];" | express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | $@ flows to here and is interpreted as code. | express.js:9:54:9:72 | req.param("wobble") | User-provided value |
+| express.js:12:8:12:53 | "return ... + "];" | express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | $@ flows to here and is interpreted as code. | express.js:12:28:12:46 | req.param("wobble") | User-provided value |
+| react-native.js:8:32:8:38 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:8:32:8:38 | tainted | $@ flows to here and is interpreted as code. | react-native.js:7:17:7:33 | req.param("code") | User-provided value |
+| react-native.js:10:23:10:29 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:10:23:10:29 | tainted | $@ flows to here and is interpreted as code. | react-native.js:7:17:7:33 | req.param("code") | User-provided value |
+| tst.js:2:6:2:83 | documen ... t=")+8) | tst.js:2:6:2:22 | document.location | tst.js:2:6:2:83 | documen ... t=")+8) | $@ flows to here and is interpreted as code. | tst.js:2:6:2:22 | document.location | User-provided value |
+| tst.js:5:12:5:33 | documen ... on.hash | tst.js:5:12:5:28 | document.location | tst.js:5:12:5:33 | documen ... on.hash | $@ flows to here and is interpreted as code. | tst.js:5:12:5:28 | document.location | User-provided value |
+| tst.js:14:10:14:65 | documen ... , "$1") | tst.js:14:10:14:24 | document.cookie | tst.js:14:10:14:65 | documen ... , "$1") | $@ flows to here and is interpreted as code. | tst.js:14:10:14:24 | document.cookie | User-provided value |
+| tst.js:17:21:17:42 | documen ... on.hash | tst.js:17:21:17:37 | document.location | tst.js:17:21:17:42 | documen ... on.hash | $@ flows to here and is interpreted as code. | tst.js:17:21:17:37 | document.location | User-provided value |
+| tst.js:20:30:20:51 | documen ... on.hash | tst.js:20:30:20:46 | document.location | tst.js:20:30:20:51 | documen ... on.hash | $@ flows to here and is interpreted as code. | tst.js:20:30:20:46 | document.location | 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 92190be6b619..161ad1ecbbb7 100644
--- a/javascript/ql/test/query-tests/Security/CWE-134/TaintedFormatString.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-134/TaintedFormatString.expected
@@ -1,20 +1,43 @@
-| tst.js:5:15:5:30 | req.query.format | $@ flows here and is used in a format string. | tst.js:5:15:5:30 | req.query.format | User-provided value |
-| tst.js:6:26:6:41 | req.query.format | $@ flows here and is used in a format string. | tst.js:6:26:6:41 | req.query.format | User-provided value |
-| tst.js:7:15:7:30 | req.query.format | $@ flows here and is used in a format string. | tst.js:7:15:7:30 | req.query.format | User-provided value |
-| tst.js:8:17:8:32 | req.query.format | $@ flows here and is used in a format string. | tst.js:8:17:8:32 | req.query.format | User-provided value |
-| tst.js:9:16:9:31 | req.query.format | $@ flows here and is used in a format string. | tst.js:9:16:9:31 | req.query.format | User-provided value |
-| tst.js:10:12:10:27 | req.query.format | $@ flows here and is used in a format string. | tst.js:10:12:10:27 | req.query.format | User-provided value |
-| tst.js:11:32:11:47 | req.query.format | $@ flows here and is used in a format string. | tst.js:11:32:11:47 | req.query.format | User-provided value |
-| tst.js:12:21:12:36 | req.query.format | $@ flows here and is used in a format string. | tst.js:12:21:12:36 | req.query.format | User-provided value |
-| tst.js:13:35:13:50 | req.query.format | $@ flows here and is used in a format string. | tst.js:13:35:13:50 | req.query.format | User-provided value |
-| tst.js:14:29:14:44 | req.query.format | $@ flows here and is used in a format string. | tst.js:14:29:14:44 | req.query.format | User-provided value |
-| tst.js:15:30:15:45 | req.query.format | $@ flows here and is used in a format string. | tst.js:15:30:15:45 | req.query.format | User-provided value |
-| tst.js:16:26:16:41 | req.query.format | $@ flows here and is used in a format string. | tst.js:16:26:16:41 | req.query.format | User-provided value |
-| tst.js:17:30:17:45 | req.query.format | $@ flows here and is used in a format string. | tst.js:17:30:17:45 | req.query.format | User-provided value |
-| tst.js:18:38:18:53 | req.query.format | $@ flows here and is used in a format string. | tst.js:18:38:18:53 | req.query.format | User-provided value |
-| tst.js:20:17:20:32 | req.query.format | $@ flows here and is used in a format string. | tst.js:20:17:20:32 | req.query.format | User-provided value |
-| tst.js:21:16:21:31 | req.query.format | $@ flows here and is used in a format string. | tst.js:21:16:21:31 | req.query.format | User-provided value |
-| tst.js:22:17:22:32 | req.query.format | $@ flows here and is used in a format string. | tst.js:22:17:22:32 | req.query.format | User-provided value |
-| tst.js:24:25:24:40 | req.query.format | $@ flows here and is used in a format string. | tst.js:24:25:24:40 | req.query.format | User-provided value |
-| tst.js:25:33:25:48 | req.query.format | $@ flows here and is used in a format string. | tst.js:25:33:25:48 | req.query.format | User-provided value |
-| tst.js:26:34:26:49 | req.query.format | $@ flows here and is used in a format string. | tst.js:26:34:26:49 | req.query.format | User-provided value |
+nodes
+| tst.js:5:15:5:30 | req.query.format |
+| tst.js:6:26:6:41 | req.query.format |
+| tst.js:7:15:7:30 | req.query.format |
+| tst.js:8:17:8:32 | req.query.format |
+| tst.js:9:16:9:31 | req.query.format |
+| tst.js:10:12:10:27 | req.query.format |
+| tst.js:11:32:11:47 | req.query.format |
+| tst.js:12:21:12:36 | req.query.format |
+| tst.js:13:35:13:50 | req.query.format |
+| tst.js:14:29:14:44 | req.query.format |
+| tst.js:15:30:15:45 | req.query.format |
+| tst.js:16:26:16:41 | req.query.format |
+| tst.js:17:30:17:45 | req.query.format |
+| tst.js:18:38:18:53 | req.query.format |
+| tst.js:20:17:20:32 | req.query.format |
+| tst.js:21:16:21:31 | req.query.format |
+| tst.js:22:17:22:32 | req.query.format |
+| tst.js:24:25:24:40 | req.query.format |
+| tst.js:25:33:25:48 | req.query.format |
+| tst.js:26:34:26:49 | req.query.format |
+edges
+#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 | $@ flows here and is used in a format string. | 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 | $@ flows here and is used in a format string. | tst.js:6:26:6:41 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:7:15:7:30 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:8:17:8:32 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:9:16:9:31 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:10:12:10:27 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:11:32:11:47 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:12:21:12:36 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:13:35:13:50 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:14:29:14:44 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:15:30:15:45 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:16:26:16:41 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:17:30:17:45 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:18:38:18:53 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:20:17:20:32 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:21:16:21:31 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:22:17:22:32 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:24:25:24:40 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:25:33:25:48 | req.query.format | User-provided value |
+| 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 | $@ flows here and is used in a format string. | tst.js:26:34:26:49 | req.query.format | User-provided value |
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 34dbdec53817..eaabdbaf5d2c 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,110 @@
-| bufferRead.js:33:21:33:28 | postData | $@ flows directly to outbound network request | bufferRead.js:12:22:12:43 | new Buf ... s.size) | File data |
-| googlecompiler.js:38:18:38:26 | post_data | $@ flows directly to outbound network request | googlecompiler.js:44:54:44:57 | data | File data |
-| readFileSync.js:26:18:26:18 | s | $@ flows directly to outbound network request | readFileSync.js:5:12:5:39 | fs.read ... t.txt") | File data |
-| readStreamRead.js:30:19:30:23 | chunk | $@ flows directly to outbound network request | readStreamRead.js:13:21:13:35 | readable.read() | File data |
-| request.js:8:11:8:20 | {jsonData} | $@ flows directly to outbound network request | request.js:28:52:28:55 | data | File data |
-| request.js:16:11:23:3 | {\\n u ... ody\\n } | $@ flows directly to outbound network request | request.js:43:51:43:54 | data | File data |
-| sentAsHeaders.js:14:20:19:9 | {\\n ... } | $@ flows directly to outbound network request | sentAsHeaders.js:10:79:10:84 | buffer | File data |
-| sentAsHeaders.js:20:20:25:9 | {\\n ... } | $@ flows directly to outbound network request | sentAsHeaders.js:10:79:10:84 | buffer | File data |
+nodes
+| bufferRead.js:12:13:12:43 | buffer |
+| bufferRead.js:12:22:12:43 | new Buf ... s.size) |
+| bufferRead.js:13:53:13:52 | buffer |
+| 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 |
+| 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:44:54:44:57 | data |
+| googlecompiler.js:55:6:55:9 | 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: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 |
+| readStreamRead.js:13:13:13:35 | chunk |
+| readStreamRead.js:13:21:13:35 | readable.read() |
+| readStreamRead.js:30:19:30:23 | chunk |
+| request.js:6:19:6:26 | 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:22:11:22:17 | xmlData |
+| request.js:28:52:28:55 | data |
+| request.js:34:6:34:9 | data |
+| request.js:35:14:35:17 | data |
+| request.js:43:51:43:54 | data |
+| request.js:49:6:49:9 | data |
+| request.js:50:13:50:16 | data |
+| 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: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:24:20:24:55 | { Refer ... ntent } |
+| sentAsHeaders.js:24:31:24:53 | "http:/ ... content |
+| sentAsHeaders.js:24:47:24:53 | content |
+edges
+| bufferRead.js:12:13:12:43 | buffer | bufferRead.js:13:53:13:52 | buffer |
+| bufferRead.js:12:22:12:43 | new Buf ... s.size) | bufferRead.js:12:13:12:43 | buffer |
+| bufferRead.js:13:53:13:52 | 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: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:55:6:55:9 | data |
+| googlecompiler.js:55:6:55:9 | 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: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:12:8:19 | jsonData | request.js:8:11:8:20 | {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:28:52:28:55 | data | request.js:34:6:34:9 | data |
+| request.js:34:6:34:9 | 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:49:6:49:9 | data |
+| request.js:49:6:49:9 | 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: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: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:31:24:53 | "http:/ ... content | sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } |
+| sentAsHeaders.js:24:47:24:53 | content | sentAsHeaders.js:24:31:24:53 | "http:/ ... content |
+#select
+| bufferRead.js:33:21:33:28 | postData | bufferRead.js:12:22:12:43 | new Buf ... s.size) | bufferRead.js:33:21:33:28 | postData | $@ flows directly to outbound network request | 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 | $@ flows directly to outbound network request | 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 | $@ flows directly to outbound network request | 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 | $@ flows directly to outbound network request | 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} | $@ flows directly to outbound network request | request.js:28:52:28:55 | data | File data |
+| request.js:16:11:23:3 | {\\n u ... ody\\n } | request.js:43:51:43:54 | data | request.js:16:11:23:3 | {\\n u ... ody\\n } | $@ flows directly to outbound network request | request.js:43:51:43:54 | data | File data |
+| sentAsHeaders.js:14:20:19:9 | {\\n ... } | sentAsHeaders.js:10:79:10:84 | buffer | sentAsHeaders.js:14:20:19:9 | {\\n ... } | $@ flows directly to outbound network request | sentAsHeaders.js:10:79:10:84 | buffer | File data |
+| sentAsHeaders.js:20:20:25:9 | {\\n ... } | sentAsHeaders.js:10:79:10:84 | buffer | sentAsHeaders.js:20:20:25:9 | {\\n ... } | $@ flows directly to outbound network request | sentAsHeaders.js:10:79:10:84 | buffer | File data |
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 8ec5b31e6e9d..e85b168c31eb 100644
--- a/javascript/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected
@@ -1,3 +1,22 @@
-| node.js:11:13:11:21 | err.stack | Stack trace information from $@ may be exposed to an external user here. | node.js:8:10:8:12 | err | here |
-| tst.js:7:13:7:13 | e | Stack trace information from $@ may be exposed to an external user here. | tst.js:6:12:6:12 | e | here |
-| tst.js:17:11:17:17 | e.stack | Stack trace information from $@ may be exposed to an external user here. | tst.js:6:12:6:12 | e | here |
+nodes
+| node.js:8:10:8:12 | 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: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 |
+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 |
+#select
+| node.js:11:13:11:21 | err.stack | node.js:8:10:8:12 | err | node.js:11:13:11:21 | err.stack | Stack trace information from $@ may be exposed to an external user here. | node.js:8:10:8:12 | err | here |
+| tst.js:7:13:7:13 | e | tst.js:6:12:6:12 | e | tst.js:7:13:7:13 | e | Stack trace information from $@ may be exposed to an external user here. | tst.js:6:12:6:12 | e | here |
+| tst.js:17:11:17:17 | e.stack | tst.js:6:12:6:12 | e | tst.js:17:11:17:17 | e.stack | Stack trace information from $@ may be exposed to an external user here. | tst.js:6:12:6:12 | e | here |
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 61b46506f0a9..fb3e8e11bba8 100644
--- a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected
@@ -1,26 +1,120 @@
-| passwords.js:2:17:2:24 | password | Sensitive data returned by $@ is logged here. | passwords.js:2:17:2:24 | password | an access to password |
-| passwords.js:3:17:3:26 | o.password | Sensitive data returned by $@ is logged here. | passwords.js:3:17:3:26 | o.password | an access to password |
-| passwords.js:4:17:4:29 | getPassword() | Sensitive data returned by $@ is logged here. | passwords.js:4:17:4:29 | getPassword() | a call to getPassword |
-| passwords.js:5:17:5:31 | o.getPassword() | Sensitive data returned by $@ is logged here. | passwords.js:5:17:5:31 | o.getPassword() | a call to getPassword |
-| passwords.js:8:21:8:21 | x | Sensitive data returned by $@ is logged here. | passwords.js:10:11:10:18 | password | an access to password |
-| passwords.js:12:18:12:25 | password | Sensitive data returned by $@ is logged here. | passwords.js:12:18:12:25 | password | an access to password |
-| passwords.js:14:17:14:38 | name + ... assword | Sensitive data returned by $@ is logged here. | passwords.js:14:31:14:38 | password | an access to password |
-| passwords.js:16:17:16:38 | `${name ... sword}` | Sensitive data returned by $@ is logged here. | passwords.js:16:29:16:36 | password | an access to password |
-| passwords.js:21:17:21:20 | obj1 | Sensitive data returned by $@ is logged here. | passwords.js:18:16:20:5 | {\\n ... x\\n } | an access to password |
-| passwords.js:26:17:26:20 | obj2 | Sensitive data returned by $@ is logged here. | passwords.js:24:12:24:19 | password | an access to password |
-| passwords.js:29:17:29:20 | obj3 | Sensitive data returned by $@ is logged here. | passwords.js:30:14:30:21 | password | an access to password |
-| passwords.js:78:17:78:38 | temp.en ... assword | Sensitive data returned by $@ is logged here. | passwords.js:77:37:77:53 | req.body.password | an access to password |
-| passwords.js:81:17:81:31 | `pw: ${secret}` | Sensitive data returned by $@ is logged here. | passwords.js:80:18:80:25 | password | an access to password |
-| passwords.js:93:21:93:46 | "Passwo ... assword | Sensitive data returned by $@ is logged here. | passwords.js:93:39:93:46 | password | an access to password |
-| passwords.js:98:21:98:46 | "Passwo ... assword | Sensitive data returned by $@ is logged here. | passwords.js:98:39:98:46 | password | an access to password |
-| passwords.js:105:21:105:46 | "Passwo ... assword | Sensitive data returned by $@ is logged here. | passwords.js:105:39:105:46 | password | an access to password |
-| passwords.js:110:21:110:46 | "Passwo ... assword | Sensitive data returned by $@ is logged here. | passwords.js:110:39:110:46 | password | an access to password |
-| passwords.js:114:25:114:50 | "Passwo ... assword | Sensitive data returned by $@ is logged here. | passwords.js:114:43:114:50 | password | an access to password |
-| passwords.js:119:21:119:46 | "Passwo ... assword | Sensitive data returned by $@ is logged here. | passwords.js:119:39:119:46 | password | an access to password |
-| passwords.js:122:17:122:49 | name + ... tring() | Sensitive data returned by $@ is logged here. | passwords.js:122:31:122:38 | password | an access to password |
-| passwords.js:123:17:123:48 | name + ... lueOf() | Sensitive data returned by $@ is logged here. | passwords.js:123:31:123:38 | password | an access to password |
-| passwords_in_server_1.js:6:13:6:20 | password | Sensitive data returned by $@ is logged here. | passwords_in_server_1.js:6:13:6:20 | password | an access to password |
-| passwords_in_server_2.js:3:13:3:20 | password | Sensitive data returned by $@ is logged here. | passwords_in_server_2.js:3:13:3:20 | password | an access to password |
-| passwords_in_server_3.js:2:13:2:20 | password | Sensitive data returned by $@ is logged here. | passwords_in_server_3.js:2:13:2:20 | password | an access to password |
-| passwords_in_server_4.js:2:13:2:20 | password | Sensitive data returned by $@ is logged here. | passwords_in_server_4.js:2:13:2:20 | password | an access to password |
-| passwords_in_server_5.js:8:17:8:17 | x | Sensitive data returned by $@ is logged here. | passwords_in_server_5.js:4:7:4:24 | req.query.password | an access to password |
+nodes
+| passwords.js:2:17:2:24 | password |
+| passwords.js:3:17:3:26 | o.password |
+| passwords.js:4:17:4:29 | 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:10:11:10:18 | password |
+| passwords.js:12:18:12:25 | password |
+| passwords.js:14:17:14:38 | name + ... assword |
+| passwords.js:14:31:14:38 | password |
+| passwords.js:16:17:16:38 | `${name ... sword}` |
+| 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: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: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:30:14:30:21 | password |
+| passwords.js:77:9:77:55 | temp |
+| passwords.js:77:16:77:55 | { encry ... sword } |
+| passwords.js:77:37:77:53 | req.body.password |
+| passwords.js:78:17:78:20 | temp |
+| 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:81:17:81:31 | `pw: ${secret}` |
+| passwords.js:81:24:81:29 | secret |
+| passwords.js:93:21:93:46 | "Passwo ... assword |
+| passwords.js:93:39:93:46 | password |
+| passwords.js:98:21:98:46 | "Passwo ... assword |
+| passwords.js:98:39:98:46 | password |
+| passwords.js:105:21:105:46 | "Passwo ... assword |
+| passwords.js:105:39:105:46 | password |
+| passwords.js:110:21:110:46 | "Passwo ... assword |
+| passwords.js:110:39:110:46 | password |
+| passwords.js:114:25:114:50 | "Passwo ... assword |
+| passwords.js:114:43:114:50 | password |
+| passwords.js:119:21:119:46 | "Passwo ... assword |
+| passwords.js:119:39:119:46 | password |
+| passwords.js:122:17:122:49 | name + ... tring() |
+| 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:31:123:38 | password |
+| passwords.js:123:31:123:48 | password.valueOf() |
+| passwords_in_browser1.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_2.js:3:13:3: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_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 |
+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 | 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: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: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:77:9:77:55 | temp | passwords.js:78:17:78:20 | temp |
+| passwords.js:77:16:77:55 | { encry ... sword } | passwords.js:77:9:77:55 | temp |
+| passwords.js:77:37:77:53 | req.body.password | passwords.js:77:16:77:55 | { encry ... sword } |
+| passwords.js:77:37:77:53 | req.body.password | passwords.js:78:17:78:38 | temp.en ... assword |
+| passwords.js:78:17:78:20 | temp | 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_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 |
+#select
+| passwords.js:2:17:2:24 | password | passwords.js:2:17:2:24 | password | passwords.js:2:17:2:24 | password | Sensitive data returned by $@ is logged here. | 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 | Sensitive data returned by $@ is logged here. | passwords.js:3:17:3:26 | o.password | an access to password |
+| passwords.js:4:17:4:29 | getPassword() | passwords.js:4:17:4:29 | getPassword() | passwords.js:4:17:4:29 | getPassword() | Sensitive data returned by $@ is logged here. | passwords.js:4:17:4:29 | getPassword() | a call to 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() | Sensitive data returned by $@ is logged here. | passwords.js:5:17:5:31 | o.getPassword() | a call to getPassword |
+| passwords.js:8:21:8:21 | x | passwords.js:10:11:10:18 | password | passwords.js:8:21:8:21 | x | Sensitive data returned by $@ is logged here. | passwords.js:10:11:10:18 | password | an access to password |
+| passwords.js:12:18:12:25 | password | passwords.js:12:18:12:25 | password | passwords.js:12:18:12:25 | password | Sensitive data returned by $@ is logged here. | 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 | Sensitive data returned by $@ is logged here. | 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}` | Sensitive data returned by $@ is logged here. | 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 | Sensitive data returned by $@ is logged here. | passwords.js:18:16:20:5 | {\\n ... x\\n } | 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 | Sensitive data returned by $@ is logged here. | 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 | Sensitive data returned by $@ is logged here. | 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 | Sensitive data returned by $@ is logged here. | 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}` | Sensitive data returned by $@ is logged here. | 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 | Sensitive data returned by $@ is logged here. | passwords.js:93:39:93:46 | password | an access to password |
+| passwords.js:98:21:98:46 | "Passwo ... assword | passwords.js:98:39:98:46 | password | passwords.js:98:21:98:46 | "Passwo ... assword | Sensitive data returned by $@ is logged here. | passwords.js:98:39:98:46 | password | an access to password |
+| passwords.js:105:21:105:46 | "Passwo ... assword | passwords.js:105:39:105:46 | password | passwords.js:105:21:105:46 | "Passwo ... assword | Sensitive data returned by $@ is logged here. | passwords.js:105:39:105:46 | password | an access to password |
+| passwords.js:110:21:110:46 | "Passwo ... assword | passwords.js:110:39:110:46 | password | passwords.js:110:21:110:46 | "Passwo ... assword | Sensitive data returned by $@ is logged here. | passwords.js:110:39:110:46 | password | an access to password |
+| passwords.js:114:25:114:50 | "Passwo ... assword | passwords.js:114:43:114:50 | password | passwords.js:114:25:114:50 | "Passwo ... assword | Sensitive data returned by $@ is logged here. | passwords.js:114:43:114:50 | password | an access to password |
+| passwords.js:119:21:119:46 | "Passwo ... assword | passwords.js:119:39:119:46 | password | passwords.js:119:21:119:46 | "Passwo ... assword | Sensitive data returned by $@ is logged here. | 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() | Sensitive data returned by $@ is logged here. | 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() | Sensitive data returned by $@ is logged here. | passwords.js:123:31:123:38 | password | an access to 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 | Sensitive data returned by $@ is logged here. | passwords_in_server_1.js:6:13:6:20 | password | an access to 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 | Sensitive data returned by $@ is logged here. | passwords_in_server_2.js:3:13:3:20 | password | an access to 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 | Sensitive data returned by $@ is logged here. | passwords_in_server_3.js:2:13:2:20 | password | an access to 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 | Sensitive data returned by $@ is logged here. | passwords_in_server_4.js:2:13:2:20 | password | an access to password |
+| passwords_in_server_5.js:8:17:8:17 | x | passwords_in_server_5.js:4:7:4:24 | req.query.password | passwords_in_server_5.js:8:17:8:17 | x | Sensitive data returned by $@ is logged here. | passwords_in_server_5.js:4:7:4:24 | req.query.password | an access to 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 c78fa28340d2..94c95115969d 100644
--- a/javascript/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected
@@ -1,10 +1,33 @@
-| CleartextStorage2.js:7:19:7:36 | 'AccountName=' + a | Sensitive data returned by $@ is stored here. | CleartextStorage2.js:5:11:5:52 | url.par ... untName | an access to AccountName |
-| CleartextStorage.js:7:29:7:29 | a | Sensitive data returned by $@ is stored here. | CleartextStorage.js:5:11:5:34 | req.par ... tName") | a call to param |
-| tst-angularjs.js:3:32:3:45 | data1.password | Sensitive data returned by $@ is stored here. | tst-angularjs.js:3:32:3:45 | data1.password | an access to password |
-| tst-angularjs.js:4:33:4:46 | data2.password | Sensitive data returned by $@ is stored here. | tst-angularjs.js:4:33:4:46 | data2.password | an access to password |
-| tst-angularjs.js:5:27:5:40 | data3.password | Sensitive data returned by $@ is stored here. | tst-angularjs.js:5:27:5:40 | data3.password | an access to password |
-| tst-angularjs.js:6:33:6:46 | data4.password | Sensitive data returned by $@ is stored here. | tst-angularjs.js:6:33:6:46 | data4.password | an access to password |
-| tst-webstorage.js:1:18:1:30 | data.password | Sensitive data returned by $@ is stored here. | tst-webstorage.js:1:18:1:30 | data.password | an access to password |
-| tst-webstorage.js:2:27:2:39 | data.password | Sensitive data returned by $@ is stored here. | tst-webstorage.js:2:27:2:39 | data.password | an access to password |
-| tst-webstorage.js:3:20:3:32 | data.password | Sensitive data returned by $@ is stored here. | tst-webstorage.js:3:20:3:32 | data.password | an access to password |
-| tst-webstorage.js:4:29:4:41 | data.password | Sensitive data returned by $@ is stored here. | tst-webstorage.js:4:29:4:41 | data.password | an access to password |
+nodes
+| CleartextStorage2.js:5:7:5:52 | a |
+| CleartextStorage2.js:5:11:5:52 | url.par ... untName |
+| CleartextStorage2.js:7:19:7:36 | 'AccountName=' + a |
+| CleartextStorage2.js:7:36:7:36 | a |
+| CleartextStorage.js:5:7:5:34 | a |
+| CleartextStorage.js:5:11:5:34 | req.par ... tName") |
+| CleartextStorage.js:7:29:7:29 | a |
+| tst-angularjs.js:3:32:3:45 | data1.password |
+| tst-angularjs.js:4:33:4:46 | data2.password |
+| tst-angularjs.js:5:27:5:40 | data3.password |
+| tst-angularjs.js:6:33:6:46 | data4.password |
+| tst-webstorage.js:1:18:1:30 | data.password |
+| tst-webstorage.js:2:27:2:39 | data.password |
+| tst-webstorage.js:3:20:3:32 | data.password |
+| tst-webstorage.js:4:29:4:41 | data.password |
+edges
+| CleartextStorage2.js:5:7:5:52 | a | CleartextStorage2.js:7:36:7:36 | a |
+| CleartextStorage2.js:5:11:5:52 | url.par ... untName | CleartextStorage2.js:5:7:5:52 | a |
+| CleartextStorage2.js:7:36:7:36 | a | CleartextStorage2.js:7:19:7:36 | 'AccountName=' + a |
+| CleartextStorage.js:5:7:5:34 | a | CleartextStorage.js:7:29:7:29 | a |
+| CleartextStorage.js:5:11:5:34 | req.par ... tName") | CleartextStorage.js:5:7:5:34 | a |
+#select
+| CleartextStorage2.js:7:19:7:36 | 'AccountName=' + a | CleartextStorage2.js:5:11:5:52 | url.par ... untName | CleartextStorage2.js:7:19:7:36 | 'AccountName=' + a | Sensitive data returned by $@ is stored here. | CleartextStorage2.js:5:11:5:52 | url.par ... untName | an access to AccountName |
+| CleartextStorage.js:7:29:7:29 | a | CleartextStorage.js:5:11:5:34 | req.par ... tName") | CleartextStorage.js:7:29:7:29 | a | Sensitive data returned by $@ is stored here. | CleartextStorage.js:5:11:5:34 | req.par ... tName") | a call to param |
+| 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 | Sensitive data returned by $@ is stored here. | tst-angularjs.js:3:32:3:45 | data1.password | an access to 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 | Sensitive data returned by $@ is stored here. | tst-angularjs.js:4:33:4:46 | data2.password | an access to 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 | Sensitive data returned by $@ is stored here. | tst-angularjs.js:5:27:5:40 | data3.password | an access to 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 | Sensitive data returned by $@ is stored here. | tst-angularjs.js:6:33:6:46 | data4.password | an access to 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 | Sensitive data returned by $@ is stored here. | tst-webstorage.js:1:18:1:30 | data.password | an access to 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 | Sensitive data returned by $@ is stored here. | tst-webstorage.js:2:27:2:39 | data.password | an access to 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 | Sensitive data returned by $@ is stored here. | tst-webstorage.js:3:20:3:32 | data.password | an access to 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 | Sensitive data returned by $@ is stored here. | tst-webstorage.js:4:29:4:41 | data.password | an access to password |
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 9ef08fe441b8..a8b7a6f3598d 100644
--- a/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected
@@ -1,3 +1,13 @@
-| tst.js:11:17:11:26 | secretText | Sensitive data from $@ is used in a broken or weak cryptographic algorithm. | tst.js:3:18:3:24 | trusted | an access to trusted |
-| tst.js:11:17:11:26 | secretText | Sensitive data from $@ is used in a broken or weak cryptographic algorithm. | tst.js:11:17:11:26 | secretText | an access to secretText |
-| tst.js:17:17:17:25 | o.trusted | Sensitive data from $@ is used in a broken or weak cryptographic algorithm. | tst.js:17:17:17:25 | o.trusted | an access to trusted |
+nodes
+| tst.js:3:5:3:24 | secretText |
+| tst.js:3:18:3:24 | trusted |
+| tst.js:11:17:11:26 | secretText |
+| tst.js:17:17:17:25 | o.trusted |
+| tst.js:19:17:19:24 | password |
+edges
+| tst.js:3:5:3:24 | secretText | tst.js:11:17:11:26 | secretText |
+| tst.js:3:18:3:24 | trusted | tst.js:3:5:3:24 | secretText |
+#select
+| tst.js:11:17:11:26 | secretText | tst.js:3:18:3:24 | trusted | tst.js:11:17:11:26 | secretText | Sensitive data from $@ is used in a broken or weak cryptographic algorithm. | tst.js:3:18:3:24 | trusted | 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 | Sensitive data from $@ is used in a broken or weak cryptographic algorithm. | tst.js:11:17:11:26 | secretText | an access to 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 | Sensitive data from $@ is used in a broken or weak cryptographic algorithm. | tst.js:17:17:17:25 | o.trusted | an access to 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 7b250dc08ab6..3b4f56f3326d 100644
--- a/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected
@@ -1,16 +1,73 @@
-| tst.js:2:20:2:32 | Math.random() | Cryptographically insecure $@ in a security context. | tst.js:2:20:2:32 | Math.random() | random value |
-| tst.js:6:20:6:43 | "prefix ... andom() | Cryptographically insecure $@ in a security context. | tst.js:6:31:6:43 | Math.random() | random value |
-| tst.js:10:20:10:32 | Math.random() | Cryptographically insecure $@ in a security context. | tst.js:10:20:10:32 | Math.random() | random value |
-| tst.js:20:20:20:36 | "prefix" + suffix | Cryptographically insecure $@ in a security context. | tst.js:19:18:19:30 | Math.random() | random value |
-| tst.js:29:20:29:21 | pw | Cryptographically insecure $@ in a security context. | tst.js:28:14:28:26 | Math.random() | random value |
-| tst.js:41:20:41:33 | !Math.random() | Cryptographically insecure $@ in a security context. | tst.js:41:21:41:33 | Math.random() | random value |
-| tst.js:45:18:45:30 | Math.random() | Cryptographically insecure $@ in a security context. | tst.js:45:18:45:30 | Math.random() | random value |
-| tst.js:50:16:50:28 | Math.random() | Cryptographically insecure $@ in a security context. | tst.js:50:16:50:28 | Math.random() | random value |
-| tst.js:55:17:55:29 | Math.random() | Cryptographically insecure $@ in a security context. | tst.js:55:17:55:29 | Math.random() | random value |
-| tst.js:61:17:61:34 | '' + Math.random() | Cryptographically insecure $@ in a security context. | tst.js:61:22:61:34 | Math.random() | random value |
-| tst.js:66:18:66:42 | Math.fl ... ndom()) | Cryptographically insecure $@ in a security context. | tst.js:66:29:66:41 | Math.random() | random value |
-| tst.js:73:23:73:28 | concat | Cryptographically insecure $@ in a security context. | tst.js:71:27:71:39 | Math.random() | random value |
-| tst.js:77:16:77:21 | secret | Cryptographically insecure $@ in a security context. | tst.js:80:7:80:19 | Math.random() | random value |
-| tst.js:84:19:84:31 | Math.random() | Cryptographically insecure $@ in a security context. | tst.js:84:19:84:31 | Math.random() | random value |
-| tst.js:90:32:90:44 | Math.random() | Cryptographically insecure $@ in a security context. | tst.js:90:32:90:44 | Math.random() | random value |
-| tst.js:95:33:95:45 | Math.random() | Cryptographically insecure $@ in a security context. | tst.js:95:33:95:45 | Math.random() | random value |
+nodes
+| tst.js:2:20:2:32 | Math.random() |
+| tst.js:6:20:6:43 | "prefix ... andom() |
+| tst.js:6:31:6:43 | 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:36 | Math.random() % 255 |
+| 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:29:20:29:21 | pw |
+| tst.js:41:20:41:33 | !Math.random() |
+| tst.js:41:21:41:33 | Math.random() |
+| tst.js:45:18:45:30 | Math.random() |
+| tst.js:50:16:50:28 | Math.random() |
+| tst.js:55:17:55:29 | Math.random() |
+| tst.js:61:17:61:34 | '' + Math.random() |
+| tst.js:61:22:61:34 | Math.random() |
+| tst.js:66:18:66:42 | Math.fl ... ndom()) |
+| 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: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:77:16:77:21 | secret |
+| tst.js:80:7:80:19 | Math.random() |
+| tst.js:84:19:84:31 | Math.random() |
+| tst.js:90:32:90:44 | Math.random() |
+| tst.js:95:33:95:45 | Math.random() |
+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:80:7:80:19 | Math.random() | tst.js:77:16:77:21 | secret |
+#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() | Cryptographically insecure $@ in a security context. | tst.js:2:20:2:32 | Math.random() | random value |
+| tst.js:6:20:6:43 | "prefix ... andom() | tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | Cryptographically insecure $@ in a security context. | tst.js:6:31:6:43 | Math.random() | random value |
+| tst.js:10:20:10:32 | Math.random() | tst.js:10:20:10:32 | Math.random() | tst.js:10:20:10:32 | Math.random() | Cryptographically insecure $@ in a security context. | tst.js:10:20:10:32 | Math.random() | random value |
+| tst.js:20:20:20:36 | "prefix" + suffix | tst.js:19:18:19:30 | Math.random() | tst.js:20:20:20:36 | "prefix" + suffix | Cryptographically insecure $@ in a security context. | tst.js:19:18:19:30 | Math.random() | random value |
+| tst.js:29:20:29:21 | pw | tst.js:28:14:28:26 | Math.random() | tst.js:29:20:29:21 | pw | Cryptographically insecure $@ in a security context. | tst.js:28:14:28:26 | Math.random() | random value |
+| tst.js:41:20:41:33 | !Math.random() | tst.js:41:21:41:33 | Math.random() | tst.js:41:20:41:33 | !Math.random() | Cryptographically insecure $@ in a security context. | tst.js:41:21:41:33 | Math.random() | random value |
+| tst.js:45:18:45:30 | Math.random() | tst.js:45:18:45:30 | Math.random() | tst.js:45:18:45:30 | Math.random() | Cryptographically insecure $@ in a security context. | tst.js:45:18:45:30 | Math.random() | random value |
+| tst.js:50:16:50:28 | Math.random() | tst.js:50:16:50:28 | Math.random() | tst.js:50:16:50:28 | Math.random() | Cryptographically insecure $@ in a security context. | tst.js:50:16:50:28 | Math.random() | random value |
+| tst.js:55:17:55:29 | Math.random() | tst.js:55:17:55:29 | Math.random() | tst.js:55:17:55:29 | Math.random() | Cryptographically insecure $@ in a security context. | tst.js:55:17:55:29 | Math.random() | random value |
+| tst.js:61:17:61:34 | '' + Math.random() | tst.js:61:22:61:34 | Math.random() | tst.js:61:17:61:34 | '' + Math.random() | Cryptographically insecure $@ in a security context. | tst.js:61:22:61:34 | Math.random() | random value |
+| 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()) | Cryptographically insecure $@ in a security context. | tst.js:66:29:66:41 | Math.random() | random value |
+| tst.js:73:23:73:28 | concat | tst.js:71:27:71:39 | Math.random() | tst.js:73:23:73:28 | concat | Cryptographically insecure $@ in a security context. | tst.js:71:27:71:39 | Math.random() | random value |
+| tst.js:77:16:77:21 | secret | tst.js:80:7:80:19 | Math.random() | tst.js:77:16:77:21 | secret | Cryptographically insecure $@ in a security context. | tst.js:80:7:80:19 | Math.random() | random value |
+| tst.js:84:19:84:31 | Math.random() | tst.js:84:19:84:31 | Math.random() | tst.js:84:19:84:31 | Math.random() | Cryptographically insecure $@ in a security context. | tst.js:84:19:84:31 | Math.random() | random value |
+| tst.js:90:32:90:44 | Math.random() | tst.js:90:32:90:44 | Math.random() | tst.js:90:32:90:44 | Math.random() | Cryptographically insecure $@ in a security context. | tst.js:90:32:90:44 | Math.random() | random value |
+| tst.js:95:33:95:45 | Math.random() | tst.js:95:33:95:45 | Math.random() | tst.js:95:33:95:45 | Math.random() | Cryptographically insecure $@ in a security context. | tst.js:95:33:95:45 | Math.random() | random 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 15be8b44c96b..e1c2b8765012 100644
--- a/javascript/ql/test/query-tests/Security/CWE-346/CorsMisconfigurationForCredentials.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-346/CorsMisconfigurationForCredentials.expected
@@ -1,3 +1,19 @@
-| tst.js:13:50:13:55 | origin | $@ leak vulnerability due to $@. | tst.js:14:5:14:59 | res.set ... , true) | Credential | tst.js:12:28:12:34 | req.url | a misconfigured CORS header value |
-| tst.js:18:50:18:53 | null | $@ leak vulnerability due to $@. | tst.js:19:5:19:59 | res.set ... , true) | Credential | tst.js:18:50:18:53 | null | a misconfigured CORS header value |
-| tst.js:23:50:23:55 | "null" | $@ leak vulnerability due to $@. | tst.js:24:5:24:59 | res.set ... , true) | Credential | tst.js:23:50:23:55 | "null" | a misconfigured CORS header value |
+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:13:50:13:55 | origin |
+| tst.js:18:50:18:53 | 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: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:28:12:34 | req.url | tst.js:12:18:12:41 | url.par ... , true) |
+#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 $@. | tst.js:14:5:14:59 | res.set ... , true) | Credential | tst.js:12:28:12:34 | req.url | a 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 $@. | tst.js:19:5:19:59 | res.set ... , true) | Credential | tst.js:18:50:18:53 | null | a misconfigured CORS header value |
+| tst.js:23:50:23:55 | "null" | tst.js:23:50:23:55 | "null" | tst.js:23:50:23:55 | "null" | $@ leak vulnerability due to $@. | tst.js:24:5:24:59 | res.set ... , true) | Credential | tst.js:23:50:23:55 | "null" | a misconfigured CORS header value |
diff --git a/javascript/ql/test/query-tests/Security/CWE-400/RemotePropertyInjection.expected b/javascript/ql/test/query-tests/Security/CWE-400/RemotePropertyInjection.expected
index 02de1bddcf4c..db2cbb1288c8 100644
--- a/javascript/ql/test/query-tests/Security/CWE-400/RemotePropertyInjection.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-400/RemotePropertyInjection.expected
@@ -1,6 +1,29 @@
-| tst.js:9:8:9:11 | prop | A $@ is used as a property name to write to. | tst.js:8:28:8:51 | req.que ... trolled | user-provided value |
-| tst.js:11:16:11:19 | prop | A $@ is used as a method name to be called. | tst.js:8:28:8:51 | req.que ... trolled | user-provided value |
-| tst.js:13:15:13:18 | prop | A $@ is used as a property name to write to. | tst.js:8:28:8:51 | req.que ... trolled | user-provided value |
-| tst.js:14:31:14:34 | prop | A $@ is used as a property name to write to. | tst.js:8:28:8:51 | req.que ... trolled | user-provided value |
-| tst.js:16:10:16:13 | prop | A $@ is used as a property name to write to. | tst.js:8:28:8:51 | req.que ... trolled | user-provided value |
-| tstNonExpr.js:8:17:8:23 | userVal | A $@ is used as a header name. | tstNonExpr.js:5:17:5:23 | req.url | user-provided value |
+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:9:8:9:11 | prop |
+| tst.js:11:16:11:19 | prop |
+| tst.js:13:15:13:18 | prop |
+| tst.js:14:31:14:34 | 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: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:11:16:11:19 | 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) |
+| 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 |
+#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 $@ is used as a property name to write to. | tst.js:8:28:8:51 | req.que ... trolled | user-provided value |
+| tst.js:11:16:11:19 | prop | tst.js:8:28:8:51 | req.que ... trolled | tst.js:11:16:11:19 | prop | A $@ is used as a method name to be called. | 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 $@ is used as a property name to write to. | tst.js:8:28:8:51 | req.que ... trolled | user-provided value |
+| tst.js:14:31:14:34 | prop | tst.js:8:28:8:51 | req.que ... trolled | tst.js:14:31:14:34 | prop | A $@ is used as a property name to write to. | tst.js:8:28:8:51 | req.que ... trolled | user-provided value |
+| tst.js:16:10:16:13 | prop | tst.js:8:28:8:51 | req.que ... trolled | tst.js:16:10:16:13 | prop | A $@ is used as a property name to write to. | tst.js:8:28:8:51 | req.que ... trolled | user-provided value |
+| tstNonExpr.js:8:17:8:23 | userVal | tstNonExpr.js:5:17:5:23 | req.url | tstNonExpr.js:8:17:8:23 | userVal | A $@ is used as a header name. | tstNonExpr.js:5:17:5:23 | req.url | 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 d3703e8796c9..d898f17eb60f 100644
--- a/javascript/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected
@@ -1,4 +1,11 @@
-| tst.js:7:22:7:36 | req.params.data | Unsafe deserialization of $@. | tst.js:7:22:7:36 | req.params.data | user input |
-| tst.js:8:25:8:39 | req.params.data | Unsafe deserialization of $@. | tst.js:8:25:8:39 | req.params.data | user input |
-| tst.js:12:26:12:40 | req.params.data | Unsafe deserialization of $@. | tst.js:12:26:12:40 | req.params.data | user input |
-| tst.js:13:29:13:43 | req.params.data | Unsafe deserialization of $@. | tst.js:13:29:13:43 | req.params.data | user input |
+nodes
+| tst.js:7:22:7:36 | req.params.data |
+| tst.js:8:25:8:39 | req.params.data |
+| tst.js:12:26:12:40 | req.params.data |
+| tst.js:13:29:13:43 | req.params.data |
+edges
+#select
+| tst.js:7:22:7:36 | req.params.data | tst.js:7:22:7:36 | req.params.data | tst.js:7:22:7:36 | req.params.data | Unsafe deserialization of $@. | tst.js:7:22:7:36 | req.params.data | user input |
+| tst.js:8:25:8:39 | req.params.data | tst.js:8:25:8:39 | req.params.data | tst.js:8:25:8:39 | req.params.data | Unsafe deserialization of $@. | tst.js:8:25:8:39 | req.params.data | user input |
+| tst.js:12:26:12:40 | req.params.data | tst.js:12:26:12:40 | req.params.data | tst.js:12:26:12:40 | req.params.data | Unsafe deserialization of $@. | tst.js:12:26:12:40 | req.params.data | user input |
+| tst.js:13:29:13:43 | req.params.data | tst.js:13:29:13:43 | req.params.data | tst.js:13:29:13:43 | req.params.data | Unsafe deserialization of $@. | tst.js:13:29:13:43 | req.params.data | user input |
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 a2b2d6f8dce6..b9427528e411 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,8 +1,62 @@
-| tst2.js:4:21:4:55 | href.su ... '?')+1) | Untrusted URL redirection due to $@. | tst2.js:2:14:2:28 | window.location | user-provided value |
-| tst6.js:4:21:4:28 | redirect | Untrusted URL redirection due to $@. | tst6.js:2:18:2:45 | $locati ... irect') | user-provided value |
-| tst6.js:6:17:6:24 | redirect | Untrusted URL redirection due to $@. | tst6.js:2:18:2:45 | $locati ... irect') | user-provided value |
-| tst6.js:8:21:8:56 | $locati ... + "foo" | Untrusted URL redirection due to $@. | tst6.js:8:21:8:48 | $locati ... irect') | user-provided value |
-| tst7.js:2:12:2:35 | documen ... .search | Untrusted URL redirection due to $@. | tst7.js:2:12:2:28 | document.location | user-provided value |
-| tst7.js:5:27:5:50 | documen ... .search | Untrusted URL redirection due to $@. | tst7.js:5:27:5:43 | document.location | user-provided value |
-| tst9.js:2:21:2:55 | documen ... ring(1) | Untrusted URL redirection due to $@. | tst9.js:2:21:2:37 | document.location | user-provided value |
-| tst.js:2:19:2:72 | /.*redi ... ref)[1] | Untrusted URL redirection due to $@. | tst.js:2:47:2:63 | document.location | user-provided value |
+nodes
+| tst2.js:2:7:2:33 | href |
+| 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:24 | href |
+| 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:4:21:4:28 | redirect |
+| tst6.js:6:17:6:24 | redirect |
+| tst6.js:8:21:8:48 | $locati ... irect') |
+| tst6.js:8:21:8:56 | $locati ... + "foo" |
+| tst7.js:2:12:2:28 | document.location |
+| tst7.js:2:12:2:35 | documen ... .search |
+| tst7.js:5:27:5:43 | document.location |
+| tst7.js:5:27:5:50 | documen ... .search |
+| tst9.js:2:21:2:37 | document.location |
+| tst9.js:2:21:2:37 | document.location |
+| tst9.js:2:21:2:42 | documen ... on.hash |
+| tst9.js:2:21:2:55 | documen ... ring(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 |
+edges
+| tst2.js:2:7:2:33 | href | tst2.js:4:21:4:24 | href |
+| 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) |
+| tst2.js:4:21:4:55 | href.su ... '?')+1) | tst2.js:2:14:2:28 | window.location |
+| 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" |
+| tst7.js:2:12:2:28 | document.location | tst7.js:2:12:2:35 | documen ... .search |
+| tst7.js:5:27:5:43 | document.location | tst7.js:5:27:5:50 | documen ... .search |
+| tst9.js:2:21:2:37 | document.location | tst9.js:2:21:2:42 | documen ... on.hash |
+| tst9.js:2:21:2:37 | document.location | 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) | tst9.js:2:21:2:37 | document.location |
+| 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:68 | documen ... on.href | tst.js:2:19:2:69 | /.*redi ... n.href) |
+#select
+| 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 due to $@. | 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:28 | window.location | tst2.js:4:21:4:55 | href.su ... '?')+1) | Untrusted URL redirection due to $@. | tst2.js:2:14:2:28 | window.location | 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 due to $@. | 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 due to $@. | tst6.js:2:18:2:45 | $locati ... irect') | user-provided value |
+| tst6.js:8:21:8:56 | $locati ... + "foo" | tst6.js:8:21:8:48 | $locati ... irect') | tst6.js:8:21:8:56 | $locati ... + "foo" | Untrusted URL redirection due to $@. | tst6.js:8:21:8:48 | $locati ... irect') | user-provided value |
+| tst7.js:2:12:2:35 | documen ... .search | tst7.js:2:12:2:28 | document.location | tst7.js:2:12:2:35 | documen ... .search | Untrusted URL redirection due to $@. | tst7.js:2:12:2:28 | document.location | user-provided value |
+| tst7.js:5:27:5:50 | documen ... .search | tst7.js:5:27:5:43 | document.location | tst7.js:5:27:5:50 | documen ... .search | Untrusted URL redirection due to $@. | tst7.js:5:27:5:43 | document.location | user-provided value |
+| tst9.js:2:21:2:55 | documen ... ring(1) | tst9.js:2:21:2:37 | document.location | tst9.js:2:21:2:55 | documen ... ring(1) | Untrusted URL redirection due to $@. | tst9.js:2:21:2:37 | document.location | user-provided value |
+| tst9.js:2:21:2:55 | documen ... ring(1) | tst9.js:2:21:2:37 | document.location | tst9.js:2:21:2:55 | documen ... ring(1) | Untrusted URL redirection due to $@. | tst9.js:2:21:2:37 | document.location | 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 due to $@. | tst.js:2:47:2:63 | document.location | 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 012bb85379fe..2d57e091ba27 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,15 +1,106 @@
-| express.js:7:16:7:34 | req.param("target") | Untrusted URL redirection due to $@. | express.js:7:16:7:34 | req.param("target") | user-provided value |
-| express.js:12:26:12:44 | req.param("target") | Untrusted URL redirection due to $@. | express.js:12:26:12:44 | req.param("target") | user-provided value |
-| express.js:33:18:33:23 | target | Untrusted URL redirection due to $@. | express.js:27:16:27:34 | req.param("target") | user-provided value |
-| express.js:35:16:35:21 | target | Untrusted URL redirection due to $@. | express.js:27:16:27:34 | req.param("target") | user-provided value |
-| express.js:40:16:40:108 | (req.pa ... ntacts" | Untrusted URL redirection due to $@. | express.js:40:69:40:87 | req.param('action') | user-provided value |
-| express.js:49:26:49:28 | url | Untrusted URL redirection due to $@. | express.js:44:16:44:28 | req.params[0] | user-provided value |
-| express.js:74:16:74:43 | `${req. ... )}/foo` | Untrusted URL redirection due to $@. | express.js:74:19:74:37 | req.param("target") | user-provided value |
-| express.js:90:18:90:23 | target | Untrusted URL redirection due to $@. | express.js:83:16:83:34 | req.param("target") | user-provided value |
-| express.js:97:16:97:21 | target | Untrusted URL redirection due to $@. | express.js:83:16:83:34 | req.param("target") | user-provided value |
-| express.js:118:16:118:72 | [req.qu ... oin('') | Untrusted URL redirection due to $@. | express.js:118:17:118:30 | req.query.page | user-provided value |
-| node.js:7:34:7:39 | target | Untrusted URL redirection due to $@. | node.js:6:26:6:32 | req.url | user-provided value |
-| node.js:15:34:15:45 | '/' + target | Untrusted URL redirection due to $@. | node.js:11:26:11:32 | req.url | user-provided value |
-| node.js:32:34:32:55 | target ... =" + me | Untrusted URL redirection due to $@. | node.js:29:26:29:32 | req.url | user-provided value |
-| react-native.js:8:17:8:23 | tainted | Untrusted URL redirection due to $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value |
-| react-native.js:9:26:9:32 | tainted | Untrusted URL redirection due to $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value |
+nodes
+| express.js:7:16:7:34 | 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:33:18:33:23 | target |
+| express.js:35:16:35:21 | target |
+| express.js:40:16:40:108 | (req.pa ... ntacts" |
+| express.js:40:69:40:87 | req.param('action') |
+| express.js:44:7:44:28 | handle |
+| express.js:44:16:44:28 | req.params[0] |
+| express.js:45:7:45:33 | url |
+| express.js:45:13:45:27 | "/Me/" + handle |
+| express.js:45:13:45:33 | "/Me/" ... e + "/" |
+| express.js:45:22:45:27 | handle |
+| express.js:49:3:49:3 | url |
+| express.js:49:26:49:28 | url |
+| express.js:74:16:74:43 | `${req. ... )}/foo` |
+| 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:90:18:90:23 | 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:17:118:30 | req.query.page |
+| node.js:6:7:6:52 | target |
+| node.js:6:16:6:39 | url.par ... , true) |
+| node.js:6:16:6:45 | url.par ... ).query |
+| node.js:6:16:6:52 | url.par ... .target |
+| node.js:6:26:6:32 | req.url |
+| node.js:7:34:7:39 | target |
+| node.js:11:7:11:52 | target |
+| node.js:11:16:11:39 | url.par ... , true) |
+| node.js:11:16:11:45 | url.par ... ).query |
+| node.js:11:16:11:52 | url.par ... .target |
+| node.js:11:26:11:32 | req.url |
+| node.js:15:34:15:45 | '/' + target |
+| node.js:15:40:15:45 | target |
+| node.js:29:7:29:52 | target |
+| node.js:29:16:29:39 | url.par ... , true) |
+| node.js:29:16:29:45 | url.par ... ).query |
+| node.js:29:16:29:52 | url.par ... .target |
+| node.js:29:26:29:32 | req.url |
+| node.js:32:34:32:39 | target |
+| node.js:32:34:32:50 | target + "?from=" |
+| node.js:32:34:32:55 | target ... =" + me |
+| react-native.js:7:7:7:33 | tainted |
+| react-native.js:7:17:7:33 | req.param("code") |
+| react-native.js:8:17:8:23 | tainted |
+| react-native.js:9:26:9:32 | tainted |
+edges
+| 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:44:7:44:28 | handle | express.js:45:22:45:27 | handle |
+| express.js:44:16:44:28 | req.params[0] | express.js:44:7:44:28 | handle |
+| express.js:45:7:45:33 | url | express.js:49:3:49:3 | url |
+| express.js:45:13:45:27 | "/Me/" + handle | express.js:45:13:45:33 | "/Me/" ... e + "/" |
+| express.js:45:13:45:33 | "/Me/" ... e + "/" | express.js:45:7:45:33 | url |
+| express.js:45:22:45:27 | handle | express.js:45:13:45:27 | "/Me/" + handle |
+| express.js:49:3:49:3 | url | express.js:49:26:49:28 | url |
+| 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: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] |
+| node.js:6:7:6:52 | target | node.js:7:34:7:39 | target |
+| node.js:6:16:6:39 | url.par ... , true) | node.js:6:16:6:45 | url.par ... ).query |
+| node.js:6:16:6:45 | url.par ... ).query | node.js:6:16:6:52 | url.par ... .target |
+| node.js:6:16:6:52 | url.par ... .target | node.js:6:7:6:52 | target |
+| node.js:6:26:6:32 | req.url | node.js:6:16:6:39 | url.par ... , true) |
+| node.js:11:7:11:52 | target | node.js:15:40:15:45 | target |
+| node.js:11:16:11:39 | url.par ... , true) | node.js:11:16:11:45 | url.par ... ).query |
+| node.js:11:16:11:45 | url.par ... ).query | node.js:11:16:11:52 | url.par ... .target |
+| node.js:11:16:11:52 | url.par ... .target | node.js:11:7:11:52 | target |
+| node.js:11:26:11:32 | req.url | node.js:11:16:11:39 | url.par ... , true) |
+| node.js:15:40:15:45 | target | node.js:15:34:15:45 | '/' + target |
+| node.js:29:7:29:52 | target | node.js:32:34:32:39 | target |
+| node.js:29:16:29:39 | url.par ... , true) | node.js:29:16:29:45 | url.par ... ).query |
+| node.js:29:16:29:45 | url.par ... ).query | node.js:29:16:29:52 | url.par ... .target |
+| node.js:29:16:29:52 | url.par ... .target | node.js:29:7:29:52 | target |
+| node.js:29:26:29:32 | req.url | node.js:29:16:29:39 | url.par ... , true) |
+| node.js:32:34:32:39 | target | node.js:32:34:32:50 | target + "?from=" |
+| node.js:32:34:32:50 | target + "?from=" | node.js:32:34:32: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 |
+#select
+| 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 due to $@. | 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 due to $@. | express.js:12:26:12:44 | 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 due to $@. | 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 due to $@. | 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 due to $@. | express.js:40:69:40:87 | req.param('action') | user-provided value |
+| express.js:49:26:49:28 | url | express.js:44:16:44:28 | req.params[0] | express.js:49:26:49:28 | url | Untrusted URL redirection due to $@. | express.js:44:16:44:28 | req.params[0] | user-provided value |
+| 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` | Untrusted URL redirection due to $@. | express.js:74:19:74:37 | req.param("target") | user-provided value |
+| express.js:90:18:90:23 | target | express.js:83:16:83:34 | req.param("target") | express.js:90:18:90:23 | target | Untrusted URL redirection due to $@. | express.js:83:16:83:34 | req.param("target") | user-provided value |
+| express.js:97:16:97:21 | target | express.js:83:16:83:34 | req.param("target") | express.js:97:16:97:21 | target | Untrusted URL redirection due to $@. | express.js:83:16:83:34 | req.param("target") | user-provided value |
+| express.js:118:16:118:72 | [req.qu ... oin('') | express.js:118:17:118:30 | req.query.page | express.js:118:16:118:72 | [req.qu ... oin('') | Untrusted URL redirection due to $@. | express.js:118:17:118:30 | req.query.page | user-provided value |
+| node.js:7:34:7:39 | target | node.js:6:26:6:32 | req.url | node.js:7:34:7:39 | target | Untrusted URL redirection due to $@. | node.js:6:26:6:32 | req.url | user-provided value |
+| node.js:15:34:15:45 | '/' + target | node.js:11:26:11:32 | req.url | node.js:15:34:15:45 | '/' + target | Untrusted URL redirection due to $@. | node.js:11:26:11:32 | req.url | user-provided value |
+| node.js:32:34:32:55 | target ... =" + me | node.js:29:26:29:32 | req.url | node.js:32:34:32:55 | target ... =" + me | Untrusted URL redirection due to $@. | node.js:29:26:29:32 | req.url | user-provided value |
+| react-native.js:8:17:8:23 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:8:17:8:23 | tainted | Untrusted URL redirection due to $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value |
+| react-native.js:9:26:9:32 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:9:26:9:32 | tainted | Untrusted URL redirection due to $@. | react-native.js:7:17:7:33 | req.param("code") | 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 c02efeef5e9e..982bd6ee841d 100644
--- a/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected
@@ -1,5 +1,20 @@
-| domparser.js:11:55:11:57 | src | A $@ is parsed as XML without guarding against external entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
-| domparser.js:14:57:14:59 | src | A $@ is parsed as XML without guarding against external entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
-| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | A $@ is parsed as XML without guarding against external entity expansion. | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | user-provided value |
-| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | A $@ is parsed as XML without guarding against external entity expansion. | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | user-provided value |
-| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | A $@ is parsed as XML without guarding against external entity expansion. | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | user-provided value |
+nodes
+| domparser.js:2:7:2:36 | src |
+| domparser.js:2:13:2:29 | document.location |
+| domparser.js:2:13:2:36 | documen ... .search |
+| domparser.js:11:55:11:57 | src |
+| domparser.js:14:57:14:59 | src |
+| libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
+| libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
+| libxml.saxpush.js:7:15:7: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:14:57:14:59 | src |
+| domparser.js:2:13:2:29 | document.location | domparser.js:2:13:2:36 | documen ... .search |
+| domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src |
+#select
+| domparser.js:11:55:11:57 | src | domparser.js:2:13:2:29 | document.location | domparser.js:11:55:11:57 | src | A $@ is parsed as XML without guarding against external entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
+| domparser.js:14:57:14:59 | src | domparser.js:2:13:2:29 | document.location | domparser.js:14:57:14:59 | src | A $@ is parsed as XML without guarding against external entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
+| 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") | A $@ is parsed as XML without guarding against external entity expansion. | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | user-provided value |
+| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | A $@ is parsed as XML without guarding against external entity expansion. | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | user-provided value |
+| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | A $@ is parsed as XML without guarding against external entity expansion. | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | user-provided value |
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 78488fcd732e..0fe75f2e75e5 100644
--- a/javascript/ql/test/query-tests/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.expected
@@ -1,2 +1,11 @@
-| tst.js:17:11:17:113 | `Hi, lo ... token}` | Links in this email can be hijacked by poisoning the HTTP host header $@. | tst.js:17:84:17:91 | req.host | here |
-| tst.js:18:11:18:127 | `Hi, lo ... reset.` | Links in this email can be hijacked by poisoning the HTTP host header $@. | tst.js:18:78:18:85 | req.host | here |
+nodes
+| tst.js:17:11:17:113 | `Hi, lo ... token}` |
+| tst.js:17:84:17:91 | req.host |
+| tst.js:18:11:18:127 | `Hi, lo ... reset.` |
+| 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:18:78:18:85 | req.host | tst.js:18:11:18:127 | `Hi, lo ... reset.` |
+#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 HTTP host header $@. | tst.js:17:84:17:91 | req.host | here |
+| 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 HTTP host header $@. | tst.js:18:78:18:85 | req.host | here |
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 c97516665743..06e027f70dc4 100644
--- a/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected
@@ -1,7 +1,39 @@
-| XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | $@ flows here and is used in an XPath expression. | XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | User-provided value |
-| tst2.js:2:27:2:31 | query | $@ flows here and is used in an XPath expression. | tst2.js:1:13:1:29 | document.location | User-provided value |
-| tst2.js:3:19:3:23 | query | $@ flows here and is used in an XPath expression. | tst2.js:1:13:1:29 | document.location | User-provided value |
-| tst.js:7:15:7:21 | tainted | $@ flows here and is used in an XPath expression. | tst.js:6:17:6:37 | req.par ... rName") | User-provided value |
-| tst.js:8:16:8:22 | tainted | $@ flows here and is used in an XPath expression. | tst.js:6:17:6:37 | req.par ... rName") | User-provided value |
-| tst.js:9:17:9:23 | tainted | $@ flows here and is used in an XPath expression. | tst.js:6:17:6:37 | req.par ... rName") | User-provided value |
-| tst.js:11:8:11:14 | tainted | $@ flows here and is used in an XPath expression. | tst.js:6:17:6:37 | req.par ... rName") | User-provided value |
+nodes
+| XpathInjectionBad.js:6:7:6:38 | userName |
+| XpathInjectionBad.js:6:18:6:38 | req.par ... rName") |
+| XpathInjectionBad.js:9:34:9:73 | "//user ... serName |
+| XpathInjectionBad.js:9:34:9:96 | "//user ... text()" |
+| XpathInjectionBad.js:9:66:9:73 | userName |
+| tst2.js:1:13:1:29 | document.location |
+| 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:3:19:3:23 | query |
+| tst.js:6:7:6:37 | tainted |
+| tst.js:6:17:6:37 | req.par ... rName") |
+| tst.js:7:15:7:21 | tainted |
+| tst.js:8:16:8:22 | tainted |
+| tst.js:9:17:9:23 | 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:9:34:9:73 | "//user ... serName | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" |
+| XpathInjectionBad.js:9:66:9:73 | userName | XpathInjectionBad.js:9:34:9:73 | "//user ... serName |
+| tst2.js:1:13:1:29 | document.location | 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: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 |
+#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()" | $@ flows here and is used in an XPath expression. | XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | User-provided value |
+| tst2.js:2:27:2:31 | query | tst2.js:1:13:1:29 | document.location | tst2.js:2:27:2:31 | query | $@ flows here and is used in an XPath expression. | tst2.js:1:13:1:29 | document.location | User-provided value |
+| tst2.js:3:19:3:23 | query | tst2.js:1:13:1:29 | document.location | tst2.js:3:19:3:23 | query | $@ flows here and is used in an XPath expression. | tst2.js:1:13:1:29 | document.location | User-provided value |
+| tst.js:7:15:7:21 | tainted | tst.js:6:17:6:37 | req.par ... rName") | tst.js:7:15:7:21 | tainted | $@ flows here and is used in an XPath expression. | tst.js:6:17:6:37 | req.par ... rName") | User-provided value |
+| tst.js:8:16:8:22 | tainted | tst.js:6:17:6:37 | req.par ... rName") | tst.js:8:16:8:22 | tainted | $@ flows here and is used in an XPath expression. | tst.js:6:17:6:37 | req.par ... rName") | User-provided value |
+| tst.js:9:17:9:23 | tainted | tst.js:6:17:6:37 | req.par ... rName") | tst.js:9:17:9:23 | tainted | $@ flows here and is used in an XPath expression. | tst.js:6:17:6:37 | req.par ... rName") | User-provided value |
+| tst.js:11:8:11:14 | tainted | tst.js:6:17:6:37 | req.par ... rName") | tst.js:11:8:11:14 | tainted | $@ flows here and is used in an XPath expression. | tst.js:6:17:6:37 | req.par ... rName") | User-provided value |
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 669b363a45db..c4bd46ed4e73 100644
--- a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected
@@ -1,14 +1,81 @@
-| 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) | This regular expression is constructed from a $@. | RegExpInjection.js:5:13:5:28 | req.param("key") | user-provided value |
-| RegExpInjection.js:21:14:21:22 | wrap(key) | This regular expression is constructed from a $@. | RegExpInjection.js:5:13:5:28 | req.param("key") | user-provided value |
-| RegExpInjection.js:27:14:27:21 | getKey() | This regular expression is constructed from a $@. | RegExpInjection.js:24:12:24:27 | req.param("key") | user-provided value |
-| RegExpInjection.js:31:23:31:23 | s | This regular expression is constructed from a $@. | RegExpInjection.js:5:13:5:28 | req.param("key") | user-provided value |
-| RegExpInjection.js:31:23:31:23 | s | This regular expression is constructed from a $@. | RegExpInjection.js:24:12:24:27 | req.param("key") | user-provided value |
-| RegExpInjection.js:40:19:40:23 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value |
-| RegExpInjection.js:41:22:41:26 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value |
-| RegExpInjection.js:42:21:42:25 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value |
-| RegExpInjection.js:45:20:45:24 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value |
-| RegExpInjection.js:46:23:46:27 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value |
-| RegExpInjection.js:47:22:47:26 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value |
-| RegExpInjection.js:50:46:50:50 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value |
-| 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 |
+nodes
+| RegExpInjection.js:5:7:5:28 | 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:8:23:8:33 | "\\\\b" + key |
+| 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:19:19:21 | 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: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:33:12:33:14 | key |
+| RegExpInjection.js:34:12:34:19 | getKey() |
+| RegExpInjection.js:40:19:40:23 | input |
+| RegExpInjection.js:41:22:41:26 | input |
+| RegExpInjection.js:42:21:42:25 | input |
+| RegExpInjection.js:45:20:45:24 | input |
+| RegExpInjection.js:46:23:46:27 | input |
+| RegExpInjection.js:47:22:47:26 | input |
+| RegExpInjection.js:50:46:50:50 | input |
+| 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:29 | "^"+ 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 |
+| 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:13:5:28 | req.param("key") | RegExpInjection.js:5:7:5:28 | key |
+| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:40:19:40:23 | input |
+| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:41:22:41:26 | input |
+| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:42:21:42:25 | input |
+| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:45:20:45:24 | input |
+| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:46:23:46:27 | input |
+| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:47:22:47:26 | input |
+| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:50:46:50:50 | input |
+| RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:5:31:5:56 | input |
+| RegExpInjection.js:8:23:8:33 | "\\\\b" + key | RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" |
+| RegExpInjection.js:8:31:8:33 | key | RegExpInjection.js:8:23:8:33 | "\\\\b" + 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: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: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 |
+| 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:16:3:29 | "^"+ 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 |
+| tst.js:3:21:3:29 | data.name | tst.js:3:16:3:29 | "^"+ data.name |
+#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 |
+| RegExpInjection.js:21:14:21:22 | wrap(key) | RegExpInjection.js:5:13:5:28 | req.param("key") | RegExpInjection.js:21:14:21:22 | wrap(key) | This regular expression is constructed from a $@. | RegExpInjection.js:5:13:5:28 | req.param("key") | user-provided value |
+| RegExpInjection.js:27:14:27:21 | getKey() | RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:27:14:27:21 | getKey() | This regular expression is constructed from a $@. | RegExpInjection.js:24:12:24:27 | req.param("key") | user-provided value |
+| RegExpInjection.js:31:23:31:23 | s | RegExpInjection.js:5:13:5:28 | req.param("key") | RegExpInjection.js:31:23:31:23 | s | This regular expression is constructed from a $@. | RegExpInjection.js:5:13:5:28 | req.param("key") | user-provided value |
+| RegExpInjection.js:31:23:31:23 | s | RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:31:23:31:23 | s | This regular expression is constructed from a $@. | RegExpInjection.js:24:12:24:27 | req.param("key") | user-provided value |
+| RegExpInjection.js:40:19:40:23 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:40:19:40:23 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value |
+| RegExpInjection.js:41:22:41:26 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:41:22:41:26 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value |
+| RegExpInjection.js:42:21:42:25 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:42:21:42:25 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value |
+| RegExpInjection.js:45:20:45:24 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:45:20:45:24 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value |
+| RegExpInjection.js:46:23:46:27 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:46:23:46:27 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value |
+| RegExpInjection.js:47:22:47:26 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:47:22:47:26 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value |
+| RegExpInjection.js:50:46:50:50 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:50:46:50:50 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value |
+| 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 |
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 38c27d211441..483d2d585c7a 100644
--- a/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected
@@ -1,10 +1,43 @@
-| closure.js:4:24:4:26 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | closure.js:2:13:2:29 | document.location | user-provided value |
-| domparser.js:6:37:6:39 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
-| domparser.js:11:55:11:57 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
-| domparser.js:14:57:14:59 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
-| expat.js:7:16:7:36 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | expat.js:7:16:7:36 | req.par ... e-xml") | user-provided value |
-| jquery.js:5:14:5:16 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | jquery.js:2:13:2:29 | document.location | user-provided value |
-| libxml.js:6:21:6:41 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.js:6:21:6:41 | req.par ... e-xml") | user-provided value |
-| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | user-provided value |
-| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | user-provided value |
-| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | user-provided value |
+nodes
+| closure.js:2:7:2:36 | src |
+| closure.js:2:13:2:29 | document.location |
+| closure.js:2:13:2:36 | documen ... .search |
+| closure.js:4:24:4:26 | src |
+| domparser.js:2:7:2:36 | src |
+| domparser.js:2:13:2:29 | document.location |
+| domparser.js:2:13:2:36 | documen ... .search |
+| domparser.js:6:37:6:39 | src |
+| domparser.js:11:55:11:57 | src |
+| domparser.js:14:57:14:59 | src |
+| expat.js:7:16:7:36 | req.par ... e-xml") |
+| jquery.js:2:7:2:36 | src |
+| jquery.js:2:13:2:29 | document.location |
+| jquery.js:2:13:2:36 | documen ... .search |
+| jquery.js:5:14:5:16 | src |
+| libxml.js:6:21:6:41 | req.par ... e-xml") |
+| libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
+| libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
+| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
+edges
+| closure.js:2:7:2:36 | src | closure.js:4:24:4:26 | src |
+| closure.js:2:13:2:29 | document.location | closure.js:2:13:2:36 | documen ... .search |
+| 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:29 | document.location | domparser.js:2:13:2:36 | documen ... .search |
+| 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:29 | document.location | jquery.js:2:13:2:36 | documen ... .search |
+| jquery.js:2:13:2:36 | documen ... .search | jquery.js:2:7:2:36 | src |
+#select
+| closure.js:4:24:4:26 | src | closure.js:2:13:2:29 | document.location | closure.js:4:24:4:26 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | closure.js:2:13:2:29 | document.location | user-provided value |
+| domparser.js:6:37:6:39 | src | domparser.js:2:13:2:29 | document.location | domparser.js:6:37:6:39 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
+| domparser.js:11:55:11:57 | src | domparser.js:2:13:2:29 | document.location | domparser.js:11:55:11:57 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
+| domparser.js:14:57:14:59 | src | domparser.js:2:13:2:29 | document.location | domparser.js:14:57:14:59 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
+| expat.js:7:16:7:36 | req.par ... e-xml") | expat.js:7:16:7:36 | req.par ... e-xml") | expat.js:7:16:7:36 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | expat.js:7:16:7:36 | req.par ... e-xml") | user-provided value |
+| jquery.js:5:14:5:16 | src | jquery.js:2:13:2:29 | document.location | jquery.js:5:14:5:16 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | jquery.js:2:13:2:29 | document.location | user-provided value |
+| 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") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.js:6:21:6:41 | req.par ... e-xml") | user-provided value |
+| 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") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | user-provided value |
+| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | user-provided value |
+| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | 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 a6f208d1ea85..44cca50c842b 100644
--- a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected
@@ -1,51 +1,107 @@
-| 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:34 | 'secretpassword' | The hard-coded value "secretpassword" is used as $@. | HardcodedCredentials.js:8:19:8:34 | 'secretpassword' | password |
-| HardcodedCredentials.js:15:36:15:50 | "user:password" | The hard-coded value "user:password" is used as $@. | HardcodedCredentials.js:15:36:15:50 | "user:password" | credentials |
-| HardcodedCredentials.js:16:37:16:51 | "user:password" | The hard-coded value "user:password" is used as $@. | HardcodedCredentials.js:16:37:16:51 | "user:password" | credentials |
-| HardcodedCredentials.js:18:16:18:30 | "user:password" | The hard-coded value "user:password" is used as $@. | HardcodedCredentials.js:20:36:20:51 | getCredentials() | credentials |
-| HardcodedCredentials.js:27:25:27:31 | 'admin' | The hard-coded value "admin" is used as $@. | HardcodedCredentials.js:27:25:27:31 | 'admin' | user name |
-| HardcodedCredentials.js:27:34:27:46 | 'supersecret' | The hard-coded value "supersecret" is used as $@. | HardcodedCredentials.js:27:34:27:46 | 'supersecret' | password |
-| HardcodedCredentials.js:29:11:29:30 | 'unknown-admin-name' | The hard-coded value "unknown-admin-name" is used as $@. | HardcodedCredentials.js:29:11:29:30 | 'unknown-admin-name' | user name |
-| HardcodedCredentials.js:29:35:29:47 | 'supersecret' | The hard-coded value "supersecret" is used as $@. | HardcodedCredentials.js:29:35:29:47 | 'supersecret' | password |
-| HardcodedCredentials.js:35:15:35:24 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:35:15:35:24 | 'username' | user name |
-| HardcodedCredentials.js:35:27:35:36 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:35:27:35:36 | 'password' | password |
-| HardcodedCredentials.js:41:38:41:47 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:41:38:41:47 | 'username' | user name |
-| HardcodedCredentials.js:41:67:41:76 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:41:67:41:76 | 'password' | password |
-| HardcodedCredentials.js:42:35:42:44 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:42:35:42:44 | 'username' | user name |
-| HardcodedCredentials.js:42:64:42:73 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:42:64:42:73 | 'password' | password |
-| HardcodedCredentials.js:44:34:44:43 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:44:34:44:43 | 'username' | user name |
-| HardcodedCredentials.js:44:63:44:72 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:44:63:44:72 | 'password' | password |
-| HardcodedCredentials.js:46:25:46:34 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:46:25:46:34 | 'password' | password |
-| HardcodedCredentials.js:53:27:53:36 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:53:27:53:36 | 'username' | user name |
-| HardcodedCredentials.js:53:39:53:48 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:53:39:53:48 | 'password' | password |
-| HardcodedCredentials.js:56:21:56:30 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:56:21:56:30 | 'username' | user name |
-| HardcodedCredentials.js:57:21:57:30 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:57:21:57:30 | 'password' | password |
-| HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | The hard-coded value "bearerToken" is used as $@. | HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | token |
-| HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | The hard-coded value "bearerToken" is used as $@. | HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | token |
-| HardcodedCredentials.js:69:28:69:37 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:69:28:69:37 | 'username' | user name |
-| HardcodedCredentials.js:69:40:69:49 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:69:40:69:49 | 'password' | password |
-| HardcodedCredentials.js:70:28:70:37 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:70:28:70:37 | 'username' | user name |
-| HardcodedCredentials.js:70:40:70:49 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:70:40:70:49 | 'password' | password |
-| HardcodedCredentials.js:72:23:72:32 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:72:23:72:32 | 'username' | user name |
-| HardcodedCredentials.js:72:35:72:44 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:72:35:72:44 | 'password' | password |
-| HardcodedCredentials.js:75:21:75:30 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:75:21:75:30 | 'username' | user name |
-| HardcodedCredentials.js:76:21:76:30 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:76:21:76:30 | 'password' | password |
-| HardcodedCredentials.js:84:38:84:47 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:84:38:84:47 | 'username' | user name |
-| HardcodedCredentials.js:84:50:84:59 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:84:50:84:59 | 'password' | password |
-| HardcodedCredentials.js:86:44:86:53 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:86:44:86:53 | 'username' | user name |
-| HardcodedCredentials.js:86:56:86:65 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:86:56:86:65 | 'password' | password |
-| HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | The hard-coded value "TOKEN" is used as $@. | HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | token |
-| HardcodedCredentials.js:98:18:98:21 | 'x1' | The hard-coded value "x1" is used as $@. | HardcodedCredentials.js:98:18:98:21 | 'x1' | user name |
-| HardcodedCredentials.js:99:16:99:19 | 'x2' | The hard-coded value "x2" is used as $@. | HardcodedCredentials.js:99:16:99:19 | 'x2' | user name |
-| HardcodedCredentials.js:100:25:100:28 | 'x3' | The hard-coded value "x3" is used as $@. | HardcodedCredentials.js:100:25:100:28 | 'x3' | user name |
-| HardcodedCredentials.js:101:19:101:22 | 'x4' | The hard-coded value "x4" is used as $@. | HardcodedCredentials.js:101:19:101:22 | 'x4' | user name |
-| HardcodedCredentials.js:102:14:102:17 | 'y1' | The hard-coded value "y1" is used as $@. | HardcodedCredentials.js:102:14:102:17 | 'y1' | password |
-| HardcodedCredentials.js:103:17:103:20 | 'y2' | The hard-coded value "y2" is used as $@. | HardcodedCredentials.js:103:17:103:20 | 'y2' | password |
-| HardcodedCredentials.js:104:27:104:30 | 'y3' | The hard-coded value "y3" is used as $@. | HardcodedCredentials.js:104:27:104:30 | 'y3' | password |
-| HardcodedCredentials.js:105:19:105:22 | 'y4' | The hard-coded value "y4" is used as $@. | HardcodedCredentials.js:105:19:105:22 | 'y4' | password |
-| HardcodedCredentials.js:106:16:106:19 | 'z1' | The hard-coded value "z1" is used as $@. | HardcodedCredentials.js:106:16:106:19 | 'z1' | token |
-| HardcodedCredentials.js:112:19:112:22 | 'x5' | The hard-coded value "x5" is used as $@. | HardcodedCredentials.js:112:19:112:22 | 'x5' | user name |
-| HardcodedCredentials.js:113:19:113:22 | 'y5' | The hard-coded value "y5" is used as $@. | HardcodedCredentials.js:113:19:113:22 | 'y5' | password |
-| HardcodedCredentials.js:130:44:130:58 | 'crypto secret' | The hard-coded value "crypto secret" is used as $@. | HardcodedCredentials.js:130:44:130:58 | 'crypto secret' | key |
-| HardcodedCredentials.js:131:52:131:73 | 'crypto ... secret' | The hard-coded value "crypto-js/aes secret" is used as $@. | HardcodedCredentials.js:131:52:131:73 | 'crypto ... secret' | key |
-| HardcodedCredentials.js:135:41:135:63 | "cookie ... secret" | The hard-coded value "cookie-session secret" is used as $@. | HardcodedCredentials.js:135:41:135:63 | "cookie ... secret" | key |
+nodes
+| HardcodedCredentials.js:5:15:5:22 | 'dbuser' |
+| HardcodedCredentials.js:8:19:8:34 | 'secretpassword' |
+| HardcodedCredentials.js:15:36:15:50 | "user:password" |
+| HardcodedCredentials.js:16:37:16:51 | "user:password" |
+| HardcodedCredentials.js:18:16:18:30 | "user:password" |
+| HardcodedCredentials.js:20:36:20:51 | getCredentials() |
+| HardcodedCredentials.js:27:25:27:31 | 'admin' |
+| HardcodedCredentials.js:27:34:27:46 | 'supersecret' |
+| HardcodedCredentials.js:29:11:29:30 | 'unknown-admin-name' |
+| HardcodedCredentials.js:29:35:29:47 | 'supersecret' |
+| HardcodedCredentials.js:35:15:35:24 | 'username' |
+| HardcodedCredentials.js:35:27:35:36 | 'password' |
+| HardcodedCredentials.js:41:38:41:47 | 'username' |
+| HardcodedCredentials.js:41:67:41:76 | 'password' |
+| HardcodedCredentials.js:42:35:42:44 | 'username' |
+| HardcodedCredentials.js:42:64:42:73 | 'password' |
+| HardcodedCredentials.js:44:34:44:43 | 'username' |
+| HardcodedCredentials.js:44:63:44:72 | 'password' |
+| HardcodedCredentials.js:46:25:46:34 | 'password' |
+| HardcodedCredentials.js:53:27:53:36 | 'username' |
+| HardcodedCredentials.js:53:39:53:48 | 'password' |
+| HardcodedCredentials.js:56:21:56:30 | 'username' |
+| HardcodedCredentials.js:57:21:57:30 | 'password' |
+| HardcodedCredentials.js:61:42:61:54 | 'bearerToken' |
+| HardcodedCredentials.js:65:23:65:35 | 'bearerToken' |
+| HardcodedCredentials.js:69:28:69:37 | 'username' |
+| HardcodedCredentials.js:69:40:69:49 | 'password' |
+| HardcodedCredentials.js:70:28:70:37 | 'username' |
+| HardcodedCredentials.js:70:40:70:49 | 'password' |
+| HardcodedCredentials.js:72:23:72:32 | 'username' |
+| HardcodedCredentials.js:72:35:72:44 | 'password' |
+| HardcodedCredentials.js:75:21:75:30 | 'username' |
+| HardcodedCredentials.js:76:21:76:30 | 'password' |
+| HardcodedCredentials.js:84:38:84:47 | 'username' |
+| HardcodedCredentials.js:84:50:84:59 | 'password' |
+| HardcodedCredentials.js:86:44:86:53 | 'username' |
+| HardcodedCredentials.js:86:56:86:65 | 'password' |
+| HardcodedCredentials.js:91:25:91:31 | 'TOKEN' |
+| HardcodedCredentials.js:98:18:98:21 | 'x1' |
+| HardcodedCredentials.js:99:16:99:19 | 'x2' |
+| HardcodedCredentials.js:100:25:100:28 | 'x3' |
+| HardcodedCredentials.js:101:19:101:22 | 'x4' |
+| HardcodedCredentials.js:102:14:102:17 | 'y1' |
+| HardcodedCredentials.js:103:17:103:20 | 'y2' |
+| HardcodedCredentials.js:104:27:104:30 | 'y3' |
+| HardcodedCredentials.js:105:19:105:22 | 'y4' |
+| HardcodedCredentials.js:106:16:106:19 | 'z1' |
+| HardcodedCredentials.js:112:19:112:22 | 'x5' |
+| HardcodedCredentials.js:113:19:113:22 | 'y5' |
+| HardcodedCredentials.js:130:44:130:58 | 'crypto secret' |
+| HardcodedCredentials.js:131:52:131:73 | 'crypto ... secret' |
+| HardcodedCredentials.js:135:41:135:63 | "cookie ... secret" |
+edges
+| HardcodedCredentials.js:18:16:18:30 | "user:password" | HardcodedCredentials.js:20:36:20:51 | getCredentials() |
+#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:34 | 'secretpassword' | HardcodedCredentials.js:8:19:8:34 | 'secretpassword' | HardcodedCredentials.js:8:19:8:34 | 'secretpassword' | The hard-coded value "secretpassword" is used as $@. | HardcodedCredentials.js:8:19:8:34 | 'secretpassword' | password |
+| HardcodedCredentials.js:15:36:15:50 | "user:password" | HardcodedCredentials.js:15:36:15:50 | "user:password" | HardcodedCredentials.js:15:36:15:50 | "user:password" | The hard-coded value "user:password" is used as $@. | HardcodedCredentials.js:15:36:15:50 | "user:password" | credentials |
+| HardcodedCredentials.js:16:37:16:51 | "user:password" | HardcodedCredentials.js:16:37:16:51 | "user:password" | HardcodedCredentials.js:16:37:16:51 | "user:password" | The hard-coded value "user:password" is used as $@. | HardcodedCredentials.js:16:37:16:51 | "user:password" | credentials |
+| HardcodedCredentials.js:18:16:18:30 | "user:password" | HardcodedCredentials.js:18:16:18:30 | "user:password" | HardcodedCredentials.js:20:36:20:51 | getCredentials() | The hard-coded value "user:password" is used as $@. | HardcodedCredentials.js:20:36:20:51 | getCredentials() | credentials |
+| HardcodedCredentials.js:27:25:27:31 | 'admin' | HardcodedCredentials.js:27:25:27:31 | 'admin' | HardcodedCredentials.js:27:25:27:31 | 'admin' | The hard-coded value "admin" is used as $@. | HardcodedCredentials.js:27:25:27:31 | 'admin' | user name |
+| HardcodedCredentials.js:27:34:27:46 | 'supersecret' | HardcodedCredentials.js:27:34:27:46 | 'supersecret' | HardcodedCredentials.js:27:34:27:46 | 'supersecret' | The hard-coded value "supersecret" is used as $@. | HardcodedCredentials.js:27:34:27:46 | 'supersecret' | password |
+| 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' | The hard-coded value "unknown-admin-name" is used as $@. | HardcodedCredentials.js:29:11:29:30 | 'unknown-admin-name' | user name |
+| HardcodedCredentials.js:29:35:29:47 | 'supersecret' | HardcodedCredentials.js:29:35:29:47 | 'supersecret' | HardcodedCredentials.js:29:35:29:47 | 'supersecret' | The hard-coded value "supersecret" is used as $@. | HardcodedCredentials.js:29:35:29:47 | 'supersecret' | password |
+| HardcodedCredentials.js:35:15:35:24 | 'username' | HardcodedCredentials.js:35:15:35:24 | 'username' | HardcodedCredentials.js:35:15:35:24 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:35:15:35:24 | 'username' | user name |
+| HardcodedCredentials.js:35:27:35:36 | 'password' | HardcodedCredentials.js:35:27:35:36 | 'password' | HardcodedCredentials.js:35:27:35:36 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:35:27:35:36 | 'password' | password |
+| HardcodedCredentials.js:41:38:41:47 | 'username' | HardcodedCredentials.js:41:38:41:47 | 'username' | HardcodedCredentials.js:41:38:41:47 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:41:38:41:47 | 'username' | user name |
+| HardcodedCredentials.js:41:67:41:76 | 'password' | HardcodedCredentials.js:41:67:41:76 | 'password' | HardcodedCredentials.js:41:67:41:76 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:41:67:41:76 | 'password' | password |
+| HardcodedCredentials.js:42:35:42:44 | 'username' | HardcodedCredentials.js:42:35:42:44 | 'username' | HardcodedCredentials.js:42:35:42:44 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:42:35:42:44 | 'username' | user name |
+| HardcodedCredentials.js:42:64:42:73 | 'password' | HardcodedCredentials.js:42:64:42:73 | 'password' | HardcodedCredentials.js:42:64:42:73 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:42:64:42:73 | 'password' | password |
+| HardcodedCredentials.js:44:34:44:43 | 'username' | HardcodedCredentials.js:44:34:44:43 | 'username' | HardcodedCredentials.js:44:34:44:43 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:44:34:44:43 | 'username' | user name |
+| HardcodedCredentials.js:44:63:44:72 | 'password' | HardcodedCredentials.js:44:63:44:72 | 'password' | HardcodedCredentials.js:44:63:44:72 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:44:63:44:72 | 'password' | password |
+| HardcodedCredentials.js:46:25:46:34 | 'password' | HardcodedCredentials.js:46:25:46:34 | 'password' | HardcodedCredentials.js:46:25:46:34 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:46:25:46:34 | 'password' | password |
+| HardcodedCredentials.js:53:27:53:36 | 'username' | HardcodedCredentials.js:53:27:53:36 | 'username' | HardcodedCredentials.js:53:27:53:36 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:53:27:53:36 | 'username' | user name |
+| HardcodedCredentials.js:53:39:53:48 | 'password' | HardcodedCredentials.js:53:39:53:48 | 'password' | HardcodedCredentials.js:53:39:53:48 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:53:39:53:48 | 'password' | password |
+| HardcodedCredentials.js:56:21:56:30 | 'username' | HardcodedCredentials.js:56:21:56:30 | 'username' | HardcodedCredentials.js:56:21:56:30 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:56:21:56:30 | 'username' | user name |
+| HardcodedCredentials.js:57:21:57:30 | 'password' | HardcodedCredentials.js:57:21:57:30 | 'password' | HardcodedCredentials.js:57:21:57:30 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:57:21:57:30 | 'password' | password |
+| HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | The hard-coded value "bearerToken" is used as $@. | HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | token |
+| HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | The hard-coded value "bearerToken" is used as $@. | HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | token |
+| HardcodedCredentials.js:69:28:69:37 | 'username' | HardcodedCredentials.js:69:28:69:37 | 'username' | HardcodedCredentials.js:69:28:69:37 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:69:28:69:37 | 'username' | user name |
+| HardcodedCredentials.js:69:40:69:49 | 'password' | HardcodedCredentials.js:69:40:69:49 | 'password' | HardcodedCredentials.js:69:40:69:49 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:69:40:69:49 | 'password' | password |
+| HardcodedCredentials.js:70:28:70:37 | 'username' | HardcodedCredentials.js:70:28:70:37 | 'username' | HardcodedCredentials.js:70:28:70:37 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:70:28:70:37 | 'username' | user name |
+| HardcodedCredentials.js:70:40:70:49 | 'password' | HardcodedCredentials.js:70:40:70:49 | 'password' | HardcodedCredentials.js:70:40:70:49 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:70:40:70:49 | 'password' | password |
+| HardcodedCredentials.js:72:23:72:32 | 'username' | HardcodedCredentials.js:72:23:72:32 | 'username' | HardcodedCredentials.js:72:23:72:32 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:72:23:72:32 | 'username' | user name |
+| HardcodedCredentials.js:72:35:72:44 | 'password' | HardcodedCredentials.js:72:35:72:44 | 'password' | HardcodedCredentials.js:72:35:72:44 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:72:35:72:44 | 'password' | password |
+| HardcodedCredentials.js:75:21:75:30 | 'username' | HardcodedCredentials.js:75:21:75:30 | 'username' | HardcodedCredentials.js:75:21:75:30 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:75:21:75:30 | 'username' | user name |
+| HardcodedCredentials.js:76:21:76:30 | 'password' | HardcodedCredentials.js:76:21:76:30 | 'password' | HardcodedCredentials.js:76:21:76:30 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:76:21:76:30 | 'password' | password |
+| HardcodedCredentials.js:84:38:84:47 | 'username' | HardcodedCredentials.js:84:38:84:47 | 'username' | HardcodedCredentials.js:84:38:84:47 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:84:38:84:47 | 'username' | user name |
+| HardcodedCredentials.js:84:50:84:59 | 'password' | HardcodedCredentials.js:84:50:84:59 | 'password' | HardcodedCredentials.js:84:50:84:59 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:84:50:84:59 | 'password' | password |
+| HardcodedCredentials.js:86:44:86:53 | 'username' | HardcodedCredentials.js:86:44:86:53 | 'username' | HardcodedCredentials.js:86:44:86:53 | 'username' | The hard-coded value "username" is used as $@. | HardcodedCredentials.js:86:44:86:53 | 'username' | user name |
+| HardcodedCredentials.js:86:56:86:65 | 'password' | HardcodedCredentials.js:86:56:86:65 | 'password' | HardcodedCredentials.js:86:56:86:65 | 'password' | The hard-coded value "password" is used as $@. | HardcodedCredentials.js:86:56:86:65 | 'password' | password |
+| HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | The hard-coded value "TOKEN" is used as $@. | HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | token |
+| HardcodedCredentials.js:98:18:98:21 | 'x1' | HardcodedCredentials.js:98:18:98:21 | 'x1' | HardcodedCredentials.js:98:18:98:21 | 'x1' | The hard-coded value "x1" is used as $@. | HardcodedCredentials.js:98:18:98:21 | 'x1' | user name |
+| HardcodedCredentials.js:99:16:99:19 | 'x2' | HardcodedCredentials.js:99:16:99:19 | 'x2' | HardcodedCredentials.js:99:16:99:19 | 'x2' | The hard-coded value "x2" is used as $@. | HardcodedCredentials.js:99:16:99:19 | 'x2' | user name |
+| HardcodedCredentials.js:100:25:100:28 | 'x3' | HardcodedCredentials.js:100:25:100:28 | 'x3' | HardcodedCredentials.js:100:25:100:28 | 'x3' | The hard-coded value "x3" is used as $@. | HardcodedCredentials.js:100:25:100:28 | 'x3' | user name |
+| HardcodedCredentials.js:101:19:101:22 | 'x4' | HardcodedCredentials.js:101:19:101:22 | 'x4' | HardcodedCredentials.js:101:19:101:22 | 'x4' | The hard-coded value "x4" is used as $@. | HardcodedCredentials.js:101:19:101:22 | 'x4' | user name |
+| HardcodedCredentials.js:102:14:102:17 | 'y1' | HardcodedCredentials.js:102:14:102:17 | 'y1' | HardcodedCredentials.js:102:14:102:17 | 'y1' | The hard-coded value "y1" is used as $@. | HardcodedCredentials.js:102:14:102:17 | 'y1' | password |
+| HardcodedCredentials.js:103:17:103:20 | 'y2' | HardcodedCredentials.js:103:17:103:20 | 'y2' | HardcodedCredentials.js:103:17:103:20 | 'y2' | The hard-coded value "y2" is used as $@. | HardcodedCredentials.js:103:17:103:20 | 'y2' | password |
+| HardcodedCredentials.js:104:27:104:30 | 'y3' | HardcodedCredentials.js:104:27:104:30 | 'y3' | HardcodedCredentials.js:104:27:104:30 | 'y3' | The hard-coded value "y3" is used as $@. | HardcodedCredentials.js:104:27:104:30 | 'y3' | password |
+| HardcodedCredentials.js:105:19:105:22 | 'y4' | HardcodedCredentials.js:105:19:105:22 | 'y4' | HardcodedCredentials.js:105:19:105:22 | 'y4' | The hard-coded value "y4" is used as $@. | HardcodedCredentials.js:105:19:105:22 | 'y4' | password |
+| HardcodedCredentials.js:106:16:106:19 | 'z1' | HardcodedCredentials.js:106:16:106:19 | 'z1' | HardcodedCredentials.js:106:16:106:19 | 'z1' | The hard-coded value "z1" is used as $@. | HardcodedCredentials.js:106:16:106:19 | 'z1' | token |
+| HardcodedCredentials.js:112:19:112:22 | 'x5' | HardcodedCredentials.js:112:19:112:22 | 'x5' | HardcodedCredentials.js:112:19:112:22 | 'x5' | The hard-coded value "x5" is used as $@. | HardcodedCredentials.js:112:19:112:22 | 'x5' | user name |
+| HardcodedCredentials.js:113:19:113:22 | 'y5' | HardcodedCredentials.js:113:19:113:22 | 'y5' | HardcodedCredentials.js:113:19:113:22 | 'y5' | The hard-coded value "y5" is used as $@. | HardcodedCredentials.js:113:19:113:22 | 'y5' | password |
+| HardcodedCredentials.js:130:44:130:58 | 'crypto secret' | HardcodedCredentials.js:130:44:130:58 | 'crypto secret' | HardcodedCredentials.js:130:44:130:58 | 'crypto secret' | The hard-coded value "crypto secret" is used as $@. | HardcodedCredentials.js:130:44:130:58 | 'crypto secret' | key |
+| HardcodedCredentials.js:131:52:131:73 | 'crypto ... secret' | HardcodedCredentials.js:131:52:131:73 | 'crypto ... secret' | HardcodedCredentials.js:131:52:131:73 | 'crypto ... secret' | The hard-coded value "crypto-js/aes secret" is used as $@. | HardcodedCredentials.js:131:52:131:73 | 'crypto ... secret' | key |
+| HardcodedCredentials.js:135:41:135:63 | "cookie ... secret" | HardcodedCredentials.js:135:41:135:63 | "cookie ... secret" | HardcodedCredentials.js:135:41:135:63 | "cookie ... secret" | The hard-coded value "cookie-session secret" is used as $@. | HardcodedCredentials.js:135:41:135:63 | "cookie ... secret" | key |
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 0ee7194b924b..8c2d94e0a9d1 100644
--- a/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected
@@ -1,14 +1,51 @@
-| tst.js:9:8:9:26 | req.params.shutDown | This condition guards a sensitive $@, but $@ controls it. | tst.js:11:9:11:22 | process.exit() | action | tst.js:9:8:9:26 | req.params.shutDown | a user-provided value |
-| tst.js:14:9:14:30 | req.coo ... inThing | This condition guards a sensitive $@, but $@ controls it. | tst.js:16:9:16:17 | o.login() | action | tst.js:14:9:14:19 | req.cookies | a user-provided value |
-| tst.js:31:9:31:10 | v3 | This condition guards a sensitive $@, but $@ controls it. | tst.js:33:9:33:22 | process.exit() | action | tst.js:30:17:30:27 | req.cookies | a user-provided value |
-| tst.js:37:13:37:32 | req.cookies.cookieId | This condition guards a sensitive $@, but $@ controls it. | tst.js:39:13:39:26 | process.exit() | action | tst.js:37:13:37:23 | req.cookies | a user-provided value |
-| tst.js:43:9:43:28 | req.cookies.cookieId | This condition guards a sensitive $@, but $@ controls it. | tst.js:46:13:46:26 | process.exit() | action | tst.js:43:9:43:19 | req.cookies | a user-provided value |
-| tst.js:50:8:50:23 | req.params.login | This condition guards a sensitive $@, but $@ controls it. | tst.js:54:9:54:15 | login() | action | tst.js:50:8:50:23 | req.params.login | a user-provided value |
-| tst.js:65:8:65:23 | req.params.login | This condition guards a sensitive $@, but $@ controls it. | tst.js:67:9:67:15 | login() | action | tst.js:65:8:65:23 | req.params.login | a user-provided value |
-| tst.js:70:9:70:53 | req.coo ... questId | This condition guards a sensitive $@, but $@ controls it. | tst.js:72:9:72:22 | process.exit() | action | tst.js:70:9:70:19 | req.cookies | a user-provided value |
-| tst.js:70:9:70:53 | req.coo ... questId | This condition guards a sensitive $@, but $@ controls it. | tst.js:72:9:72:22 | process.exit() | action | tst.js:70:34:70:53 | req.params.requestId | a user-provided value |
-| tst.js:76:9:76:10 | v1 | This condition guards a sensitive $@, but $@ controls it. | tst.js:78:9:78:22 | process.exit() | action | tst.js:75:14:75:24 | req.cookies | a user-provided value |
-| tst.js:76:9:76:10 | v1 | This condition guards a sensitive $@, but $@ controls it. | tst.js:78:9:78:22 | process.exit() | action | tst.js:75:39:75:58 | req.params.requestId | a user-provided value |
-| tst.js:90:9:90:41 | req.coo ... secret" | This condition guards a sensitive $@, but $@ controls it. | tst.js:92:9:92:22 | process.exit() | action | tst.js:90:9:90:19 | req.cookies | a user-provided value |
-| tst.js:111:13:111:32 | req.query.vulnerable | This condition guards a sensitive $@, but $@ controls it. | tst.js:114:9:114:16 | verify() | action | tst.js:111:13:111:32 | req.query.vulnerable | a user-provided value |
-| tst.js:118:13:118:32 | req.query.vulnerable | This condition guards a sensitive $@, but $@ controls it. | tst.js:121:13:121:20 | verify() | action | tst.js:118:13:118:32 | req.query.vulnerable | a user-provided value |
+nodes
+| tst.js:9:8:9:26 | req.params.shutDown |
+| tst.js:14:9:14:19 | req.cookies |
+| tst.js:14:9:14:30 | req.coo ... inThing |
+| tst.js:30:9:30:37 | v3 |
+| tst.js:30:14:30:37 | id(req. ... okieId) |
+| tst.js:30:17:30:27 | req.cookies |
+| tst.js:30:17:30:36 | req.cookies.cookieId |
+| tst.js:31:9:31:10 | v3 |
+| tst.js:37:13:37:23 | req.cookies |
+| tst.js:37:13:37:32 | req.cookies.cookieId |
+| tst.js:43:9:43:19 | req.cookies |
+| tst.js:43:9:43:28 | req.cookies.cookieId |
+| tst.js:50:8:50:23 | req.params.login |
+| tst.js:65:8:65:23 | req.params.login |
+| tst.js:70:9:70:19 | req.cookies |
+| tst.js:70:9:70:28 | req.cookies.cookieId |
+| tst.js:70:34:70:53 | req.params.requestId |
+| tst.js:75:14:75:24 | req.cookies |
+| tst.js:75:14:75:33 | req.cookies.cookieId |
+| tst.js:75:39:75:58 | req.params.requestId |
+| tst.js:90:9:90:19 | req.cookies |
+| tst.js:90:9:90:28 | req.cookies.cookieId |
+| tst.js:90:9:90:41 | req.coo ... secret" |
+| tst.js:104:10:104:17 | req.body |
+| tst.js:111:13:111:32 | req.query.vulnerable |
+| tst.js:118:13:118:32 | req.query.vulnerable |
+| tst.js:126:13:126:32 | req.query.vulnerable |
+edges
+| tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing |
+| tst.js:30:9:30:37 | v3 | tst.js:31:9:31:10 | v3 |
+| tst.js:30:14:30:37 | id(req. ... okieId) | tst.js:30:9:30:37 | v3 |
+| tst.js:30:17:30:27 | req.cookies | tst.js:30:17:30:36 | req.cookies.cookieId |
+| tst.js:30:17:30:36 | req.cookies.cookieId | tst.js:30:14:30:37 | id(req. ... okieId) |
+| tst.js:37:13:37:23 | req.cookies | tst.js:37:13:37:32 | req.cookies.cookieId |
+| tst.js:43:9:43:19 | req.cookies | tst.js:43:9:43:28 | req.cookies.cookieId |
+| tst.js:70:9:70:19 | req.cookies | tst.js:70:9:70:28 | req.cookies.cookieId |
+| tst.js:75:14:75:24 | req.cookies | tst.js:75:14:75:33 | req.cookies.cookieId |
+| tst.js:90:9:90:19 | req.cookies | tst.js:90:9:90:28 | req.cookies.cookieId |
+| tst.js:90:9:90:28 | req.cookies.cookieId | tst.js:90:9:90:41 | req.coo ... secret" |
+#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 $@ controls it. | tst.js:11:9:11:22 | process.exit() | action | tst.js:9:8:9:26 | req.params.shutDown | a user-provided value |
+| tst.js:14:9:14:30 | req.coo ... inThing | tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing | This condition guards a sensitive $@, but $@ controls it. | tst.js:16:9:16:17 | o.login() | action | tst.js:14:9:14:19 | req.cookies | a user-provided value |
+| tst.js:31:9:31:10 | v3 | tst.js:30:17:30:27 | req.cookies | tst.js:31:9:31:10 | v3 | This condition guards a sensitive $@, but $@ controls it. | tst.js:33:9:33:22 | process.exit() | action | tst.js:30:17:30:27 | req.cookies | a user-provided value |
+| tst.js:37:13:37:32 | req.cookies.cookieId | tst.js:37:13:37:23 | req.cookies | tst.js:37:13:37:32 | req.cookies.cookieId | This condition guards a sensitive $@, but $@ controls it. | tst.js:39:13:39:26 | process.exit() | action | tst.js:37:13:37:23 | req.cookies | a user-provided value |
+| tst.js:43:9:43:28 | req.cookies.cookieId | tst.js:43:9:43:19 | req.cookies | tst.js:43:9:43:28 | req.cookies.cookieId | This condition guards a sensitive $@, but $@ controls it. | tst.js:46:13:46:26 | process.exit() | action | tst.js:43:9:43:19 | req.cookies | a user-provided value |
+| tst.js:50:8:50:23 | req.params.login | tst.js:50:8:50:23 | req.params.login | tst.js:50:8:50:23 | req.params.login | This condition guards a sensitive $@, but $@ controls it. | tst.js:54:9:54:15 | login() | action | tst.js:50:8:50:23 | req.params.login | a user-provided value |
+| tst.js:65:8:65:23 | req.params.login | tst.js:65:8:65:23 | req.params.login | tst.js:65:8:65:23 | req.params.login | This condition guards a sensitive $@, but $@ controls it. | tst.js:67:9:67:15 | login() | action | tst.js:65:8:65:23 | req.params.login | a user-provided value |
+| tst.js:90:9:90:41 | req.coo ... secret" | tst.js:90:9:90:19 | req.cookies | tst.js:90:9:90:41 | req.coo ... secret" | This condition guards a sensitive $@, but $@ controls it. | tst.js:92:9:92:22 | process.exit() | action | tst.js:90:9:90:19 | req.cookies | a user-provided value |
+| tst.js:111:13:111:32 | req.query.vulnerable | tst.js:111:13:111:32 | req.query.vulnerable | tst.js:111:13:111:32 | req.query.vulnerable | This condition guards a sensitive $@, but $@ controls it. | tst.js:114:9:114:16 | verify() | action | tst.js:111:13:111:32 | req.query.vulnerable | a user-provided value |
+| tst.js:118:13:118:32 | req.query.vulnerable | tst.js:118:13:118:32 | req.query.vulnerable | tst.js:118:13:118:32 | req.query.vulnerable | This condition guards a sensitive $@, but $@ controls it. | tst.js:121:13:121:20 | verify() | action | tst.js:118:13:118:32 | req.query.vulnerable | a user-provided value |
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 7431c4677138..8eace9eab8e9 100644
--- a/javascript/ql/test/query-tests/Security/CWE-843/TypeConfusionThroughParameterTampering.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-843/TypeConfusionThroughParameterTampering.expected
@@ -1,9 +1,49 @@
-| tst.js:6:5:6:7 | foo | Potential type confusion for $@. | tst.js:5:15:5:27 | req.query.foo | HTTP request parameter |
-| tst.js:8:5:8:7 | foo | Potential type confusion for $@. | tst.js:5:15:5:27 | req.query.foo | HTTP request parameter |
-| tst.js:11:9:11:11 | foo | Potential type confusion for $@. | tst.js:5:15:5:27 | req.query.foo | HTTP request parameter |
-| tst.js:15:9:15:11 | bar | Potential type confusion for $@. | tst.js:5:15:5:27 | req.query.foo | HTTP request parameter |
-| tst.js:27:5:27:7 | foo | Potential type confusion for $@. | tst.js:5:15:5:27 | req.query.foo | HTTP request parameter |
-| tst.js:28:5:28:7 | foo | Potential type confusion for $@. | tst.js:5:15:5:27 | req.query.foo | HTTP request parameter |
-| tst.js:36:9:36:11 | foo | Potential type confusion for $@. | tst.js:5:15:5:27 | req.query.foo | HTTP request parameter |
-| tst.js:41:5:41:7 | foo | Potential type confusion for $@. | tst.js:5:15:5:27 | req.query.foo | HTTP request parameter |
-| tst.js:46:5:46:7 | foo | Potential type confusion for $@. | tst.js:45:15:45:35 | ctx.req ... ery.foo | HTTP request parameter |
+nodes
+| tst.js:5:9:5:27 | foo |
+| tst.js:5:15:5:27 | req.query.foo |
+| tst.js:6:5:6:7 | foo |
+| tst.js:8:5:8:7 | foo |
+| tst.js:10:5:10:4 | foo |
+| tst.js:11:9:11:11 | foo |
+| tst.js:14:16:14:18 | bar |
+| tst.js:15:9:15:11 | bar |
+| tst.js:17:7:17:9 | foo |
+| tst.js:27:5:27:7 | foo |
+| tst.js:28:5:28:7 | foo |
+| tst.js:30:9:30:31 | foo |
+| tst.js:30:9:30:31 | foo |
+| tst.js:35:5:35:5 | foo |
+| tst.js:36:9:36:11 | foo |
+| tst.js:41:5:41:7 | foo |
+| tst.js:45:9:45:35 | foo |
+| tst.js:45:15:45:35 | ctx.req ... ery.foo |
+| tst.js:46:5:46:7 | foo |
+edges
+| 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:10:5:10:4 | foo |
+| tst.js:5:9:5:27 | foo | tst.js:17:7:17:9 | 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:30:9:30:31 | foo |
+| tst.js:5:9:5:27 | foo | tst.js:30:9:30:31 | foo |
+| tst.js:5:15:5:27 | req.query.foo | tst.js:5:9:5:27 | foo |
+| tst.js:10:5:10:4 | foo | tst.js:11:9:11:11 | 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:30:9:30:31 | foo | tst.js:35:5:35:5 | foo |
+| tst.js:30:9:30:31 | foo | tst.js:35:5:35:5 | foo |
+| tst.js:35:5:35:5 | foo | tst.js:36:9:36:11 | foo |
+| tst.js:35:5:35:5 | foo | tst.js:41:5:41:7 | 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 |
+#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 for $@. | tst.js:5:15:5:27 | req.query.foo | 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 for $@. | tst.js:5:15:5:27 | req.query.foo | HTTP request parameter |
+| tst.js:11:9:11:11 | foo | tst.js:5:15:5:27 | req.query.foo | tst.js:11:9:11:11 | foo | Potential type confusion for $@. | tst.js:5:15:5:27 | req.query.foo | HTTP request parameter |
+| tst.js:15:9:15:11 | bar | tst.js:5:15:5:27 | req.query.foo | tst.js:15:9:15:11 | bar | Potential type confusion for $@. | tst.js:5:15:5:27 | req.query.foo | HTTP request parameter |
+| tst.js:27:5:27:7 | foo | tst.js:5:15:5:27 | req.query.foo | tst.js:27:5:27:7 | foo | Potential type confusion for $@. | tst.js:5:15:5:27 | req.query.foo | HTTP request parameter |
+| tst.js:28:5:28:7 | foo | tst.js:5:15:5:27 | req.query.foo | tst.js:28:5:28:7 | foo | Potential type confusion for $@. | tst.js:5:15:5:27 | req.query.foo | HTTP request parameter |
+| tst.js:36:9:36:11 | foo | tst.js:5:15:5:27 | req.query.foo | tst.js:36:9:36:11 | foo | Potential type confusion for $@. | tst.js:5:15:5:27 | req.query.foo | HTTP request parameter |
+| tst.js:41:5:41:7 | foo | tst.js:5:15:5:27 | req.query.foo | tst.js:41:5:41:7 | foo | Potential type confusion for $@. | tst.js:5:15:5:27 | req.query.foo | HTTP request parameter |
+| tst.js:46:5:46:7 | foo | tst.js:45:15:45:35 | ctx.req ... ery.foo | tst.js:46:5:46:7 | foo | Potential type confusion for $@. | tst.js:45:15:45:35 | ctx.req ... ery.foo | HTTP request parameter |
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 5799343dd262..05b6a4a08495 100644
--- a/javascript/ql/test/query-tests/Security/CWE-912/HttpToFileAccess.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-912/HttpToFileAccess.expected
@@ -1,3 +1,15 @@
-| tst.js:16:33:16:33 | c | $@ flows to file system | tst.js:15:26:15:26 | c | Untrusted data |
-| tst.js:19:25:19:25 | c | $@ flows to file system | tst.js:15:26:15:26 | c | Untrusted data |
-| tst.js:24:22:24:22 | c | $@ flows to file system | tst.js:15:26:15:26 | c | Untrusted data |
+nodes
+| tst.js:15:26:15:26 | c |
+| tst.js:16:33:16:33 | c |
+| tst.js:19:25:19:25 | c |
+| tst.js:23:27:23:26 | c |
+| tst.js:24:22:24:22 | c |
+edges
+| 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:23:27:23:26 | c |
+| tst.js:23:27:23:26 | c | tst.js:24:22:24:22 | c |
+#select
+| tst.js:16:33:16:33 | c | tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | $@ flows to file system | tst.js:15:26:15:26 | c | Untrusted data |
+| tst.js:19:25:19:25 | c | tst.js:15:26:15:26 | c | tst.js:19:25:19:25 | c | $@ flows to file system | tst.js:15:26:15:26 | c | Untrusted data |
+| tst.js:24:22:24:22 | c | tst.js:15:26:15:26 | c | tst.js:24:22:24:22 | c | $@ flows to file system | tst.js:15:26:15:26 | c | Untrusted data |
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 947e48dd2598..cdd69e35a19b 100644
--- a/javascript/ql/test/query-tests/Security/CWE-916/InsufficientPasswordHash.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-916/InsufficientPasswordHash.expected
@@ -1,3 +1,9 @@
-| 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 | Password from $@ is hashed insecurely. | tst.js:7:46:7:53 | password | an access to password |
-| tst.js:9:43:9:50 | password | Password from $@ is hashed insecurely. | tst.js:9:43:9:50 | password | an access to password |
+nodes
+| tst.js:5:48:5:55 | password |
+| tst.js:7:46:7:53 | password |
+| tst.js:9:43:9:50 | password |
+edges
+#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 |
+| tst.js:9:43:9:50 | password | tst.js:9:43:9:50 | password | tst.js:9:43:9:50 | password | Password from $@ is hashed insecurely. | tst.js:9:43:9:50 | password | an access to password |
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 d114b6a8e389..b4368363730a 100644
--- a/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected
@@ -1,6 +1,36 @@
-| tst.js:16:5:16:20 | request(tainted) | The $@ of this request depends on $@. | tst.js:16:13:16:19 | tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value |
-| tst.js:18:5:18:24 | request.get(tainted) | The $@ of this request depends on $@. | tst.js:18:17:18:23 | tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value |
-| tst.js:22:5:22:20 | request(options) | The $@ of this request depends on $@. | tst.js:21:19:21:25 | tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value |
-| tst.js:24:5:24:32 | request ... ainted) | The $@ of this request depends on $@. | tst.js:24:13:24:31 | "http://" + tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value |
-| tst.js:26:5:26:43 | request ... ainted) | The $@ of this request depends on $@. | tst.js:26:13:26:42 | "http:/ ... tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value |
-| tst.js:28:5:28:44 | request ... ainted) | The $@ of this request depends on $@. | tst.js:28:13:28:43 | "http:/ ... tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value |
+nodes
+| tst.js:12:9:12:52 | tainted |
+| tst.js:12:19:12:42 | url.par ... , true) |
+| tst.js:12:19:12:48 | url.par ... ).query |
+| tst.js:12:19:12:52 | url.par ... ery.url |
+| tst.js:12:29:12:35 | req.url |
+| tst.js:16:13:16:19 | tainted |
+| tst.js:18:17:18:23 | tainted |
+| tst.js:21:19:21:25 | tainted |
+| tst.js:24:13:24:31 | "http://" + tainted |
+| tst.js:24:25:24:31 | tainted |
+| tst.js:26:13:26:42 | "http:/ ... tainted |
+| tst.js:26:36:26:42 | tainted |
+| tst.js:28:13:28:43 | "http:/ ... tainted |
+| tst.js:28:37:28:43 | tainted |
+edges
+| tst.js:12:9:12:52 | tainted | tst.js:16:13:16:19 | tainted |
+| tst.js:12:9:12:52 | tainted | tst.js:18:17:18:23 | tainted |
+| tst.js:12:9:12:52 | tainted | tst.js:21:19:21:25 | tainted |
+| tst.js:12:9:12:52 | tainted | tst.js:24:25:24:31 | tainted |
+| tst.js:12:9:12:52 | tainted | tst.js:26:36:26:42 | tainted |
+| tst.js:12:9:12:52 | tainted | tst.js:28:37:28:43 | tainted |
+| tst.js:12:19:12:42 | url.par ... , true) | tst.js:12:19:12:48 | url.par ... ).query |
+| tst.js:12:19:12:48 | url.par ... ).query | tst.js:12:19:12:52 | url.par ... ery.url |
+| tst.js:12:19:12:52 | url.par ... ery.url | tst.js:12:9:12:52 | tainted |
+| tst.js:12:29:12:35 | req.url | tst.js:12:19:12:42 | url.par ... , true) |
+| tst.js:24:25:24:31 | tainted | tst.js:24:13:24:31 | "http://" + tainted |
+| tst.js:26:36:26:42 | tainted | tst.js:26:13:26:42 | "http:/ ... tainted |
+| tst.js:28:37:28:43 | tainted | tst.js:28:13:28:43 | "http:/ ... tainted |
+#select
+| tst.js:16:5:16:20 | request(tainted) | tst.js:12:29:12:35 | req.url | tst.js:16:13:16:19 | tainted | The $@ of this request depends on $@. | tst.js:16:13:16:19 | tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value |
+| tst.js:18:5:18:24 | request.get(tainted) | tst.js:12:29:12:35 | req.url | tst.js:18:17:18:23 | tainted | The $@ of this request depends on $@. | tst.js:18:17:18:23 | tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value |
+| tst.js:22:5:22:20 | request(options) | tst.js:12:29:12:35 | req.url | tst.js:21:19:21:25 | tainted | The $@ of this request depends on $@. | tst.js:21:19:21:25 | tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value |
+| tst.js:24:5:24:32 | request ... ainted) | tst.js:12:29:12:35 | req.url | tst.js:24:13:24:31 | "http://" + tainted | The $@ of this request depends on $@. | tst.js:24:13:24:31 | "http://" + tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value |
+| tst.js:26:5:26:43 | request ... ainted) | tst.js:12:29:12:35 | req.url | tst.js:26:13:26:42 | "http:/ ... tainted | The $@ of this request depends on $@. | tst.js:26:13:26:42 | "http:/ ... tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value |
+| tst.js:28:5:28:44 | request ... ainted) | tst.js:12:29:12:35 | req.url | tst.js:28:13:28:43 | "http:/ ... tainted | The $@ of this request depends on $@. | tst.js:28:13:28:43 | "http:/ ... tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value |