Skip to content

Commit 722d89f

Browse files
Mark Shannonmarkshannon
authored andcommitted
Upgrade taint-tracking security queries to path-problem queries.
1 parent 24bf292 commit 722d89f

File tree

10 files changed

+87
-33
lines changed

10 files changed

+87
-33
lines changed

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* @name Uncontrolled data used in path expression
33
* @description Accessing paths influenced by users can allow an attacker to access unexpected resources.
4-
* @kind problem
4+
* @kind path-problem
55
* @problem.severity error
66
* @sub-severity high
77
* @precision high
@@ -17,6 +17,7 @@
1717
*/
1818

1919
import python
20+
import semmle.python.security.Paths
2021

2122
/* Sources */
2223
import semmle.python.web.HttpRequest
@@ -25,7 +26,8 @@ import semmle.python.web.HttpRequest
2526
import semmle.python.security.injection.Path
2627

2728

28-
from TaintSource src, TaintSink sink
29-
where src.flowsToSink(sink)
3029

31-
select sink, "This path depends on $@.", src, "a user-provided value"
30+
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
31+
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
32+
33+
select sink, srcnode, sinknode, "This path depends on $@.", src, "a user-provided value"

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @name Uncontrolled command line
33
* @description Using externally controlled strings in a command line may allow a malicious
44
* user to change the meaning of the command.
5-
* @kind problem
5+
* @kind path-problem
66
* @problem.severity error
77
* @sub-severity high
88
* @precision high
@@ -15,14 +15,15 @@
1515
*/
1616

1717
import python
18+
import semmle.python.security.Paths
1819

1920
/* Sources */
2021
import semmle.python.web.HttpRequest
2122

2223
/* Sinks */
2324
import semmle.python.security.injection.Command
2425

25-
from TaintSource src, TaintSink sink
26-
where src.flowsToSink(sink)
26+
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
27+
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
2728

28-
select sink, "This command depends on $@.", src, "a user-provided value"
29+
select sink, srcnode, sinknode, "This command depends on $@.", src, "a user-provided value"

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @name Reflected server-side cross-site scripting
33
* @description Writing user input directly to a web page
44
* allows for a cross-site scripting vulnerability.
5-
* @kind problem
5+
* @kind path-problem
66
* @problem.severity error
77
* @sub-severity high
88
* @precision high
@@ -13,6 +13,7 @@
1313
*/
1414

1515
import python
16+
import semmle.python.security.Paths
1617

1718
/* Sources */
1819
import semmle.python.web.HttpRequest
@@ -24,9 +25,9 @@ import semmle.python.web.HttpResponse
2425
/* Flow */
2526
import semmle.python.security.strings.Untrusted
2627

27-
from TaintSource src, TaintSink sink
28-
where src.flowsToSink(sink)
28+
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
29+
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
2930

30-
select sink, "Cross-site scripting vulnerability due to $@.",
31+
select sink, srcnode, sinknode, "Cross-site scripting vulnerability due to $@.",
3132
src, "user-provided value"
3233

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @name SQL query built from user-controlled sources
33
* @description Building a SQL query from user-controlled sources is vulnerable to insertion of
44
* malicious SQL code by the user.
5-
* @kind problem
5+
* @kind path-problem
66
* @problem.severity error
77
* @precision high
88
* @id py/sql-injection
@@ -12,6 +12,7 @@
1212
*/
1313

1414
import python
15+
import semmle.python.security.Paths
1516

1617
/* Sources */
1718
import semmle.python.web.HttpRequest
@@ -22,7 +23,7 @@ import semmle.python.web.django.Db
2223
import semmle.python.web.django.Model
2324

2425

25-
from TaintSource src, TaintSink sink
26-
where src.flowsToSink(sink)
26+
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
27+
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
2728

28-
select sink, "This SQL query depends on $@.", src, "a user-provided value"
29+
select sink, srcnode, sinknode, "This SQL query depends on $@.", src, "a user-provided value"

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @name Code injection
33
* @description Interpreting unsanitized user input as code allows a malicious user arbitrary
44
* code execution.
5-
* @kind problem
5+
* @kind path-problem
66
* @problem.severity error
77
* @sub-severity high
88
* @precision high
@@ -15,6 +15,7 @@
1515
*/
1616

1717
import python
18+
import semmle.python.security.Paths
1819

1920
/* Sources */
2021
import semmle.python.web.HttpRequest
@@ -23,7 +24,7 @@ import semmle.python.web.HttpRequest
2324
import semmle.python.security.injection.Exec
2425

2526

26-
from TaintSource src, TaintSink sink
27-
where src.flowsToSink(sink)
27+
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
28+
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
2829

