mirror of
https://github.com/github/codeql.git
synced 2026-05-03 04:39:29 +02:00
JS: add models of logging frameworks
This commit is contained in:
@@ -58,6 +58,7 @@ import semmle.javascript.frameworks.DigitalOcean
|
||||
import semmle.javascript.frameworks.Electron
|
||||
import semmle.javascript.frameworks.jQuery
|
||||
import semmle.javascript.frameworks.LodashUnderscore
|
||||
import semmle.javascript.frameworks.Logging
|
||||
import semmle.javascript.frameworks.HttpFrameworks
|
||||
import semmle.javascript.frameworks.NoSQL
|
||||
import semmle.javascript.frameworks.PkgCloud
|
||||
|
||||
137
javascript/ql/src/semmle/javascript/frameworks/Logging.qll
Normal file
137
javascript/ql/src/semmle/javascript/frameworks/Logging.qll
Normal file
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* Provides classes for working with logging libraries.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
/**
|
||||
* A call to a logging mechanism.
|
||||
*/
|
||||
abstract class LoggerCall extends DataFlow::CallNode {
|
||||
|
||||
/**
|
||||
* Gets a node that contributes to the logged message.
|
||||
*/
|
||||
abstract DataFlow::Node getAMessageComponent();
|
||||
|
||||
}
|
||||
|
||||
private string getAStandardLoggerMethodName() {
|
||||
// log level names used in RFC5424, `npm`, `console`
|
||||
result = "crit" or
|
||||
result = "debug" or
|
||||
result = "error" or
|
||||
result = "emerg" or
|
||||
result = "fatal" or
|
||||
result = "info" or
|
||||
result = "log" or
|
||||
result = "notice" or
|
||||
result = "silly" or
|
||||
result = "trace" or
|
||||
result = "warn"
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides classes for working the builtin NodeJS/Browser `console`.
|
||||
*/
|
||||
private module Console {
|
||||
|
||||
/**
|
||||
* Gets a data flow source node for the console library.
|
||||
*/
|
||||
private DataFlow::SourceNode console() {
|
||||
result = DataFlow::moduleImport("console") or
|
||||
result = DataFlow::globalVarRef("console")
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the console logging mechanism.
|
||||
*/
|
||||
class ConsoleLoggerCall extends LoggerCall {
|
||||
string name;
|
||||
|
||||
ConsoleLoggerCall() {
|
||||
(
|
||||
name = getAStandardLoggerMethodName() or
|
||||
name = "assert"
|
||||
) and
|
||||
this = console().getAMethodCall(name)
|
||||
}
|
||||
|
||||
override DataFlow::Node getAMessageComponent() {
|
||||
if name = "assert" then
|
||||
result = getArgument([1..getNumArgument()])
|
||||
else
|
||||
result = getAnArgument()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides classes for working with [loglevel](https://github.com/pimterry/loglevel).
|
||||
*/
|
||||
private module Loglevel {
|
||||
|
||||
/**
|
||||
* A call to the loglevel logging mechanism.
|
||||
*/
|
||||
class LoglevelLoggerCall extends LoggerCall {
|
||||
LoglevelLoggerCall() {
|
||||
this = DataFlow::moduleMember("loglevel", getAStandardLoggerMethodName()).getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAMessageComponent() {
|
||||
result = getAnArgument()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provides classes for working with [winston](https://github.com/winstonjs/winston).
|
||||
*/
|
||||
private module Winston {
|
||||
|
||||
/**
|
||||
* A call to the winston logging mechanism.
|
||||
*/
|
||||
class WinstonLoggerCall extends LoggerCall, DataFlow::MethodCallNode {
|
||||
WinstonLoggerCall() {
|
||||
this = DataFlow::moduleMember("winston", "createLogger").getACall().getAMethodCall(getAStandardLoggerMethodName())
|
||||
}
|
||||
|
||||
override DataFlow::Node getAMessageComponent() {
|
||||
if getMethodName() = "log" then
|
||||
result = getOptionArgument(0, "message")
|
||||
else
|
||||
result = getAnArgument()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides classes for working with [log4js](https://github.com/log4js-node/log4js-node).
|
||||
*/
|
||||
private module log4js {
|
||||
|
||||
/**
|
||||
* A call to the log4js logging mechanism.
|
||||
*/
|
||||
class Log4jsLoggerCall extends LoggerCall {
|
||||
Log4jsLoggerCall() {
|
||||
this = DataFlow::moduleMember("log4js", "getLogger").getACall().getAMethodCall(getAStandardLoggerMethodName())
|
||||
}
|
||||
|
||||
override DataFlow::Node getAMessageComponent() {
|
||||
result = getAnArgument()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
| tst.js:3:1:3:26 | console ... ", arg) | tst.js:3:13:3:20 | "msg %s" |
|
||||
| tst.js:3:1:3:26 | console ... ", arg) | tst.js:3:23:3:25 | arg |
|
||||
| tst.js:4:1:4:28 | console ... ", arg) | tst.js:4:15:4:22 | "msg %s" |
|
||||
| tst.js:4:1:4:28 | console ... ", arg) | tst.js:4:25:4:27 | arg |
|
||||
| tst.js:5:1:5:28 | console ... ", arg) | tst.js:5:15:5:22 | "msg %s" |
|
||||
| tst.js:5:1:5:28 | console ... ", arg) | tst.js:5:25:5:27 | arg |
|
||||
| tst.js:7:1:7:34 | require ... ", arg) | tst.js:7:21:7:28 | "msg %s" |
|
||||
| tst.js:7:1:7:34 | require ... ", arg) | tst.js:7:31:7:33 | arg |
|
||||
| tst.js:9:1:9:38 | require ... ", arg) | tst.js:9:25:9:32 | "msg %s" |
|
||||
| tst.js:9:1:9:38 | require ... ", arg) | tst.js:9:35:9:37 | arg |
|
||||
| tst.js:11:1:11:73 | require ... other) | tst.js:11:50:11:63 | "msg with arg" |
|
||||
| tst.js:12:1:12:53 | require ... ", arg) | tst.js:12:40:12:47 | "msg %s" |
|
||||
| tst.js:12:1:12:53 | require ... ", arg) | tst.js:12:50:12:52 | arg |
|
||||
| tst.js:14:1:14:48 | require ... ", arg) | tst.js:14:35:14:42 | "msg %s" |
|
||||
| tst.js:14:1:14:48 | require ... ", arg) | tst.js:14:45:14:47 | arg |
|
||||
| tst.js:16:1:16:35 | console ... ", arg) | tst.js:16:22:16:29 | "msg %s" |
|
||||
| tst.js:16:1:16:35 | console ... ", arg) | tst.js:16:32:16:34 | arg |
|
||||
@@ -0,0 +1,4 @@
|
||||
import javascript
|
||||
|
||||
from LoggerCall log
|
||||
select log, log.getAMessageComponent()
|
||||
16
javascript/ql/test/library-tests/frameworks/Logging/tst.js
Normal file
16
javascript/ql/test/library-tests/frameworks/Logging/tst.js
Normal file
@@ -0,0 +1,16 @@
|
||||
var requiredConsole = require("console");
|
||||
|
||||
console.log("msg %s", arg);
|
||||
console.fatal("msg %s", arg);
|
||||
console.debug("msg %s", arg);
|
||||
|
||||
requiredConsole.log("msg %s", arg);
|
||||
|
||||
require("loglevel").log("msg %s", arg);
|
||||
|
||||
require("winston").createLogger().log({ message: "msg with arg" }, other);
|
||||
require("winston").createLogger().info("msg %s", arg);
|
||||
|
||||
require("log4js").getLogger().log("msg %s", arg);
|
||||
|
||||
console.assert(true, "msg %s", arg);
|
||||
Reference in New Issue
Block a user