Merge remote-tracking branch 'upstream/master' into CVE74

This commit is contained in:
Erik Krogh Kristensen
2020-02-17 13:18:52 +01:00
122 changed files with 1765 additions and 1001 deletions

View File

@@ -78,7 +78,7 @@ predicate importLookup(ASTNode path, Module target, string kind) {
or
exists(ReExportDeclaration red |
path = red.getImportedPath() and
target = red.getImportedModule()
target = red.getReExportedModule()
)
)
}

View File

@@ -273,12 +273,12 @@ class BulkReExportDeclaration extends ReExportDeclaration, @exportalldeclaration
override ConstantString getImportedPath() { result = getChildExpr(0) }
override predicate exportsAs(LexicalName v, string name) {
getImportedModule().exportsAs(v, name) and
getReExportedES2015Module().exportsAs(v, name) and
not isShadowedFromBulkExport(this, name)
}
override DataFlow::Node getSourceNode(string name) {
result = getImportedModule().getAnExport().getSourceNode(name)
result = getReExportedES2015Module().getAnExport().getSourceNode(name)
}
}
@@ -379,7 +379,7 @@ class ExportNamedDeclaration extends ExportDeclaration, @exportnameddeclaration
exists(ExportSpecifier spec | spec = getASpecifier() and name = spec.getExportedName() |
v = spec.getLocal().(LexicalAccess).getALexicalName()
or
this.(ReExportDeclaration).getImportedModule().exportsAs(v, spec.getLocalName())
this.(ReExportDeclaration).getReExportedES2015Module().exportsAs(v, spec.getLocalName())
)
}
@@ -393,7 +393,7 @@ class ExportNamedDeclaration extends ExportDeclaration, @exportnameddeclaration
not exists(getImportedPath()) and result = DataFlow::valueNode(spec.getLocal())
or
exists(ReExportDeclaration red | red = this |
result = red.getImportedModule().getAnExport().getSourceNode(spec.getLocalName())
result = red.getReExportedES2015Module().getAnExport().getSourceNode(spec.getLocalName())
)
)
}
@@ -545,14 +545,18 @@ class ReExportDefaultSpecifier extends ExportDefaultSpecifier {
}
/**
* A namespace export specifier.
* A namespace export specifier, that is `*` or `* as x` occuring in an export declaration.
*
* Example:
* Examples:
*
* ```
* export
* * // namespace export specifier
* from 'a';
*
* export
* * as x // namespace export specifier
* from 'a';
* ```
*/
class ExportNamespaceSpecifier extends ExportSpecifier, @exportnamespacespecifier { }
@@ -564,6 +568,7 @@ class ExportNamespaceSpecifier extends ExportSpecifier, @exportnamespacespecifie
*
* ```
* export * from 'a'; // bulk re-export declaration
* export * as x from 'a'; // namespace re-export declaration
* export { x } from 'a'; // named re-export declaration
* export x from 'a'; // default re-export declaration
* ```
@@ -572,8 +577,23 @@ abstract class ReExportDeclaration extends ExportDeclaration {
/** Gets the path of the module from which this declaration re-exports. */
abstract ConstantString getImportedPath();
/** Gets the module from which this declaration re-exports. */
/**
* DEPRECATED. Use `getReExportedES2015Module()` instead.
*
* Gets the module from which this declaration re-exports.
*/
deprecated
ES2015Module getImportedModule() {
result = getReExportedModule()
}
/** Gets the module from which this declaration re-exports, if it is an ES2015 module. */
ES2015Module getReExportedES2015Module() {
result = getReExportedModule()
}
/** Gets the module from which this declaration re-exports. */
Module getReExportedModule() {
result.getFile() = getEnclosingModule().resolve(getImportedPath().(PathExpr))
or
result = resolveFromTypeRoot()
@@ -641,4 +661,4 @@ class OriginalExportDeclaration extends ExportDeclaration {
result = this.(ExportDefaultDeclaration).getSourceNode(name) or
result = this.(ExportNamedDeclaration).getSourceNode(name)
}
}
}

View File

