Skip to content

Commit 3e5fddd

Browse files
committed
Python: Update all remaining taint-tracking queries to use configurations.
1 parent 8443f68 commit 3e5fddd

File tree

12 files changed

+116
-33
lines changed

12 files changed

+116
-33
lines changed

python/ql/src/Security/CWE-022/PathInjection.ql

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,26 @@ import semmle.python.web.HttpRequest
2525
/* Sinks */
2626
import semmle.python.security.injection.Path
2727

28+
class PathInjectionConfiguration extends TaintTracking::Configuration {
2829

29-
from TaintedPathSource src, TaintedPathSink sink
30-
where src.flowsTo(sink)
30+
PathInjectionConfiguration() { this = "Path injection configuration" }
31+
32+
override predicate isSource(TaintTracking::Source source) { source instanceof HttpRequestTaintSource }
33+
34+
override predicate isSink(TaintTracking::Sink sink) { sink instanceof OpenNode }
35+
36+
override predicate isSanitizer(Sanitizer sanitizer) {
37+
sanitizer instanceof PathSanitizer or
38+
sanitizer instanceof NormalizedPathSanitizer
39+
}
40+
41+
override predicate isExtension(TaintTracking::Extension extension) {
42+
extension instanceof AbsPath
43+
}
44+
45+
}
46+
47+
48+
from PathInjectionConfiguration config, TaintedPathSource src, TaintedPathSink sink
49+
where config.hasFlowPath(src, sink)
3150
select sink.getSink(), src, sink, "This path depends on $@.", src.getSource(), "a user-provided value"

python/ql/src/Security/CWE-078/CommandInjection.ql

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,23 @@ import semmle.python.web.HttpRequest
2323
/* Sinks */
2424
import semmle.python.security.injection.Command
2525

26-
from TaintedPathSource src, TaintedPathSink sink
27-
where src.flowsTo(sink)
26+
class CommandInjectionConfiguration extends TaintTracking::Configuration {
27+
28+
CommandInjectionConfiguration() { this = "Command injection configuration" }
29+
30+
override predicate isSource(TaintTracking::Source source) { source instanceof HttpRequestTaintSource }
31+
32+
override predicate isSink(TaintTracking::Sink sink) {
33+
sink instanceof OsCommandFirstArgument or
34+
sink instanceof ShellCommand
35+
}
36+
37+
override predicate isExtension(TaintTracking::Extension extension) {
38+
extension instanceof FirstElementFlow
39+
}
40+
41+
}
42+
43+
from CommandInjectionConfiguration config, TaintedPathSource src, TaintedPathSink sink
44+
where config.hasFlowPath(src, sink)
2845
select sink.getSink(), src, sink, "This command depends on $@.", src.getSource(), "a user-provided value"

python/ql/src/Security/CWE-209/StackTraceExposure.ql

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ import semmle.python.security.Paths
1818
import semmle.python.security.Exceptions
1919
import semmle.python.web.HttpResponse
2020

21-
from TaintedPathSource src, TaintedPathSink sink
22-
where src.flowsTo(sink) and src.getSource() instanceof ErrorInfoSource
21+
class StackTraceExposureConfiguration extends TaintTracking::Configuration {
22+
23+
StackTraceExposureConfiguration() { this = "Stack trace exposure configuration" }
24+
25+
override predicate isSource(TaintTracking::Source source) { source instanceof ErrorInfoSource }
26+
27+
override predicate isSink(TaintTracking::Sink sink) {
28+
sink instanceof HttpResponseTaintSink
29+
}
30+
31+
}
32+
33+
from StackTraceExposureConfiguration config, TaintedPathSource src, TaintedPathSink sink
34+
where config.hasFlowPath(src, sink)
2335
select sink.getSink(), src, sink, "$@ may be exposed to an external user", src.getSource(), "Error information"

python/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,20 @@ import python
1212
import semmle.python.security.SensitiveData
1313
import semmle.python.security.Crypto
1414

15-
from SensitiveDataSource src, WeakCryptoSink sink
16-
where src.flowsToSink(sink)
15+
class BrokenCryptoConfiguration extends TaintTracking::Configuration {
16+
17+
BrokenCryptoConfiguration() { this = "Broken crypto configuration" }
18+
19+
override predicate isSource(TaintTracking::Source source) { source instanceof SensitiveDataSource }
20+
21+
override predicate isSink(TaintTracking::Sink sink) {
22+
sink instanceof WeakCryptoSink
23+
}
24+
25+
}
26+
27+
28+
from BrokenCryptoConfiguration config, SensitiveDataSource src, WeakCryptoSink sink
29+
where config.hasFlow(src, sink)
1730

