mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Add shutil module path injection sinks
This commit is contained in:
@@ -2942,6 +2942,97 @@ private module StdlibPrivate {
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// shutil
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Gets a reference to the `shutil` module. */
|
||||
private API::Node shutil() { result = API::moduleImport("shutil") }
|
||||
|
||||
/**
|
||||
* A call to the `shutil.rmtree` function.
|
||||
*
|
||||
* See https://docs.python.org/3/library/shutil.html#shutil.rmtree
|
||||
*/
|
||||
private class ShutilRmtreeCall extends FileSystemAccess::Range, DataFlow::CallCfgNode {
|
||||
ShutilRmtreeCall() { this = shutil().getMember("rmtree").getACall() }
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result in [this.getArg(0), this.getArgByName("path")]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `shutil` module provides methods to copy, move files or copy file attributes.
|
||||
* See:
|
||||
* - https://docs.python.org/3/library/shutil.html#shutil.copyfile
|
||||
* - https://docs.python.org/3/library/shutil.html#shutil.copymode
|
||||
* - https://docs.python.org/3/library/shutil.html#shutil.copystat
|
||||
* - https://docs.python.org/3/library/shutil.html#shutil.copy
|
||||
* - https://docs.python.org/3/library/shutil.html#shutil.copy2
|
||||
* - https://docs.python.org/3/library/shutil.html#shutil.copytree
|
||||
* - https://docs.python.org/3/library/shutil.html#shutil.move
|
||||
*/
|
||||
private class ShutilCopyCall extends FileSystemAccess::Range, DataFlow::CallCfgNode {
|
||||
ShutilCopyCall() {
|
||||
this =
|
||||
shutil()
|
||||
.getMember([
|
||||
// these are used to copy files
|
||||
"copyfile", "copy", "copy2", "copytree",
|
||||
// these are used to move files
|
||||
"move",
|
||||
// these are used to copy some attributes of the file
|
||||
"copymode", "copystat"
|
||||
])
|
||||
.getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result in [this.getArg(0), this.getArgByName("src"), this.getArg(1), this.getArgByName("dst")]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the `shutil.copyfileobj` function.
|
||||
*
|
||||
* See https://docs.python.org/3/library/shutil.html#shutil.copyfileobj
|
||||
*/
|
||||
private class ShutilCopyfileobjCall extends FileSystemAccess::Range, DataFlow::CallCfgNode {
|
||||
ShutilCopyfileobjCall() { this = shutil().getMember("copyfileobj").getACall() }
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result in [
|
||||
this.getArg(0), this.getArgByName("fsrc"), this.getArg(1), this.getArgByName("fdst")
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the `shutil.disk_usage` function.
|
||||
*
|
||||
* See https://docs.python.org/3/library/shutil.html#shutil.disk_usage
|
||||
*/
|
||||
private class ShutilDiskUsageCall extends FileSystemAccess::Range, DataFlow::CallCfgNode {
|
||||
ShutilDiskUsageCall() { this = shutil().getMember("disk_usage").getACall() }
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result in [this.getArg(0), this.getArgByName("path")]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the `shutil.chown` function.
|
||||
*
|
||||
* See https://docs.python.org/3/library/shutil.html#shutil.chown
|
||||
*/
|
||||
private class ShutilChownCall extends FileSystemAccess::Range, DataFlow::CallCfgNode {
|
||||
ShutilChownCall() { this = shutil().getMember("chown").getACall() }
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result in [this.getArg(0), this.getArgByName("path")]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import shutil
|
||||
from flask import Flask, request
|
||||
app = Flask(__name__)
|
||||
|
||||
STATIC_DIR = "/server/static/"
|
||||
|
||||
@app.route("/shutil-path1")
|
||||
def path_injection1():
|
||||
dir = request.args.get('dir', '')
|
||||
shutil.rmtree(dir) # NOT OK
|
||||
|
||||
@app.route("/shutil-path2")
|
||||
def path_injection2():
|
||||
path1 = request.args.get('path1', '')
|
||||
path2 = request.args.get('path2', '')
|
||||
shutil.copyfile(path1, path2) # NOT OK
|
||||
|
||||
@app.route("/shutil-path3")
|
||||
def path_injection3():
|
||||
path1 = request.args.get('path1', '')
|
||||
path2 = request.args.get('path2', '')
|
||||
shutil.copy(path1, path2) # NOT OK
|
||||
|
||||
@app.route("/shutil-path4")
|
||||
def path_injection4():
|
||||
path1 = request.args.get('path1', '')
|
||||
path2 = request.args.get('path2', '')
|
||||
shutil.move(path1, path2) # NOT OK
|
||||
|
||||
@app.route("/shutil-path4")
|
||||
def path_injection5():
|
||||
path1 = request.args.get('path1', '')
|
||||
path2 = request.args.get('path2', '')
|
||||
shutil.copymode(path1, path2) # NOT OK
|
||||
Reference in New Issue
Block a user