@@ -271,69 +271,84 @@ module TaintTracking {
ArrayFunctionTaintStep() { this = call }
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
// `array.map(function (elt, i, ary) { ... })`: if `array` is tainted, then so are
// `elt` and `ary`; similar for `forEach`
exists(string name, Function f, int i |
(name = "map" or name = "forEach") and
(i = 0 or i = 2) and
call.getArgument(0).analyze().getAValue().(AbstractFunction).getFunction() = f and
call.(DataFlow::MethodCallNode).getMethodName() = name and
pred = call.getReceiver() and
succ = DataFlow::parameterNode(f.getParameter(i))
)
or
// `array.map` with tainted return value in callback
exists(DataFlow::FunctionNode f |
call.(DataFlow::MethodCallNode).getMethodName() = "map" and
call.getArgument(0) = f and // Require the argument to be a closure to avoid spurious call/return flow
pred = f.getAReturn() and
succ = call
)
or
// `array.push(e)`, `array.unshift(e)`: if `e` is tainted, then so is `array`.
exists(string name |
name = "push" or
name = "unshift"
|
pred = call.getAnArgument() and
succ.(DataFlow::SourceNode).getAMethodCall(name) = call
)
or
// `array.push(...e)`, `array.unshift(...e)`: if `e` is tainted, then so is `array`.
exists(string name |
name = "push" or
name = "unshift"
|
pred = call.getASpreadArgument() and
// Make sure we handle reflective calls
succ = call.getReceiver().getALocalSource() and
call.getCalleeName() = name
)
or
// `array.splice(i, del, e)`: if `e` is tainted, then so is `array`.
exists(string name | name = "splice" |
pred = call.getArgument(2) and
succ.(DataFlow::SourceNode).getAMethodCall(name) = call
)
or
// `e = array.pop()`, `e = array.shift()`, or similar: if `array` is tainted, then so is `e`.
exists(string name |
name = "pop" or
name = "shift" or
name = "slice" or
name = "splice"
|
call.(DataFlow::MethodCallNode).calls(pred, name) and
succ = call
)
or
// `e = Array.from(x)`: if `x` is tainted, then so is `e`.
call = DataFlow::globalVarRef("Array").getAPropertyRead("from").getACall() and
pred = call.getAnArgument() and
succ = call
arrayFunctionTaintStep(pred, succ, call)
}
}
/**
* A taint propagating data flow edge from `pred` to `succ` caused by a call `call` to a builtin array functions.
*/
predicate arrayFunctionTaintStep(DataFlow::Node pred, DataFlow::Node succ, DataFlow::CallNode call) {
// `array.map(function (elt, i, ary) { ... })`: if `array` is tainted, then so are
// `elt` and `ary`; similar for `forEach`
exists(string name, Function f, int i |
(name = "map" or name = "forEach") and
(i = 0 or i = 2) and
call.getArgument(0).analyze().getAValue().(AbstractFunction).getFunction() = f and
call.(DataFlow::MethodCallNode).getMethodName() = name and
pred = call.getReceiver() and
succ = DataFlow::parameterNode(f.getParameter(i))
)
or
// `array.map` with tainted return value in callback
exists(DataFlow::FunctionNode f |
call.(DataFlow::MethodCallNode).getMethodName() = "map" and
call.getArgument(0) = f and // Require the argument to be a closure to avoid spurious call/return flow
pred = f.getAReturn() and
succ = call
)
or
// `array.push(e)`, `array.unshift(e)`: if `e` is tainted, then so is `array`.
exists(string name |
name = "push" or
name = "unshift"
|
pred = call.getAnArgument() and
succ.(DataFlow::SourceNode).getAMethodCall(name) = call
)
or
// `array.push(...e)`, `array.unshift(...e)`: if `e` is tainted, then so is `array`.
exists(string name |
name = "push" or
name = "unshift"
|
pred = call.getASpreadArgument() and
// Make sure we handle reflective calls
succ = call.getReceiver().getALocalSource() and
call.getCalleeName() = name
)
or
// `array.splice(i, del, e)`: if `e` is tainted, then so is `array`.
exists(string name | name = "splice" |
pred = call.getArgument(2) and
succ.(DataFlow::SourceNode).getAMethodCall(name) = call
)
or
// `e = array.pop()`, `e = array.shift()`, or similar: if `array` is tainted, then so is `e`.
exists(string name |
name = "pop" or
name = "shift" or
name = "slice" or
name = "splice"
|
call.(DataFlow::MethodCallNode).calls(pred, name) and
succ = call
)
or
// `e = Array.from(x)`: if `x` is tainted, then so is `e`.
call = DataFlow::globalVarRef("Array").getAPropertyRead("from").getACall() and
pred = call.getAnArgument() and
succ = call
or
// `e = arr1.concat(arr2, arr3)`: if any of the `arr` is tainted, then so is `e`.
call.(DataFlow::MethodCallNode).calls(pred, "concat") and
succ = call
or
call.(DataFlow::MethodCallNode).getMethodName() = "concat" and
succ = call and
pred = call.getAnArgument()
}
/**
* A taint propagating data flow edge for assignments of the form `o[k] = v`, where
* `k` is not a constant and `o` refers to some object literal; in this case, we consider

View File

@@ -65,7 +65,7 @@ private predicate mayDynamicallyComputeExports(Module m) {
or
// `m` re-exports all exports of some other module that dynamically computes its exports
exists(BulkReExportDeclaration rexp | rexp = m.(ES2015Module).getAnExport() |
mayDynamicallyComputeExports(rexp.getImportedModule())
mayDynamicallyComputeExports(rexp.getReExportedModule())
)
}
@@ -79,7 +79,7 @@ private predicate relevantExport(ES2015Module m, string x) {
)
or
exists(ReExportDeclaration rexp, string y |
rexp.getImportedModule() = m and
rexp.getReExportedModule() = m and
reExportsAs(rexp, x, y)
)
}
@@ -110,9 +110,9 @@ private predicate incompleteExport(ES2015Module m, string y) {
mayDependOnLookupPath(rexp.getImportedPath().getStringValue())
or
// unresolvable path
not exists(rexp.getImportedModule())
not exists(rexp.getReExportedModule())
or
exists(Module n | n = rexp.getImportedModule() |
exists(Module n | n = rexp.getReExportedModule() |
// re-export from CommonJS/AMD
mayDynamicallyComputeExports(n)
or
@@ -399,3 +399,16 @@ private class AnalyzedClosureGlobalAccessPath extends AnalyzedNode, AnalyzedProp
)
}
}
/**
* A namespace export declaration analyzed as a property write.
*/
private class AnalyzedExportNamespaceSpecifier extends AnalyzedPropertyWrite, DataFlow::ValueNode {
override ExportNamespaceSpecifier astNode;
override predicate writesValue(AbstractValue baseVal, string propName, AbstractValue value) {
baseVal = TAbstractExportsObject(getTopLevel()) and
propName = astNode.getExportedName() and
value = TAbstractExportsObject(astNode.getExportDeclaration().(ReExportDeclaration).getReExportedModule())
}
}

View File

@@ -549,4 +549,72 @@ module ClientRequest {
)
}
}
/**
* Gets a reference to an instance of `chrome-remote-interface`.
*
* An instantiation of `chrome-remote-interface` either accepts a callback or returns a promise.
*
* The `isPromise` parameter reflects whether the reference is a promise containing
* an instance of `chrome-remote-interface`, or an instance of `chrome-remote-interface`.
*/
private DataFlow::SourceNode chromeRemoteInterface(DataFlow::TypeTracker t, boolean isPromise) {
t.start() and
exists(DataFlow::CallNode call |
call = DataFlow::moduleImport("chrome-remote-interface").getAnInvocation()
|
result = call and isPromise = true
or
result = call.getCallback([0 .. 1]).getParameter(0) and isPromise = false
)
or
exists(DataFlow::TypeTracker t2 | result = chromeRemoteInterface(t2, isPromise).track(t2, t))
or
// Simple promise tracking.
exists(DataFlow::TypeTracker t2, DataFlow::SourceNode pred |
pred = chromeRemoteInterface(t2, true) and
isPromise = false and
(
t2 = t and
exists(AwaitExpr await | DataFlow::valueNode(await.getOperand()).getALocalSource() = pred |
result.getEnclosingExpr() = await
)
or
t2 = t and
exists(DataFlow::MethodCallNode thenCall |
thenCall.getMethodName() = "then" and pred = thenCall.getReceiver().getALocalSource()
|
result = thenCall.getCallback(0).getParameter(0)
)
)
)
}
/**
* A call to navigate a browser controlled by `chrome-remote-interface` to a specific URL.
*/
class ChromeRemoteInterfaceRequest extends ClientRequest::Range, DataFlow::CallNode {
int optionsArg;
ChromeRemoteInterfaceRequest() {
exists(DataFlow::SourceNode instance |
instance = chromeRemoteInterface(DataFlow::TypeTracker::end(), false)
|
optionsArg = 0 and
this = instance.getAPropertyRead("Page").getAMemberCall("navigate")
or
optionsArg = 1 and
this = instance.getAMemberCall("send") and
this.getArgument(0).mayHaveStringValue("Page.navigate")
)
}
override DataFlow::Node getUrl() {
result = getArgument(optionsArg).getALocalSource().getAPropertyWrite("url").getRhs()
}
override DataFlow::Node getHost() { none() }
override DataFlow::Node getADataNode() { none() }
}
}

View File