1831
select sink, "Sensitive data from $@ is used in a broken or weak cryptographic algorithm.", src , src.toString()

python/ql/src/Security/CWE-601/UrlRedirect.ql

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,19 @@ class UntrustedPrefixStringKind extends UntrustedStringKind {
2828

2929
}
3030

31-
from TaintedPathSource src, TaintedPathSink sink
32-
where src.flowsTo(sink)
31+
class UrlRedirectConfiguration extends TaintTracking::Configuration {
32+
33+
UrlRedirectConfiguration() { this = "URL redirect configuration" }
34+
35+
override predicate isSource(TaintTracking::Source source) { source instanceof HttpRequestTaintSource }
36+
37+
override predicate isSink(TaintTracking::Sink sink) {
38+
sink instanceof HttpRedirectTaintSink
39+
}
40+
41+
}
42+
43+
from UrlRedirectConfiguration config, TaintedPathSource src, TaintedPathSink sink
44+
where config.hasFlowPath(src, sink)
3345
select sink.getSink(), src, sink, "Untrusted URL redirection due to $@.", src.getSource(), "a user-provided value"
3446

python/ql/src/Security/CWE-798/HardcodedCredentials.ql

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,23 @@ private string getACredentialRegex() {
140140
result = "(?i).*(cert)(?!.*(format|name)).*"
141141
}
142142

143-
from TaintSource src, TaintSink sink
143+
class HardcodedCredentialsConfiguration extends TaintTracking::Configuration {
144144

145-
where src.flowsToSink(sink) and
145+
HardcodedCredentialsConfiguration() { this = "Hardcoded coredentials configuration" }
146+
147+
override predicate isSource(TaintTracking::Source source) { source instanceof HardcodedValueSource }
148+
149+
override predicate isSink(TaintTracking::Sink sink) {
150+
sink instanceof CredentialSink
151+
}
152+
153+
}
154+
155+
156+
157+
from HardcodedCredentialsConfiguration config, TaintSource src, TaintSink sink
158+
159+
where config.hasFlow(src, sink) and
146160
not any(TestScope test).contains(src.(ControlFlowNode).getNode())
147161

148162
select sink, "Use of hardcoded credentials from $@.", src, src.toString()

python/ql/src/semmle/python/security/injection/Path.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import semmle.python.security.strings.Untrusted
66
/** Prevents taint flowing through ntpath.normpath()
77
* NormalizedPath below handles that case.
88
*/
9-
private class PathSanitizer extends Sanitizer {
9+
class PathSanitizer extends Sanitizer {
1010

1111
PathSanitizer() {
1212
this = "path.sanitizer"

python/ql/src/semmle/python/web/Http.qll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,12 @@ abstract class HttpResponseTaintSink extends TaintSink {
8181
}
8282

8383
}
84+
85+
abstract class HttpRedirectTaintSink extends TaintSink {
86+
87+
override predicate sinks(TaintKind kind) {
88+
kind instanceof ExternalStringKind
89+
}
90+
91+
}
92+

python/ql/src/semmle/python/web/django/Redirect.qll

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ import python
77
import semmle.python.security.TaintTracking
88
import semmle.python.security.strings.Basic
99
private import semmle.python.web.django.Shared
10+
private import semmle.python.web.Http
1011

1112

1213
/**
1314
* Represents an argument to the `django.redirect` function.
1415
*/
15-
class DjangoRedirect extends TaintSink {
16+
class DjangoRedirect extends HttpRedirectTaintSink {
1617

1718
override string toString() {
1819
result = "django.redirect"
@@ -25,8 +26,4 @@ class DjangoRedirect extends TaintSink {
2526
)
2627
}
2728

28-
override predicate sinks(TaintKind kind) {
29-
kind instanceof StringKind
30-
}
31-
3229
}

python/ql/src/semmle/python/web/flask/Redirect.qll

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ FunctionObject flask_redirect() {
1515
/**
1616
* Represents an argument to the `flask.redirect` function.
1717
*/
18-
class FlaskRedirect extends TaintSink {
18+
class FlaskRedirect extends HttpRedirectTaintSink {
1919

2020
override string toString() {
2121
result = "flask.redirect"
@@ -28,8 +28,4 @@ class FlaskRedirect extends TaintSink {
2828
)
2929
}
3030

31-
override predicate sinks(TaintKind kind) {
32-
kind instanceof StringKind
33-
}
34-
3531
}

0 commit comments

Comments
 (0)