mirror of
https://github.com/github/codeql.git
synced 2025-12-20 10:46:30 +01:00
Python: Model os.path.join and add taint-step
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
/** Gets a reference to the `os` module. */
|
||||
DataFlow::Node os(DataFlow::TypeTracker t) {
|
||||
@@ -20,6 +22,7 @@ private module Stdlib {
|
||||
/** Gets a reference to the `os` module. */
|
||||
DataFlow::Node os() { result = os(DataFlow::TypeTracker::end()) }
|
||||
|
||||
/** Provides models for the `os` module. */
|
||||
module os {
|
||||
/** Gets a reference to the `os.system` function. */
|
||||
DataFlow::Node system(DataFlow::TypeTracker t) {
|
||||
@@ -48,6 +51,41 @@ private module Stdlib {
|
||||
|
||||
/** Gets a reference to the `os.popen` function. */
|
||||
DataFlow::Node popen() { result = os::popen(DataFlow::TypeTracker::end()) }
|
||||
|
||||
/** Gets a reference to the `os.path` module. */
|
||||
private DataFlow::Node path(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
(
|
||||
result = DataFlow::importMember("os", "path")
|
||||
or
|
||||
result = DataFlow::importModule("os.path")
|
||||
)
|
||||
or
|
||||
t.startInAttr("path") and
|
||||
result = os()
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = path(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to the `os.path` module. */
|
||||
DataFlow::Node path() { result = path(DataFlow::TypeTracker::end()) }
|
||||
|
||||
/** 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.join` module. */
|
||||
DataFlow::Node join() { result = join(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,4 +111,16 @@ private module Stdlib {
|
||||
result.asCfgNode() = this.asCfgNode().(CallNode).getArg(0)
|
||||
}
|
||||
}
|
||||
|
||||
/** 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user