@@ -119,8 +119,11 @@ module HTTP {
}
/**
* DEPRECATED: Use `http` or `https` directly as appropriate.
*
* Gets the string `http` or `https`.
*/
deprecated
string httpOrHttps() { result = "http" or result = "https" }
/**

View File

@@ -42,7 +42,18 @@ module NodeJSLib {
* Holds if `call` is an invocation of `http.createServer` or `https.createServer`.
*/
predicate isCreateServer(CallExpr call) {
call = DataFlow::moduleMember(HTTP::httpOrHttps(), "createServer").getAnInvocation().asExpr()
exists(string pkg, string fn |
pkg = "http" and fn = "createServer"
or
pkg = "https" and fn = "createServer"
or
// http2 compatibility API
pkg = "http2" and fn = "createServer"
or
pkg = "http2" and fn = "createSecureServer"
|
call = DataFlow::moduleMember(pkg, fn).getAnInvocation().asExpr()
)
}
/**
@@ -356,10 +367,12 @@ module NodeJSLib {
/** An expression that is passed as `http.request({ auth: <expr> }, ...)`. */
class Credentials extends CredentialsExpr {
Credentials() {
this = DataFlow::moduleMember(HTTP::httpOrHttps(), "request")
.getACall()
.getOptionArgument(0, "auth")
.asExpr()
exists(string http | http = "http" or http = "https" |
this = DataFlow::moduleMember(http, "request")
.getACall()
.getOptionArgument(0, "auth")
.asExpr()
)
}
override string getCredentialsKind() { result = "credentials" }
@@ -881,7 +894,6 @@ module NodeJSLib {
override string getSourceType() { result = "NodeJSClientRequest error event" }
}
/**
* An NodeJS EventEmitter instance.
* Events dispatched on this EventEmitter will be handled by event handlers registered on this EventEmitter.

View File

@@ -30,9 +30,14 @@ private DataFlow::Node commandArgument(SystemCommandExecution sys, DataFlow::Typ
t.start() and
result = sys.getACommandArgument()
or
exists(DataFlow::TypeBackTracker t2 |
t = t2.smallstep(result, commandArgument(sys, t2))
)
exists(DataFlow::TypeBackTracker t2 | t = t2.smallstep(result, commandArgument(sys, t2)))
}
/**
* Gets a data-flow node whose value ends up being interpreted as the command argument in `sys`.
*/
private DataFlow::Node commandArgument(SystemCommandExecution sys) {
result = commandArgument(sys, DataFlow::TypeBackTracker::end())
}
/**
@@ -43,11 +48,23 @@ private DataFlow::SourceNode argumentList(SystemCommandExecution sys, DataFlow::
t.start() and
result = sys.getArgumentList().getALocalSource()
or
exists(DataFlow::TypeBackTracker t2 |
result = argumentList(sys, t2).backtrack(t2, t)
exists(DataFlow::TypeBackTracker t2, DataFlow::SourceNode pred |
pred = argumentList(sys, t2)
|
result = pred.backtrack(t2, t)
or
t = t2.continue() and
TaintTracking::arrayFunctionTaintStep(result, pred, _)
)
}
/**
* Gets a data-flow node whose value ends up being interpreted as the argument list in `sys`.
*/
private DataFlow::SourceNode argumentList(SystemCommandExecution sys) {
result = argumentList(sys, DataFlow::TypeBackTracker::end())
}
/**
* Holds if `source` contributes to the arguments of an indirect command execution `sys`.
*
@@ -61,15 +78,22 @@ private DataFlow::SourceNode argumentList(SystemCommandExecution sys, DataFlow::
* let args = ["-c", cmd];
* childProcess.spawn(sh, args, cb);
* ```
* or
* ```
* let cmd = getCommand();
* childProcess.spawn("cmd.exe", ["/c"].concat(cmd), cb);
* ```
*/
predicate isIndirectCommandArgument(DataFlow::Node source, SystemCommandExecution sys) {
exists(
DataFlow::ArrayCreationNode args, DataFlow::Node shell, string dashC
|
exists(DataFlow::ArrayCreationNode args, DataFlow::Node shell, string dashC |
shellCmd(shell.asExpr(), dashC) and
shell = commandArgument(sys, DataFlow::TypeBackTracker::end()) and
args = argumentList(sys, DataFlow::TypeBackTracker::end()) and
shell = commandArgument(sys) and
args.getAPropertyWrite().getRhs().mayHaveStringValue(dashC) and
source = args.getAPropertyWrite().getRhs()
args = argumentList(sys) and
(
source = argumentList(sys)
or
source = argumentList(sys).getAPropertyWrite().getRhs()
)
)
}

View File

@@ -0,0 +1 @@
semmle-extractor-options: --experimental

View File

@@ -0,0 +1 @@
export * as ns from "./lib";

View File

@@ -0,0 +1,4 @@
import { ns } from "./reExportLib";
/** calls:lib.f */
ns.f();

View File

@@ -146,8 +146,10 @@
| import.js:5:5:5:7 | myf | import.js:5:11:5:11 | f | n.js:1:1:1:15 | function f |
| import.js:8:5:8:11 | someVar | import.js:8:15:8:23 | someStuff | file://:0:0:0:0 | indefinite value (call) |
| import.js:11:5:11:6 | h1 | import.js:11:10:11:10 | h | file://:0:0:0:0 | indefinite value (import) |
| import.js:11:5:11:6 | h1 | import.js:11:10:11:10 | h | h.js:1:1:3:0 | exports object of module h |
| import.js:12:5:12:6 | hf | import.js:12:10:12:12 | h.f | file://:0:0:0:0 | indefinite value (heap) |
| import.js:12:5:12:6 | hf | import.js:12:10:12:12 | h.f | file://:0:0:0:0 | indefinite value (import) |
| import.js:12:5:12:6 | hf | import.js:12:10:12:12 | h.f | h.js:1:8:1:22 | function f |
| imports.ts:2:5:2:6 | ax | imports.ts:2:10:2:11 | Ax | file://:0:0:0:0 | indefinite value (global) |
| imports.ts:2:5:2:6 | ax | imports.ts:2:10:2:11 | Ax | file://:0:0:0:0 | indefinite value (heap) |
| imports.ts:5:5:5:7 | fs_ | imports.ts:5:11:5:12 | fs | file://:0:0:0:0 | indefinite value (import) |

View File

@@ -1,3 +0,0 @@
import semmle.javascript.ES2015Modules
query predicate test_BulkReExportDeclarations(BulkReExportDeclaration bred) { any() }

View File

@@ -1,3 +0,0 @@
import semmle.javascript.ES2015Modules
query predicate test_ExportDeclarations(ExportDeclaration ed) { any() }

View File

@@ -1,3 +0,0 @@
import semmle.javascript.ES2015Modules
query predicate test_ExportDefaultDeclarations(ExportDefaultDeclaration edd) { any() }

View File

@@ -1,5 +0,0 @@
import semmle.javascript.ES2015Modules
query predicate test_ExportSpecifiers(ExportSpecifier es, Identifier res0, Identifier res1) {
res0 = es.getLocal() and res1 = es.getExported()
}

View File

@@ -1,5 +0,0 @@
import javascript
query predicate test_GlobalVariableRef(VarAccess access) {
access.getVariable() instanceof GlobalVariable
}

View File

@@ -1,3 +0,0 @@
import semmle.javascript.ES2015Modules
query predicate test_ImportDefaultSpecifiers(ImportDefaultSpecifier ids) { any() }

View File

@@ -1,5 +0,0 @@
import semmle.javascript.ES2015Modules
query predicate test_ImportMetaExpr(ImportMetaExpr meta) {
any()
}

View File

@@ -1,3 +0,0 @@
import semmle.javascript.ES2015Modules
query predicate test_ImportNamespaceSpecifier(ImportNamespaceSpecifier ins) { any() }

View File

@@ -1,3 +0,0 @@
import semmle.javascript.ES2015Modules
query predicate test_ImportSpecifiers(ImportSpecifier is, VarDecl res) { res = is.getLocal() }

View File

@@ -1,5 +0,0 @@
import semmle.javascript.ES2015Modules
query predicate test_Imports(ImportDeclaration id, PathExprInModule res0, int res1) {
res0 = id.getImportedPath() and res1 = count(id.getASpecifier())
}

View File

@@ -1,5 +0,0 @@
import javascript
query predicate test_Module_exports(Module m, string name, ASTNode export) {
m.exports(name, export)
}

View File

@@ -1,3 +0,0 @@
import semmle.javascript.ES2015Modules
query predicate test_NamedImportSpecifier(NamedImportSpecifier nis) { any() }

View File

@@ -1,5 +0,0 @@
import javascript
query predicate test_OtherImports(Import imprt, Module res) {
not imprt instanceof ImportDeclaration and res = imprt.getImportedModule()
}

View File

@@ -1,5 +0,0 @@
import semmle.javascript.ES2015Modules
query predicate test_ReExportDeclarations(ReExportDeclaration red, ConstantString res) {
res = red.getImportedPath()
}

View File

@@ -1,8 +0,0 @@
import javascript
query predicate test_getAnImportedModule(string res0, string res1) {
exists(Module mod |
res0 = mod.getFile().getRelativePath() and
res1 = mod.getAnImportedModule().getFile().getRelativePath()
)
}

View File

@@ -1,3 +0,0 @@
import javascript
query predicate test_getExportedName(ExportSpecifier es, string res) { res = es.getLocalName() }

View File

@@ -1,3 +0,0 @@
import javascript
query predicate test_getImportedName(ImportSpecifier is, string res) { res = is.getImportedName() }

View File

@@ -1,3 +0,0 @@
import javascript
query predicate test_getLocalName(ExportSpecifier es, string res) { res = es.getLocalName() }

View File

@@ -1,5 +0,0 @@
import javascript
query predicate test_getSourceNode(ExportDeclaration ed, string name, DataFlow::Node res) {
res = ed.getSourceNode(name)
}

View File

@@ -0,0 +1 @@
export * as ns from "./a";

View File

@@ -0,0 +1,3 @@
import { ns } from "./reExportNamespace";
ns.x(); // Calls f() from a.js

View File

@@ -1,57 +1,5 @@
test_ImportSpecifiers
| b.js:1:8:1:8 | f | b.js:1:8:1:8 | f |
| d.js:1:10:1:21 | default as g | d.js:1:21:1:21 | g |
| d.js:1:24:1:29 | x as y | d.js:1:29:1:29 | y |
| exports.js:1:8:1:17 | * as dummy | exports.js:1:13:1:17 | dummy |
| f.ts:1:8:1:8 | g | f.ts:1:8:1:8 | g |
| g.ts:1:9:1:11 | foo | g.ts:1:9:1:11 | foo |
| import-in-mjs.mjs:1:8:1:24 | exported_from_mjs | import-in-mjs.mjs:1:8:1:24 | exported_from_mjs |
| import-ts-with-js-extension.ts:1:10:1:12 | foo | import-ts-with-js-extension.ts:1:10:1:12 | foo |
| importcss.js:1:8:1:8 | A | importcss.js:1:8:1:8 | A |
| m/c.js:1:8:1:13 | * as b | m/c.js:1:13:1:13 | b |
| tst.html:5:10:5:10 | f | tst.html:5:10:5:10 | f |
| unresolved.js:1:8:1:8 | f | unresolved.js:1:8:1:8 | f |
test_getLocalName
| b.js:5:10:5:15 | f as g | f |
| b.js:7:8:7:9 | f2 | default |
| e.js:2:10:2:10 | x | x |
| e.js:2:13:2:13 | y | y |
| e.js:3:10:3:21 | default as g | default |
| m/c.js:5:10:5:15 | g as h | g |
test_getExportedName
| b.js:5:10:5:15 | f as g | f |
| b.js:7:8:7:9 | f2 | default |
| e.js:2:10:2:10 | x | x |
| e.js:2:13:2:13 | y | y |
| e.js:3:10:3:21 | default as g | default |
| m/c.js:5:10:5:15 | g as h | g |
test_OtherImports
| es2015_require.js:1:11:1:24 | require('./d') | d.js:1:1:5:0 | <toplevel> |
test_ImportMetaExpr
| importmeta.js:1:33:1:43 | import.meta |
test_ReExportDeclarations
| b.js:7:1:7:21 | export ... './a'; | b.js:7:16:7:20 | './a' |
| d.js:4:1:4:20 | export * from 'm/c'; | d.js:4:15:4:19 | 'm/c' |
| e.js:3:1:3:35 | export ... './a'; | e.js:3:30:3:34 | './a' |
| m/c.js:5:1:5:30 | export ... '../b'; | m/c.js:5:24:5:29 | '../b' |
test_ImportDefaultSpecifiers
| b.js:1:8:1:8 | f |
| f.ts:1:8:1:8 | g |
| import-in-mjs.mjs:1:8:1:24 | exported_from_mjs |
| importcss.js:1:8:1:8 | A |
| tst.html:5:10:5:10 | f |
| unresolved.js:1:8:1:8 | f |
test_getImportedName
| b.js:1:8:1:8 | f | default |
| d.js:1:10:1:21 | default as g | default |
| d.js:1:24:1:29 | x as y | x |
| f.ts:1:8:1:8 | g | default |
| g.ts:1:9:1:11 | foo | foo |
| import-in-mjs.mjs:1:8:1:24 | exported_from_mjs | default |
| import-ts-with-js-extension.ts:1:10:1:12 | foo | foo |
| importcss.js:1:8:1:8 | A | default |
| tst.html:5:10:5:10 | f | default |
| unresolved.js:1:8:1:8 | f | default |
test_BulkReExportDeclarations
| d.js:4:1:4:20 | export * from 'm/c'; |
test_ExportDeclarations
| a.js:1:1:3:1 | export ... n 23;\\n} |
| a.js:5:1:5:32 | export ... } = o; |
@@ -64,29 +12,48 @@ test_ExportDeclarations
| export-in-mjs.mjs:1:1:1:34 | export ... s = 42; |
| f.ts:5:1:5:24 | export ... oo() {} |
| m/c.js:5:1:5:30 | export ... '../b'; |
| reExportNamespace.js:1:1:1:26 | export ... "./a"; |
| tst.html:7:3:7:22 | export const y = 42; |
test_getAnImportedModule
| library-tests/Modules/b.js | library-tests/Modules/a.js |
| library-tests/Modules/d.js | library-tests/Modules/a.js |
| library-tests/Modules/d.js | library-tests/Modules/b.js |
| library-tests/Modules/es2015_require.js | library-tests/Modules/d.js |
| library-tests/Modules/f.ts | library-tests/Modules/e.js |
| library-tests/Modules/g.ts | library-tests/Modules/f.ts |
| library-tests/Modules/import-ts-with-js-extension.ts | library-tests/Modules/f.ts |
| library-tests/Modules/m/c.js | library-tests/Modules/b.js |
test_getSourceNode
| a.js:1:1:3:1 | export ... n 23;\\n} | default | a.js:1:16:3:1 | functio ... n 23;\\n} |
| a.js:5:1:5:32 | export ... } = o; | x | a.js:5:18:5:20 | f() |
| b.js:5:1:5:18 | export { f as g }; | g | b.js:5:10:5:10 | f |
| b.js:7:1:7:21 | export ... './a'; | f2 | a.js:1:16:3:1 | functio ... n 23;\\n} |
| e.js:2:1:2:16 | export { x, y }; | x | e.js:2:10:2:10 | x |
| e.js:2:1:2:16 | export { x, y }; | y | e.js:2:13:2:13 | y |
| e.js:3:1:3:35 | export ... './a'; | g | a.js:1:16:3:1 | functio ... n 23;\\n} |
| es2015_require.js:3:1:3:25 | export ... ss C {} | default | es2015_require.js:3:16:3:25 | class C {} |
| export-in-mjs.mjs:1:1:1:34 | export ... s = 42; | exported_from_mjs | export-in-mjs.mjs:1:32:1:33 | 42 |
| f.ts:5:1:5:24 | export ... oo() {} | foo | f.ts:5:8:5:24 | function foo() {} |
| m/c.js:5:1:5:30 | export ... '../b'; | h | b.js:5:10:5:10 | f |
| tst.html:7:3:7:22 | export const y = 42; | y | tst.html:7:20:7:21 | 42 |
test_ExportDefaultDeclarations
| a.js:1:1:3:1 | export ... n 23;\\n} |
| es2015_require.js:3:1:3:25 | export ... ss C {} |
test_ExportSpecifiers
| b.js:5:10:5:15 | f as g | b.js:5:10:5:10 | f | b.js:5:15:5:15 | g |
| e.js:2:10:2:10 | x | e.js:2:10:2:10 | x | e.js:2:10:2:10 | x |
| e.js:2:13:2:13 | y | e.js:2:13:2:13 | y | e.js:2:13:2:13 | y |
| e.js:3:10:3:21 | default as g | e.js:3:10:3:16 | default | e.js:3:21:3:21 | g |
| m/c.js:5:10:5:15 | g as h | m/c.js:5:10:5:10 | g | m/c.js:5:15:5:15 | h |
test_GlobalVariableRef
| a.js:5:31:5:31 | o |
| exports.js:3:9:3:15 | exports |
| importmeta.js:1:15:1:17 | URL |
| tst.html:6:3:6:7 | alert |
test_ImportDefaultSpecifiers
| b.js:1:8:1:8 | f |
| f.ts:1:8:1:8 | g |
| import-in-mjs.mjs:1:8:1:24 | exported_from_mjs |
| importcss.js:1:8:1:8 | A |
| tst.html:5:10:5:10 | f |
| unresolved.js:1:8:1:8 | f |
test_ImportMetaExpr
| importmeta.js:1:33:1:43 | import.meta |
test_ImportNamespaceSpecifier
| exports.js:1:8:1:17 | * as dummy |
| m/c.js:1:8:1:13 | * as b |
test_ImportSpecifiers
| b.js:1:8:1:8 | f | b.js:1:8:1:8 | f |
| d.js:1:10:1:21 | default as g | d.js:1:21:1:21 | g |
| d.js:1:24:1:29 | x as y | d.js:1:29:1:29 | y |
| exports.js:1:8:1:17 | * as dummy | exports.js:1:13:1:17 | dummy |
| f.ts:1:8:1:8 | g | f.ts:1:8:1:8 | g |
| g.ts:1:9:1:11 | foo | g.ts:1:9:1:11 | foo |
| import-in-mjs.mjs:1:8:1:24 | exported_from_mjs | import-in-mjs.mjs:1:8:1:24 | exported_from_mjs |
| import-ts-with-js-extension.ts:1:10:1:12 | foo | import-ts-with-js-extension.ts:1:10:1:12 | foo |
| importcss.js:1:8:1:8 | A | importcss.js:1:8:1:8 | A |
| m/c.js:1:8:1:13 | * as b | m/c.js:1:13:1:13 | b |
| reExportNamespaceClient.js:1:10:1:11 | ns | reExportNamespaceClient.js:1:10:1:11 | ns |
| tst.html:5:10:5:10 | f | tst.html:5:10:5:10 | f |
| unresolved.js:1:8:1:8 | f | unresolved.js:1:8:1:8 | f |
test_Imports
| b.js:1:1:1:20 | import f from './a'; | b.js:1:15:1:19 | './a' | 1 |
| d.js:1:1:1:43 | import ... './a'; | d.js:1:38:1:42 | './a' | 2 |
@@ -98,20 +65,9 @@ test_Imports
| import-ts-with-js-extension.ts:1:1:1:29 | import ... /f.js"; | import-ts-with-js-extension.ts:1:21:1:28 | "./f.js" | 1 |
| importcss.js:1:1:1:24 | import ... a.css"; | importcss.js:1:15:1:23 | "./a.css" | 1 |
| m/c.js:1:1:1:26 | import ... '../b'; | m/c.js:1:20:1:25 | '../b' | 1 |
| reExportNamespaceClient.js:1:1:1:41 | import ... space"; | reExportNamespaceClient.js:1:20:1:40 | "./reEx ... espace" | 1 |
| tst.html:5:3:5:20 | import f from 'a'; | tst.html:5:17:5:19 | 'a' | 1 |
| unresolved.js:1:1:1:18 | import f from 'a'; | unresolved.js:1:15:1:17 | 'a' | 1 |
test_NamedImportSpecifier
| d.js:1:10:1:21 | default as g |
| d.js:1:24:1:29 | x as y |
| g.ts:1:9:1:11 | foo |
| import-ts-with-js-extension.ts:1:10:1:12 | foo |
test_GlobalVariableRef
| a.js:5:31:5:31 | o |
| exports.js:3:9:3:15 | exports |
| importmeta.js:1:15:1:17 | URL |
| tst.html:6:3:6:7 | alert |
test_BulkReExportDeclarations
| d.js:4:1:4:20 | export * from 'm/c'; |
test_Module_exports
| a.js:1:1:5:32 | <toplevel> | default | a.js:1:1:3:1 | export ... n 23;\\n} |
| a.js:1:1:5:32 | <toplevel> | x | a.js:5:1:5:32 | export ... } = o; |
@@ -126,15 +82,67 @@ test_Module_exports
| f.ts:1:1:6:0 | <toplevel> | foo | f.ts:5:1:5:24 | export ... oo() {} |
| m/c.js:1:1:6:0 | <toplevel> | h | m/c.js:5:1:5:30 | export ... '../b'; |
| tst.html:4:23:8:0 | <toplevel> | y | tst.html:7:3:7:22 | export const y = 42; |
test_ExportDefaultDeclarations
| a.js:1:1:3:1 | export ... n 23;\\n} |
| es2015_require.js:3:1:3:25 | export ... ss C {} |
test_ExportSpecifiers
| b.js:5:10:5:15 | f as g | b.js:5:10:5:10 | f | b.js:5:15:5:15 | g |
| e.js:2:10:2:10 | x | e.js:2:10:2:10 | x | e.js:2:10:2:10 | x |
| e.js:2:13:2:13 | y | e.js:2:13:2:13 | y | e.js:2:13:2:13 | y |
| e.js:3:10:3:21 | default as g | e.js:3:10:3:16 | default | e.js:3:21:3:21 | g |
| m/c.js:5:10:5:15 | g as h | m/c.js:5:10:5:10 | g | m/c.js:5:15:5:15 | h |
test_ImportNamespaceSpecifier
| exports.js:1:8:1:17 | * as dummy |
| m/c.js:1:8:1:13 | * as b |
test_NamedImportSpecifier
| d.js:1:10:1:21 | default as g |
| d.js:1:24:1:29 | x as y |
| g.ts:1:9:1:11 | foo |
| import-ts-with-js-extension.ts:1:10:1:12 | foo |
| reExportNamespaceClient.js:1:10:1:11 | ns |
test_OtherImports
| es2015_require.js:1:11:1:24 | require('./d') | d.js:1:1:5:0 | <toplevel> |
test_ReExportDeclarations
| b.js:7:1:7:21 | export ... './a'; | b.js:7:16:7:20 | './a' |
| d.js:4:1:4:20 | export * from 'm/c'; | d.js:4:15:4:19 | 'm/c' |
| e.js:3:1:3:35 | export ... './a'; | e.js:3:30:3:34 | './a' |
| m/c.js:5:1:5:30 | export ... '../b'; | m/c.js:5:24:5:29 | '../b' |
| reExportNamespace.js:1:1:1:26 | export ... "./a"; | reExportNamespace.js:1:21:1:25 | "./a" |
test_getAnImportedModule
| library-tests/Modules/b.js | library-tests/Modules/a.js |
| library-tests/Modules/d.js | library-tests/Modules/a.js |
| library-tests/Modules/d.js | library-tests/Modules/b.js |
| library-tests/Modules/es2015_require.js | library-tests/Modules/d.js |
| library-tests/Modules/f.ts | library-tests/Modules/e.js |
| library-tests/Modules/g.ts | library-tests/Modules/f.ts |
| library-tests/Modules/import-ts-with-js-extension.ts | library-tests/Modules/f.ts |
| library-tests/Modules/m/c.js | library-tests/Modules/b.js |
| library-tests/Modules/reExportNamespaceClient.js | library-tests/Modules/reExportNamespace.js |
test_getExportedName
| b.js:5:10:5:15 | f as g | g |
| b.js:7:8:7:9 | f2 | f2 |
| e.js:2:10:2:10 | x | x |
| e.js:2:13:2:13 | y | y |
| e.js:3:10:3:21 | default as g | g |
| m/c.js:5:10:5:15 | g as h | h |
| reExportNamespace.js:1:8:1:14 | * as ns | ns |
test_getImportedName
| b.js:1:8:1:8 | f | default |
| d.js:1:10:1:21 | default as g | default |
| d.js:1:24:1:29 | x as y | x |
| f.ts:1:8:1:8 | g | default |
| g.ts:1:9:1:11 | foo | foo |
| import-in-mjs.mjs:1:8:1:24 | exported_from_mjs | default |
| import-ts-with-js-extension.ts:1:10:1:12 | foo | foo |
| importcss.js:1:8:1:8 | A | default |
| reExportNamespaceClient.js:1:10:1:11 | ns | ns |
| tst.html:5:10:5:10 | f | default |
| unresolved.js:1:8:1:8 | f | default |
test_getLocalName
| b.js:5:10:5:15 | f as g | f |
| b.js:7:8:7:9 | f2 | default |
| e.js:2:10:2:10 | x | x |
| e.js:2:13:2:13 | y | y |
| e.js:3:10:3:21 | default as g | default |
| m/c.js:5:10:5:15 | g as h | g |
test_getSourceNode
| a.js:1:1:3:1 | export ... n 23;\\n} | default | a.js:1:16:3:1 | functio ... n 23;\\n} |
| a.js:5:1:5:32 | export ... } = o; | x | a.js:5:18:5:20 | f() |
| b.js:5:1:5:18 | export { f as g }; | g | b.js:5:10:5:10 | f |
| b.js:7:1:7:21 | export ... './a'; | f2 | a.js:1:16:3:1 | functio ... n 23;\\n} |
| e.js:2:1:2:16 | export { x, y }; | x | e.js:2:10:2:10 | x |
| e.js:2:1:2:16 | export { x, y }; | y | e.js:2:13:2:13 | y |
| e.js:3:1:3:35 | export ... './a'; | g | a.js:1:16:3:1 | functio ... n 23;\\n} |
| es2015_require.js:3:1:3:25 | export ... ss C {} | default | es2015_require.js:3:16:3:25 | class C {} |
| export-in-mjs.mjs:1:1:1:34 | export ... s = 42; | exported_from_mjs | export-in-mjs.mjs:1:32:1:33 | 42 |
| f.ts:5:1:5:24 | export ... oo() {} | foo | f.ts:5:8:5:24 | function foo() {} |
| m/c.js:5:1:5:30 | export ... '../b'; | h | b.js:5:10:5:10 | f |
| tst.html:7:3:7:22 | export const y = 42; | y | tst.html:7:20:7:21 | 42 |

