Skip to content

Commit 61f5c2e

Browse files
authored
Merge pull request #516 from markshannon/python-path-queries
Python path queries
2 parents 472c042 + 61bd868 commit 61f5c2e

29 files changed

+300
-60
lines changed

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

Lines changed: 5 additions & 5 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,6 @@ 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)
30-
31-
select sink, "This path depends on $@.", src, "a user-provided value"
29+
from TaintedPathSource src, TaintedPathSink sink
30+
where src.flowsTo(sink)
31+
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: 5 additions & 5 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,14 @@
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)
27-
28-
select sink, "This command depends on $@.", src, "a user-provided value"
26+
from TaintedPathSource src, TaintedPathSink sink
27+
where src.flowsTo(sink)
28+
select sink.getSink(), src, sink, "This command depends on $@.", src.getSource(), "a user-provided value"

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

Lines changed: 5 additions & 7 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,6 @@ 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)
29-
30-
select sink, "Cross-site scripting vulnerability due to $@.",
31-
src, "user-provided value"
32-
28+
from TaintedPathSource src, TaintedPathSink sink
29+
where src.flowsTo(sink)
30+
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: 5 additions & 5 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,6 @@ 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)
27-
28-
select sink, "This SQL query depends on $@.", src, "a user-provided value"
26+
from TaintedPathSource src, TaintedPathSink sink
27+
where src.flowsTo(sink)
28+
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: 5 additions & 5 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,6 @@ 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)
28-
29-
select sink, "$@ flows to here and is interpreted as code.", src, "User-provided value"
27+
from TaintedPathSource src, TaintedPathSink sink
28+
where src.flowsTo(sink)
29+
select sink.getSink(), src, sink, "$@ flows to here and is interpreted as code.", src.getSource(), "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 TaintedPathSource src, TaintedPathSink sink
22+
where src.flowsTo(sink)
23+
select sink.getSink(), src, sink, "$@ may be exposed to an external user", src.getSource(), "Error information"

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

Lines changed: 5 additions & 5 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,7 @@ 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)
29-
30-
select sink, "Deserializing of $@.", src, "untrusted input"
28+
from TaintedPathSource src, TaintedPathSink sink
29+
where src.flowsTo(sink)
30+
select sink.getSink(), src, sink, "Deserializing of $@.", src.getSource(), "untrusted input"

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

Lines changed: 5 additions & 6 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,7 @@ class UntrustedPrefixStringKind extends UntrustedStringKind {
2828

2929
}
3030

31-
from TaintSource src, TaintSink sink
32-
where src.flowsToSink(sink)
33-
34-
select sink, "Untrusted URL redirection due to $@.", src, "a user-provided value"
31+
from TaintedPathSource src, TaintedPathSink sink
32+
where src.flowsTo(sink)
33+
select sink.getSink(), src, sink, "Untrusted URL redirection due to $@.", src.getSource(), "a user-provided value"
3534

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ class ExceptionInfo extends StringKind {
2424
ExceptionInfo() {
2525
this = "exception.info"
2626
}
27+
28+
override string repr() {
29+
result = "exception info"
30+
}
31+
2732
}
2833

2934

@@ -36,6 +41,10 @@ class ExceptionKind extends TaintKind {
3641
this = "exception.kind"
3742
}
3843

44+
override string repr() {
45+
result = "exception"
46+
}
47+
3948
override TaintKind getTaintOfAttribute(string name) {
4049
name = "args" and result instanceof ExceptionInfoSequence
4150
or
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)