Skip to content

Commit aa91c26

Browse files
committed
Python: Add missing taint steps
1 parent 4521a9f commit aa91c26

File tree

1 file changed

+44
-28
lines changed

1 file changed

+44
-28
lines changed

python/ql/lib/semmle/python/frameworks/Stdlib.qll

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -243,26 +243,62 @@ private module StdlibPrivate {
243243
}
244244
}
245245

246+
// Functions with non-standard arguments:
247+
// - os.path.join(path, *paths)
248+
// - os.path.relpath(path, start=os.curdir)
249+
// Functions that need summaries:
250+
// - os.path.commonpath(paths): takes a sequence
251+
// - os.path.commonprefix(list): takes a list argument
252+
// - os.path.splitdrive: retunrs a tuple
253+
// - os.path.splittext: returns a tuple
254+
private string pathComputation() {
255+
result in [
256+
"abspath", "basename", "commonpath", "dirname", "expanduser", "expandvars", "join",
257+
"normcase", "normpath", "realpath", "relpath", "split"
258+
]
259+
}
260+
246261
/**
247-
* A call to `os.path.normpath`.
248-
* See https://docs.python.org/3/library/os.path.html#os.path.normpath
262+
* The `os.path` module offers a number of methods for computing new paths from existing paths.
263+
* These should all propagate taint.
249264
*/
250-
private class OsPathNormpathCall extends Path::PathNormalization::Range, DataFlow::CallCfgNode {
251-
OsPathNormpathCall() { this = os::path().getMember("normpath").getACall() }
265+
private class OsPathComputation extends DataFlow::CallCfgNode {
266+
string methodName;
252267

253-
DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
268+
OsPathComputation() {
269+
methodName = pathComputation() and
270+
this = os::path().getMember(methodName).getACall()
271+
}
272+
273+
DataFlow::Node getPathArg() {
274+
result in [this.getArg(0), this.getArgByName("path")]
275+
or
276+
methodName = "join" and result = this.getArg(_)
277+
or
278+
methodName = "relpath" and result in [this.getArg(1), this.getArgByName("start")]
279+
}
254280
}
255281

256-
/** An additional taint step for calls to `os.path.normpath` */
257-
private class OsPathNormpathCallAdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
282+
/** An additional taint step for path computations. */
283+
private class OsPathComputationAdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
258284
override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
259-
exists(OsPathNormpathCall call |
285+
exists(OsPathComputation call |
260286
nodeTo = call and
261287
nodeFrom = call.getPathArg()
262288
)
263289
}
264290
}
265291

292+
/**
293+
* A call to `os.path.normpath`.
294+
* See https://docs.python.org/3/library/os.path.html#os.path.normpath
295+
*/
296+
private class OsPathNormpathCall extends Path::PathNormalization::Range, DataFlow::CallCfgNode {
297+
OsPathNormpathCall() { this = os::path().getMember("normpath").getACall() }
298+
299+
DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
300+
}
301+
266302
/**
267303
* A call to `os.path.abspath`.
268304
* See https://docs.python.org/3/library/os.path.html#os.path.abspath
@@ -273,16 +309,6 @@ private module StdlibPrivate {
273309
DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
274310
}
275311

276-
/** An additional taint step for calls to `os.path.abspath` */
277-
private class OsPathAbspathCallAdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
278-
override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
279-
exists(OsPathAbspathCall call |
280-
nodeTo = call and
281-
nodeFrom = call.getPathArg()
282-
)
283-
}
284-
}
285-
286312
/**
287313
* A call to `os.path.realpath`.
288314
* See https://docs.python.org/3/library/os.path.html#os.path.realpath
@@ -293,16 +319,6 @@ private module StdlibPrivate {
293319
DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
294320
}
295321

296-
/** An additional taint step for calls to `os.path.realpath` */
297-
private class OsPathRealpathCallAdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
298-
override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
299-
exists(OsPathRealpathCall call |
300-
nodeTo = call and
301-
nodeFrom = call.getPathArg()
302-
)
303-
}
304-
}
305-
306322
/**
307323
* A call to `os.system`.
308324
* See https://docs.python.org/3/library/os.html#os.system

0 commit comments

Comments
 (0)