View File

@@ -1,19 +1,58 @@
import ImportSpecifiers
import getLocalName
import getExportedName
import OtherImports
import ImportMeta
import ReExportDeclarations
import ImportDefaultSpecifiers
import getImportedName
import ExportDeclarations
import getAnImportedModule
import getSourceNode
import Imports
import NamedImportSpecifier
import GlobalVariableRef
import BulkReExportDeclarations
import Module_exports
import ExportDefaultDeclarations
import ExportSpecifiers
import ImportNamespaceSpecifier
import javascript
query predicate test_BulkReExportDeclarations(BulkReExportDeclaration bred) { any() }
query predicate test_ExportDeclarations(ExportDeclaration ed) { any() }
query predicate test_ExportDefaultDeclarations(ExportDefaultDeclaration edd) { any() }
query predicate test_ExportSpecifiers(ExportSpecifier es, Identifier res0, Identifier res1) {
res0 = es.getLocal() and res1 = es.getExported()
}
query predicate test_GlobalVariableRef(VarAccess access) {
access.getVariable() instanceof GlobalVariable
}
query predicate test_ImportDefaultSpecifiers(ImportDefaultSpecifier ids) { any() }
query predicate test_ImportMetaExpr(ImportMetaExpr meta) { any() }
query predicate test_ImportNamespaceSpecifier(ImportNamespaceSpecifier ins) { any() }
query predicate test_ImportSpecifiers(ImportSpecifier is, VarDecl res) { res = is.getLocal() }
query predicate test_Imports(ImportDeclaration id, PathExprInModule res0, int res1) {
res0 = id.getImportedPath() and res1 = count(id.getASpecifier())
}
query predicate test_Module_exports(Module m, string name, ASTNode export) {
m.exports(name, export)
}
query predicate test_NamedImportSpecifier(NamedImportSpecifier nis) { any() }
query predicate test_OtherImports(Import imprt, Module res) {
not imprt instanceof ImportDeclaration and res = imprt.getImportedModule()
}
query predicate test_ReExportDeclarations(ReExportDeclaration red, ConstantString res) {
res = red.getImportedPath()
}
query predicate test_getAnImportedModule(string res0, string res1) {
exists(Module mod |
res0 = mod.getFile().getRelativePath() and
res1 = mod.getAnImportedModule().getFile().getRelativePath()
)
}
query predicate test_getExportedName(ExportSpecifier es, string res) { res = es.getExportedName() }
query predicate test_getImportedName(ImportSpecifier is, string res) { res = is.getImportedName() }
query predicate test_getLocalName(ExportSpecifier es, string res) { res = es.getLocalName() }
query predicate test_getSourceNode(ExportDeclaration ed, string name, DataFlow::Node res) {
res = ed.getSourceNode(name)
}

