Skip to content

Commit 7c71223

Browse files
committed
Python: Port py/url-redirection to use proper source/sink customization
1 parent b4c0b1b commit 7c71223

File tree

3 files changed

+100
-24
lines changed

3 files changed

+100
-24
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import python
1616
import semmle.python.security.dataflow.UrlRedirect
1717
import DataFlow::PathGraph
1818

19-
from UrlRedirectConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
19+
from UrlRedirect::Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
2020
where config.hasFlowPath(source, sink)
2121
select sink.getNode(), source, sink, "Untrusted URL redirection due to $@.", source.getNode(),
2222
"A user-provided value"
Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,42 @@
11
/**
2-
* Provides a taint-tracking configuration for detecting URL redirection
3-
* vulnerabilities.
2+
* Provides a taint-tracking configuration for detecting "URL redirection" vulnerabilities.
3+
*
4+
* Note, for performance reasons: only import this file if
5+
* `UrlRedirect::Configuration` is needed, otherwise
6+
* `UrlRedirectCustomizations` should be imported instead.
47
*/
58

6-
import python
9+
private import python
710
import semmle.python.dataflow.new.DataFlow
811
import semmle.python.dataflow.new.TaintTracking
9-
import semmle.python.Concepts
10-
import semmle.python.dataflow.new.RemoteFlowSources
11-
import semmle.python.dataflow.new.BarrierGuards
1212

1313
/**
14-
* A taint-tracking configuration for detecting URL redirection vulnerabilities.
14+
* Provides a taint-tracking configuration for detecting "URL redirection" vulnerabilities.
1515
*/
16-
class UrlRedirectConfiguration extends TaintTracking::Configuration {
17-
UrlRedirectConfiguration() { this = "UrlRedirectConfiguration" }
16+
module UrlRedirect {
17+
import UrlRedirectCustomizations::UrlRedirect
1818

19-
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
19+
/**
20+
* A taint-tracking configuration for detecting "URL redirection" vulnerabilities.
21+
*/
22+
class Configuration extends TaintTracking::Configuration {
23+
Configuration() { this = "UrlRedirect" }
2024

21-
override predicate isSink(DataFlow::Node sink) {
22-
sink = any(HTTP::Server::HttpRedirectResponse e).getRedirectLocation()
23-
}
25+
override predicate isSource(DataFlow::Node source) { source instanceof Source }
2426

25-
override predicate isSanitizer(DataFlow::Node node) {
26-
// Url redirection is a problem only if the user controls the prefix of the URL.
27-
// TODO: This is a copy of the taint-sanitizer from the old points-to query, which doesn't
28-
// cover formatting.
29-
exists(BinaryExprNode string_concat | string_concat.getOp() instanceof Add |
30-
string_concat.getRight() = node.asCfgNode()
31-
)
32-
}
27+
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
28+
29+
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
3330

34-
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
35-
guard instanceof StringConstCompare
31+
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
32+
guard instanceof SanitizerGuard
33+
}
3634
}
3735
}
36+
37+
/**
38+
* DEPRECATED: Don't extend this class for customization, since this will lead to bad
39+
* performance, instead use the new `UrlRedirectCustomizations.qll` file, and extend
40+
* its' classes.
41+
*/
42+
deprecated class UrlRedirectConfiguration = UrlRedirect::Configuration;
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* Provides default sources, sinks and sanitizers for detecting
3+
* "URL redirection"
4+
* vulnerabilities, as well as extension points for adding your own.
5+
*/
6+
7+
private import python
8+
private import semmle.python.dataflow.new.DataFlow
9+
private import semmle.python.Concepts
10+
private import semmle.python.dataflow.new.RemoteFlowSources
11+
private import semmle.python.dataflow.new.BarrierGuards
12+
13+
/**
14+
* Provides default sources, sinks and sanitizers for detecting
15+
* "URL redirection"
16+
* vulnerabilities, as well as extension points for adding your own.
17+
*/
18+
module UrlRedirect {
19+
/**
20+
* A data flow source for "URL redirection" vulnerabilities.
21+
*/
22+
abstract class Source extends DataFlow::Node { }
23+
24+
/**
25+
* A data flow sink for "URL redirection" vulnerabilities.
26+
*/
27+
abstract class Sink extends DataFlow::Node { }
28+
29+
/**
30+
* A sanitizer for "URL redirection" vulnerabilities.
31+
*/
32+
abstract class Sanitizer extends DataFlow::Node { }
33+
34+
/**
35+
* A sanitizer guard for "URL redirection" vulnerabilities.
36+
*/
37+
abstract class SanitizerGuard extends DataFlow::BarrierGuard { }
38+
39+
/**
40+
* A source of remote user input, considered as a flow source.
41+
*/
42+
class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { }
43+
44+
/**
45+
* A HTTP redirect response, considered as a flow sink.
46+
*/
47+
class RedirectLocationAsSink extends Sink {
48+
RedirectLocationAsSink() {
49+
this = any(HTTP::Server::HttpRedirectResponse e).getRedirectLocation()
50+
}
51+
}
52+
53+
/**
54+
* The right side of a string-concat, considered as a sanitizer.
55+
*/
56+
class StringConcatAsSanitizer extends Sanitizer {
57+
StringConcatAsSanitizer() {
58+
// Url redirection is a problem only if the user controls the prefix of the URL.
59+
// TODO: This is a copy of the taint-sanitizer from the old points-to query, which doesn't
60+
// cover formatting.
61+
exists(BinaryExprNode string_concat | string_concat.getOp() instanceof Add |
62+
string_concat.getRight() = this.asCfgNode()
63+
)
64+
}
65+
}
66+
67+
/**
68+
* A comparison with a constant string, considered as a sanitizer-guard.
69+
*/
70+
class StringConstCompareAsSanitizerGuard extends SanitizerGuard, StringConstCompare { }
71+
}

0 commit comments

Comments
 (0)