29-
select sink, "$@ flows to here and is interpreted as code.", src, "User-provided value"
30+
select sink, srcnode, sinknode, "$@ flows to here and is interpreted as code.", src, "User-provided value"

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* @description Leaking information about an exception, such as messages and stack traces, to an
44
* external user can expose implementation details that are useful to an attacker for
55
* developing a subsequent exploit.
6-
* @kind problem
6+
* @kind path-problem
77
* @problem.severity error
88
* @precision high
99
* @id py/stack-trace-exposure
@@ -13,10 +13,11 @@
1313
*/
1414

1515
import python
16+
import semmle.python.security.Paths
1617

1718
import semmle.python.security.Exceptions
1819
import semmle.python.web.HttpResponse
1920

20-
from TaintSource src, TaintSink sink
21-
where src.flowsToSink(sink)
22-
select sink, "$@ may be exposed to an external user", src, "Error information"
21+
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
22+
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
23+
select sink, srcnode, sinknode, "$@ may be exposed to an external user", src, "Error information"

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* @name Deserializing untrusted input
33
* @description Deserializing user-controlled data may allow attackers to execute arbitrary code.
4-
* @kind problem
4+
* @kind path-problem
55
* @id py/unsafe-deserialization
66
* @problem.severity error
77
* @sub-severity high
@@ -14,6 +14,7 @@ import python
1414

1515
// Sources -- Any untrusted input
1616
import semmle.python.web.HttpRequest
17+
import semmle.python.security.Paths
1718

1819
// Flow -- untrusted string
1920
import semmle.python.security.strings.Untrusted
@@ -23,8 +24,8 @@ import semmle.python.security.injection.Pickle
2324
import semmle.python.security.injection.Marshal
2425
import semmle.python.security.injection.Yaml
2526

26-
from TaintSource src, TaintSink sink
2727

28-
where src.flowsToSink(sink)
28+
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
29+
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
2930

30-
select sink, "Deserializing of $@.", src, "untrusted input"
31+
select sink, srcnode, sinknode, "Deserializing of $@.", src, "untrusted input"

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @name URL redirection from remote source
33
* @description URL redirection based on unvalidated user input
44
* may cause redirection to malicious web sites.
5-
* @kind problem
5+
* @kind path-problem
66
* @problem.severity error
77
* @sub-severity low
88
* @id py/url-redirection
@@ -12,7 +12,7 @@
1212
*/
1313

1414
import python
15-
15+
import semmle.python.security.Paths
1616

1717
import semmle.python.web.HttpRedirect
1818
import semmle.python.web.HttpRequest
@@ -28,8 +28,8 @@ class UntrustedPrefixStringKind extends UntrustedStringKind {
2828

2929
}
3030

31-
from TaintSource src, TaintSink sink
32-
where src.flowsToSink(sink)
31+
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
32+
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
3333

34-
select sink, "Untrusted URL redirection due to $@.", src, "a user-provided value"
34+
select sink, srcnode, sinknode, "Untrusted URL redirection due to $@.", src, "a user-provided value"
3535

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,27 @@ class TaintedNode extends TTaintedNode {
675675

676676
}
677677

678+
class TaintedNodeSource extends TaintedNode {
679+
680+
TaintedNodeSource() {
681+
this.getNode().(TaintSource).isSourceOf(this.getTaintKind(), this.getContext())
682+
}
683+
684+
/** Holds if taint can flow from this source to sink `sink` */
685+
final predicate flowsTo(TaintedNodeSink sink) {
686+
this.getASuccessor*() = sink
687+
}
688+
689+
}
690+
691+
class TaintedNodeSink extends TaintedNode {
692+
693+
TaintedNodeSink() {
694+
this.getNode().(TaintSink).sinks(this.getTaintKind())
695+
}
696+
697+
}
698+
678699
/** This module contains the implementation of taint-flow.
679700
* It is recommended that users use the `TaintedNode` class, rather than using this module directly
680701
* as the interface of this module may change without warning.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import python
2+
3+
import semmle.python.security.TaintTracking
4+
5+
query predicate edges(TaintedNode fromnode, TaintedNode tonode) {
6+
fromnode.getASuccessor() = tonode
7+
}
8+
9+
private TaintedNode first_child(TaintedNode parent) {
10+
result.getContext().getCaller() = parent.getContext() and
11+
parent.getASuccessor() = result
12+
}
13+
14+
private TaintedNode next_sibling(TaintedNode child) {
15+
child.getASuccessor() = result and
16+
child.getContext() = result.getContext()
17+
}
18+
19+
query predicate parents(TaintedNode child, TaintedNode parent) {
20+
child = first_child(parent) or
21+
exists(TaintedNode prev |
22+
parents(prev, parent) and
23+
child = next_sibling(child)
24+
)
25+
}

0 commit comments

Comments
 (0)