View File

@@ -1,3 +1,4 @@
var https = require('https');
https.createServer(function (req, res) {});
https.createServer(o, function (req, res) {});
require('http2').createServer((req, res) => {});

View File

@@ -1,6 +1,7 @@
test_isCreateServer
| createServer.js:2:1:2:42 | https.c ... es) {}) |
| createServer.js:3:1:3:45 | https.c ... es) {}) |
| createServer.js:4:1:4:47 | require ... => {}) |
| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) |
| src/http.js:12:1:16:2 | http.cr ... r");\\n}) |
| src/http.js:57:1:57:31 | http.cr ... dler()) |
@@ -51,6 +52,7 @@ test_HeaderDefinition
test_RouteSetup_getServer
| createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:1:2:42 | https.c ... es) {}) |
| createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:1:3:45 | https.c ... es) {}) |
| createServer.js:4:1:4:47 | require ... => {}) | createServer.js:4:1:4:47 | require ... => {}) |
| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) |
| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | src/http.js:12:1:16:2 | http.cr ... r");\\n}) |
| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:57:1:57:31 | http.cr ... dler()) |
@@ -72,6 +74,7 @@ test_HeaderDefinition_getAHeaderName
test_ServerDefinition
| createServer.js:2:1:2:42 | https.c ... es) {}) |
| createServer.js:3:1:3:45 | https.c ... es) {}) |
| createServer.js:4:1:4:47 | require ... => {}) |
| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) |
| src/http.js:12:1:16:2 | http.cr ... r");\\n}) |
| src/http.js:57:1:57:31 | http.cr ... dler()) |
@@ -103,6 +106,7 @@ test_RouteHandler_getAResponseExpr
test_ServerDefinition_getARouteHandler
| createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:20:2:41 | functio ... res) {} |
| createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:23:3:44 | functio ... res) {} |
| createServer.js:4:1:4:47 | require ... => {}) | createServer.js:4:31:4:46 | (req, res) => {} |
| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | src/http.js:12:19:16:1 | functio ... ar");\\n} |
| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:55:12:55:30 | function(req,res){} |
@@ -120,6 +124,7 @@ test_ResponseSendArgument
test_RouteSetup_getARouteHandler
| createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:20:2:41 | functio ... res) {} |
| createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:23:3:44 | functio ... res) {} |
| createServer.js:4:1:4:47 | require ... => {}) | createServer.js:4:31:4:46 | (req, res) => {} |
| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | src/http.js:12:19:16:1 | functio ... ar");\\n} |
| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:55:12:55:30 | function(req,res){} |
@@ -147,6 +152,7 @@ test_RemoteFlowSources
test_RouteHandler
| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:1:2:42 | https.c ... es) {}) |
| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:1:3:45 | https.c ... es) {}) |
| createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:1:4:47 | require ... => {}) |
| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) |
| src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:12:1:16:2 | http.cr ... r");\\n}) |
| src/http.js:55:12:55:30 | function(req,res){} | src/http.js:57:1:57:31 | http.cr ... dler()) |

