From e723c6e790d2fbf65ff96f85692658cefb5dd34d Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Thu, 25 Jun 2020 11:53:42 +0200 Subject: [PATCH] JS: core improvements --- .../semmle/javascript/frameworks/Logging.qll | 28 +++++++++++++++++++ .../javascript/frameworks/NodeJSLib.qll | 16 +++++++++-- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/javascript/ql/src/semmle/javascript/frameworks/Logging.qll b/javascript/ql/src/semmle/javascript/frameworks/Logging.qll index c40e579c850..ad110e8c5bd 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/Logging.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/Logging.qll @@ -28,6 +28,7 @@ string getAStandardLoggerMethodName() { result = "notice" or result = "silly" or result = "trace" or + result = "verbose" or result = "warn" } @@ -131,3 +132,30 @@ private module log4js { override DataFlow::Node getAMessageComponent() { result = getAnArgument() } } } + +/** + * Provides classes for working with [npmlog](https://github.com/npm/npmlog) + */ +private module Npmlog { + /** + * A call to the console logging mechanism. + */ + class Npmlog extends LoggerCall { + string name; + + Npmlog() { + this = DataFlow::moduleMember("npmlog", name).getACall() and + name = getAStandardLoggerMethodName() + } + + override DataFlow::Node getAMessageComponent() { + ( + if name = "log" + then result = getArgument([1 .. getNumArgument()]) + else result = getAnArgument() + ) + or + result = getASpreadArgument() + } + } +} diff --git a/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll index 6aaf571ec62..87027333fb7 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll @@ -444,9 +444,11 @@ module NodeJSLib { * A member `member` from module `fs` or its drop-in replacements `graceful-fs`, `fs-extra`, `original-fs`. */ DataFlow::SourceNode moduleMember(string member) { - result = fsModule(DataFlow::TypeTracker::end()).getAPropertyRead(member) + result = fsModule().getAPropertyRead(member) } + DataFlow::SourceNode fsModule() { result = fsModule(DataFlow::TypeTracker::end()) } + private DataFlow::SourceNode fsModule(DataFlow::TypeTracker t) { exists(string moduleName | moduleName = ["mz/fs", "original-fs", "fs-extra", "graceful-fs", "fs"] @@ -468,7 +470,15 @@ module NodeJSLib { private class NodeJSFileSystemAccess extends FileSystemAccess, DataFlow::CallNode { string methodName; - NodeJSFileSystemAccess() { this = maybePromisified(FS::moduleMember(methodName)).getACall() } + NodeJSFileSystemAccess() { + this = maybePromisified(FS::moduleMember(methodName)).getACall() + or + exists(DataFlow::CallNode promisifyAll | + promisifyAll = DataFlow::moduleMember("bluebird", "promisifyAll").getACall() and + FS::fsModule().flowsTo(promisifyAll.getArgument(0)) and + this = promisifyAll.getAMemberCall(methodName) + ) + } /** * Gets the name of the called method. @@ -604,7 +614,7 @@ module NodeJSLib { result = callback or exists(DataFlow::CallNode promisify | - promisify = DataFlow::moduleMember("util", "promisify").getACall() + promisify = DataFlow::moduleMember(["util", "bluebird"], "promisify").getACall() | result = promisify and promisify.getArgument(0).getALocalSource() = callback )