remove CLI sources Library file and local sources for lower FPs

This commit is contained in:
amammad
2023-10-01 05:44:13 +10:00
parent 77dcd68a86
commit e81a4fc330
4 changed files with 2 additions and 208 deletions

View File

@@ -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(_)
}
}

View File

@@ -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

View File

@@ -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"

View File

@@ -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())
}
}