Skip to content

Commit a3885cd

Browse files
committed
Replace sanitizer by exclusion from sink definition
1 parent b4cb2c3 commit a3885cd

File tree

3 files changed

+19
-16
lines changed

3 files changed

+19
-16
lines changed

python/ql/lib/semmle/python/Concepts.qll

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ module SystemCommandExecution {
116116
class FileSystemAccess extends DataFlow::Node instanceof FileSystemAccess::Range {
117117
/** Gets an argument to this file system access that is interpreted as a path. */
118118
DataFlow::Node getAPathArgument() { result = super.getAPathArgument() }
119+
120+
/**
121+
* Gets an argument to this file system access that is interpreted as a path,
122+
* but which is not vulnerable to path injection.
123+
*/
124+
DataFlow::Node getASafePathArgument() { result = super.getASafePathArgument() }
119125
}
120126

121127
/** Provides a class for modeling new file system access APIs. */
@@ -130,6 +136,12 @@ module FileSystemAccess {
130136
abstract class Range extends DataFlow::Node {
131137
/** Gets an argument to this file system access that is interpreted as a path. */
132138
abstract DataFlow::Node getAPathArgument();
139+
140+
/**
141+
* Gets an argument to this file system access that is interpreted as a path,
142+
* but which is not vulnerable to path injection.
143+
*/
144+
DataFlow::Node getASafePathArgument() { none() }
133145
}
134146
}
135147

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

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -621,24 +621,14 @@ module Flask {
621621
}
622622

623623
override DataFlow::Node getAPathArgument() {
624-
result in [
625-
this.getArg(0), this.getArgByName("directory"),
626-
// as described in the docs, the `filename` argument is restrained to be within
627-
// the provided directory, so is not exposed to path-injection. (but is still a
628-
// path-argument).
629-
this.getArg(1), this.getArgByName("filename")
630-
]
624+
result = this.getArg([0, 1]) or
625+
result = this.getArgByName(["directory", "filename"])
631626
}
632-
}
633627

634-
/**
635-
* To exclude `filename` argument to `flask.send_from_directory` as a path-injection sink.
636-
*/
637-
private class FlaskSendFromDirectoryCallFilenameSanitizer extends PathInjection::Sanitizer {
638-
FlaskSendFromDirectoryCallFilenameSanitizer() {
639-
this = any(FlaskSendFromDirectoryCall c).getArg(1)
640-
or
641-
this = any(FlaskSendFromDirectoryCall c).getArgByName("filename")
628+
override DataFlow::Node getASafePathArgument() {
629+
// as described in the docs, the `filename` argument is restrained to be within
630+
// the provided directory, so is not exposed to path-injection.
631+
result in [this.getArg(1), this.getArgByName("filename")]
642632
}
643633
}
644634

python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ module PathInjection {
5858
class FileSystemAccessAsSink extends Sink {
5959
FileSystemAccessAsSink() {
6060
this = any(FileSystemAccess e).getAPathArgument() and
61+
not this = any(FileSystemAccess e).getASafePathArgument() and
6162
// since implementation of Path.open in pathlib.py is like
6263
// ```py
6364
// def open(self, ...):

0 commit comments

Comments
 (0)