mirror of
https://github.com/github/codeql.git
synced 2026-04-26 09:15:12 +02:00
remove CLI sources Library file and local sources for lower FPs
This commit is contained in:
@@ -1,105 +0,0 @@
|
||||
import javascript
|
||||
import DataFlow::PathGraph
|
||||
import API
|
||||
|
||||
/**
|
||||
* A Command Line argument as a Flow Source
|
||||
* there are FP when the types are not str
|
||||
* because int,boolean types are not really dangerous as a source node
|
||||
*/
|
||||
abstract class CommandLineFlowSource extends API::Node { }
|
||||
|
||||
class Yargs extends CommandLineFlowSource {
|
||||
Yargs() {
|
||||
this = API::moduleImport("yargs/yargs").getASuccessor*().getMember("argv") or
|
||||
this = API::moduleImport("yargs/yargs").getASuccessor*().getMember("argv").getAMember()
|
||||
}
|
||||
}
|
||||
|
||||
class Argv extends CommandLineFlowSource {
|
||||
Argv() {
|
||||
exists(string numOfArg |
|
||||
this = API::moduleImport(["node:process", "process"]).getMember("argv").getMember(numOfArg) and
|
||||
not numOfArg = ["0", "1", "forEach"]
|
||||
)
|
||||
or
|
||||
this =
|
||||
API::moduleImport("node:process")
|
||||
.getMember("argv")
|
||||
.getMember("forEach")
|
||||
.getParameter(0)
|
||||
.getParameter(1)
|
||||
}
|
||||
}
|
||||
|
||||
predicate test(API::Node n) {
|
||||
n = API::moduleImport("commander").getMember("Command").getASuccessor*().getInstance()
|
||||
}
|
||||
|
||||
class Commander extends CommandLineFlowSource {
|
||||
Commander() {
|
||||
// opts() are { key : value }
|
||||
// args are remaining arguments
|
||||
exists(API::Node n |
|
||||
n =
|
||||
[
|
||||
API::moduleImport("commander").getMember("Command").getASuccessor*().getInstance(),
|
||||
// https://github.com/tj/commander.js#life-cycle-hooks
|
||||
// https://github.com/tj/commander.js/blob/master/examples/hook.js
|
||||
API::moduleImport("commander")
|
||||
.getMember("Command")
|
||||
.getASuccessor*()
|
||||
.getMember("hook")
|
||||
.getParameter(1)
|
||||
.getParameter(_),
|
||||
// https://github.com/tj/commander.js/blob/master/examples/action-this.js
|
||||
API::moduleImport("commander")
|
||||
.getMember("Command")
|
||||
.getASuccessor*()
|
||||
.getMember("action")
|
||||
.getParameter(0)
|
||||
.getReceiver()
|
||||
]
|
||||
|
|
||||
this = n.getMember("opts").getReturn().getMember(_)
|
||||
or
|
||||
this = n.getMember("args")
|
||||
)
|
||||
or
|
||||
// action handlers has FP because of options and command in `.action((name, options, command)`
|
||||
// https://github.com/tj/commander.js#action-handler
|
||||
// https://github.com/tj/commander.js#commands
|
||||
this =
|
||||
API::moduleImport("commander")
|
||||
.getMember("Command")
|
||||
.getASuccessor*()
|
||||
.getMember("action")
|
||||
.getParameter(0)
|
||||
.getParameter(_)
|
||||
or
|
||||
// why we can't have forEach global taintStep?
|
||||
// https://github.com/tj/commander.js#command-arguments
|
||||
this =
|
||||
API::moduleImport("commander")
|
||||
.getMember("Command")
|
||||
.getASuccessor*()
|
||||
.getMember("action")
|
||||
.getParameter(0)
|
||||
.getParameter(_)
|
||||
.getASuccessor*()
|
||||
.getMember("forEach")
|
||||
.getParameter(0)
|
||||
.getParameter(0)
|
||||
or
|
||||
// Custom option processing
|
||||
// https://github.com/tj/commander.js#custom-option-processing
|
||||
// https://github.com/tj/commander.js/blob/master/examples/options-custom-processing.js
|
||||
this =
|
||||
API::moduleImport("commander")
|
||||
.getMember("Command")
|
||||
.getASuccessor*()
|
||||
.getMember("option")
|
||||
.getParameter(2)
|
||||
.getParameter(_)
|
||||
}
|
||||
}
|
||||
@@ -12,39 +12,13 @@
|
||||
*/
|
||||
|
||||
import javascript
|
||||
import CommandLineSource
|
||||
import ReadableAdditionalStep
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class BombConfiguration extends TaintTracking::Configuration {
|
||||
BombConfiguration() { this = "DecompressionBombs" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(Function f | source.asExpr() = f.getAParameter() |
|
||||
not exists(source.getALocalSource().getStringValue())
|
||||
)
|
||||
or
|
||||
source instanceof RemoteFlowSource
|
||||
or
|
||||
source.asExpr() = any(Parameter cls)
|
||||
or
|
||||
exists(FileSystemReadAccess fsra | source = fsra.getADataNode() |
|
||||
not exists(fsra.getALocalSource().getStringValue())
|
||||
)
|
||||
or
|
||||
exists(API::Node node |
|
||||
source = node.getParameter(0).asSink() and
|
||||
node = API::moduleImport("adm-zip") and
|
||||
not exists(source.getALocalSource().getStringValue())
|
||||
)
|
||||
or
|
||||
source =
|
||||
API::moduleImport("tar")
|
||||
.getMember(["x", "extract"])
|
||||
.getParameter(0)
|
||||
.getMember("file")
|
||||
.asSink() and
|
||||
not source.getALocalSource().mayHaveStringValue(_)
|
||||
}
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
// jszip
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
/**
|
||||
* @id javascript/sequlize
|
||||
* @kind path-problem
|
||||
* @name demonstrate sequlize additional taint step for findByPk method
|
||||
* @description add sequlize methods calls on custom models as sinks and additional taint steps
|
||||
* @problem.severity error
|
||||
* @precision low
|
||||
* @tags experimental
|
||||
*/
|
||||
|
||||
import javascript
|
||||
import DataFlow::PathGraph
|
||||
import sequelizeModelTypes::SequelizeModel
|
||||
import API
|
||||
|
||||
class SequelizeModelConfiguration extends TaintTracking::Configuration {
|
||||
SequelizeModelConfiguration() { this = "Bombs" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source instanceof RemoteFlowSource and
|
||||
exists(source.getTopLevel().getFile().getRelativePath())
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(DataFlow::CallNode n |
|
||||
n.getCalleeName() = "findByPk" and
|
||||
sequelizeModelAsSourceNode().(DataFlow::LocalSourceNode).flowsTo(n.getReceiver()) and
|
||||
sink = n.getArgument(0)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(DataFlow::CallNode n |
|
||||
// any related method of sequelize can be added here
|
||||
n.getCalleeName() = "findByPk" and
|
||||
sequelizeModelAsSourceNode().(DataFlow::LocalSourceNode).flowsTo(n.getReceiver()) and
|
||||
pred = n.getArgument(0) and
|
||||
succ = n
|
||||
)
|
||||
or
|
||||
// succ = { pred : pred} I think it has high FP rate for be a global taint step!
|
||||
exists(DataFlow::Node sinkhelper, AstNode an |
|
||||
an = sinkhelper.asExpr().(ObjectExpr).getAChild().(Property).getAChild()
|
||||
|
|
||||
pred.asExpr() = an and
|
||||
succ = sinkhelper
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from SequelizeModelConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink, source, sink, "from ==> to"
|
||||
@@ -1,22 +0,0 @@
|
||||
import javascript
|
||||
import DataFlow
|
||||
|
||||
module SequelizeModel {
|
||||
SourceNode sequelizeModelAsSourceNode(TypeTracker t) {
|
||||
t.start() and
|
||||
exists(
|
||||
DataFlow::ClassNode baseModelFirstDirectChild, DataFlow::ClassNode baseModelAllLevelSubClasses
|
||||
|
|
||||
DataFlow::moduleMember("sequelize-typescript", "Model")
|
||||
.flowsTo(baseModelFirstDirectChild.getASuperClassNode()) and
|
||||
baseModelAllLevelSubClasses = baseModelFirstDirectChild.getADirectSubClass*() and
|
||||
result = baseModelAllLevelSubClasses
|
||||
)
|
||||
or
|
||||
exists(TypeTracker t2 | result = sequelizeModelAsSourceNode(t2).track(t2, t))
|
||||
}
|
||||
|
||||
SourceNode sequelizeModelAsSourceNode() {
|
||||
result = sequelizeModelAsSourceNode(TypeTracker::end())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user