Python: Add modeling of tempfile module

This commit is contained in:
Rasmus Wriedt Larsen
2021-11-29 15:06:59 +01:00
parent b68538376c
commit cbd7434a7e
3 changed files with 124 additions and 12 deletions

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* Added modeling of the `tempfile` module for creating temporary files and directories, such as the functions `tempfile.NamedTemporaryFile` and `tempfile.TemporaryDirectory`. The `suffix`, `prefix`, and `dir` arguments are all vulnerable to path-injection, and these are new sinks for the _Uncontrolled data used in path expression_ (`py/path-injection`) query.

View File

@@ -2637,6 +2637,116 @@ private module StdlibPrivate {
nodeTo.(UrllibParseUrlsplitCall).getUrl() = nodeFrom
}
}
// ---------------------------------------------------------------------------
// tempfile
// ---------------------------------------------------------------------------
/**
* A call to `tempfile.mkstemp`.
*
* See https://docs.python.org/3/library/tempfile.html#tempfile.mkstemp
*/
private class TempfileMkstempCall extends FileSystemAccess::Range, DataFlow::CallCfgNode {
TempfileMkstempCall() { this = API::moduleImport("tempfile").getMember("mkstemp").getACall() }
override DataFlow::Node getAPathArgument() {
result in [
this.getArg(0), this.getArgByName("suffix"), this.getArg(1), this.getArgByName("prefix"),
this.getArg(2), this.getArgByName("dir")
]
}
}
/**
* A call to `tempfile.NamedTemporaryFile`.
*
* See https://docs.python.org/3/library/tempfile.html#tempfile.NamedTemporaryFile
*/
private class TempfileNamedTemporaryFileCall extends FileSystemAccess::Range,
DataFlow::CallCfgNode {
TempfileNamedTemporaryFileCall() {
this = API::moduleImport("tempfile").getMember("NamedTemporaryFile").getACall()
}
override DataFlow::Node getAPathArgument() {
result in [
this.getArg(4), this.getArgByName("suffix"), this.getArg(5), this.getArgByName("prefix"),
this.getArg(6), this.getArgByName("dir")
]
}
}
/**
* A call to `tempfile.TemporaryFile`.
*
* See https://docs.python.org/3/library/tempfile.html#tempfile.TemporaryFile
*/
private class TempfileTemporaryFileCall extends FileSystemAccess::Range, DataFlow::CallCfgNode {
TempfileTemporaryFileCall() {
this = API::moduleImport("tempfile").getMember("TemporaryFile").getACall()
}
override DataFlow::Node getAPathArgument() {
result in [
this.getArg(4), this.getArgByName("suffix"), this.getArg(5), this.getArgByName("prefix"),
this.getArg(6), this.getArgByName("dir")
]
}
}
/**
* A call to `tempfile.SpooledTemporaryFile`.
*
* See https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile
*/
private class TempfileSpooledTemporaryFileCall extends FileSystemAccess::Range,
DataFlow::CallCfgNode {
TempfileSpooledTemporaryFileCall() {
this = API::moduleImport("tempfile").getMember("SpooledTemporaryFile").getACall()
}
override DataFlow::Node getAPathArgument() {
result in [
this.getArg(5), this.getArgByName("suffix"), this.getArg(6), this.getArgByName("prefix"),
this.getArg(7), this.getArgByName("dir")
]
}
}
/**
* A call to `tempfile.mkdtemp`.
*
* See https://docs.python.org/3/library/tempfile.html#tempfile.mkdtemp
*/
private class TempfileMkdtempCall extends FileSystemAccess::Range, DataFlow::CallCfgNode {
TempfileMkdtempCall() { this = API::moduleImport("tempfile").getMember("mkdtemp").getACall() }
override DataFlow::Node getAPathArgument() {
result in [
this.getArg(0), this.getArgByName("suffix"), this.getArg(1), this.getArgByName("prefix"),
this.getArg(2), this.getArgByName("dir")
]
}
}
/**
* A call to `tempfile.TemporaryDirectory`.
*
* See https://docs.python.org/3/library/tempfile.html#tempfile.TemporaryDirectory
*/
private class TempfileTemporaryDirectoryCall extends FileSystemAccess::Range,
DataFlow::CallCfgNode {
TempfileTemporaryDirectoryCall() {
this = API::moduleImport("tempfile").getMember("TemporaryDirectory").getACall()
}
override DataFlow::Node getAPathArgument() {
result in [
this.getArg(0), this.getArgByName("suffix"), this.getArg(1), this.getArgByName("prefix"),
this.getArg(2), this.getArgByName("dir")
]
}
}
}
// ---------------------------------------------------------------------------

View File

@@ -220,21 +220,21 @@ os.startfile(path="path") # $ getAPathArgument="path"
# _mkstemp_inner does `_os.path.join(dir, pre + name + suf)`
tempfile.mkstemp("suffix", "prefix", "dir") # $ MISSING: getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.mkstemp(suffix="suffix", prefix="prefix", dir="dir") # $ MISSING: getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.mkstemp("suffix", "prefix", "dir") # $ getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.mkstemp(suffix="suffix", prefix="prefix", dir="dir") # $ getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.NamedTemporaryFile('w+b', -1, None, None, "suffix", "prefix", "dir") # $ MISSING: getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.NamedTemporaryFile(suffix="suffix", prefix="prefix", dir="dir") # $ MISSING: getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.NamedTemporaryFile('w+b', -1, None, None, "suffix", "prefix", "dir") # $ getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.NamedTemporaryFile(suffix="suffix", prefix="prefix", dir="dir") # $ getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.TemporaryFile('w+b', -1, None, None, "suffix", "prefix", "dir") # $ MISSING: getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.TemporaryFile(suffix="suffix", prefix="prefix", dir="dir") # $ MISSING: getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.TemporaryFile('w+b', -1, None, None, "suffix", "prefix", "dir") # $ getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.TemporaryFile(suffix="suffix", prefix="prefix", dir="dir") # $ getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.SpooledTemporaryFile(0, 'w+b', -1, None, None, "suffix", "prefix", "dir") # $ MISSING: getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.SpooledTemporaryFile(suffix="suffix", prefix="prefix", dir="dir") # $ MISSING: getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.SpooledTemporaryFile(0, 'w+b', -1, None, None, "suffix", "prefix", "dir") # $ getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.SpooledTemporaryFile(suffix="suffix", prefix="prefix", dir="dir") # $ getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
# mkdtemp does `_os.path.join(dir, prefix + name + suffix)`
tempfile.mkdtemp("suffix", "prefix", "dir") # $ MISSING: getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.mkdtemp(suffix="suffix", prefix="prefix", dir="dir") # $ MISSING: getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.mkdtemp("suffix", "prefix", "dir") # $ getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.mkdtemp(suffix="suffix", prefix="prefix", dir="dir") # $ getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.TemporaryDirectory("suffix", "prefix", "dir") # $ MISSING: getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.TemporaryDirectory(suffix="suffix", prefix="prefix", dir="dir") # $ MISSING: getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.TemporaryDirectory("suffix", "prefix", "dir") # $ getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"
tempfile.TemporaryDirectory(suffix="suffix", prefix="prefix", dir="dir") # $ getAPathArgument="suffix" getAPathArgument="prefix" getAPathArgument="dir"