View File

@@ -22,12 +22,23 @@ nodes
| child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" |
| child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" |
| child_process-test.js:25:21:25:23 | cmd |
| child_process-test.js:39:18:39:30 | [ flag, cmd ] |
| child_process-test.js:39:18:39:30 | [ flag, cmd ] |
| child_process-test.js:39:26:39:28 | cmd |
| child_process-test.js:39:26:39:28 | cmd |
| child_process-test.js:43:15:43:17 | cmd |
| child_process-test.js:43:15:43:17 | cmd |
| child_process-test.js:50:15:50:17 | cmd |
| child_process-test.js:50:15:50:17 | cmd |
| child_process-test.js:53:25:53:58 | ['/C', ... , cmd]) |
| child_process-test.js:53:25:53:58 | ['/C', ... , cmd]) |
| child_process-test.js:53:46:53:57 | ["bar", cmd] |
| child_process-test.js:53:46:53:57 | ["bar", cmd] |
| child_process-test.js:53:54:53:56 | cmd |
| child_process-test.js:53:54:53:56 | cmd |
| child_process-test.js:54:25:54:49 | ['/C', ... at(cmd) |
| child_process-test.js:54:25:54:49 | ['/C', ... at(cmd) |
| child_process-test.js:54:46:54:48 | cmd |
| execSeries.js:3:20:3:22 | arr |
| execSeries.js:6:14:6:16 | arr |
| execSeries.js:6:14:6:21 | arr[i++] |
@@ -100,6 +111,9 @@ edges
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:43:15:43:17 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:50:15:50:17 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:50:15:50:17 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:53:54:53:56 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:53:54:53:56 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:54:46:54:48 | cmd |
| child_process-test.js:6:15:6:38 | url.par ... , true) | child_process-test.js:6:15:6:44 | url.par ... ).query |
| child_process-test.js:6:15:6:44 | url.par ... ).query | child_process-test.js:6:15:6:49 | url.par ... ry.path |
| child_process-test.js:6:15:6:49 | url.par ... ry.path | child_process-test.js:6:9:6:49 | cmd |
@@ -107,6 +121,14 @@ edges
| child_process-test.js:6:25:6:31 | req.url | child_process-test.js:6:15:6:38 | url.par ... , true) |
| child_process-test.js:25:21:25:23 | cmd | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" |
| child_process-test.js:25:21:25:23 | cmd | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" |
| child_process-test.js:39:26:39:28 | cmd | child_process-test.js:39:18:39:30 | [ flag, cmd ] |
| child_process-test.js:39:26:39:28 | cmd | child_process-test.js:39:18:39:30 | [ flag, cmd ] |
| child_process-test.js:53:46:53:57 | ["bar", cmd] | child_process-test.js:53:25:53:58 | ['/C', ... , cmd]) |
| child_process-test.js:53:46:53:57 | ["bar", cmd] | child_process-test.js:53:25:53:58 | ['/C', ... , cmd]) |
| child_process-test.js:53:54:53:56 | cmd | child_process-test.js:53:46:53:57 | ["bar", cmd] |
| child_process-test.js:53:54:53:56 | cmd | child_process-test.js:53:46:53:57 | ["bar", cmd] |
| child_process-test.js:54:46:54:48 | cmd | child_process-test.js:54:25:54:49 | ['/C', ... at(cmd) |
| child_process-test.js:54:46:54:48 | cmd | child_process-test.js:54:25:54:49 | ['/C', ... at(cmd) |
| execSeries.js:3:20:3:22 | arr | execSeries.js:6:14:6:16 | arr |
| execSeries.js:6:14:6:16 | arr | execSeries.js:6:14:6:21 | arr[i++] |
| execSeries.js:6:14:6:21 | arr[i++] | execSeries.js:14:24:14:30 | command |
@@ -165,10 +187,16 @@ edges
| 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:18:39:30 | [ flag, cmd ] | 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:51:5:51:39 | cp.exec ... , args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:50:15:50:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:56:3:56: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 |
| child_process-test.js:53:5:53:59 | cp.spaw ... cmd])) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:53:25:53:58 | ['/C', ... , cmd]) | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:53:5:53:59 | cp.spaw ... cmd])) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:53:46:53:57 | ["bar", cmd] | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:53:5:53:59 | cp.spaw ... cmd])) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:53:54:53:56 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:54:5:54:50 | cp.spaw ... t(cmd)) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:54:25:54:49 | ['/C', ... at(cmd) | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:59:5:59:39 | cp.exec ... , args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:50:15:50:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:64:3:64: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 |
| execSeries.js:14:41:14:47 | command | execSeries.js:18:34:18:40 | req.url | execSeries.js:14:41:14:47 | command | This command depends on $@. | execSeries.js:18:34:18:40 | req.url | a user-provided value |
| other.js:7:33:7:35 | cmd | other.js:5:25:5:31 | req.url | other.js:7:33:7:35 | cmd | This command depends on $@. | other.js:5:25:5:31 | req.url | a user-provided value |
| other.js:8:28:8:30 | cmd | other.js:5:25:5:31 | req.url | other.js:8:28:8:30 | cmd | This command depends on $@. | other.js:5:25:5:31 | req.url | a user-provided value |

View File

@@ -50,6 +50,14 @@ var server = http.createServer(function(req, res) {
args[1] = cmd;
cp.execFile(`/bin` + "/bash", args); // NOT OK
cp.spawn('cmd.exe', ['/C', 'foo'].concat(["bar", cmd])); // NOT OK
cp.spawn('cmd.exe', ['/C', 'foo'].concat(cmd)); // NOT OK
let myArgs = [];
myArgs.push(`-` + "c");
myArgs.push(cmd);
cp.execFile(`/bin` + "/bash", args); // NOT OK
});
function run(cmd, args) {

View File

@@ -37,6 +37,16 @@ nodes
| tst.js:45:13:45:56 | 'http:/ ... tainted |
| tst.js:45:13:45:56 | 'http:/ ... tainted |
| tst.js:45:50:45:56 | tainted |
| tst.js:58:9:58:52 | tainted |
| tst.js:58:19:58:42 | url.par ... , true) |
| tst.js:58:19:58:48 | url.par ... ).query |
| tst.js:58:19:58:52 | url.par ... ery.url |
| tst.js:58:29:58:35 | req.url |
| tst.js:58:29:58:35 | req.url |
| tst.js:61:29:61:35 | tainted |
| tst.js:61:29:61:35 | tainted |
| tst.js:64:30:64:36 | tainted |
| tst.js:64:30:64:36 | tainted |
edges
| tst.js:14:9:14:52 | tainted | tst.js:18:13:18:19 | tainted |
| tst.js:14:9:14:52 | tainted | tst.js:18:13:18:19 | tainted |
@@ -75,6 +85,15 @@ edges
| tst.js:43:46:43:52 | tainted | tst.js:43:13:43:54 | `http:/ ... inted}` |
| tst.js:45:50:45:56 | tainted | tst.js:45:13:45:56 | 'http:/ ... tainted |
| tst.js:45:50:45:56 | tainted | tst.js:45:13:45:56 | 'http:/ ... tainted |
| tst.js:58:9:58:52 | tainted | tst.js:61:29:61:35 | tainted |
| tst.js:58:9:58:52 | tainted | tst.js:61:29:61:35 | tainted |
| tst.js:58:9:58:52 | tainted | tst.js:64:30:64:36 | tainted |
| tst.js:58:9:58:52 | tainted | tst.js:64:30:64:36 | tainted |
| tst.js:58:19:58:42 | url.par ... , true) | tst.js:58:19:58:48 | url.par ... ).query |
| tst.js:58:19:58:48 | url.par ... ).query | tst.js:58:19:58:52 | url.par ... ery.url |
| tst.js:58:19:58:52 | url.par ... ery.url | tst.js:58:9:58:52 | tainted |
| tst.js:58:29:58:35 | req.url | tst.js:58:19:58:42 | url.par ... , true) |
| tst.js:58:29:58:35 | req.url | tst.js:58:19:58:42 | url.par ... , true) |
#select
| tst.js:18:5:18:20 | request(tainted) | tst.js:14:29:14:35 | req.url | tst.js:18:13:18:19 | tainted | The $@ of this request depends on $@. | tst.js:18:13:18:19 | tainted | URL | tst.js:14:29:14:35 | req.url | a user-provided value |
| tst.js:20:5:20:24 | request.get(tainted) | tst.js:14:29:14:35 | req.url | tst.js:20:17:20:23 | tainted | The $@ of this request depends on $@. | tst.js:20:17:20:23 | tainted | URL | tst.js:14:29:14:35 | req.url | a user-provided value |
@@ -88,3 +107,5 @@ edges
| tst.js:41:5:41:52 | request ... nted}`) | tst.js:14:29:14:35 | req.url | tst.js:41:13:41:51 | `http:/ ... inted}` | The $@ of this request depends on $@. | tst.js:41:13:41:51 | `http:/ ... inted}` | URL | tst.js:14:29:14:35 | req.url | a user-provided value |
| tst.js:43:5:43:55 | request ... nted}`) | tst.js:14:29:14:35 | req.url | tst.js:43:13:43:54 | `http:/ ... inted}` | The $@ of this request depends on $@. | tst.js:43:13:43:54 | `http:/ ... inted}` | URL | tst.js:14:29:14:35 | req.url | a user-provided value |
| tst.js:45:5:45:57 | request ... ainted) | tst.js:14:29:14:35 | req.url | tst.js:45:13:45:56 | 'http:/ ... tainted | The $@ of this request depends on $@. | tst.js:45:13:45:56 | 'http:/ ... tainted | URL | tst.js:14:29:14:35 | req.url | a user-provided value |
| tst.js:61:2:61:37 | client. ... inted}) | tst.js:58:29:58:35 | req.url | tst.js:61:29:61:35 | tainted | The $@ of this request depends on $@. | tst.js:61:29:61:35 | tainted | URL | tst.js:58:29:58:35 | req.url | a user-provided value |
| tst.js:64:3:64:38 | client. ... inted}) | tst.js:58:29:58:35 | req.url | tst.js:64:30:64:36 | tainted | The $@ of this request depends on $@. | tst.js:64:30:64:36 | tainted | URL | tst.js:58:29:58:35 | req.url | a user-provided value |

View File

@@ -52,3 +52,15 @@ var server = http.createServer(function(req, res) {
request(`${base}${tainted}`); // OK - assumed safe
})
var CDP = require("chrome-remote-interface");
var server = http.createServer(async function(req, res) {
var tainted = url.parse(req.url, true).query.url;
var client = await CDP(options);
client.Page.navigate({url: tainted}); // NOT OK.
CDP(options, (client) => {
client.Page.navigate({url: tainted}); // NOT OK.
});
})