Merge branch 'main' into python-command-execution-modeling

This commit is contained in:
Rasmus Wriedt Larsen
2020-09-30 17:38:59 +02:00
18 changed files with 735 additions and 82 deletions

View File

@@ -101,7 +101,7 @@ predicate stringManipulation(DataFlow::CfgNode nodeFrom, DataFlow::CfgNode nodeT
nodeFrom.getNode() = object and
method_name in ["partition", "rpartition", "rsplit", "split", "splitlines"]
or
// List[str] -> str
// Iterable[str] -> str
// TODO: check if these should be handled differently in regards to content
method_name = "join" and
nodeFrom.getNode() = call.getArg(0)
@@ -130,7 +130,6 @@ predicate stringManipulation(DataFlow::CfgNode nodeFrom, DataFlow::CfgNode nodeT
// f-strings
nodeTo.asExpr().(Fstring).getAValue() = nodeFrom.asExpr()
// TODO: Handle encode/decode from base64/quopri
// TODO: Handle os.path.join
// TODO: Handle functions in https://docs.python.org/3/library/binascii.html
}

View File

@@ -5,9 +5,11 @@
private import python
private import experimental.dataflow.DataFlow
private import experimental.dataflow.TaintTracking
private import experimental.dataflow.RemoteFlowSources
private import experimental.semmle.python.Concepts
/** Provides models for the Python standard library. */
private module Stdlib {
// ---------------------------------------------------------------------------
// os
@@ -35,7 +37,9 @@ private module Stdlib {
"execl", "execle", "execlp", "execlpe", "execv", "execve", "execvp", "execvpe",
// spawn
"spawnl", "spawnle", "spawnlp", "spawnlpe", "spawnv", "spawnve", "spawnvp", "spawnvpe",
"posix_spawn", "posix_spawnp"] and
"posix_spawn", "posix_spawnp",
// modules
"path"] and
(
t.start() and
result = DataFlow::importMember("os", attr_name)
@@ -71,6 +75,29 @@ private module Stdlib {
result = os_attr(DataFlow::TypeTracker::end(), attr_name)
}
/** Provides models for the `os` module. */
module os {
/** Gets a reference to the `os.path` module. */
DataFlow::Node path() { result = os_attr("path") }
/** Provides models for the `os.path` module */
module path {
/** Gets a reference to the `os.path.join` function. */
private DataFlow::Node join(DataFlow::TypeTracker t) {
t.start() and
result = DataFlow::importMember("os.path", "join")
or
t.startInAttr("join") and
result = os::path()
or
exists(DataFlow::TypeTracker t2 | result = join(t2).track(t2, t))
}
/** Gets a reference to the `os.path.join` function. */
DataFlow::Node join() { result = join(DataFlow::TypeTracker::end()) }
}
}
/**
* A call to `os.system`.
* See https://docs.python.org/3/library/os.html#os.system
@@ -142,6 +169,18 @@ private module Stdlib {
}
}
/** An additional taint step for calls to `os.path.join` */
private class OsPathJoinCallAdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
exists(CallNode call |
nodeTo.asCfgNode() = call and
call.getFunction() = os::path::join().asCfgNode() and
call.getAnArg() = nodeFrom.asCfgNode()
)
// TODO: Handle pathlib (like we do for os.path.join)
}
}
// ---------------------------------------------------------------------------
// subprocess
// ---------------------------------------------------------------------------