Skip to content

Commit adf8cdc

Browse files
authored
Merge pull request #1203 from markshannon/python-taint-tracking-configuration-2
Python: Use taint tracking configuration for queries.
2 parents 3f403b8 + 52b3f77 commit adf8cdc

File tree

26 files changed

+118
-44
lines changed

26 files changed

+118
-44
lines changed

python/ql/src/Security/CWE-079/ReflectedXss.ql

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@ import semmle.python.web.HttpResponse
2525
/* Flow */
2626
import semmle.python.security.strings.Untrusted
2727

28-
from TaintedPathSource src, TaintedPathSink sink
29-
where src.flowsTo(sink)
28+
29+
class ReflectedXssConfiguration extends TaintTracking::Configuration {
30+
31+
ReflectedXssConfiguration() { this = "Reflected XSS configuration" }
32+
33+
override predicate isSource(TaintTracking::Source source) { source instanceof HttpRequestTaintSource }
34+
35+
override predicate isSink(TaintTracking::Sink sink) { sink instanceof HttpResponseTaintSink }
36+
37+
}
38+
39+
from ReflectedXssConfiguration config, TaintedPathSource src, TaintedPathSink sink
40+
where config.hasFlowPath(src, sink)
3041
select sink.getSink(), src, sink, "Cross-site scripting vulnerability due to $@.", src.getSource(), "user-provided value"

python/ql/src/Security/CWE-089/SqlInjection.ql

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,16 @@ import semmle.python.security.injection.Sql
2222
import semmle.python.web.django.Db
2323
import semmle.python.web.django.Model
2424

25+
class SQLInjectionConfiguration extends TaintTracking::Configuration {
2526

26-
from TaintedPathSource src, TaintedPathSink sink
27-
where src.flowsTo(sink)
27+
SQLInjectionConfiguration() { this = "SQL injection configuration" }
28+
29+
override predicate isSource(TaintTracking::Source source) { source instanceof HttpRequestTaintSource }
30+
31+
override predicate isSink(TaintTracking::Sink sink) { sink instanceof SqlInjectionSink }
32+
33+
}
34+
35+
from SQLInjectionConfiguration config, TaintedPathSource src, TaintedPathSink sink
36+
where config.hasFlowPath(src, sink)
2837
select sink.getSink(), src, sink, "This SQL query depends on $@.", src.getSource(), "a user-provided value"

python/ql/src/Security/CWE-094/CodeInjection.ql

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

26+
class CodeInjectionConfiguration extends TaintTracking::Configuration {
2627

27-
from TaintedPathSource src, TaintedPathSink sink
28-
where src.flowsTo(sink)
28+
CodeInjectionConfiguration() { this = "Code injection configuration" }
29+
30+
override predicate isSource(TaintTracking::Source source) { source instanceof HttpRequestTaintSource }
31+
32+
override predicate isSink(TaintTracking::Sink sink) { sink instanceof StringEvaluationNode }
33+
34+
}
35+
36+
37+
from CodeInjectionConfiguration config, TaintedPathSource src, TaintedPathSink sink
38+
where config.hasFlowPath(src, sink)
2939
select sink.getSink(), src, sink, "$@ flows to here and is interpreted as code.", src.getSource(), "User-provided value"

python/ql/src/Security/CWE-502/UnsafeDeserialization.ql

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,16 @@ import semmle.python.security.injection.Pickle
2424
import semmle.python.security.injection.Marshal
2525
import semmle.python.security.injection.Yaml
2626

27+
class UnsafeDeserializationConfiguration extends TaintTracking::Configuration {
2728

28-
from TaintedPathSource src, TaintedPathSink sink
29-
where src.flowsTo(sink)
29+
UnsafeDeserializationConfiguration() { this = "Unsafe deserialization configuration" }
30+
31+
override predicate isSource(TaintTracking::Source source) { source instanceof HttpRequestTaintSource }
32+
33+
override predicate isSink(TaintTracking::Sink sink) { sink instanceof DeserializationSink }
34+
35+
}
36+
37+
from UnsafeDeserializationConfiguration config, TaintedPathSource src, TaintedPathSink sink
38+
where config.hasFlowPath(src, sink)
3039
select sink.getSink(), src, sink, "Deserializing of $@.", src.getSource(), "untrusted input"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import python
2+
import semmle.python.security.TaintTracking
3+
4+
abstract class SqlInjectionSink extends TaintSink {}

python/ql/src/semmle/python/security/TaintTracking.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,3 +1668,4 @@ private predicate sequence_call(ControlFlowNode fromnode, CallNode tonode) {
16681668
cls.refersTo(theSetType())
16691669
)
16701670
}
1671+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
import python
3+
import semmle.python.security.TaintTracking
4+
5+
6+
/** `pickle.loads(untrusted)` vulnerability. */
7+
abstract class DeserializationSink extends TaintSink {
8+
9+
bindingset[this]
10+
DeserializationSink() {
11+
this = this
12+
}
13+
14+
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import python
99

1010
import semmle.python.security.TaintTracking
1111
import semmle.python.security.strings.Untrusted
12+
import semmle.python.security.injection.Deserialization
1213

1314

1415
private FunctionObject marshalLoads() {
@@ -18,7 +19,7 @@ private FunctionObject marshalLoads() {
1819

1920
/** A taint sink that is potentially vulnerable to malicious marshaled objects.
2021
* The `vuln` in `marshal.loads(vuln)`. */
21-
class UnmarshalingNode extends TaintSink {
22+
class UnmarshalingNode extends DeserializationSink {
2223

2324
override string toString() { result = "unmarshaling vulnerability" }
2425

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import python
99

1010
import semmle.python.security.TaintTracking
1111
import semmle.python.security.strings.Untrusted
12+
import semmle.python.security.injection.Deserialization
1213

1314

1415
private ModuleObject pickleModule() {
@@ -24,7 +25,7 @@ private FunctionObject pickleLoads() {
2425
}
2526

2627
/** `pickle.loads(untrusted)` vulnerability. */
27-
class UnpicklingNode extends TaintSink {
28+
class UnpicklingNode extends DeserializationSink {
2829

2930
override string toString() { result = "unpickling untrusted data" }
3031

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import python
99

1010
import semmle.python.security.TaintTracking
1111
import semmle.python.security.strings.Untrusted
12+
import semmle.python.security.SQL
1213

1314

1415
private StringObject first_part(ControlFlowNode command) {
@@ -48,11 +49,10 @@ abstract class DbCursor extends TaintKind {
4849

4950
}
5051

51-
5252
/** A part of a string that appears to be a SQL command and is thus
5353
* vulnerable to malicious input.
5454
*/
55-
class SimpleSqlStringInjection extends TaintSink {
55+
class SimpleSqlStringInjection extends SqlInjectionSink {
5656

5757
override string toString() { result = "simple SQL string injection" }
5858

@@ -76,7 +76,7 @@ abstract class DbConnectionSource extends TaintSource {
7676
/** A taint sink that is vulnerable to malicious SQL queries.
7777
* The `vuln` in `db.connection.execute(vuln)` and similar.
7878
*/
79-
class DbConnectionExecuteArgument extends TaintSink {
79+
class DbConnectionExecuteArgument extends SqlInjectionSink {
8080

8181
override string toString() { result = "db.connection.execute" }
8282

0 commit comments

Comments
 (0)