From 16c33b54b6d6dcdf0b721a5eab3f47bd0c482109 Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Thu, 6 Jun 2019 11:48:18 +0100 Subject: [PATCH 1/2] JavaScript: Recognise references to the `process` global. --- .../javascript/frameworks/NodeJSLib.qll | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll index 1c7f61d8d047..9f875daf2d4e 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll @@ -8,19 +8,23 @@ import semmle.javascript.security.SensitiveActions module NodeJSLib { /** - * Gets a reference to the 'process' object. + * An access to the global `process` variable in a Node.js module, interpreted as + * an import of the `process` module. */ - DataFlow::SourceNode process() { - result = DataFlow::globalVarRef("process") or - result = DataFlow::moduleImport("process") + private class ImplicitProcessImport extends DataFlow::ModuleImportNode::Range { + ImplicitProcessImport() { + this = DataFlow::globalVarRef("process") and + getTopLevel() instanceof NodeModule + } + + override string getPath() { result = "process" } } /** - * Gets a reference to a member of the 'process' object. + * Gets a reference to the 'process' object. */ - private DataFlow::SourceNode processMember(string member) { - result = process().getAPropertyRead(member) or - result = DataFlow::moduleMember("process", member) + DataFlow::SourceNode process() { + result = DataFlow::moduleImport("process") } /** @@ -363,7 +367,7 @@ module NodeJSLib { ProcessTermination() { this = DataFlow::moduleImport("exit").getAnInvocation() or - this = processMember("exit").getACall() + this = DataFlow::moduleMember("process", "exit").getACall() } } From 70cf32c8892ad1f0a300d23882a84ad635e8d231 Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Tue, 11 Jun 2019 08:44:14 +0100 Subject: [PATCH 2/2] JavaScript: Add a few more tests. --- .../ql/test/library-tests/ModuleImportNodes/process.js | 2 ++ .../ql/test/library-tests/ModuleImportNodes/process2.js | 2 ++ .../test/library-tests/ModuleImportNodes/tests.expected | 9 +++++++++ 3 files changed, 13 insertions(+) create mode 100644 javascript/ql/test/library-tests/ModuleImportNodes/process.js create mode 100644 javascript/ql/test/library-tests/ModuleImportNodes/process2.js diff --git a/javascript/ql/test/library-tests/ModuleImportNodes/process.js b/javascript/ql/test/library-tests/ModuleImportNodes/process.js new file mode 100644 index 000000000000..7679ff09cf99 --- /dev/null +++ b/javascript/ql/test/library-tests/ModuleImportNodes/process.js @@ -0,0 +1,2 @@ +var p1 = require('process'); +var p2 = global.process; diff --git a/javascript/ql/test/library-tests/ModuleImportNodes/process2.js b/javascript/ql/test/library-tests/ModuleImportNodes/process2.js new file mode 100644 index 000000000000..26a6efebc72c --- /dev/null +++ b/javascript/ql/test/library-tests/ModuleImportNodes/process2.js @@ -0,0 +1,2 @@ +require('fs'); +var p3 = process; \ No newline at end of file diff --git a/javascript/ql/test/library-tests/ModuleImportNodes/tests.expected b/javascript/ql/test/library-tests/ModuleImportNodes/tests.expected index 5d6588b78b65..120baab41625 100644 --- a/javascript/ql/test/library-tests/ModuleImportNodes/tests.expected +++ b/javascript/ql/test/library-tests/ModuleImportNodes/tests.expected @@ -13,6 +13,7 @@ test_ModuleImportNode | moduleUses.js:1:11:1:24 | require('mod') | mod | moduleUses.js:11:1:11:3 | mod | mod | | moduleUses.js:1:11:1:24 | require('mod') | mod | moduleUses.js:13:1:13:3 | mod | mod | | moduleUses.js:1:11:1:24 | require('mod') | mod | moduleUses.js:15:5:15:7 | mod | mod | +| process2.js:2:10:2:16 | process | process | process2.js:2:10:2:16 | process | process | test_ModuleImportNode_getAConstructorInvocation | destructuringES6.js:1:1:1:41 | import ... ctron'; | destructuringES6.js:2:1:2:19 | new BrowserWindow() | | destructuringRequire.js:1:27:1:45 | require('electron') | destructuringRequire.js:2:1:2:19 | new BrowserWindow() | @@ -22,11 +23,15 @@ test_moduleImport | electron | destructuringRequire.js:1:27:1:45 | require('electron') | | fs | amd1.js:1:25:1:26 | fs | | fs | amd2.js:2:12:2:24 | require('fs') | +| fs | process2.js:1:1:1:13 | require('fs') | | mod | moduleUses.js:1:11:1:24 | require('mod') | | myDefaultImportedModuleInstance | instanceThroughDefaultImport.js:1:1:1:82 | import ... tance'; | | myDefaultImportedModuleInstance | instanceThroughDefaultImport.js:1:8:1:42 | myDefaultImportedModuleInstanceName | | myNamespaceImportedModuleInstance | instanceThroughNamespaceImport.js:1:8:1:49 | myNamespaceImportedModuleInstanceName | | myRequiredModuleInstance | instanceThroughRequire.js:1:36:1:70 | require ... tance') | +| process | process2.js:2:10:2:16 | process | +| process | process.js:1:10:1:27 | require('process') | +| process | process.js:2:10:2:23 | global.process | test_moduleMember | electron | BrowserWindow | destructuringES6.js:1:10:1:22 | BrowserWindow | | electron | BrowserWindow | destructuringRequire.js:1:9:1:21 | BrowserWindow | @@ -47,6 +52,10 @@ test_ModuleImportNode_getPath | instanceThroughNamespaceImport.js:1:8:1:49 | myNamespaceImportedModuleInstanceName | myNamespaceImportedModuleInstance | | instanceThroughRequire.js:1:36:1:70 | require ... tance') | myRequiredModuleInstance | | moduleUses.js:1:11:1:24 | require('mod') | mod | +| process2.js:1:1:1:13 | require('fs') | fs | +| process2.js:2:10:2:16 | process | process | +| process.js:1:10:1:27 | require('process') | process | +| process.js:2:10:2:23 | global.process | process | test_ModuleImportNode_getAMethodCall | amd1.js:1:25:1:26 | fs | amd1.js:2:3:2:29 | fs.read ... a.txt") | | amd2.js:2:12:2:24 | require('fs') | amd2.js:3:3:3:29 | fs.read ... a.txt") |