Skip to content

Commit 2051356

Browse files
authored
Merge pull request #2459 from RasmusWL/python-modernise-TurboGears-library
Python: modernise TurboGears library
2 parents 2b0eef3 + 44cc9dd commit 2051356

File tree

6 files changed

+17
-52
lines changed

6 files changed

+17
-52
lines changed
Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
import python
22
import semmle.python.security.strings.Untrusted
3-
43
import TurboGears
54

65
private class ValidatedMethodParameter extends Parameter {
7-
86
ValidatedMethodParameter() {
97
exists(string name, TurboGearsControllerMethod method |
108
method.getArgByName(name) = this and
119
method.getValidationDict().getItem(_).(KeyValuePair).getKey().(StrConst).getText() = name
1210
)
1311
}
14-
1512
}
1613

1714
class UnvalidatedControllerMethodParameter extends TaintSource {
18-
1915
UnvalidatedControllerMethodParameter() {
2016
exists(Parameter p |
2117
any(TurboGearsControllerMethod m | not m.getName() = "onerror").getAnArg() = p and
@@ -25,9 +21,5 @@ class UnvalidatedControllerMethodParameter extends TaintSource {
2521
)
2622
}
2723

28-
override predicate isSourceOf(TaintKind kind) {
29-
kind instanceof UntrustedStringKind
30-
}
31-
24+
override predicate isSourceOf(TaintKind kind) { kind instanceof UntrustedStringKind }
3225
}
33-
Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,27 @@
11
import python
2-
32
import semmle.python.security.TaintTracking
43
import semmle.python.security.strings.Basic
54
import semmle.python.web.Http
65
import TurboGears
76

8-
9-
107
class ControllerMethodReturnValue extends HttpResponseTaintSink {
11-
128
ControllerMethodReturnValue() {
139
exists(TurboGearsControllerMethod m |
1410
m.getAReturnValueFlowNode() = this and
1511
not m.isTemplated()
1612
)
1713
}
1814

19-
override predicate sinks(TaintKind kind) {
20-
kind instanceof StringKind
21-
}
22-
15+
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
2316
}
2417

2518
class ControllerMethodTemplatedReturnValue extends HttpResponseTaintSink {
26-
2719
ControllerMethodTemplatedReturnValue() {
2820
exists(TurboGearsControllerMethod m |
2921
m.getAReturnValueFlowNode() = this and
3022
m.isTemplated()
3123
)
3224
}
3325

34-
override predicate sinks(TaintKind kind) {
35-
kind instanceof StringDictKind
36-
}
37-
26+
override predicate sinks(TaintKind kind) { kind instanceof StringDictKind }
3827
}
Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,33 @@
11
import python
2-
32
import semmle.python.security.TaintTracking
43

5-
private ClassObject theTurboGearsControllerClass() {
6-
result = ModuleObject::named("tg").attr("TGController")
7-
}
8-
9-
10-
ClassObject aTurboGearsControllerClass() {
11-
result.getASuperType() = theTurboGearsControllerClass()
12-
}
4+
private ClassValue theTurboGearsControllerClass() { result = Value::named("tg.TGController") }
135

6+
ClassValue aTurboGearsControllerClass() { result.getABaseType+() = theTurboGearsControllerClass() }
147

158
class TurboGearsControllerMethod extends Function {
16-
179
ControlFlowNode decorator;
1810

1911
TurboGearsControllerMethod() {
20-
aTurboGearsControllerClass().getPyClass() = this.getScope() and
12+
aTurboGearsControllerClass().getScope() = this.getScope() and
2113
decorator = this.getADecorator().getAFlowNode() and
2214
/* Is decorated with @expose() or @expose(path) */
2315
(
2416
decorator.(CallNode).getFunction().(NameNode).getId() = "expose"
2517
or
26-
decorator.refersTo(_, ModuleObject::named("tg").attr("expose"), _)
18+
decorator.pointsTo().getClass() = Value::named("tg.expose")
2719
)
2820
}
2921

30-
private ControlFlowNode templateName() {
31-
result = decorator.(CallNode).getArg(0)
32-
}
22+
private ControlFlowNode templateName() { result = decorator.(CallNode).getArg(0) }
3323

34-
predicate isTemplated() {
35-
exists(templateName())
36-
}
37-
38-
string getTemplateName() {
39-
exists(StringObject str |
40-
templateName().refersTo(str) and
41-
result = str.getText()
42-
)
43-
}
24+
predicate isTemplated() { exists(templateName()) }
4425

4526
Dict getValidationDict() {
46-
exists(Call call, Object dict |
27+
exists(Call call, Value dict |
4728
call = this.getADecorator() and
4829
call.getFunc().(Name).getId() = "validate" and
49-
call.getArg(0).refersTo(dict) and
50-
result = dict.getOrigin()
30+
call.getArg(0).pointsTo(dict, result)
5131
)
5232
}
53-
5433
}
55-

python/ql/test/library-tests/web/turbogears/Controller.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
| test.py:13:5:13:50 | Function ok_validated |
33
| test.py:18:5:18:57 | Function partially_validated |
44
| test.py:22:5:22:51 | Function not_validated |
5+
| test.py:26:5:26:28 | Function with_template |

python/ql/test/library-tests/web/turbogears/Sinks.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
| test.py:14 | BinaryExpr | externally controlled string |
33
| test.py:19 | BinaryExpr | externally controlled string |
44
| test.py:23 | BinaryExpr | externally controlled string |
5+
| test.py:27 | Dict | {externally controlled string} |

python/ql/test/library-tests/web/turbogears/test.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ def partially_validated(self, a=None, b=None, *args):
2121
@expose()
2222
def not_validated(self, a=None, b=None, *args):
2323
return 'Values: %s, %s, %s' % (a, b, args)
24+
25+
@expose("<template_path>")
26+
def with_template(self):
27+
return {'template_var': 'foo'}

0 commit comments

Comments
 (0)